Appearance
Dynamics.applyFluidDrag()
Simulate elements falling, floating, or flying through the air, water, or even thick syrup! applyFluidDrag() calculates realistic air resistance (drag) so that falling items naturally hit Terminal Velocity and don't accelerate forever.
1. High Drag Drop
Watch how a high drag value simulates dropping a ball into a thick fluid. It accelerates at first, but quickly hits its speed limit!
Click the stage to drop the ball.
js
import { applyFluidDrag } from 'animx/plugins/Dynamics';
applyFluidDrag('.ball', {
gravity: 1200, // Downward acceleration (px/s²)
drag: 0.005, // Fluid thickness (higher = thicker syrup)
bounce: 0.5, // Energy retained after hitting walls (0-1)
bounds: '#stage' // Container element for walls/floor calculation
})2. Terminal Velocity Comparison
By tweaking the drag value, you can easily simulate different physical mediums. Notice how the syrup ball barely bounces because the fluid is so thick!
Click the stage to drop all three balls.
Air
Water
Syrup
js
// Air (bounces high)
applyFluidDrag('.air', { gravity: 1500, drag: 0.0001, bounce: 0.8 });
// Water
applyFluidDrag('.water', { gravity: 1500, drag: 0.002, bounce: 0.4 });
// Thick Syrup (barely bounces)
applyFluidDrag('.syrup', { gravity: 1500, drag: 0.02, bounce: 0.1 });3. Horizontal Splash (Initial Velocity)
Because drag scales with speed, if you throw something really fast, the air resistance slows it down incredibly quickly. Perfect for splashes or explosions!
Click the stage to fire the ball horizontally.
js
applyFluidDrag('.splash', {
gravity: 800,
drag: 0.008,
initialVelocityX: 3000, // Massive initial speed
initialVelocityY: -200, // Slight upward arc
bounce: 0.4,
bounds: '#stage'
});4. Feather vs. Cannonball (Mass)
Heavy items punch right through the air, while lighter items get caught in it! By setting the mass property, you can easily replicate the classic feather vs. cannonball experiment.
Drop the items in air, then toggle the vacuum to see them drop together!
Feather
10kg
js
// Use a toggle to switch between air (drag: 0.005) and vacuum (drag: 0)
const drag = isVacuum ? 0 : 0.005;
// Feather (mass 0.5) gets slowed down heavily by air drag, but falls at 1g in vacuum
applyFluidDrag('.feather', { gravity: 1200, drag, mass: 0.5 });
// Cannonball (mass 10) punches right through the drag either way
applyFluidDrag('.cannonball', { gravity: 1200, drag, mass: 10 });5. Underwater Bubbles (Negative Gravity)
You can use negative gravity values to make things float upwards instead of falling down! When combined with a little drag, it creates a perfect underwater bubble effect.
Click to release the bubbles!
js
// Gravity points UP (-1500), but drag stops them from flying too fast!
// Each bubble gets its own engine to allow individual scatter velocities
document.querySelectorAll('.bubbles').forEach(bubble => {
applyFluidDrag(bubble, {
gravity: -1500,
drag: 0.015,
bounce: 0.3,
bounds: '#stage',
initialVelocityX: (Math.random() - 0.5) * 800
});
});6. Directional Fluid Flow (Horizontal)
The direction property controls the axis of gravitational pull. Setting it to 'x' applies gravity and fluid resistance horizontally.
Toggle direction to see horizontal fluid drag.
js
applyFluidDrag('.ball', {
direction: 'x', // Pushes to the right
gravity: 1500, // Rightward acceleration
drag: 0.005, // Fluid thickness
bounce: 0.4,
bounds: '#stage' // Hits the right wall and slides down
});Properties & Methods
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
gravity | number | 980 | Acceleration along the active axis (px/s²). Negative values reverse the pull direction. |
direction | 'y' | 'x' | 'y' | The axis gravity acts on. 'y' pulls downward, 'x' pulls rightward. |
drag | number | 0.002 | How thick the fluid is. Higher numbers (like 0.02) simulate thick syrup, while low numbers simulate thin air. |
mass | number | 1 | The weight of the item. Heavier items ignore drag more easily. |
bounce | number | 0.5 | How bouncy the item is when it hits the bounds (0 is a dead stop, 1 is perfectly bouncy). |
bounds | string | Element | { minX?: number, maxX?: number, minY?: number, maxY?: number } | null | The container element or custom limits so items know where the floor and walls are. |
floor | number | undefined | Absolute boundary fallback in the active axis (right edge when direction: 'x'). Useful if not using bounds. |
initialVelocityX | number | 0 | Give the item an instant horizontal push when the engine starts (px/s). |
initialVelocityY | number | 0 | Give the item an instant vertical push when the engine starts (px/s). |
Engine Methods
The object returned by applyFluidDrag() lets you interact with the running simulation:
| Method | Description |
|---|---|
kill() | Stops the physics engine immediately and cleans up. |
injectVelocity(el, vx, vy) | Instantly applies a push (velocity in px/s) to the element while it's running. |