diff --git a/test_anim/CLAUDE.md b/test_anim/CLAUDE.md new file mode 100644 index 0000000..d705010 --- /dev/null +++ b/test_anim/CLAUDE.md @@ -0,0 +1,53 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +This is a **prototype for an animated image gallery component** intended for integration into a Kirby CMS project. The animation displays images in a continuous scrolling pattern across multiple columns/rows. + +## Running the Project + +This is a PHP project with no build system. To run locally: +```bash +php -S localhost:8000 +``` +Then open `http://localhost:8000` in a browser. + +## Architecture + +### Configuration (index.php:1-28) + +The animation is configured via PHP variables at the top of `index.php`: +- `$mode`: `'vertical'` or `'horizontal'` - scroll direction +- `$set`: Image set name (e.g., `'LEGACY'`, `'OLLY'`) +- `$secondsPerImage`: Controls animation speed +- `$imagesSets`: Associative array defining image paths per set + +### Animation System + +**CSS-based infinite scroll** using duplicated images: +- Images are rendered twice in each track (`index.php:63-68`) to create seamless looping +- Animation translates from 0 to -50% (or vice versa), jumping back invisibly when the duplicate starts +- Odd columns scroll down/right; even columns scroll up/left +- Column offsets and delays are calculated based on image count to stagger the animation + +**Key CSS classes** (BEM notation): +- `.gallery-animation--vertical` / `.gallery-animation--horizontal`: Mode modifiers +- `.gallery-animation__wrapper`: Flex container for columns +- `.gallery-animation__column`: Individual scrolling lane +- `.gallery-animation__track`: Animated element containing images +- `.gallery-animation__image`: Individual image styling + +**CSS custom properties**: +- `--animation-duration`: Total cycle duration (set via PHP) +- `--gap`: Spacing between columns/rows +- `--vertical-wrapper-width`: Container width in vertical mode + +### Accessibility + +Respects `prefers-reduced-motion` by disabling animations (`style.css:149-153`). + +## Language + +Code comments and documentation are in French. diff --git a/test_anim/index.php b/test_anim/index.php index e1cdf79..5628dd1 100644 --- a/test_anim/index.php +++ b/test_anim/index.php @@ -1,7 +1,7 @@ 0, 'delay' => 0], - ['offset' => (int)($count / 3), 'delay' => $duration / 4], - ['offset' => 0, 'delay' => $duration / 2], -]; +// Décalage par colonne/rangée basé sur le nombre d'images +// Colonnes/rangées impaires vont dans la même direction +// Colonnes/rangées paires vont dans l'autre direction +if ($mode === 'horizontal') { + // 5 rangées pour le mode horizontal + $columns = [ + ['offset' => 0, 'delay' => 0], + ['offset' => (int)($count / 5), 'delay' => $duration / 5], + ['offset' => (int)(2 * $count / 5),'delay' => 2 * $duration / 5], + ['offset' => (int)($count / 5), 'delay' => 3 * $duration / 5], + ['offset' => 0, 'delay' => 4 * $duration / 5], + ]; +} else { + // 3 colonnes pour le mode vertical + $columns = [ + ['offset' => 0, 'delay' => 0], + ['offset' => (int)($count / 3), 'delay' => $duration / 4], + ['offset' => 0, 'delay' => $duration / 2], + ]; +} function getShiftedImages($images, $offset) { return array_merge( diff --git a/test_anim/style.css b/test_anim/style.css index 0cf45b6..fc6ecdd 100644 --- a/test_anim/style.css +++ b/test_anim/style.css @@ -3,13 +3,16 @@ body { min-height: 100vh; } .gallery-animation { - --gap: 40px; + --gap: 20px; + --half-gap: calc(var(--gap) / 2); --vertical-wrapper-width: 900px; - --shadow-diffusion: 10px; + --shadow-diffusion: 5px; + --gallery-animation-width: 40vw; + --max-portion : 0.7; position: fixed; top: 0; left: 0; - width: 40vw; + width: var(--gallery-animation-width); height: 100vh; overflow: hidden; } @@ -21,6 +24,7 @@ body { width: 100%; height: 100%; display: flex; + background-color: green; } .gallery-animation__track { @@ -49,7 +53,7 @@ body { } .gallery-animation--vertical .gallery-animation__column { - width: 100%; + width: min(100%, calc(var(--gallery-animation-width) * var(--max-portion))); display: flex; flex-direction: column; align-items: stretch; @@ -60,14 +64,15 @@ body { flex-direction: column; align-items: stretch; width: 100%; - padding-inline: calc(var(--gap) / 2); + padding-inline: var(--half-gap); } .gallery-animation--vertical .gallery-animation__image { width: 100%; height: auto; + /* height: calc(100vh * var(--max-portion)); */ /* */ object-fit: contain; - margin-block: calc(var(--gap) / 2); + margin-block: var(--half-gap); } /* Animations verticales */ @@ -96,11 +101,13 @@ body { .gallery-animation--horizontal .gallery-animation__wrapper { flex-direction: column; - padding: var(--gap) 0; + padding: var(--half-gap) 0; + height: auto; } .gallery-animation--horizontal .gallery-animation__column { - flex: 1; + --gallery-animation__wrapper-inner-height: calc(100vh - var(--half-gap) * 2) ; + height: clamp(calc(var(--gallery-animation__wrapper-inner-height) / 5), calc(var(--gallery-animation-width) / 2), calc(var(--gallery-animation__wrapper-inner-height) / 3)); display: flex; flex-direction: row; align-items: stretch; @@ -111,14 +118,14 @@ body { flex-direction: row; align-items: stretch; height: 100%; - padding-block: calc(var(--gap) / 2); + padding-block: var(--half-gap); } .gallery-animation--horizontal .gallery-animation__image { - height: 100%; + height: 100%; width: auto; object-fit: contain; - margin-inline: calc(var(--gap) / 2); + margin-inline: var(--half-gap); } /* Animations horizontales */ diff --git a/test_anim__archive1/CLAUDE.md b/test_anim__archive1/CLAUDE.md new file mode 100644 index 0000000..d705010 --- /dev/null +++ b/test_anim__archive1/CLAUDE.md @@ -0,0 +1,53 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +This is a **prototype for an animated image gallery component** intended for integration into a Kirby CMS project. The animation displays images in a continuous scrolling pattern across multiple columns/rows. + +## Running the Project + +This is a PHP project with no build system. To run locally: +```bash +php -S localhost:8000 +``` +Then open `http://localhost:8000` in a browser. + +## Architecture + +### Configuration (index.php:1-28) + +The animation is configured via PHP variables at the top of `index.php`: +- `$mode`: `'vertical'` or `'horizontal'` - scroll direction +- `$set`: Image set name (e.g., `'LEGACY'`, `'OLLY'`) +- `$secondsPerImage`: Controls animation speed +- `$imagesSets`: Associative array defining image paths per set + +### Animation System + +**CSS-based infinite scroll** using duplicated images: +- Images are rendered twice in each track (`index.php:63-68`) to create seamless looping +- Animation translates from 0 to -50% (or vice versa), jumping back invisibly when the duplicate starts +- Odd columns scroll down/right; even columns scroll up/left +- Column offsets and delays are calculated based on image count to stagger the animation + +**Key CSS classes** (BEM notation): +- `.gallery-animation--vertical` / `.gallery-animation--horizontal`: Mode modifiers +- `.gallery-animation__wrapper`: Flex container for columns +- `.gallery-animation__column`: Individual scrolling lane +- `.gallery-animation__track`: Animated element containing images +- `.gallery-animation__image`: Individual image styling + +**CSS custom properties**: +- `--animation-duration`: Total cycle duration (set via PHP) +- `--gap`: Spacing between columns/rows +- `--vertical-wrapper-width`: Container width in vertical mode + +### Accessibility + +Respects `prefers-reduced-motion` by disabling animations (`style.css:149-153`). + +## Language + +Code comments and documentation are in French. diff --git a/test_anim__archive1/NOTES.md b/test_anim__archive1/NOTES.md new file mode 100644 index 0000000..39807c4 --- /dev/null +++ b/test_anim__archive1/NOTES.md @@ -0,0 +1,50 @@ +# Animation Galerie d'Images + +## Fichiers + +- `style.css` : CSS de l'animation (à intégrer dans le projet Kirby) +- `index.html` : Page de test +- `images/` : Images de test + +## Usage + +```html + +``` + +### Variables CSS + +```css +.gallery-animation { + --animation-duration: 30s; /* Durée de l'animation */ + --gap: 1rem; /* Espacement entre colonnes/rangées */ +} +``` + +### Structure HTML + +**Mode vertical** (3 colonnes) : +```html + +``` + +**Mode horizontal** (3 rangées) : remplacer `--vertical` par `--horizontal` et `__column` par `__row`. + +## Comportement + +- Colonnes impaires : défilent vers le bas / droite +- Colonnes paires : défilent vers le haut / gauche +- Images dupliquées dans le HTML pour transition fluide +- Décalage automatique entre colonnes/rangées via `animation-delay` diff --git a/test_anim__archive1/images/LEGACY/apples-averywhere.png b/test_anim__archive1/images/LEGACY/apples-averywhere.png new file mode 100644 index 0000000..8739857 Binary files /dev/null and b/test_anim__archive1/images/LEGACY/apples-averywhere.png differ diff --git a/test_anim__archive1/images/LEGACY/legacy-menu-pause.png b/test_anim__archive1/images/LEGACY/legacy-menu-pause.png new file mode 100644 index 0000000..7f70a11 Binary files /dev/null and b/test_anim__archive1/images/LEGACY/legacy-menu-pause.png differ diff --git a/test_anim__archive1/images/LEGACY/legacy-screen-6.png b/test_anim__archive1/images/LEGACY/legacy-screen-6.png new file mode 100644 index 0000000..a2db396 Binary files /dev/null and b/test_anim__archive1/images/LEGACY/legacy-screen-6.png differ diff --git a/test_anim__archive1/images/LEGACY/legacy-screen-7.png b/test_anim__archive1/images/LEGACY/legacy-screen-7.png new file mode 100644 index 0000000..a58506a Binary files /dev/null and b/test_anim__archive1/images/LEGACY/legacy-screen-7.png differ diff --git a/test_anim__archive1/images/LEGACY/run-and-eat-to-survive.png b/test_anim__archive1/images/LEGACY/run-and-eat-to-survive.png new file mode 100644 index 0000000..4f6c0c7 Binary files /dev/null and b/test_anim__archive1/images/LEGACY/run-and-eat-to-survive.png differ diff --git a/test_anim__archive1/images/LEGACY/you-won_t-live-forever.png b/test_anim__archive1/images/LEGACY/you-won_t-live-forever.png new file mode 100644 index 0000000..cbfd4f9 Binary files /dev/null and b/test_anim__archive1/images/LEGACY/you-won_t-live-forever.png differ diff --git a/test_anim__archive1/images/OLLY/lesson_contentblock01.png b/test_anim__archive1/images/OLLY/lesson_contentblock01.png new file mode 100644 index 0000000..0f5865d Binary files /dev/null and b/test_anim__archive1/images/OLLY/lesson_contentblock01.png differ diff --git a/test_anim__archive1/images/OLLY/lesson_contentblock04.png b/test_anim__archive1/images/OLLY/lesson_contentblock04.png new file mode 100644 index 0000000..acf132c Binary files /dev/null and b/test_anim__archive1/images/OLLY/lesson_contentblock04.png differ diff --git a/test_anim__archive1/images/OLLY/lesson_contentblock05.png b/test_anim__archive1/images/OLLY/lesson_contentblock05.png new file mode 100644 index 0000000..2cd70f8 Binary files /dev/null and b/test_anim__archive1/images/OLLY/lesson_contentblock05.png differ diff --git a/test_anim__archive1/images/OLLY/lesson_cover01.png b/test_anim__archive1/images/OLLY/lesson_cover01.png new file mode 100644 index 0000000..301a42f Binary files /dev/null and b/test_anim__archive1/images/OLLY/lesson_cover01.png differ diff --git a/test_anim__archive1/images/OLLY/quiz_choosemode.png b/test_anim__archive1/images/OLLY/quiz_choosemode.png new file mode 100644 index 0000000..478d0ed Binary files /dev/null and b/test_anim__archive1/images/OLLY/quiz_choosemode.png differ diff --git a/test_anim__archive1/images/OLLY/quiz_quadmode.png b/test_anim__archive1/images/OLLY/quiz_quadmode.png new file mode 100644 index 0000000..a02327f Binary files /dev/null and b/test_anim__archive1/images/OLLY/quiz_quadmode.png differ diff --git a/test_anim__archive1/index.php b/test_anim__archive1/index.php new file mode 100644 index 0000000..8ef5840 --- /dev/null +++ b/test_anim__archive1/index.php @@ -0,0 +1,76 @@ + [ + 'images/LEGACY/apples-averywhere.png', + 'images/LEGACY/legacy-menu-pause.png', + 'images/LEGACY/legacy-screen-6.png', + 'images/LEGACY/legacy-screen-7.png', + 'images/LEGACY/run-and-eat-to-survive.png', + 'images/LEGACY/you-won_t-live-forever.png', + ], + 'OLLY' => [ + 'images/OLLY/lesson_contentblock01.png', + 'images/OLLY/lesson_contentblock04.png', + 'images/OLLY/lesson_contentblock05.png', + 'images/OLLY/lesson_cover01.png', + 'images/OLLY/quiz_choosemode.png', + 'images/OLLY/quiz_quadmode.png', + ], +]; + +$images = $imagesSets[$set]; +$count = count($images); +$duration = $count * $secondsPerImage; // durée calculée selon le nombre d'images + +// Décalage par colonne basé sur le nombre d'images +// Colonnes 1 et 3 vont dans la même direction, donc décalées de 1/2 +// Colonne 2 va dans l'autre direction, décalée de 1/4 +$columns = [ + ['offset' => 0, 'delay' => 0], + ['offset' => (int)($count / 3), 'delay' => $duration / 4], + ['offset' => 0, 'delay' => $duration / 2], +]; + +function getShiftedImages($images, $offset) { + return array_merge( + array_slice($images, $offset), + array_slice($images, 0, $offset) + ); +} +?> + + + + + + Test Animation Galerie + + + + + + + + diff --git a/test_anim__archive1/style.css b/test_anim__archive1/style.css new file mode 100644 index 0000000..fe48b32 --- /dev/null +++ b/test_anim__archive1/style.css @@ -0,0 +1,158 @@ +* { margin: 0; padding: 0; box-sizing: border-box; } +body { + min-height: 100vh; +} +.gallery-animation { + --gap: 20px; + --vertical-wrapper-width: 900px; + --shadow-diffusion: 5px; + --gallery-animation-width: 40vw; + --max-portion : 0.7; + position: fixed; + top: 0; + left: 0; + width: var(--gallery-animation-width); + height: 100vh; + overflow: hidden; +} + +.gallery-animation__wrapper { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex; + background-color: green; +} + +.gallery-animation__track { + display: flex; + animation-timing-function: linear; + animation-iteration-count: infinite; +} + +.gallery-animation__image { + object-fit: cover; + flex-shrink: 0; + filter: drop-shadow(0px 0px var(--shadow-diffusion) rgb(0, 0, 0)); +} + +/* ========================================================================== + MODE VERTICAL + ========================================================================== */ + +.gallery-animation--vertical .gallery-animation__wrapper{ + width: var(--vertical-wrapper-width); + flex-direction: row; + justify-content: center; + padding: 0 var(--gap); + left: 50%; + transform: translateX(-50%); +} + +.gallery-animation--vertical .gallery-animation__column { + width: min(100%, calc(var(--gallery-animation-width) * var(--max-portion))); + display: flex; + flex-direction: column; + align-items: stretch; + overflow: hidden; +} + +.gallery-animation--vertical .gallery-animation__track { + flex-direction: column; + align-items: stretch; + width: 100%; + padding-inline: calc(var(--gap) / 2); +} + +.gallery-animation--vertical .gallery-animation__image { + width: 100%; + height: auto; + /* height: calc(100vh * var(--max-portion)); */ /* */ + object-fit: contain; + margin-block: calc(var(--gap) / 2); +} + +/* Animations verticales */ +.gallery-animation--vertical .gallery-animation__column:nth-child(odd) .gallery-animation__track { + animation: scrollDown var(--animation-duration) linear infinite; +} + +.gallery-animation--vertical .gallery-animation__column:nth-child(even) .gallery-animation__track { + animation: scrollUp var(--animation-duration) linear infinite; +} + + +@keyframes scrollDown { + from { transform: translateY(0); } + to { transform: translateY(-50%); } +} + +@keyframes scrollUp { + from { transform: translateY(-50%); } + to { transform: translateY(0); } +} + +/* ========================================================================== + MODE HORIZONTAL + ========================================================================== */ + +.gallery-animation--horizontal .gallery-animation__wrapper { + flex-direction: column; + padding: var(--gap) 0; +} + +.gallery-animation--horizontal .gallery-animation__column { + flex: 1; + display: flex; + flex-direction: row; + align-items: stretch; + overflow: hidden; +} + +.gallery-animation--horizontal .gallery-animation__track { + flex-direction: row; + align-items: stretch; + height: 100%; + padding-block: calc(var(--gap) / 2); +} + +.gallery-animation--horizontal .gallery-animation__image { + height: 100%; + width: auto; + /* width: calc(var(--gallery-animation-width) * var(--max-portion)); */ + /* width: min(100%, calc(var(--gallery-animation-width) * var(--max-portion))); */ + object-fit: contain; + margin-inline: calc(var(--gap) / 2); +} + +/* Animations horizontales */ +.gallery-animation--horizontal .gallery-animation__column:nth-child(odd) .gallery-animation__track { + animation: scrollRight var(--animation-duration) linear infinite; +} + +.gallery-animation--horizontal .gallery-animation__column:nth-child(even) .gallery-animation__track { + animation: scrollLeft var(--animation-duration) linear infinite; +} + + +@keyframes scrollRight { + from { transform: translateX(-50%); } + to { transform: translateX(0); } +} + +@keyframes scrollLeft { + from { transform: translateX(0); } + to { transform: translateX(-50%); } +} + +/* ========================================================================== + REDUCED MOTION + ========================================================================== */ + +@media (prefers-reduced-motion: reduce) { + .gallery-animation__track { + animation: none !important; + } +}