Splash Effect
Au clic, 30 gouttelettes bleues jaillissent du point touché, montent, retombent sous la gravité, et trois anneaux indigo s'élargissent à 100 ms d'intervalle, sur un canvas qui garde une traînée : une éclaboussure brève et franche, dessinée en vectoriel donc nette sur écran Retina — 5,2 Ko de JavaScript, aucune image calculée entre deux clics.
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



Comment ça marche
Le bloc .fx-0399-root fait 300 px de haut et toute la largeur disponible. Son conteneur .splash-container (curseur en main) porte un <canvas class="splash-canvas"> en display: block à 100 % du cadre, peint en #1a1a24, et une ligne d'aide en bas, « Cliquez pour créer un splash ». La hauteur vient du CSS de la racine et le canvas s'y cale : 20 redimensionnements de suite, 0 px de dérive (Chromium et Firefox).
Un clic crée 30 gouttelettes au point touché. Chacune part dans une direction au hasard à 2 à 8 px par image, avec une poussée de 5 px vers le haut, puis la gravité lui ajoute 0,2 px par image vers le bas : la gerbe monte en couronne et retombe. Rayon de 2 à 6 px, teinte de 200 à 240° (bleu ciel à bleu indigo), opacité qui baisse de 0,02 à 0,04 par image : chaque goutte vit 25 à 50 images. En même temps partent trois anneaux indigo (rgba(99, 102, 241)), lancés à 0, 100 et 200 ms : ils grandissent de 3 px par image de 5 à 80 px de rayon en s'effaçant, leur trait passant de 3 px à rien. À chaque image, le canvas n'est pas effacé mais recouvert d'un voile du fond à 20 % d'opacité : le tracé des images précédentes s'estompe en quelques images, d'où les traînées qui suivent les gouttes.
La boucle ne tourne que pendant une éclaboussure. Quand la dernière goutte et le dernier anneau ont disparu, le script passe encore 30 images de voile pour effacer les traînées, repeint le fond à neuf et s'arrête : environ 77 images en tout (1,3 s à 60 Hz), puis 0 appel à requestAnimationFrame jusqu'au clic suivant (mesuré). Elle se suspend aussi hors écran (IntersectionObserver) et onglet caché. Le canvas compte devicePixelRatio pixels par pixel CSS (jusqu'à 3) et le script dessine en pixels CSS grâce à setTransform : gouttes et anneaux restent ronds et nets sur écran Retina. Coût mesuré : moins de 0,1 ms par image dans Chromium et WebKit, jusqu'à 4 ms dans Firefox selon la taille du canvas (le voile repeint toute la surface). Le script anime chaque .fx-0399-root de la page séparément.
Accessibilité
- Mouvement réduit : sous
prefers-reduced-motion: reduce, rien ne jaillit ni ne tombe. Les 30 gouttes apparaissent directement en couronne autour du point touché (12 à 52 px, aplatie de 30 % en hauteur) et trois anneaux fixes de 18, 34 et 50 px ; tout s'efface sur place, sans bouger, en 25 à 50 images. Mesuré dans Chromium et Firefox : la boucle s'arrête ensuite d'elle-même. - Clavier : l'éclaboussure suit le clic (souris ou doigt), pas le clavier. Quand elle accompagne une action (tir, don, signalement), déclenchez l'action par un bouton ou un formulaire atteignable au clavier et annoncez le résultat dans une zone
role="status"; l'éclaboussure n'en est que l'écho visuel. - Brièveté : l'éclaboussure dure moins de deux secondes et ne porte aucune information à elle seule. Écrivez toujours le résultat en texte (« À l'eau ! », « Vœu lancé », « Fuite signalée »), comme dans les trois exemples.
- Contraste : le texte d'aide, blanc à 50 % sur
#1a1a24, atteint 5,2:1 (calculé).
Compatibilité navigateur
Canvas 2D (arc, setTransform, globalAlpha), ResizeObserver, IntersectionObserver, matchMedia : 5,2 Ko de JavaScript, aucune dépendance. Mesuré dans Chromium 151, Firefox 153 et WebKit 26 : même gerbe, mêmes anneaux, canvas à 1 280 × 600 sur écran Retina, boucle arrêtée entre deux clics, couronne fixe sous mouvement réduit, 0 erreur. Vitesses et durées sont comptées par image affichée : sur un écran à 120 Hz, l'éclaboussure dure deux fois moins longtemps qu'à 60 Hz.
Sans ResizeObserver, le script suit l'événement resize de la fenêtre ; sans IntersectionObserver, une éclaboussure en cours se termine hors écran. Sans JavaScript, le cadre reste vide avec son texte d'aide.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :
<div class="fx-0399-root">
<div class="splash-container">
<canvas class="splash-canvas"></canvas>
<span class="splash-hint">Cliquez pour créer un splash</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éfaut | Effet |
|---|---|---|
Nombre de gouttes (JS — for (var i = 0; i < 30; i++) dans l'écouteur de clic) |
30 | 12 gouttes pour une goutte d'eau discrète, 60 pour une gerbe dense. |
Force et gravité (JS — 2 + 6 * Math.random(), - 5, this.gravity = 0.2) |
2 à 8 px par image, poussée de 5 px vers le haut, gravité 0,2 | Une poussée de - 2 et une gravité de 0.1 donnent une gerbe basse et lente ; une poussée de - 8, un jet haut. Avec une gravité de 0, les gouttes partent en étoile, décalée vers le haut par la poussée, sans retomber. |
Couleurs (JS — 'hsl(' + (200 + 40 * Math.random()) + ', 80%, 60%)' et rgba(99, 102, 241, …)) |
gouttes bleu ciel à indigo, anneaux indigo | 'hsl(' + (150 + 30 * Math.random()) + ', 70%, 55%)' pour une éclaboussure verte. Gardez une luminosité de 55 à 65 % pour que les gouttes ressortent du fond sombre. |
Traînée (JS — TRAIL = 'rgba(26, 26, 36, 0.2)') |
voile du fond à 20 % | 0,4 efface presque tout d'une image à l'autre (gouttes nettes, sans traînée) ; 0,1 allonge les traînées en longs filets. Gardez la même couleur que BACKGROUND. |
Anneaux (JS — this.maxRadius = 80, this.speed = still ? 0 : 3, délais de 100 et 200 ms) |
de 5 à 80 px, +3 px par image, trois anneaux | maxRadius = 140 pour des ronds plus larges qui durent plus longtemps ; retirez les deux setTimeout pour un seul anneau. |
Fond (JS — BACKGROUND = '#1a1a24' et CSS de la racine) |
#1a1a24 | Changez la couleur ici, dans TRAIL (mêmes valeurs en rgba) et sur .fx-0399-root. Le canvas est opaque : il repeint son fond à chaque image. |
FAQ
container.dispatchEvent(new MouseEvent('click', { bubbles: true, clientX: x, clientY: y })), avec des coordonnées de la fenêtre (le coin du canvas plus le décalage voulu). C'est ce que font les exemples pour rejouer l'éclaboussure toutes les 1,9 s tant que personne n'a touché.#1a1a24) à 20 % à chaque image pour faire les traînées. Pour un canvas transparent, remplacez ce voile par un effacement partiel, ctx.globalCompositeOperation = 'destination-out' puis le même fillRect à 20 % et retour à 'source-over', et la repeinte finale par ctx.clearRect ; la photo passe alors dessous, traînées comprises.