Communitygithub.com

Scroll Zoom Reveal

Effets cinématiques pour sites web : dévoilement par zoom arrière avec scène épinglée et galerie à fondu enchaîné, ainsi qu'un champ de pixels OLED interactif au curseur.

Qu'est-ce que Scroll Zoom Reveal ?

Cette compétence fournit un effet de défilement sophistiqué, sans dépendance, pour créer des pages d'accueil, des fiches produits ou des portfolios au style Apple. Le composant principal `ZoomReveal` épingle une scène plein écran (image, vidéo ou canvas) pendant que l'utilisateur défile, puis effectue un zoom arrière pour révéler que la scène est en réalité affichée dans une maquette d'ordinateur portable (ou de moniteur). Une légende s'affiche ensuite par fondu, suivie d'une galerie à onglets avec fondu enchaîné et curseur coulissant. Un composant optionnel `OledField` génère un fond de grille de sous-pixels RVB réactif au curseur : le déplacement de la souris laisse une traînée lumineuse et changeante, et un clic produit une ondulation. L'effet fonctionne avec tout framework (React, Next.js, Vue, Astro) grâce à une API manuelle en JS, et utilise WebGL1 avec une simulation fluide CPU pour le champ OLED. L'utilisateur doit copier les fichiers prêts à l'emploi (`assets/`), structurer son balisage exactement comme dans `demo.html`, remplacer les médias et textes de démonstration par son propre contenu, et peut configurer de nombreuses options via un attribut JSON ou le constructeur JavaScript.

Compatible avec~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/MaybeIceloveU2/scroll-zoom-reveal/tree/HEAD

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Aperçu

Depuis le README du skill

Scroll Zoom Reveal preview

Documentation

Que fait Scroll Zoom Reveal ?

Effet de défilement prêt à l'emploi, sans dépendance :

  1. Scène épinglée plein écran : un titre surplombe une scène assombrie qui remplit la fenêtre.
  2. Dolly + recul : la scène se stabilise légèrement, puis la « caméra » recule. La scène se révèle être sur un écran d'ordinateur portable (la bordure et la base apparaissent).
  3. Réapparition de l'application : les panneaux d'éditeur (barre d'outils, hiérarchie, propriétés, timeline) glissent en place et la scène se réduit dans son panneau.
  4. Fondu du texte ci-dessous (data-zr-fade), puis une galerie à onglets avec fondu enchaîné et un curseur coulissant.

Tous les fichiers prêts à l'emploi se trouvent dans assets/ à côté de ce fichier :

FichierObjectif
assets/zoom-reveal.cssTous les styles (jetons de thème sur .zr)
assets/zoom-reveal.jsComposant + fadeds + galerie. Exporte window.ZoomReveal, auto-initialise [data-zoom-reveal] / [data-zr-gallery] / [data-zr-fade]
assets/oled-field.jsOptionnel. Champ de sous-pixels OLED réactif au curseur (window.OledField, auto-initialise [data-zr-oled]). Les styles sont dans zoom-reveal.css
assets/placeholder-scenes.jsOptionnel. Peint de manière procédurale les œuvres de substitution originales sur canvas (ZRScenes.drawCity, ZRScenes.drawCanyon) jusqu'à ce que des images réelles existent
assets/demo.htmlPage de démonstration complète et fonctionnelle. Partez de ce balisage.

Comment l'utiliser sur un site

  1. Copiez les assets dans le projet (par exemple public/zoom-reveal/ ou src/vendor/zoom-reveal/). Copiez placeholder-scenes.js uniquement s'il n'y a pas encore d'œuvre réelle.
  2. Lisez assets/demo.html et copiez le bloc <section class="zr" data-zoom-reveal>…</section> (ainsi que le bloc de galerie si souhaité). Conservez exactement la structure des classes :
section.zr[data-zoom-reveal]          ← la longueur de défilement est ici (--zr-length)
  .zr-sticky                          ← arrière-plan fixe de 100vh
    .zr-glow                          (lueur ambiante optionnelle)
    .zr-device                        ← mis à l'échelle par JS
      .zr-lid > .zr-display
        .zr-viewport > .zr-media > img | video | canvas   ← VOTRE SCÈNE
        .zr-chrome > .zr-panel.zr-toolbar / .zr-left / .zr-right / .zr-bottom  (interface utilisateur de l'application optionnelle)
      .zr-base                        (base de l'ordinateur portable ; supprimer pour un moniteur/tablette)
    .zr-scrim + header.zr-intro       ← titre au-dessus de la scène, disparaît en premier
    .zr-caption                       ← petite légende, apparaît à la fin
  1. Chargez zoom-reveal.css dans <head> et zoom-reveal.js à la fin de <body>.
  2. Remplacez le média : remplacez le canvas de démonstration par la scène réelle :
    • Image : <img src="scene.avif" alt="" decoding="async">. Exportez-la au moins avec la taille de la fenêtre × DPR (2560–3200px de large). L'effet commence avec l'image remplissant tout l'écran.
    • Vidéo avec défilement : <video data-zr-scrub muted playsinline preload="auto" src="scene.mp4"></video>. Le JS mappe la progression du défilement sur currentTime. Encodez chaque image comme une image clé pour que la recherche reste fluide : ffmpeg -i in.mov -c:v libx264 -g 1 -crf 22 -an -movflags +faststart scene.mp4.
  3. Réécrivez tout le texte (sourcil, titre, légende, étiquettes des panneaux, nom de fichier, étiquettes de la galerie) pour correspondre au site. Ne livrez jamais le texte fictif « Orbit / Forge » de la démo.
  4. Thème avec les jetons sur .zr : --zr-bg, --zr-fg, --zr-muted, --zr-accent, --zr-length (distance de défilement, défaut 360vh).

Options

Passez du JSON dans l'attribut, par exemple data-zoom-reveal='{"maxWidth":1000,"viewport":{"top":0,"right":0,"bottom":0,"left":0}}', ou construisez-le en JS : new ZoomReveal(el, options).

OptionDéfautSignification
maxWidth1180Largeur maximale finale de l'affichage (px)
widthRatio / heightRatio0.82 / 0.64Taille finale de l'affichage par rapport à la fenêtre
aspect0.625Hauteur ÷ largeur de l'affichage (16:10). Téléphone ≈ 2.16, ultra-large ≈ 0.42
overscan1.04Distance au-delà de la fenêtre où commence l'affichage (masque la bordure)
dolly1.14Zoom interne initial du média ; se stabilise à 1
lift0.035De combien l'appareil s'élève à la fin
timelinevoir JSFenêtres de progression [début,fin] pour intro, dolly, zoom, chrome, caption
viewport{top:6.5,right:21,bottom:22,left:15}Marges finales (% de l'affichage) du panneau de scène à l'intérieur de l'interface utilisateur. Mettez tout à 0 et supprimez .zr-chrome pour un pur recul « scène → écran de l'appareil » sans interface d'application
onProgress—Fonction de rappel fn(p) avec progression 0..1

Événements : la section émet zr:resize avec {width, height, finalWidth}, la taille en pixels à laquelle le média est disposé. Utilisez-la pour dimensionner les canvas ou choisir une source d'image.

React / Next.js

Importez le CSS globalement. Supprimez data-zoom-reveal du balisage et construisez-le manuellement pour qu'il soit lié au cycle de vie du composant ('use client' dans Next) :

useEffect(() => {
  import('./zoom-reveal/zoom-reveal.js').then(() => {  // enregistre window.ZoomReveal
    const zr = new window.ZoomReveal(ref.current, { maxWidth: 1100 });
    const gal = galRef.current && new window.ZoomReveal.Gallery(galRef.current);
    window.ZoomReveal.initFades();
    cleanup = () => zr.destroy();
  });
  let cleanup = () => {};
  return () => cleanup();
}, []);

Convertissez class → className et style="--v:78%" → style={{'--v':'78%'}}.

Champ de pixels OLED (effet de survol du curseur)

Un arrière-plan plein écran de fines barres de sous-pixels RVB, faiblement éclairées. Le déplacement du curseur agite une petite simulation de fluide. Les pixels le long du chemin s'allument, grandissent et changent de couleur du violet au cyan au vert lime au blanc chaud, puis la lueur dérive dans la direction du curseur, se propage et s'estompe. Un clic ou un tapotement produit une ondulation. Lorsque le curseur est inactif (et sur les écrans tactiles), un lent « curseur fantôme » le maintient en vie. Le rendu est un fragment shader WebGL1, la simulation est une petite grille CPU, et elle ne s'exécute que lorsque la section est visible à l'écran. Sans WebGL, elle revient à un projecteur CSS.

Utilisez-le derrière un bloc de spécifications/statistiques, un héros ou une bande d'appel à l'action. N'importe quel élément fonctionne : ajoutez class="zr-oled" data-zr-oled, placez le contenu à l'intérieur, chargez zoom-reveal.css + oled-field.js. Le composant insère lui-même le canvas. Voir le bloc « OLED PIXEL FIELD » dans assets/demo.html.

<section class="zr-oled" data-zr-oled='{"cell":7}'>
  <div class="your-content">…stats / headline…</div>
</section>
<script src="oled-field.js"></script>
OptionDéfautSignification
cell6Pixels CSS par pixel (3 barres de sous-pixels). 5–9 semble correct ; utilisez une valeur plus grande sur mobile pour la performance
radius2.4Rayon du pinceau en cellules
strength0.55Quantité de lumière ajoutée par le curseur. Les valeurs par défaut sont délibérément subtiles ; 1 est audacieux
decay0.94Atténuation par image ; plus élevé = traînées plus longues (0.92 court … 0.97 long)
flow0.55Distance de dérive de la lueur dans la direction du curseur
diffusion0.35Vitesse de propagation de la lueur
base0.09Luminosité de la grille non éclairée
palette['#5a3cff','#1fd6ff','#b6ff4a','#fff4d8']4 couleurs, basse → haute énergie. Adaptez à la marque, par exemple chaud ['#ff3c5a','#ff9a1f','#ffe14a','#fff8e8']
ambient / ripplestrueCurseur fantôme quand inactif / ondulation au clic

Pour un aspect plus audacieux (proche d'un effet de vitrine), utilisez {"radius":3.2,"strength":1,"decay":0.962,"flow":0.9}. Gardez les valeurs par défaut subtiles derrière les sections riches en texte.

API : const f = new OledField(el, opts), f.pulse(clientX, clientY) (déclenche une ondulation depuis le code), f.destroy() (appelez dans le nettoyage React). Donnez au texte au-dessus du champ une légère text-shadow sombre pour qu'il reste lisible par-dessus les traînées lumineuses.

Pièges (vérifiez-les avant de terminer)

  • Le sticky se casse si un ancêtre de .zr a overflow: hidden/auto/clip ou transform. Utilisez overflow-x: clip sur body si le débordement horizontal doit être masqué.
  • N'enveloppez pas .zr dans des bibliothèques de défilement fluide qui transforment la page (Locomotive v4 etc.). Lenis convient.
  • L'appareil est disposé grand et mis à l'échelle vers le bas, donc les médias restent nets. Ne mettez pas de tailles fixes en px à l'intérieur de .zr-device : utilisez em (1em = 1% de la largeur de l'affichage).
  • La réduction de mouvement est gérée : la section se désépingle et affiche l'état final ; la galerie arrête la lecture automatique ; le champ OLED continue de réagir au curseur mais abandonne le curseur fantôme et les ondulations.
  • Les animations se mettent en pause dans les onglets d'arrière-plan (requestAnimationFrame s'arrête). Lorsque vous testez le champ OLED dans un panneau de navigateur, gardez la page visible ou elle semblera figée.
  • En dessous d'environ 500px de large, l'ordinateur portable est petit. Envisagez {"widthRatio":0.92} ou un aspect correspondant à un cadre de téléphone sur mobile.
  • Testez en défilant lentement du haut vers le bas dans le navigateur aux largeurs de bureau et mobile. Assurez-vous que le titre disparaisse avant le début du recul, qu'aucune bordure ne soit visible au début et que la légende ne chevauche pas la base.
  • Utilisez des œuvres originales ou sous licence et du texte. Cette compétence recrée la technique de mouvement ; ne copiez pas les images, rendus de produits ou textes d'une autre marque.

Skills associés