Shader d'image au survol
Trois paysages de montagne. Passe la souris (ou le focus clavier) sur une image : elle se déforme autour du curseur, se sépare en canaux rouge / vert / bleu, puis se dissout vers une seconde photo. Au clavier, le focus déclenche exactement le même effet.
Démarche
Un fragment shader GLSL fait tout le travail, un vertex shader minimal pose juste un quad plein écran. Trois effets superposés :
- Déformation liquide — une poussée radiale autour du pointeur, modulée par la vitesse de la souris et un léger tremblement de bruit.
- Chromatic aberration — les canaux R et B sont échantillonnés à des offsets opposés du canal V, proportionnels à la distance au curseur.
- Dissolution organique — un bruit fractal (fBM, 4 octaves) décide quels pixels basculent les premiers vers l'image d'arrivée, pour un seuillage doux.
Détails techniques
- Lissage exponentiel indépendant du framerate pour la souris, la vitesse et la progression — la courbe
1 - exp(-dt * k)donne un suivi qui reste cohérent même si le navigateur drop des frames. - Mise en veille quand la carte sort du viewport (
IntersectionObserver) et quand elle est au repos (plus rien ne bouge), pour épargner le GPU. - Respect de
prefers-reduced-motion— un uniformeuReduitdésactive la déformation et la dissolution bruitée, il reste un simple fondu entre les deux images. - Accessibilité clavier —
tabindex="0"sur chaque carte,focus/blurdéclenchent la même animation quepointerenter/pointerleave, avec la souris centrée. - Chargement non bloquant — les textures sont chargées en parallèle via
Promise.all, chaque carte s'initialise dès que ses deux images sont prêtes. - Fallback sans WebGL — si
getContext('webgl')renvoie null, on tombe sur un simpledrawImage2D de l'image de départ.
Pile
WebGL 1 brut (pas de lib), ES modules, Vue 3 pour l'intégration dans le portfolio. Images : photos de paysages de montagne libres de droits Unsplash, redimensionnées en 1024 × 1280 (ratio 4:5).