Elastic String
Vingt nœuds forment une corde horizontale qui se courbe vers le curseur quand il s'en approche, puis revient en oscillant comme un ressort amorti — réponse instantanée au survol, mouvement qui s'efface en quelques secondes.
Mis à jour le
Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. Hover comprend 48 effets, dont 5 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
La corde est formée de 20 div.es382-node créés dynamiquement dans .es382-string. Chaque nœud a un déplacement vertical y et une vélocité vy. À chaque image de la boucle requestAnimationFrame, si la souris est proche du nœud (distance horizontale < 60 px), une force proportionnelle à cette proximité pousse le nœud vers la souris : vy += (target − y) × 0.1 × f. La force de rappel ramène chaque nœud vers sa position de repos (vy += −y × 0.3 × f). L'amortissement (vy *= 0.9^f) fait décroître les oscillations. Le déplacement final est appliqué en translateY.
Un lissage de Catmull-Rom (via la propriété CSS filter + SVG, ou simplement des transitions CSS) n'est pas utilisé ici : c'est la juxtaposition de 20 petits éléments qui crée l'illusion de continuité. La résolution peut être augmentée en changeant la constante de nœuds. Un IntersectionObserver met la boucle en pause quand l'effet est hors écran. Le step est normalisé à 60 fps : f = dt / 16.67.
Accessibilité
- Toucher :
touchmovedéplace la corde vers le doigt comme la souris. L'événementpreventDefault()bloque le défilement de la page pendant l'interaction.touchendlaisse la corde osciller librement. - Clavier : l'effet ne réagit pas au clavier. Il n'y a rien à sélectionner ni à activer ; l'élément est purement décoratif.
- Mouvement réduit : sous
prefers-reduced-motion: reduce, la boucle ne démarre pas et les nœuds restent àtranslateY(0)— la corde est visible comme une ligne horizontale fixe. - Rôle décoratif : le
.es382-wrapn'a pas de rôle ARIA. Si la corde illustre un séparateur de section, ajoutezrole="separator"et unaria-labeldécrivant les deux zones séparées.
Compatibilité navigateur
DOM pur et CSS, aucune dépendance. IntersectionObserver disponible depuis Chrome 51, Firefox 55, Safari 12.1. requestAnimationFrame depuis Chrome 10, Firefox 11, Safari 6. Non vérifié sur Safari réel ; attendu complet.
Sans JavaScript, la corde s'affiche comme une ligne horizontale fixe. Sans IntersectionObserver, la boucle tourne aussi hors écran.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :
<div class="fx-0382-root">
<div class="es382-wrap">
<div class="es382-track">
<div class="es382-string"></div>
</div>
<span class="es382-label" aria-hidden="true">Survolez la corde</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 nœuds (JS — constante NODE_COUNT) |
20 | 30 donne une résolution plus fine ; 10 un aspect « perlier » discret. Chaque nœud est un div : au-delà de 40, la performance sur mobile peut baisser. |
Raideur du ressort (JS — vy += -y * 0.3 * f) |
0,3 | 0,5 donne une corde plus raide qui revient vite ; 0,08 une corde très souple qui oscille longtemps. |
Amortissement (JS — vy *= Math.pow(0.9, f)) |
0,9 | 0,95 donne des oscillations qui durent plusieurs secondes ; 0,7 un retour presque immédiat sans rebond visible. |
Épaisseur et couleur (CSS — .es382-node) |
2 px de haut, dégradé indigo-violet | 4 px pour un câble visible ; une teinte unie pour un aspect fil de fer. |
Rayon d'influence de la souris (JS — if (Math.abs(dx) < 60)) |
60 px | 120 px crée une vague plus large ; 30 px un effet pincé et local. |
FAQ
nodes[10].vy = -20; crée un pic au centre. Pour une vague qui se propage, assignez des vélocités décroissantes sur une plage de nœuds consécutifs avec un délai.div par un canvas et tracez la corde avec bezierCurveTo.y après le calcul : if (node.y > 80) node.y = 80;. Faites de même vers le haut (if (node.y < -80)) si vous voulez une amplitude symétrique.