Inscriptions aux ateliers : samedi 9 h – 12 h
De 8 à 17 ans · première séance offerte
Des cartes de verre translucide de 70 × 90 px, un emoji au centre, placées en cercle par le JavaScript (l'angle se calcule, mettez autant de cartes que vous voulez) et qui tournent sans fin autour de l'axe vertical, un tour en 12 s. Leur envers reste visible à travers le verre : une galerie légère plutôt qu'un carrousel de tuiles opaques. Une simulation en CSS 3D sur un écran plat, sans casque ni WebXR. 0,6 Ko de JavaScript, immobile si l'utilisateur réduit les animations.
Mis à jour le
Cet effet est gratuit — la catégorie 3D en contient 50 au total, dont 8 gratuits. Effect.Labs regroupe 840 effets vanilla. Découvrir la catégorie →
De 8 à 17 ans · première séance offerte
Dépôts le mardi · 14 quai du Canal
Tour de la Grand-Place, puis les quais
La racine .fx-0043-root fait 250 px de haut, fond rgb(26, 26, 36), overflow: hidden. .xr-vr-gallery la remplit et porte la caméra (perspective: 600px). Au centre, .xr-vr-gallery-inner (200 × 140 px) garde ses enfants en 3D (transform-style: preserve-3d) et tourne de rotateY(0) à rotateY(360deg) en 12 s, linear, sans fin. Les .xr-vr-gcard sont toutes centrées au même endroit (left: 50%, top: 50% et marges négatives) : 70 × 90 px, coins de 8 px, dégradé indigo → violet à 30 et 20 % d'opacité, bord indigo à 30 %, flou d'arrière-plan de 4 px, emoji en 1,5 rem.
C'est le script qui forme le cercle. Pour chaque .fx-0043-root de la page, il compte les cartes et donne à la carte n° i rotateY(i / nombre × 360deg) translateZ(80px) : avec cinq cartes, un angle tous les 72°, à 80 px du centre. Ajouter ou retirer une carte dans le HTML suffit, les angles suivent. Le rayon, lui, reste fixe : jusqu'à six cartes de 70 px, elles ne se touchent pas ; à partir de sept, elles se chevauchent (la distance entre deux voisines tombe sous 70 px). Comme l'envers n'est pas masqué, les cartes de derrière restent visibles en transparence, en miroir : toute la galerie est à l'écran en même temps. Mesuré dans Chromium 151 et Firefox 153 : environ 11,7 % des pixels du bloc changent en 0,8 s, deux galeries sur une page ont chacune leurs cinq cartes placées, 0 erreur.
Le nom vient du catalogue : il n'y a pas de réalité virtuelle dans ce code. Pas de WebXR, pas de casque, pas de suivi de la tête ; c'est une galerie en CSS 3D vue sur un écran ordinaire, qui ne réagit ni à la souris ni au clavier. Le flou d'arrière-plan ne se voit que s'il y a des couleurs derrière les cartes, d'où les fonds tachetés des exemples. Le WebKit de Playwright aplatit toute 3D CSS : le rendu sur un vrai Safari n'a pas été vérifié.
prefers-reduced-motion: reduce, un bloc limité à .fx-0043-root arrête la rotation et tourne la galerie de -18deg : une vue fixe où la carte de face et ses voisines restent lisibles. Mesuré dans Chromium et Firefox : 0 animation en cours, 0 % des pixels qui changent en 0,8 s (11,7 % sans la préférence)..xr-vr-gallery:hover .xr-vr-gallery-inner { animation-play-state: paused }, ou un bouton.aria-hidden="true" sur la racine et la liste en texte à côté.CSS (transform 3D, preserve-3d, perspective, backdrop-filter) + 0,6 Ko de JavaScript qui place les cartes, aucune dépendance. Mesuré dans Chromium 151 et Firefox 153 : même galerie (0,96 % d'écart sur l'image fixe), deux galeries indépendantes, 0 erreur. Piège mesuré dans Chromium 151 : sous deux conteneurs imbriqués à coins arrondis qui coupent (overflow: hidden + border-radius), une partie des cartes floutées n'est plus dessinée ; Firefox n'est pas touché. Le WebKit de Playwright 26.5 aplatit toute 3D CSS : le vrai Safari n'a pas été vérifié. Aucun WebXR : pas de mode casque.
Sans JavaScript, les cartes restent empilées au centre et tournent ensemble comme une seule carte. Sans backdrop-filter (Chrome antérieur à 76, Firefox antérieur à 103), les cartes gardent leur verre teinté, sans flou. Si vous posez la galerie dans une carte arrondie elle-même dans un bloc arrondi, gardez un seul des deux arrondis en overflow: hidden et coupez l'autre par clip-path: inset(0 round 12px), comme le cadre des exemples de cette page, ou retirez backdrop-filter des cartes.
Copiez les trois blocs dans votre page. Aucune dépendance.
<div class="fx-0043-root">
<div class="xr-vr-gallery">
<div class="xr-vr-gallery-inner">
<div class="xr-vr-gcard">🎨</div>
<div class="xr-vr-gcard">🖼</div>
<div class="xr-vr-gcard">🎬</div>
<div class="xr-vr-gcard">🎵</div>
<div class="xr-vr-gcard">💎</div>
</div>
</div>
</div>
.fx-0043-root,
.fx-0043-root *,
.fx-0043-root *::before,
.fx-0043-root *::after {
box-sizing: border-box
}
.fx-0043-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;
}
.xr-vr-gallery {
width: 100%;
height: 100%;
perspective: 600px;
display: flex;
align-items: center;
justify-content: center;
}
.xr-vr-gallery-inner {
position: relative;
width: 200px;
height: 140px;
transform-style: preserve-3d;
animation: xrGalleryRotate 12s linear infinite;
}
.xr-vr-gcard {
position: absolute;
width: 70px;
height: 90px;
background: linear-gradient(135deg, rgba(99, 102, 241, 0.3), rgba(139, 92, 246, 0.2));
border: 1px solid rgba(99, 102, 241, 0.3);
border-radius: 8px;
left: 50%;
top: 50%;
margin-left: -35px;
margin-top: -45px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5rem;
backdrop-filter: blur(4px);
}
@keyframes xrGalleryRotate {
from {
transform: rotateY(0deg);
}
to {
transform: rotateY(360deg);
}
}
/* Mouvement réduit : la galerie s'arrête, un peu tournée pour que les cartes de côté restent lisibles. */
@media (prefers-reduced-motion: reduce) {
.fx-0043-root .xr-vr-gallery-inner { animation: none; transform: rotateY(-18deg) }
}
(function() {
// VR Card Gallery : place les cartes en cercle (angle = 360° / nombre de cartes, rayon 80 px).
// Une galerie par .fx-0043-root : plusieurs galeries peuvent vivre sur la même page.
document.querySelectorAll('.fx-0043-root').forEach(function(root) {
var gallery = root.querySelector('.xr-vr-gallery-inner');
if (!gallery) return;
var cards = gallery.querySelectorAll('.xr-vr-gcard');
var count = cards.length;
cards.forEach(function(card, i) {
var angle = (i / count) * 360;
card.style.transform = 'rotateY(' + angle + 'deg) translateZ(80px)';
});
});
})();
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
Nombre de cartes (HTML — les .xr-vr-gcard) |
5 | Ajoutez ou retirez des cartes : le script recalcule les angles. Au-delà de six, élargissez le rayon pour qu'elles ne se chevauchent pas. |
Rayon (JS — translateZ(80px)) |
80 px | Pour n cartes de 70 px sans chevauchement, il faut un rayon d'au moins 35 / sin(180° / n) : 60 px pour 5, 92 px pour 8, 114 px pour 10. Élargissez .xr-vr-gallery-inner d'autant. |
Vitesse (CSS — 12s dans l'animation de .xr-vr-gallery-inner) |
12 s par tour | 18 à 24 s pour un fond de page calme ; 8 s pour une vitrine animée. Gardez linear. |
Verre (CSS — background, border et backdrop-filter de .xr-vr-gcard) |
indigo → violet à 30 / 20 %, flou de 4 px | Plus d'opacité (50 %) rend les cartes de derrière moins visibles ; un flou de 8 px donne un verre dépoli. Le flou n'agit que sur un fond coloré ou une image. |
Perspective (CSS — perspective de .xr-vr-gallery) |
600px | 400 px rapproche la caméra : la carte de face grossit nettement, celles du fond rapetissent. 1 000 px aplatit l'anneau. |
Taille des cartes (CSS — width, height et marges de .xr-vr-gcard) |
70 × 90 px, marges −35 / −45 px | Les marges négatives valent la moitié de la taille : pour 90 × 120 px, margin-left: -45px; margin-top: -60px, et un rayon plus grand. |
Non. Le nom vient du catalogue, mais le code est une galerie en CSS 3D affichée sur un écran ordinaire : pas de WebXR, pas de casque, pas de suivi de la tête ni de la souris. Elle évoque une salle qu'on parcourt du regard ; pour une vraie scène VR, il faut une bibliothèque WebXR comme A-Frame ou Three.js.
Leur envers n'est pas masqué : à travers le verre des cartes de devant, on voit le dos des cartes de derrière, donc leur emoji inversé. C'est ce qui fait une galerie de verre. Pour ne montrer que les cartes tournées vers soi, ajoutez backface-visibility: hidden à .xr-vr-gcard.
Oui : le script traite chaque .fx-0043-root séparément et ne s'appuie sur aucun id. Mesuré avec deux galeries : chacune a ses cinq cartes en cercle et tourne de son côté.