03 · Case study · avatar-pandora

Eywa — un codex Pandora à offrir

Quatrième app du laboratoire perso. Un codex Avatar offert à une proche, fan absolue des schtroumpfs géants à trois mètres de haut. Moi je trouve ça moyen, mais bon — l'occasion d'apprendre Astro, R3F et GSAP en codant avec Claude Code, en pair-programming intégral. Zéro ligne écrite à la main.

Le pitch

Eywa (la déesse-réseau de Pandora) est un codex en français sur l'univers Avatar. Sept sections de contenu lyrique sourcé Pandorapedia + Avatar Wiki + Paul Frommer : Pandora, Clans Na'vi, Bestiaire, Flore, Personnages, Engins, Films + une page dédiée à la langue Na'vi.

Public visé : jeune adulte cinéphile, fan visuelle avant tout. Donc atmosphère cinématique, images grand format, ambiance bioluminescente. Et un codex explorable pour quand elle veut creuser. Live : eywa-eywa.pages.dev · code : github.com/Sylad/avatar-pandora.

Architecture

Astro 6 statique pur déployé sur Cloudflare Pages. Quelques îlots React 19 pour les morceaux interactifs (CinemaCanvas R3F, ParticleField WebGL, CycleBackdrop). Le backend NestJS minimal sur port 3003 n'existe que sur le NAS local pour la validation — en public, le proxy /api/wiki-image tourne en Cloudflare Function.

Architecture
Loading diagram…
Astro statique + îlots React 19 · une cible publique sans backend (Cloudflare Pages + Functions), une cible NAS pour la validation locale.

Astro statique = aucun cold start, aucun budget serveur, et un site qui charge en moins d'une seconde même sur le 4G de la destinataire. Le NestJS reste là sur le NAS uniquement pour itérer en local sans pousser à chaque fois sur main.

Le pivot — atmosphère vs scroll

La V1 livrée fin avril était un scrollytelling cinéma 700vh : cold open → forêt → Hometree → montagnes flottantes → océan Metkayina → volcan Fire & Ash → reveal du codex. J'aimais les transitions, mais dès le retour de la destinataire, le verdict est tombé : "je dois scroller pour voir quoi ?". Friction. Le scroll forcé tuait l'envie d'explorer le codex.

Pivot V2 — atmosphère temps-driven : on garde le viewport unique, on garde les images grand format, on garde les particules bioluminescentes, mais l'ambiance se transforme toute seule sur une boucle de 75 secondes. Le visiteur arrive, pose son téléphone, l'image se transforme. Six atmosphères se cross-fadent en continu. Les particules WebGL pulsent sur la même clock. Le logo, la tagline et les CTAs restent fixes au-dessus avec une dark vignette pour la lisibilité.

Validation immédiate ("c'est très bien"). Le scroll n'a pas disparu pour autant : il reste valide pour les pages dédiées du codex (sidebar warhammer-style, contenu long). Mais sur la racine, plus jamais de scrollytelling forcé. Le pattern technique — CinemaCanvas mode 'time' + CycleBackdrop cross-fade synchronisé — est devenu une référence pour les futures landings perso.

Détails techniques notables

  • CinemaCanvas en mode 'time' : react-three-fiber tourne sur une horloge globale partagée, pas sur useFrame indépendant. Toutes les couches visuelles (backdrop, particules, GSAP UI) lisent le même t / 75s pour rester synchrones.
  • ParticleField WebGL custom : shader fragment maison qui simule la bioluminescence des spores Pandora — pulsation lente sur la même clock que le backdrop, dérive vent + atténuation radiale. ~3 000 particules, 60fps stables sur mobile.
  • Logo SVG codé, pas généré, pas exporté d'Illustrator. Glyphes Na'vi-inspirés tracés en <path> Astro avec animations stroke-dasharray sur l'apparition. Custom de bout en bout.
  • Proxy /api/wiki-image Fandom→Wiki : fallback en chaîne sur Avatar Fandom puis Wikipedia (les deux n'indexent pas les mêmes choses). Implémentation NestJS sur le NAS, re-portée 1:1 en Cloudflare Function pour le public — même contrat, deux runtimes.
  • Reduced motion : hook useReducedMotion qui coupe le cinema canvas et fige le backdrop sur une atmosphère statique. Accessibilité non-négociable, même sur un cadeau perso.
  • Fair-use respecté : aucun still de film re-hosté, uniquement des proxys vers wiki + concept arts linkés. Repo public-ready, LICENSE MIT/CC, déploy auto sur git push origin main (~2 min pipeline Cloudflare).

Ce que Claude Code a apporté

Avant Eywa, je n'avais jamais touché Astro, jamais touché react-three-fiber, jamais écrit un shader. Java/Spring depuis 21 ans, oui ; WebGL non. Le projet a démarré à zéro et j'ai écrit zéro ligne à la main — tout est sorti de conversations avec Claude Code.

Le pivot scroll → temps-driven aurait pris une semaine en solo (lire la doc R3F, comprendre le rendering loop, débugger les synchronisations). Avec Claude Code en pair-programming, c'était une après-midi de discussion, deux refactos et une validation visuelle. Idem pour le shader bioluminescent : description en langage naturel ("je veux des spores qui pulsent doucement, comme dans la scène de la forêt nocturne"), itérations sur les paramètres, code GLSL généré et ajusté. Crédits IA : 100% Claude Code.

Le code est là, public, lisible. Si tu veux faire pareil — prends un sujet qui t'enflamme (un proche fan d'Avatar, dans mon cas), ouvre Claude Code, et laisse la conversation devenir ton commit log.

Stack — Astro 6 · React 19 · @react-three/fiber · GSAP · Tailwind · NestJS (NAS) · Cloudflare Pages + Functions (public).