Appearance
Dynamics.applySoftBody()
Adds spring physics to an SVG <path>. It treats every point on the path like a physical object connected by invisible springs, creating a "jelly-like" effect.
Container Resolution
You don't need to manually select the <path>. Just pass the <svg> container to Dynamics.applySoftBody(svg) and AnimX will find all the paths automatically!
When your mouse (or another element) gets close, it pushes or pulls the edges of the shape.
1. Pointer Tracking
By default, the path tracks your mouse and pushes away from it.
Hover the path to see the deformation.
js
import { Dynamics } from 'animx/dynamics'
// applySoftBody now returns a { kill() } engine instance
const engine = Dynamics.applySoftBody(pathEl, {
stiffness: 40, // Low = wobbly jello. High = stiff rubber.
damping: 5, // Low = long bouncy wobble. High = instant settle.
mass: 0.5, // Lower mass = nodes accelerate faster under the cursor.
neighborStiffness: 80, // How strongly adjacent nodes link (transfers the wave).
pullRadius: 180, // Cursor influence radius in SVG units.
pullForce: 800 // Push-away strength.
})
// Stop the simulation:
engine.kill()2. Physics Configuration
You can change how the object feels (like jelly or rubber) by adjusting stiffness and damping.
Compare low vs high stiffness properties.
Jelly
Rubber
js
// Jelly: extremely loose — deforms wildly and wobbles for a long time
const jelly = Dynamics.applySoftBody(jellyPath, {
stiffness: 15, damping: 2, neighborStiffness: 40
})
// Rubber: very stiff — resists hard and snaps back almost instantly
const rubber = Dynamics.applySoftBody(rubberPath, {
stiffness: 600, damping: 35, neighborStiffness: 800
})3. Custom Interactors
Instead of using the mouse, you can pass an array of HTML or SVG elements in the interactors option. The soft body will react to these elements as they move around the screen.
3a. Repulsion Forces
A high pullForce makes the path push away violently.
Repulsion with a high pullForce value.
js
const engine = Dynamics.applySoftBody(path, {
interactors: [svgCircle],
pullRadius: 50,
pullForce: 2200 // High force = violent parting effect
})3b. Multiple Interactors
You can pass multiple elements to interactors. Each one pushes the soft body independently.
Deformation driven by two distinct interactors.
js
const engine = Dynamics.applySoftBody(blob, {
interactors: [ballA, ballB], // Both balls drive deformation simultaneously
pullRadius: 75,
pullForce: 1100
})
// Ball A sweeps left→right; Ball B sweeps right→left
// Different durations → they meet inside the blob at unpredictable moments
AnimX.animate(ballA, { x: 370, duration: 1.8, ease: 'sine.inOut', yoyo: true, repeat: -1 })
AnimX.animate(ballB, { x: -370, duration: 2.2, ease: 'sine.inOut', yoyo: true, repeat: -1 })3c. Attractive Forces
If you use a negative pullForce, the path will be sucked towards the element instead of pushed away.
Attractive force via a negative pullForce.
js
const engine = Dynamics.applySoftBody(blob, {
interactors: [attractor],
stiffness: 30,
damping: 3,
pullRadius: 200,
pullForce: -1400 // Negative = attracted toward interactor!
})4. Programmatic Impulses
You can call punch(x, y, force, radius) directly on the <path> to hit it programmatically. Note that x and y must be inside the SVG's local coordinate system.
Click the SVG to trigger programmatic impulses.
js
// Convert screen click → SVG coordinate space, then punch
svgEl.addEventListener('pointerdown', (e) => {
const pt = svgEl.createSVGPoint()
pt.x = e.clientX
pt.y = e.clientY
const { x, y } = pt.matrixTransform(svgEl.getScreenCTM().inverse())
// Negative = implodes inward. Positive = explodes outward.
path.punch(x, y, -2000, 200)
})Properties & Methods
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
stiffness | number | 150 | Tension pulling nodes back to their original shape. 15 = loose jello. 600 = rigid rubber. |
damping | number | 12 | Wobble resistance. 2 = bounces for a long time. 35 = settles instantly. |
mass | number | 1 | Weight of each node. Lower mass = nodes respond faster to forces. |
neighborStiffness | number | 300 | How tightly points are connected to each other. Higher values make the wave travel further. |
pullRadius | number | 100 | How close the cursor needs to be before it affects the shape. |
pullForce | number | 150 | Force strength. Positive = push away. Negative = attract toward cursor. |
interactors | Element[] | undefined | Elements that push the shape instead of the mouse. |
interactive | boolean | true | Tracks the mouse. If true, the shape reacts to your cursor. |
Engine Instance
| Method | Description |
|---|---|
engine.kill() | Stops the physics and cleans up event listeners. |
path.punch(x, y, force, radius) | Hits the path at the (x, y) coordinates. |