Skip to content

Dynamics.applyTether()

Elements float or fall freely until they exceed the tether's length, at which point an elastic spring snaps them back, simulating a physical bungee cord or string!


Basic Gravity Tether

In this demo, the box is pulled down by gravity. However, if the cursor gets more than 100px away, the invisible bungee cord snaps taut and pulls it back.

Move your mouse around to drag the box!
60 FPS
js
import { applyTether } from 'animx/plugins/Dynamics';

applyTether('.box', {
  target: 'pointer',       
  length: 100,             // The resting slack length of the cord
  stiffness: 150,          // The snap-back tension
  damping: 10,             // Air friction
  gravity: 500,            // Constant downward pull
  onUpdate: ({ targetX, targetY, states }) => {
    // Draw a visual SVG line to the target
    drawLine(targetX, targetY, states[0].px, states[0].py);
  }
});

Directional Gravity

The direction and gravityAngle properties allow you to change the vector of the gravitational pull. By default, gravity pulls straight down (direction: 'y', or gravityAngle: 90). You can pass a shorthand direction string ('x', 'y', '-x', '-y'), or define a precise gravityAngle in degrees to override the default downward pull.

Use the controls to change the gravity direction!
90°
60 FPS
js
applyTether('.balloon', {
  target: '.center-dot',
  length: 60,
  gravity: 800,
  direction: 'x',
  // OR
  gravityAngle: 270
});

Zero-Gravity Space Tether

If you set gravity: 0, the object floats freely where you leave it-until you move the mouse too far away and yank the tether.

Yank the mouse quickly!
60 FPS
js
applyTether('.ship', {
  target: 'pointer',
  length: 80, 
  stiffness: 180,
  damping: 5,
  gravity: 0
});

Element Targeting

Instead of tethering to the mouse, you can pass any DOM element as the target. The dynamics engine will automatically track its position every frame.

Target
60 FPS
js
applyTether('.node', {
  target: '.target-box',
  length: 60,
  gravity: 200
});

Multi-Node Chandelier

You can pass multiple elements into applyTether and they will all attach to the single target independently.

60 FPS
js
const nodes = document.querySelectorAll('.nodes');

nodes.forEach((node, i) => {
  applyTether(node, {
    target: 'pointer',
    length: 60 + (i * 40),
    stiffness: 160 - (i * 30),
    gravity: 800
  });
});

Properties & Methods

Configuration Options

OptionTypeDefaultDescription
targetstring | Element | Object'pointer'The anchor point the cord is attached to. Use 'pointer' for the mouse, a DOM element to tether to its center, or a coordinate object like { x: 100, y: 100 }.
lengthnumber100The "slack" of the cord, in pixels. The tether has no effect while the element is closer than this distance to the target. Only when the element drifts farther away does the spring snap taut and pull it back.
stiffnessnumber150How strongly the cord snaps back when taut. Higher values = a stiffer, snappier bungee cord that yanks the element back fast. Lower values = a very elastic, stretchy cord.
dampingnumber10Air friction. Higher values stop the bouncing quickly. Lower values cause wild bouncing after the cord goes tight.
massnumber1How heavy the element feels. Higher mass = slower to respond and more momentum when it finally moves.
gravitynumber0A constant gravitational pull in px/s². 0 = zero gravity (space simulation).
directionstring'y'Shorthand gravity direction. 'y' = straight down, 'x' = horizontally right.
gravityAnglenumberundefinedExact gravity angle in degrees (90 is straight down, 0 is right). Overrides direction.
onUpdateFunctionnullA function called every frame. Receives { targetX, targetY, states }. Useful for drawing an SVG line from the target to the element.

Return Instance

MethodDescription
kill()Stops the tether and cleans up event listeners.

The states Array

When using the onUpdate callback, the physics engine passes a states array containing real-time physical data for every tethered element. This is essential for drawing SVG lines or linking other visual indicators to your elements.

Each object in the states array contains:

PropertyTypeDescription
elElementThe DOM element being animated.
pxnumberThe absolute physical center X coordinate of the element (relative to its container grid). Use this to attach SVG lines!
pynumberThe absolute physical center Y coordinate of the element.
xnumberThe current CSS transform X offset.
ynumberThe current CSS transform Y offset.
vxnumberCurrent horizontal velocity in pixels per second.
vynumberCurrent vertical velocity in pixels per second.