Iris Flip
La couleur change selon l'angle de vue : pigments interférentiels sous trois couches de vernis.
- carrosserie complète, 5 jours ouvrés
- plaque d'essai envoyée sur demande
Cinq cases de couleur en OKLCH, espacées de 72° sur le cercle des teintes, qui tournent ensemble d'un tour complet en 20 s pendant que leur luminosité ondule doucement case par case : un arc-en-ciel calculé, sans hasard ni intelligence artificielle. CSS et 1,6 Ko de JavaScript, figé si l'utilisateur réduit les animations.
Mis à jour le
Cet effet est gratuit — la catégorie Liquid en contient 31 au total, dont 6 gratuits. Effect.Labs regroupe 840 effets vanilla. Découvrir la catégorie →
La couleur change selon l'angle de vue : pigments interférentiels sous trois couches de vernis.
Mode arc-en-ciel : les cinq zones parcourent les teintes ensemble, à intervalles réguliers, un tour complet en 20 s.
Cinq verres aux teintes régulièrement espacées : regardez défiler les combinaisons, puis arrêtez-vous sur celle qui vous plaît.
Demander un devisLe bloc .ai-color-shift est une grille de cinq colonnes égales (grid-template-columns: repeat(5, 1fr), 8 px d'écart, 20 px de marge) qui remplit son cadre de 250 px de haut ; chaque .ai-color-swatch a des coins de 12 px et aucune couleur dans le CSS. C'est le script qui peint : à chaque image, il écrit dans le style.background de chaque case une couleur oklch(L% 0.2 H). La teinte de base avance de 18° par seconde (un tour en 20 s) et chaque case la décale de 72° : à tout instant, les cinq cases couvrent le cercle des couleurs à intervalles réguliers. La luminosité L ondule entre 35 et 65 % selon un sinus lent (un cycle en 17,5 s), décalé d'une case à l'autre : la vague de clarté passe d'une case à la suivante.
Le temps sert d'horloge, pas le nombre d'images : le script additionne le temps écoulé entre deux images (plafonné à 100 ms pour éviter un saut après une pause) et en déduit teinte et luminosité. Le défilement a donc la même vitesse sur un écran à 60 ou à 120 Hz, et la luminosité ne saute pas quand la teinte repasse par 0°. Les couleurs ne passent par aucune transition CSS : écrites à chaque image, elles s'affichent telles quelles, de la même façon dans Chromium, Firefox et WebKit (mesuré : 15 % des pixels changent en 500 ms dans les trois).
Pourquoi OKLCH ? Dans cet espace, la valeur L suit la clarté perçue par l'œil : un jaune et un bleu à L égal paraissent aussi clairs, ce que hsl() ne garantit pas (son jaune à 50 % paraît bien plus clair que son bleu à 50 %). Les écarts de clarté que l'on voit entre les cases viennent donc seulement de la vague voulue, pas des teintes. Avec une saturation de 0,2, certaines teintes sortent de l'espace sRGB d'un écran ordinaire : le navigateur les ramène à la couleur affichable la plus proche. Le nom du catalogue dit « AI », mais il n'y a ni modèle ni harmonie générée : une rotation calculée, cinq teintes fixes l'une par rapport à l'autre. La boucle requestAnimationFrame s'arrête quand le bloc sort de l'écran (IntersectionObserver) ou que l'onglet est masqué, et repart là où elle s'était arrêtée.
prefers-reduced-motion: reduce, le script peint les cinq cases une seule fois et ne lance pas la boucle : un arc-en-ciel fixe (teintes 0, 72, 144, 216 et 288°). Mesuré dans Chromium 151, Firefox 153 et WebKit 26 : 0 % de pixels changés en 500 ms, couleurs identiques à une seconde d'écart.CSS (grille) + 1,6 Ko de JavaScript (requestAnimationFrame, IntersectionObserver, couleurs oklch()), aucune dépendance. Mesuré dans Chromium 151, Firefox 153 et WebKit 26 : même vitesse de défilement, même image fixe sous mouvement réduit, pause hors écran vérifiée dans Chromium et Firefox. oklch() existe depuis Chrome 111, Firefox 113 et Safari 15.4.
Un navigateur qui ne connaît pas oklch() ignore la couleur écrite : les cases restent vides. Pour ces navigateurs anciens, remplacez la ligne de couleur par hsl(H, 80%, L%) : le défilement reste le même, la clarté perçue varie un peu selon la teinte. Sans JavaScript, les cases restent vides : donnez-leur une couleur de départ dans le CSS si le bloc doit rester lisible.
Copiez les trois blocs dans votre page. Aucune dépendance.
<div class="fx-0414-root">
<div class="ai-color-shift">
<div class="ai-color-swatch"></div>
<div class="ai-color-swatch"></div>
<div class="ai-color-swatch"></div>
<div class="ai-color-swatch"></div>
<div class="ai-color-swatch"></div>
</div>
</div>
.fx-0414-root,
.fx-0414-root *,
.fx-0414-root *::before,
.fx-0414-root *::after {
box-sizing: border-box
}
.fx-0414-root {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 250px;
overflow: hidden;
position: relative;
background: rgb(26, 26, 36);
color: rgb(255, 255, 255);
font-family: sans-serif;
}
.ai-color-shift {
width: 100%;
height: 100%;
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 8px;
padding: 20px;
}
.ai-color-swatch {
border-radius: 12px;
}
(function() {
// AI Color Shift : cinq teintes OKLCH espacées de 72° qui tournent ensemble
var reduce = window.matchMedia('(prefers-reduced-motion: reduce)');
document.querySelectorAll('.ai-color-shift').forEach(function(container) {
var swatches = container.querySelectorAll('.ai-color-swatch');
var elapsed = 0; // secondes d'animation écoulées
var last = 0;
var raf = 0;
var onScreen = true;
function paint() {
var hueBase = (elapsed * 18) % 360; // 18° par seconde : un tour en 20 s
swatches.forEach(function(swatch, i) {
var hue = (hueBase + i * 72) % 360;
var lightness = 50 + Math.sin(elapsed * 0.36 + i) * 15;
swatch.style.background = 'oklch(' + lightness.toFixed(1) + '% 0.2 ' + hue.toFixed(1) + ')';
});
}
function frame(now) {
elapsed += Math.min(now - last, 100) / 1000;
last = now;
paint();
raf = requestAnimationFrame(frame);
}
function update() {
// Mouvement réduit, hors écran ou onglet masqué : couleurs figées
var run = onScreen && !document.hidden && !reduce.matches;
if (run && !raf) {
last = performance.now();
raf = requestAnimationFrame(frame);
} else if (!run && raf) {
cancelAnimationFrame(raf);
raf = 0;
}
}
paint();
if ('IntersectionObserver' in window) {
new IntersectionObserver(function(entries) {
onScreen = entries[0].isIntersecting;
update();
}).observe(container);
}
document.addEventListener('visibilitychange', update);
update();
});
})();
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
Vitesse (JS — elapsed * 18) |
18° par seconde, un tour en 20 s | 9 pour un tour en 40 s, presque immobile ; 36 pour 10 s. La luminosité garde son propre rythme (elapsed * 0.36). |
Écart entre les cases (JS — i * 72) |
72°, soit 360° partagés en cinq | 30° donne une gamme de teintes voisines (un dégradé qui glisse) ; 180° fait alterner des complémentaires. Avec plus ou moins de cases, gardez 360 divisé par leur nombre. |
Vague de luminosité (JS — 50 + Math.sin(…) * 15) |
entre 35 et 65 % | * 0 donne cinq cases d'une clarté égale (L fixe à 50 %) ; * 25 une vague plus marquée. Restez entre 25 et 80 % pour garder des couleurs franches. |
Saturation (JS — 0.2 dans oklch()) |
0,2 | 0,1 donne des tons pastel, tous affichables ; au-delà de 0,25, de nombreuses teintes sortent de l'écran sRGB et le navigateur les rabote. |
Forme des cases (CSS — .ai-color-shift, .ai-color-swatch) |
grille de 5 colonnes, 8 px d'écart, coins de 12 px | Le script ne touche qu'au fond : changez la grille, les coins, ajoutez des textures en ::after. Pour 3 ou 7 cases, ajustez repeat(…) et l'écart de teinte. |
Non. Le nom vient du catalogue, mais le script ne fait qu'un calcul : une teinte de base qui avance avec le temps, cinq cases décalées de 72°, une luminosité qui suit un sinus. Pas de hasard, pas de modèle, pas d'appel réseau : deux visiteurs au même instant d'animation voient les mêmes couleurs.
La boucle s'arrête déjà d'elle-même hors écran et sous mouvement réduit, dans la fonction update(). Ajoutez une variable paused à la condition (var run = !paused && onScreen …), basculez-la au clic sur le bloc et rappelez update() : les cases gardent la dernière couleur peinte, et le défilement reprend au même point au clic suivant.
C'est voulu : une vague de luminosité (35 à 65 %) parcourt les cases, décalée de l'une à l'autre, pour donner du relief au défilement. OKLCH garantit seulement qu'à valeur égale, deux teintes paraissent aussi claires. Pour cinq cases d'une clarté identique, mettez le facteur du sinus à 0 : la luminosité reste à 50 %.