Appearance
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!
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!
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!
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.
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.
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
| Option | Type | Default | Description |
|---|---|---|---|
target | string | 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 }. |
length | number | 100 | The "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. |
stiffness | number | 150 | How 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. |
damping | number | 10 | Air friction. Higher values stop the bouncing quickly. Lower values cause wild bouncing after the cord goes tight. |
mass | number | 1 | How heavy the element feels. Higher mass = slower to respond and more momentum when it finally moves. |
gravity | number | 0 | A constant gravitational pull in px/s². 0 = zero gravity (space simulation). |
direction | string | 'y' | Shorthand gravity direction. 'y' = straight down, 'x' = horizontally right. |
gravityAngle | number | undefined | Exact gravity angle in degrees (90 is straight down, 0 is right). Overrides direction. |
onUpdate | Function | null | A function called every frame. Receives { targetX, targetY, states }. Useful for drawing an SVG line from the target to the element. |
Return Instance
| Method | Description |
|---|---|
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:
| Property | Type | Description |
|---|---|---|
el | Element | The DOM element being animated. |
px | number | The absolute physical center X coordinate of the element (relative to its container grid). Use this to attach SVG lines! |
py | number | The absolute physical center Y coordinate of the element. |
x | number | The current CSS transform X offset. |
y | number | The current CSS transform Y offset. |
vx | number | Current horizontal velocity in pixels per second. |
vy | number | Current vertical velocity in pixels per second. |