Appearance
Dynamics.throwTo()
throwTo gives an element an initial speed and lets friction slow it down naturally. It's the secret behind buttery smooth swipe, flick, and scroll physics.
1. Swipe & Flick Integration
The most common use is throwing elements after dragging them. Pairing it with Interactable and trackVelocity() lets elements be flicked across the screen naturally.
Grab the ball and flick it across the stage!
js
import { throwTo, trackVelocity } from 'animx/plugins/Dynamics';
import { Interactable } from 'animx/plugins/Interactable';
let tracker;
let throwEngine;
Interactable.create('.ball', {
bounds: '#stage',
onPress() {
// 1. Kill active inertia so it doesn't fight our dragging!
if (throwEngine) throwEngine.kill();
// 2. Start measuring velocity as the user drags
tracker = trackVelocity('.ball', 'x,y');
},
onRelease() {
// 3. When released, throw the ball with the captured speed
throwEngine = throwTo('.ball', {
x: { velocity: tracker.get('x'), friction: 0.95 },
y: { velocity: tracker.get('y'), friction: 0.95 }
}, { bounds: '#stage' });
tracker.kill();
}
});2. Programmatic Momentum
You don't need to drag an element to throw it. You can trigger throwTo in code with high speed, and it will bounce off the walls until friction stops it.
Click the button to spawn and blast the ball!
js
import { throwTo } from 'animx/plugins/Dynamics';
throwTo('.ball', {
x: { velocity: 1800, friction: 0.94 }, // Realistic flick, natural stopping friction
y: { velocity: -1200, friction: 0.94 }
}, { bounds: '#stage' });3. Numeric Limits
If you don't use a bounds element, you can set strict min and max limits for each direction. The object will bounce when it hits these limits.
Click to throw with x-axis limits (-80 to 80)
js
import { throwTo } from 'animx/plugins/Dynamics';
throwTo('.ball', {
x: {
velocity: 1500,
friction: 0.99,
min: -80,
max: 80
}
});4. Final Alignment (Snap)
Sometimes you want a thrown item to glide to a stop naturally, but then perfectly snap to an exact pixel coordinate at the very end.
If you provide an end coordinate, AnimX will let the element slide naturally until it stops, and then instantly snap it to that exact coordinate.
Click to throw. It will naturally slide, then snap exactly to the line!
x: 100
js
import { throwTo } from 'animx/plugins/Dynamics';
throwTo('.ball', {
x: {
velocity: 800, // Travels roughly 220px naturally
friction: 0.94,
end: 100 // Once it stops completely, snap exactly to 100
}
});5. Universal Property Support
Just like springTo, throwTo isn't limited to x and y positional coordinates. It dynamically supports any CSS or transform property. You can apply momentum and friction to rotate, scale, opacity, borderRadius, and more!
1. Swipe-to-Dismiss (x, rotate, opacity)
Throwing multiple properties at once creates incredibly fluid, natural interactions. Here, we throw a notification off-screen, giving momentum to its position, rotation, and opacity simultaneously.
Drag notifications left or right to dismiss!
js
import { animate } from 'animx';
import { throwTo } from 'animx/plugins/Dynamics';
import { Interactable } from 'animx/plugins/Interactable';
const notifs = document.querySelectorAll('.notif');
notifs.forEach(notif => {
let throwEngine;
Interactable.create(notif, {
type: 'x',
inertia: false,
onPress: () => {
if (throwEngine) throwEngine.kill();
apply(notif, { scale: 0.98 });
},
onDrag: (self) => {
apply(notif, {
rotate: self.x * 0.05,
opacity: 1 - Math.abs(self.x) / 400
});
},
onRelease: (self) => {
let velX = self.velocityX;
if (Math.abs(self.x) > 120 || Math.abs(velX) > 600) {
if (Math.abs(velX) < 400) velX = Math.sign(self.x) * 1200;
throwEngine = throwTo(notif, {
x: { velocity: velX, friction: 0.90 },
rotate: { velocity: velX * 0.2, friction: 0.90 },
opacity: { velocity: -10, friction: 0.85 }
});
animate(notif, { height: 0, padding: 0, margin: 0, opacity: 0, duration: 0.3 });
} else {
animate(notif, { x: 0, rotate: 0, opacity: 1, scale: 1, duration: 0.4, ease: 'back.out' });
}
}
});
});2. Full 3D Physics (rotateX, rotateY, rotateZ)
Because throwTo handles any CSS transform, you can easily throw an element in 3D space by animating multiple rotation axes together.
Click to flick the card!
AnimX
**** **** **** 4096
Universal Physics
js
import { throwTo } from 'animx/plugins/Dynamics';
throwTo('.card', {
rotateX: { velocity: 800, friction: 0.97 },
rotateY: { velocity: 1200, friction: 0.97 },
rotateZ: { velocity: 200, friction: 0.97 }
});3. "Add to Cart" Toss (x, y, scale, rotate)
By combining spatial movement (x, y), acceleration (gravity), scale, and rotate, you can create complex, satisfying animations like tossing an item into a shopping cart.
Click Add to Cart!
AnimX Kicks
$120.00
js
import { throwTo } from 'animx/plugins/Dynamics';
// 1. Toss item toward the cart in a perfect parabola (friction: 1)
throwTo('.item', {
x: { velocity: 300, friction: 1 },
y: { velocity: -600, acceleration: 2000, friction: 1 },
scale: { velocity: -3.2, friction: 1, min: 0 }, // Shrinks down
rotate: { velocity: 400, friction: 1 }
});
// 2. Cart anticipation: tip back to "open its mouth"
animate('.cart', {
rotate: -15, scaleX: 1.1, scaleY: 0.9,
duration: 0.2, delay: 0.1
});
// 3. Cart pop (catch the item)
animate('.cart', {
scale: 1.3, scaleX: 1, scaleY: 1, rotate: 5,
duration: 0.15, yoyo: true, delay: 0.3,
onComplete: () => {
animate('.cart', { rotate: 0, scale: 1, duration: 0.2 });
}
});Properties & Methods
Per-Property Options
For each property (like x:, y:, rotate:, scale:), you can set:
| Option | Type | Default | Description |
|---|---|---|---|
velocity | number | 0 | The starting speed, in units per second (e.g. pixels for x/y, degrees for rotate). 1000 is a fast launch. -500 launches in the opposite direction. |
friction | number | 0.85 | How quickly it slows down. 1.0 = frictionless glide forever. 0.85 = loses speed quickly. 0.95 = slow, gradual deceleration. |
acceleration | number | 0 | A constant push applied every tick (e.g. simulating gravity for y, or wind resistance). |
min | number | -Infinity | The minimum allowed value (e.g. leftmost boundary for x, or 0 for opacity). The value "bounces" when it drops below this limit. |
max | number | Infinity | The maximum allowed value (e.g. rightmost boundary for x, or 1 for opacity). The value "bounces" when it exceeds this limit. |
end | number | null | A final snap value. Once the property stops changing naturally, it instantly snaps to this exact value. |
Global Config Options
Global options for the whole throw effect:
| Option | Type | Description |
|---|---|---|
bounds | string | Element | { minX?: number, maxX?: number, minY?: number, maxY?: number } | A container or specific boundaries. AnimX will bounce off these limits. |
onUpdate | Function | A function called every frame. Gives you the exact speed and position of the elements. |
onComplete | Function | A function called when everything comes to a complete stop. |
onWallBounce | Function | A function called when the element hits a wall. Tells you which wall it hit and how fast it was going. |
Return Instance
| Method | Description |
|---|---|
kill() | Stops the throw immediately. |