Chargement conditionnel de Swiper (CDN UMD) sur le template event. Srcset dédié sans crop, 6 largeurs jusqu'à 3200w, toujours WebP. Première slide en eager, suivantes en lazy. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
97 lines
3.1 KiB
JavaScript
97 lines
3.1 KiB
JavaScript
import { initCharacterJump } from "./characters/jump.js";
|
|
import { initPupilTracking } from "./characters/pupilTracking.js";
|
|
import { initEventFilters } from "./filters.js";
|
|
import { initSlideshow } from "./slideshow.js";
|
|
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
const header = document.querySelector(".main-header");
|
|
const charactersWrapper = document.querySelector(".characters");
|
|
const logo = document.querySelector(".logo");
|
|
const svg = charactersWrapper.querySelector("svg");
|
|
|
|
const CHAR_SPEED = 0.6;
|
|
const LOGO_SPEED = 1.2;
|
|
const CHAR_WIDTH_MAX = 304;
|
|
const CHAR_WIDTH_MIN = 150;
|
|
|
|
// Valeurs initiales lues depuis l'attribut style HTML
|
|
const charMax = parseFloat(charactersWrapper.style.getPropertyValue("--offset"));
|
|
const logoMax = logo.offsetHeight + 100;
|
|
|
|
let menuOpen = false;
|
|
let menuTransitioning = false;
|
|
|
|
function onScroll() {
|
|
if (menuOpen || menuTransitioning) return;
|
|
const scrollY = window.scrollY;
|
|
moveCharacters(scrollY);
|
|
scaleCharacters(scrollY);
|
|
moveLogo(scrollY);
|
|
}
|
|
|
|
function moveCharacters(scrollY) {
|
|
const charOffset = Math.max(0, charMax - (scrollY / 16) * CHAR_SPEED);
|
|
charactersWrapper.style.setProperty("--offset", charOffset + "rem");
|
|
}
|
|
|
|
function scaleCharacters(scrollY) {
|
|
const charOffset = Math.max(0, charMax - (scrollY / 16) * CHAR_SPEED);
|
|
const charWidth = CHAR_WIDTH_MIN + (charOffset / charMax) * (CHAR_WIDTH_MAX - CHAR_WIDTH_MIN);
|
|
svg.setAttribute("width", charWidth + "px");
|
|
svg.setAttribute("height", charWidth + "px");
|
|
}
|
|
|
|
function moveLogo(scrollY) {
|
|
const logoOffset = Math.min(scrollY * LOGO_SPEED, logoMax);
|
|
logo.style.setProperty("--logo-offset", `-${logoOffset}px`);
|
|
}
|
|
|
|
window.addEventListener("scroll", onScroll);
|
|
|
|
{
|
|
const nav = {
|
|
toggleBtn: document.querySelector(".toggle-nav"),
|
|
strip: document.querySelector(".strip"),
|
|
};
|
|
|
|
function openMenu() {
|
|
menuOpen = true;
|
|
header.classList.add("menu-transitioning", "big");
|
|
nav.strip.classList.add("open");
|
|
nav.toggleBtn.textContent = "fermer";
|
|
document.body.style.overflow = "hidden";
|
|
}
|
|
|
|
function closeMenu() {
|
|
menuOpen = false;
|
|
menuTransitioning = true;
|
|
header.classList.remove("big");
|
|
nav.strip.classList.remove("open");
|
|
nav.toggleBtn.textContent = "menu";
|
|
document.body.style.overflow = "";
|
|
setTimeout(() => {
|
|
header.classList.remove("menu-transitioning");
|
|
menuTransitioning = false;
|
|
}, 500);
|
|
}
|
|
|
|
nav.toggleBtn.addEventListener("click", () => {
|
|
nav.strip.classList.contains("open") ? closeMenu() : openMenu();
|
|
});
|
|
|
|
document.addEventListener("keydown", (event) => {
|
|
if (event.key === "Escape" && menuOpen) closeMenu();
|
|
});
|
|
|
|
document.addEventListener("click", (event) => {
|
|
if (!menuOpen) return;
|
|
if (event.target.closest(".toggle-nav")) return;
|
|
if (!event.target.closest(".strip")) closeMenu();
|
|
});
|
|
}
|
|
|
|
initCharacterJump();
|
|
initPupilTracking(svg);
|
|
initEventFilters();
|
|
initSlideshow();
|
|
});
|