animation rendu plus responsif pour s'assurer qu'une image ne soit jamais trop grand par rapport à .gallery-animation
All checks were successful
Deploy / Deploy to Production (push) Successful in 14s

This commit is contained in:
antonin gallon 2026-02-05 16:40:40 +01:00
parent c4eb79cb79
commit c4456d587c
19 changed files with 430 additions and 21 deletions

53
test_anim/CLAUDE.md Normal file
View file

@ -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.

View file

@ -1,7 +1,7 @@
<?php
// Configuration
$mode = 'vertical'; // 'vertical' ou 'horizontal'
$set = 'LEGACY'; // 'LEGACY' ou 'OLLY'
$mode = 'horizontal'; // 'vertical' ou 'horizontal'
$set = 'OLLY'; // 'LEGACY' ou 'OLLY'
$secondsPerImage = 8; // vitesse : secondes pour défiler une image
$imagesSets = [
@ -27,14 +27,26 @@ $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],
];
// 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(

View file

@ -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 */