ldc-tregalette/resources/ts/fo/base/common.ts

238 lines
8.4 KiB
TypeScript

import { Carousel } from "bootstrap";
import Swiper from "swiper";
import { Navigation, Pagination } from "swiper/modules";
document.addEventListener("DOMContentLoaded", function () {
// * Video frames.
const videoFrameList = document.querySelectorAll(
".video-frame"
) as NodeListOf<HTMLLinkElement>;
for (const videoLink of videoFrameList) {
if (!videoLink.dataset.type) {
throw new Error("Missing dataset type");
}
if (!videoLink.dataset.frame) {
throw new Error("Missing dataset frame");
}
// @ts-ignore
window.__CN_VIDEO = window.__CN_VIDEO ?? {};
const newIframe = document.createElement("iframe");
newIframe.frameBorder = "0";
newIframe.allow = "fullscreen";
newIframe.width = "1920px";
newIframe.height = "1080px";
newIframe.setAttribute("allowfullscreen", "allowfullscreen");
// @ts-ignore
const instance = new FsLightbox();
instance.props.sources = [newIframe];
setTimeout(() => {
videoLink.addEventListener("click", (e) => {
e.preventDefault();
// * This comes fslightbox lib
// @ts-ignore
instance.open();
setTimeout(function () {
// @ts-ignore
newIframe.src = window.__CN_VIDEO[videoLink.dataset.type]
? String(videoLink.href)
: String(videoLink.dataset.frame);
}, 50);
return false;
});
}, 300);
}
// SWIPER
const swiperConfig = {
"swiper-news-index": {
modules: [Navigation],
grabCursor: true,
slidesPerView: 1,
navigation: {
nextEl: ".swiper-button-next-custom",
prevEl: ".swiper-button-prev-custom",
},
breakpoints: {
500: {
slidesPerView: 2,
},
768: {
slidesPerView: 3,
},
1200: {
slidesPerView: 4,
},
},
},
"swiper-news": {
modules: [Navigation],
grabCursor: true,
slidesPerView: 1.2,
spaceBetween: 20,
navigation: {
nextEl: ".swiper-button-next-custom",
prevEl: ".swiper-button-prev-custom",
},
breakpoints: {
576: {
slidesPerView: 1.8,
spaceBetween: 0,
},
768: {
slidesPerView: 2.2,
spaceBetween: 0,
},
1200: {
slidesPerView: 2.5,
spaceBetween: 0,
},
},
},
"swiper-product": {
modules: [Pagination],
grabCursor: true,
slidesPerView: 1,
pagination: {
el: ".swiper-product-pagination",
clickable: true,
},
},
"swiper-product-random": {
modules: [Navigation],
grabCursor: true,
slidesPerView: 1.5,
centeredSlides: true,
spaceBetween: 20,
navigation: {
nextEl: ".swiper-button-next-custom",
prevEl: ".swiper-button-prev-custom",
},
breakpoints: {
768: {
slidesPerView: 2,
}
},
},
};
type SwiperSlider = {
element: HTMLElement;
swiper: Swiper;
};
const swiperVol = document.getElementsByClassName("swiper") as HTMLCollectionOf<HTMLElement>,
sliders: SwiperSlider[] = [];
for (const htmlElt of swiperVol) {
if (!swiperConfig[htmlElt.id as keyof typeof swiperConfig]) {
throw new Error(`Undefined swiper id ${htmlElt.id}`);
}
// @ts-ignore
const swiper = new Swiper(htmlElt, swiperConfig[htmlElt.id as keyof typeof swiperConfig]);
sliders.push({
element: htmlElt,
swiper: swiper,
});
// * Modifications when slide is changing.
if (htmlElt.id === "swiper-product-random") {
changeProductLabel();
swiper.on("slideChange", function () {
setTimeout(changeProductLabel, 300);
});
}
}
// * Change product label depending on active slide.
function changeProductLabel() {
const paginatorProductLabel = document.querySelector(".swiper-product-random-label") as HTMLParagraphElement | null;
const swiperProductLabelActive = document.querySelector(".swiper-slide-active .swiper-slide-label") as HTMLParagraphElement | null;
if (paginatorProductLabel != null && swiperProductLabelActive != null) {
paginatorProductLabel.textContent = swiperProductLabelActive.textContent;
}
}
// * BR Carousel (With BS)
const couponCarousel = document.getElementById("coupons-carousel");
if (couponCarousel) {
const playPauseBtn = document.getElementById("coupons-carousel-play-btn");
const carousel = Carousel.getOrCreateInstance(couponCarousel, {
// * Start cycle on swipe (or play btn)
ride: true
});
let isRunning = false;
if (playPauseBtn) {
const updatePlayBtnStatus = () => {
// * Toggle once
if (!isRunning) {
playPauseBtn.children.item(0)?.classList.remove("d-none");
playPauseBtn.children.item(1)?.classList.add("d-none");
} else {
playPauseBtn.children.item(0)?.classList.add("d-none");
playPauseBtn.children.item(1)?.classList.remove("d-none");
}
};
playPauseBtn.addEventListener("click", () => {
if (isRunning) {
carousel.pause(true);
} else {
carousel.cycle();
}
isRunning = !isRunning;
updatePlayBtnStatus();
});
couponCarousel.addEventListener("slide.bs.carousel", () => {
isRunning = true;
updatePlayBtnStatus();
});
}
}
// * Seaguls scroll animation
const seagullsScroll = document.getElementById("seagulls-scroll");
const seagullContainer = seagullsScroll?.parentElement;
if (seagullsScroll && seagullContainer) {
const seagullsOffset = Number.parseInt(String(seagullsScroll.dataset.offset ?? 16));
const seagullsHeight = seagullsScroll.getBoundingClientRect().height;
const animateSeagull = function () {
const seagullContainerHeight = seagullContainer.getBoundingClientRect().height;
const seagullContainerScrollTop = seagullContainer.getBoundingClientRect().top + seagullContainerHeight;
const percent = (100 - ((seagullContainerScrollTop * 100 / seagullContainerHeight) * 100 / 200));
// Animate only if visible
if (percent > 0 && percent < 100) {
seagullsScroll.style.top = `${(seagullContainerHeight - seagullsHeight) * (percent / 100) + seagullsOffset}px`;
}
requestAnimationFrame(animateSeagull);
};
animateSeagull();
}
// * Keyboard navigation for news slider
const newsSlider = document.getElementById("swiper-news");
if (newsSlider) {
const navigationArrows = newsSlider?.getElementsByClassName("swiper-button") as HTMLCollectionOf<HTMLElement>;
for (const navigationArrow of navigationArrows) {
navigationArrow.addEventListener("keydown", (e: KeyboardEvent) => {
if (e.code === "Space") {
e.preventDefault();
e.stopPropagation();
navigationArrow.click();
}
});
}
}
const arrows = document.querySelectorAll(".arrow-scroll-animate") as NodeListOf<HTMLDivElement>;
if (arrows) {
window.onscroll = function() {
if (window.scrollY >= 300) {
arrows.forEach(arrow => {
arrow.classList.add("arrow-scroll-animate-active");
});
}
};
}
});