event : slide-insert avec parallax, effet créatif Swiper et animation d'entrée du titre

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-06-10 13:59:35 +02:00
parent b6653ee631
commit 54feaa46ed
5 changed files with 103 additions and 37 deletions

View file

@ -1,5 +1,8 @@
body,
html {
html,
dl,
dt,
dd {
margin: 0;
padding: 0;
}

View file

@ -9,32 +9,43 @@
.slideshow {
position: relative;
width: 100%;
height: calc(100vh - 9.8rem);
background-color: #000;
height: calc(100vh - var(--slideshow-top));
z-index: 1;
background-color: #000;
.swiper {
height: 100%;
.swiper-slide {
position: relative;
background-color: #000;
display: flex;
align-items: center;
justify-content: center;
.slide-insert {
position: absolute;
max-width: 35vw;
max-width: 70vh;
border-radius: var(--radius);
border: var(--border);
background-color: #000;
color: #fff;
// border: var(--border);
// background-color: #000;
color: var(--color-beige);
padding: 1rem;
z-index: 2;
box-shadow: var(--color-green) 0px 0px 30px;
// box-shadow: var(--glow-green);
text-align: center;
h1 {
font-size: 5vw;
font-size: 10vh;
line-height: 100%;
}
dl {
dt {
font-size: 4vh;
}
dd {
font-size: 7vh;
}
}
}

View file

@ -14,28 +14,77 @@ function rand(arr) {
}
export function initSlideshow() {
const slideshowElement = document.querySelector(".swiper");
if (!slideshowElement) return;
const slideshowEl = document.querySelector(".slideshow");
if (!slideshowEl) return;
const rem = parseFloat(getComputedStyle(document.documentElement).fontSize);
const offsetMax = 9.8 * rem;
slideshowEl.style.setProperty("--slideshow-top", offsetMax + "px");
window.addEventListener("scroll", () => {
const offset = offsetMax + window.scrollY;
slideshowEl.style.setProperty("--slideshow-top", offset + "px");
});
let pendingDir = null;
const INSERT_EASE = "cubic-bezier(0.25, 0.95, 0.02, 1)";
new Swiper(".swiper", {
effect: "creative",
speed: 500,
speed: 900,
parallax: true,
keyboard: { enabled: true },
creativeEffect: {
limitProgress: 1,
prev: {
translate: [0, 0, 0],
},
next: {
translate: ["100%", 0, 0],
},
prev: { translate: [0, 0, 0] },
next: { translate: ["100%", 0, 0] },
},
on: {
beforeTransitionStart(swiper) {
const goingForward = swiper.activeIndex > swiper.previousIndex;
swiper.params.creativeEffect.next.translate = rand(
goingForward ? enterDirs : exitDirs
init(swiper) {
const firstInner = swiper.slides[0]?.querySelector(
".slide-insert-inner"
);
if (!firstInner) return;
firstInner.style.transform = "translateX(-100vw)";
setTimeout(() => {
firstInner.style.transition =
"transform 1200ms cubic-bezier(0.16, 1, 0.3, 1)";
firstInner.style.transform = "translateX(0px)";
}, 500);
setTimeout(() => {
firstInner.style.transition = "";
firstInner.style.transform = "";
}, 1800);
},
keyPress(_swiper, key) {
if (key === "ArrowRight") pendingDir = rand(enterDirs);
else if (key === "ArrowLeft") pendingDir = rand(exitDirs);
},
beforeTransitionStart(swiper) {
swiper.slides.forEach((slide) => {
slide.style.transitionTimingFunction =
"cubic-bezier(0.34, 1.15, 0.64, 1)";
const insert = slide.querySelector(".slide-insert");
if (insert) {
setTimeout(() => {
insert.style.transitionTimingFunction = INSERT_EASE;
insert.style.transitionDuration = "2500ms";
insert.style.transitionDelay = "200ms";
}, 0);
}
});
if (pendingDir) {
swiper.params.creativeEffect.next.translate = pendingDir;
pendingDir = null;
} else {
const goingForward = swiper.activeIndex > swiper.previousIndex;
swiper.params.creativeEffect.next.translate = rand(
goingForward ? enterDirs : exitDirs
);
}
},
},
});

View file

@ -1,10 +1,14 @@
<?php
return function ($page) {
$cartouches = [$page->title()->value()];
$cartouches = [['type' => 'title', 'text' => $page->title()->value()]];
foreach ($page->mainCredits()->toStructure() as $credit) {
$cartouches[] = $credit->label() . ' : ' . $credit->value();
$cartouches[] = [
'type' => 'credit',
'label' => (string) $credit->label(),
'value' => (string) $credit->value(),
];
}
return compact('cartouches');

View file

@ -3,13 +3,6 @@
<?php $galleryImages = $page->gallery()->toFiles() ?>
<?php
$cartouches = [$page->title()->value()];
foreach ($page->mainCredits()->toStructure() as $credit) {
$cartouches[] = $credit->label() . ' : ' . $credit->value();
}
?>
<?php if ($galleryImages->count()): ?>
<div class="slideshow">
<div class="swiper">
@ -25,12 +18,18 @@ foreach ($page->mainCredits()->toStructure() as $credit) {
'lazy' => $index > 0,
]) ?>
<?php if (isset($cartouches[$index])): ?>
<?php
$top = rand(15, 70);
$left = rand(5, 40);
?>
<div class="slide-insert" style="top: <?= $top ?>%; left: <?= $left ?>%">
<h<?= e($index === 0, '1', '2') ?>><?= $cartouches[$index] ?></h<?= e($index === 0, '1', '2') ?>>
<?php $c = $cartouches[$index] ?>
<div class="slide-insert" data-swiper-parallax="-50%" style="top: <?= rand(15, 70) ?>%; left: <?= rand(2, 30) ?>%">
<div class="slide-insert-inner">
<?php if ($c['type'] === 'title'): ?>
<h1><?= $c['text'] ?></h1>
<?php else: ?>
<dl>
<dt><?= $c['label'] ?></dt>
<dd><?= $c['value'] ?></dd>
</dl>
<?php endif ?>
</div>
</div>
<?php endif ?>
</div>