Liquid✨ Premium

Water Ripple

Une eau bleu nuit, lisse et immobile, où chaque clic lâche une perturbation qui s'étale en cercles, rebondit sur les bords et croise les ondes des autres clics : une vraie équation des ondes sur une grille de hauteurs, recalculée pixel par pixel — 4,7 Ko de JavaScript, net sur écran Retina, à l'arrêt quand l'eau est calme.

CanvasInteractivePhysics

Mis à jour le

Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. Liquid comprend 31 effets, dont 6 gratuits. Découvrir la catégorie →

3 exemples d'usage

Le vieil étang de Bashō — haïku du jour dans l'appli d'un club de poésie japonaise — Water Ripple exemple 1

① Le vieil étang de Bashō — haïku du jour dans l'appli d'un club de poésie japonaise

QuandSur un fond bleu nuit plein cadre, le haïku du jour s'affiche en trois lignes en bas à gauche : « Le vieil étang — une grenouille plonge, le bruit de l'eau ». Toucher l'eau fait naître des cercles à l'endroit du doigt.
PourquoiL'onde part exactement du point touché et s'étale en cercles sur une eau immobile : le poème décrit ce geste. Une gerbe d'éclaboussures serait trop bruyante pour un haïku.
RéglagesBloc plein cadre (position: absolute; inset: 0), texte d'aide masqué ; voile sombre en haut et en bas pour le titre et le poème, texte posé dessus en pointer-events: none pour que le clic atteigne l'eau ; poème en serif 21 px, décalé de 22 px à chaque vers.
Zones de baignade d'un lac — plan tactile du poste de secours d'une base de loisirs — Water Ripple exemple 2

② Zones de baignade d'un lac — plan tactile du poste de secours d'une base de loisirs

QuandLe plan du lac vu de dessus montre trois zones balisées, « Petit bain », « Grand bain » et « Paddle ». Le visiteur touche une zone : l'onde part de son doigt, le nom de la zone passe en jaune et s'affiche dans la carte avec la température de l'eau, 21 °C.
PourquoiL'onde confirme l'endroit où le doigt s'est posé et le reste du lac reste calme : la zone choisie se repère d'un coup d'œil, sans curseur ni surbrillance ajoutés.
RéglagesEau plein cadre ; plage et pelouse dessinées en SVG par-dessus, lignes d'eau en pointillés, tout en pointer-events: none ; un script de scène écoute le même clic que l'effet sur .water-ripple-container et teste dans quelle zone il tombe ; carte d'information en role="status".
Faire des ronds dans l'eau — exercice de motricité fine dans l'appli d'un centre de rééducation — Water Ripple exemple 3

③ Faire des ronds dans l'eau — exercice de motricité fine dans l'appli d'un centre de rééducation

QuandSur la tablette posée devant le patient, la consigne « Touchez l'eau du bout de l'index, une fois par rond » et un compteur « 12 ronds » en haut à droite ; chaque toucher fait un rond et ajoute 1.
PourquoiLe cercle naît au pixel près sous le doigt puis s'amortit lentement : le patient voit la précision de son geste et le rythme qu'il tient, ce qu'une éclaboussure brève ne montre pas.
RéglagesEau sous une barre d'en-tête claire de 58 px (racine en top: 58px) ; compteur en role="status", incrémenté par un écouteur de clic posé sur .water-ripple-container ; texte d'aide remplacé par la consigne.

Comment ça marche

Le bloc .fx-0392-root fait 300 px de haut et toute la largeur disponible. Son conteneur .water-ripple-container (curseur en main) porte un <canvas class="water-ripple-canvas"> en display: block à 100 % du cadre, et une ligne d'aide en bas, « Cliquez pour créer des ondulations ». La hauteur est fixée par le CSS de la racine et le canvas se cale dessus : 20 redimensionnements de suite, 0 px de dérive (Chromium et Firefox). L'eau au repos est un bleu nuit uni, rgb(10, 45, 100).

Le script tient deux grilles de hauteurs (Float32Array), l'état présent et le précédent, une case par pixel du canvas. Un clic pose un disque de 5 px de rayon dont la hauteur vaut 500 au centre et décroît jusqu'au bord. À chaque image, chaque case prend la moyenne de ses quatre voisines dans l'état précédent, multipliée par 2, moins sa propre valeur, puis perd 1 % (damping = 0.99) : c'est la forme discrète de l'équation des ondes. La perturbation s'étale en anneaux, se réfléchit sur les bords (les cases du bord restent à 0) et les anneaux de plusieurs clics se croisent sans se gêner. Le rendu lit chaque hauteur : une crête éclaircit le bleu (jusqu'à 255), un creux l'assombrit, et le rouge monte avec l'amplitude, d'où le liseré violet au point d'impact.

La boucle ne tourne que pendant une onde. Au repos, aucune image n'est calculée (0 appel à requestAnimationFrame par seconde, mesuré) ; après un clic, elle s'arrête d'elle-même quand la plus forte hauteur repasse sous 0,5, soit environ 900 images (15 s à 60 Hz), puis remet la grille à zéro. Elle se suspend aussi hors écran (IntersectionObserver) et onglet caché. Sur écran Retina, la grille compte 2 cases par pixel CSS tant qu'elle reste sous 800 000 cases (un bloc de 640 × 300 donne 1 280 × 600, net) ; le script fait alors 2 pas de calcul par image, avec un amortissement de 0,99 partagé entre les deux, pour que l'onde avance et s'éteigne au même rythme à l'œil. Mesuré pendant une onde : 1,1 ms par image dans Chromium, 1 ms dans Firefox et WebKit à 640 × 300 ; 6, 9 et 5 ms sur Retina. Le script anime chaque .fx-0392-root de la page séparément.

Accessibilité

  • Mouvement réduit : sous prefers-reduced-motion: reduce, un clic ne lance pas d'onde. Une tache claire de 16 px de rayon apparaît sous le pointeur et s'éteint sur place en une quarantaine d'images (0,7 s à 60 Hz), sans anneau qui s'étale ; mesuré dans Chromium et Firefox, la boucle s'arrête d'elle-même ensuite. Au repos, l'eau est immobile dans les deux modes.
  • Clavier : l'eau réagit au clic (souris ou doigt), pas au clavier. Si le geste déclenche une action (choisir une zone, compter), donnez-lui aussi un bouton ou un lien atteignable au clavier, et annoncez le résultat dans une zone role="status", comme le compteur et la carte des exemples.
  • Contenu : le canvas ne dit rien aux lecteurs d'écran. Le texte d'aide « Cliquez pour créer des ondulations » est un vrai texte ; dans une interface réelle, remplacez-le par une consigne qui dit à quoi sert le geste.
  • Contraste : le texte d'aide, blanc à 50 % sur le bleu nuit, atteint 4,45:1 (calculé), juste sous le seuil de 4,5:1 pour un petit texte : passez-le à 60 % d'opacité s'il porte une consigne utile. Un texte posé sur l'eau reste lisible tant que les ondes passent dessous : elles ne varient le fond que de quelques teintes de bleu.

Compatibilité navigateur

Canvas 2D (createImageData, putImageData), Float32Array, ResizeObserver, IntersectionObserver, matchMedia : 4,7 Ko de JavaScript, aucune dépendance. Mesuré dans Chromium 151, Firefox 153 et WebKit 26 : même onde, même réflexion sur les bords, canvas à 1 280 × 600 sur écran Retina, arrêt de la boucle au repos, tache fixe sous mouvement réduit, 0 erreur. Les pas de calcul sont comptés par image affichée : sur un écran à 120 Hz, l'onde s'étale deux fois plus vite qu'à 60 Hz.

Chrome 64+✓ Complet
Firefox 69+✓ Complet
Safari 13.1+✓ Complet
Edge 79+✓ Complet
Mobile iOS 13.4+✓ Complet (au doigt)
Android Chrome 64+✓ Complet (au doigt)

Sans ResizeObserver, le script suit l'événement resize de la fenêtre ; sans IntersectionObserver, une onde continue de se calculer hors écran jusqu'à s'éteindre. Sans JavaScript, le cadre reste vide avec son texte d'aide : prévoyez un fond de secours sur .water-ripple-container si l'eau doit se voir.

Le code

Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :

index.html — structure
<div class="fx-0392-root">
  <div class="water-ripple-container">
    <canvas class="water-ripple-canvas"></canvas>
    <span class="water-hint">Cliquez pour créer des ondulations</span>
  </div>
</div>

Paiement unique, sans abonnement — le code est à toi pour toujours

Personnaliser

Options passées à l'API ou attributs data-* :

Option / propriétéDéfautEffet
Amortissement (JS — damping, calculé à partir de 0.99) 0,99 : l'onde perd 1 % par image 0.98 éteint l'onde en deux fois moins de temps, cercles plus courts ; 0.995 la laisse rebondir longtemps d'un bord à l'autre. Restez sous 1, sinon l'eau ne se calme jamais.
Taille et force de la goutte (JS — (still ? 16 : 5) * scale et 500) disque de 5 px de rayon (16 px en mouvement réduit), hauteur 500 Un rayon de 10 au lieu de 5 donne des anneaux plus larges et plus doux ; une hauteur de 250, des cercles plus discrets. Le bleu plafonne dès qu'une crête dépasse 155 : au-delà, seul le rouge monte et l'impact vire au violet.
Couleurs de l'eau (JS — fonction render) repos rgb(10, 45, 100) ; crête vers le bleu vif Le bleu vaut 100 + value, le vert (150 + value / 2) × 0,3, le rouge 10 + |value| × 0,2. Pour une eau turquoise, montez le facteur du vert à 0.8 ; pour une eau sombre, baissez le 100 du bleu à 60.
Netteté sur Retina (JS — var PIXEL_BUDGET = 800000) 800 000 cases au plus Au-delà (bloc plus grand que 200 000 pixels CSS, environ 640 × 310), la grille passe à une case par pixel CSS, un peu moins nette mais avec 4 fois moins de cases à calculer. Montez la valeur pour un grand bloc net sur ordinateur.
Hauteur (CSS — height de .fx-0392-root) 300px Le canvas suit la hauteur du bloc. Pour une eau plein écran, placez la racine en position: absolute; inset: 0.
Texte d'aide (HTML — .water-hint) « Cliquez pour créer des ondulations » Remplacez-le par la consigne de votre interface, ou masquez-le (display: none) si la page explique déjà le geste.

FAQ

Les cases du bord de la grille ne sont jamais recalculées et restent à 0 : pour l'équation des ondes, c'est un mur. L'onde qui l'atteint repart en sens inverse, comme dans un bassin. Pour une eau qui s'échappe par les bords, il faudrait une couche absorbante (amortissement plus fort sur les dernières cases), ce que ce code ne fait pas.
Water Ripple simule une surface : une onde lente qui s'étale, rebondit et se mêle aux autres pendant plusieurs secondes, sur une eau qui reste lisse au repos. Splash Effect lance une gerbe de 30 gouttelettes et trois anneaux qui retombent en moins d'une seconde, sur un fond sombre. Choisissez Water Ripple pour montrer où le doigt s'est posé et laisser la trace un moment ; Splash Effect pour une réaction brève et énergique.
Oui : la fonction qui pose la goutte est dans l'écouteur click du conteneur. Appelez le même code sur pointermove avec une hauteur faible (50 au lieu de 500), au plus une fois toutes les 50 ms, pour un sillage qui suit le pointeur. La boucle repart d'elle-même à chaque goutte et s'arrête quand l'eau redevient calme.