Les metaballs — ces formes organiques qui fusionnent quand elles se rapprochent, comme des gouttes de mercure ou de lave — ont longtemps été réputées coûteuses : le calcul exact passe par un champ scalaire évalué pour chaque pixel. Cet article décrit l'effet Cursed Blood Goo, l'effet gratuit du sprint Halloween d'octobre 2026 sur Effect.Labs : du sang liquide qui goutte, fusionne et s'accumule en flaque, avec un glob qui suit le curseur — le tout en Canvas pur et une seule ligne de filtre CSS, sans aucune bibliothèque ni asset, à 60fps.
L'astuce : blur + contrast
La technique (popularisée par Lucas Bebber) tient en deux filtres enchaînés sur la couche qui contient les blobs :
blur()étale les bords de chaque blob en un dégradé doux. Deux blobs proches voient leurs halos flous se superposer.contrast()élevé écrase ces valeurs intermédiaires : tout ce qui est sous le seuil bascule vers le fond, tout ce qui est au-dessus vers la couleur pleine. Résultat : un bord net reconstitué, et là où deux halos se chevauchaient, une seule masse organique soudée.
.goo-scene { background: #0b0406; } /* fond OPAQUE sombre, indispensable */
.goo-canvas { filter: blur(7px) contrast(16); } /* le combo metaball */
contrast() agit sur les canaux de couleur, jamais sur l'alpha. Il faut donc dessiner des blobs pleins sur un fond opaque sombre : le blur mélange la couleur du blob avec le fond, puis le contrast re-seuille. Sur un canvas transparent, aucune fusion ne se produit — c'est l'erreur la plus fréquente.
Dessiner les gouttes
Côté Canvas, c'est volontairement bête : on remplit le fond opaque, puis on dessine chaque goutte comme un simple cercle plein de la couleur du sang. Tout le « liquide » vient du filtre CSS appliqué par-dessus.
const ctx = canvas.getContext('2d');
const COLOR = '#c81e2d';
function render() {
ctx.fillStyle = '#0b0406'; // fond opaque (re-seuillé en noir par contrast)
ctx.fillRect(0, 0, W, H);
ctx.fillStyle = COLOR;
for (const d of drops) { // chaque goutte = un disque plein
ctx.beginPath();
ctx.arc(d.x, d.y, d.r, 0, 6.2832);
ctx.fill();
}
}
La physique : chute, flaque, curseur
Trois comportements donnent vie au sang, tous very cheap :
1. La dégoulinade
On fait apparaître une goutte en haut à intervalle régulier, soumise à la gravité. Quelques dizaines suffisent — la fusion visuelle fait le reste.
if (frame % 11 === 0 && drops.length < 130)
drops.push({ x: Math.random()*W, y: -12, vx: 0, vy: 1.2,
r: 9 + Math.random()*9 });
for (const d of drops) { d.vy += 0.28; d.x += d.vx; d.y += d.vy; }
2. La flaque qui monte
Quand une goutte atteint le sol, elle ne disparaît pas : elle nourrit le niveau de la flaque (proportionnel à sa surface). On dessine la flaque comme une surface ondulée par un sinus — et elle s'écoule lentement pour atteindre un équilibre plutôt que déborder.
if (d.y + d.r*0.4 >= H - pool) { pool += d.r*d.r / W * 0.8; remove(d); }
pool = Math.max(0, pool - 0.14); // drainage lent → équilibre
3. Le glob au curseur
Le curseur porte un gros blob (qui fusionne avec tout ce qu'il touche, grâce au filtre). Quand on bouge vite, il projette des gouttelettes dans la direction du mouvement, et il aspire les gouttes proches. C'est ce qui rend l'effet tactile.
// glob qui suit le curseur (lissé)
bx += (mx - bx) * 0.3; by += (my - by) * 0.3;
// vitesse du curseur → projection de gouttelettes
const speed = Math.hypot(mx - pmx, my - pmy);
if (speed > 13) drops.push({ x: bx, y: by,
vx: (mx - pmx)*0.07, vy: (my - pmy)*0.07 + 1, r: 6 + Math.random()*6 });
Le code complet (gestion du devicePixelRatio, attraction des gouttes vers le curseur, fond personnalisable) est disponible directement sur la page Effets visuels du catalogue — cet effet est gratuit.
Personnaliser : sang, slime, encre, lave
Une seule variable de couleur transforme l'effet. Deux ou trois réglages suffisent à changer l'ambiance :
| Paramètre | Plage | Effet |
|---|---|---|
| Couleur | #c81e2d / #5ad12e / #111 / #ff7a18 | Sang / slime toxique / encre / lave |
contrast() | 10 → 22 | Plus élevé = bords plus nets, plus « gélatineux » |
blur() | 5 → 10 px | Épaisseur de la fusion entre gouttes |
cadence frame % N | 6 → 20 | Débit de la dégoulinade |
Pensez à garder le fond opaque cohérent avec la teinte (un vert très sombre pour le slime, par exemple), sinon le re-seuillage du contraste vire au gris.
Performance et accessibilité
Un seul canvas, ~100 gouttes, un filtre GPU : l'effet tient le 60fps sur mobile récent. Quelques garde-fous :
- Plafonner le nombre de gouttes (130 ici) et le
devicePixelRatioà 2. - Le filtre
blur()+contrast()est exécuté par le compositeur GPU — bien plus rapide qu'un champ scalaire calculé en JS. prefers-reduced-motion: on dessine une scène figée (flaque + quelques gouttes au repos), sans boucle d'animation. L'effet est purement décoratif, le contenu reste accessible.
Ce que ChatGPT et v0 ne font pas
Demandez des « metaballs en canvas » à un générateur : vous obtenez presque toujours un champ scalaire par pixel (double boucle sur la largeur × hauteur), qui rame dès qu'on dépasse quelques blobs. Ce que l'IA rate :
- L'astuce blur + contrast : la solution GPU « gratuite » est rarement proposée spontanément.
- Le fond opaque obligatoire : le code IA dessine sur un canvas transparent → aucune fusion, et personne ne comprend pourquoi.
- La physique qui donne vie : flaque qui monte, drainage à l'équilibre, projection de gouttelettes à la vitesse du curseur.
- devicePixelRatio : oublié → rendu flou sur Retina (ironique pour un effet déjà flouté).
- prefers-reduced-motion : règle d'accessibilité régulièrement absente des résultats générés.
Questions fréquentes
Le filtre blur + contrast fonctionne-t-il aussi en DOM/SVG ?
Oui : c'est même son usage d'origine (sur des div ou un filtre SVG feGaussianBlur + feColorMatrix). Sur Canvas on garde un seul élément à composer, ce qui reste le plus simple et le plus rapide.
Peut-on l'utiliser avec React, Vue ou Svelte ?
Oui : code vanilla JS, aucune dépendance npm. Dans React, encapsuler la boucle dans un useEffect avec cleanup (cancelAnimationFrame) ; dans Svelte, onMount/onDestroy.
Le code complet, prêt à l'emploi
Cet effet est gratuit ce mois-ci. Customisez la couleur en direct et copiez-collez le code. Accès à 800+ autres effets premium avec l'abonnement.
Rejoindre les fondateurs — 9,90 € / mois