Skip to content

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. By pairing it with Interactable and Dynamics.trackVelocity(), you can flick things around the screen naturally.

Grab the ball and flick it across the stage!
60 FPS
js
import { Dynamics } from 'animx/dynamics'
import { Interactable } from 'animx/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 = Dynamics.trackVelocity('.ball', 'x,y');
  },
  onRelease() {
    // 3. When released, throw the ball with the captured speed
    throwEngine = Dynamics.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!
60 FPS
js
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 (-150 to 150)
60 FPS
js
Dynamics.throwTo('.ball', {
  x: { 
    velocity: 1500, 
    friction: 0.99, 
    min: -150, 
    max: 150 
  }
});

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: 200
60 FPS
js
Dynamics.throwTo('.ball', {
  x: { 
    velocity: 800,   // Travels roughly 220px naturally
    friction: 0.94,
    end: 200         // Once it stops completely, snap exactly to 200
  }
});

Properties & Methods

Per-Property Options

For each property (like x: or y:), you can set:

OptionTypeDefaultDescription
velocitynumber0The starting speed, in pixels per second. 1000 launches fast. -500 launches in the opposite direction.
frictionnumber0.85How quickly it slows down. 1.0 = it never slows down (frictionless glide forever). 0.85 = it loses speed quickly. 0.95 = slow, gradual deceleration.
accelerationnumber0A constant push in a specific direction. Useful for simulating gravity.
minnumber-InfinityThe leftmost (or topmost) boundary. The element bounces when its position reaches this value.
maxnumberInfinityThe rightmost (or bottommost) boundary. The element bounces when it reaches this value.
endnumbernullA final snap point. Once the element stops naturally, it will instantly snap to this exact coordinate.

Global Config Options

Global options for the whole throw effect:

OptionTypeDescription
boundsstring | Element | { minX?: number, maxX?: number, minY?: number, maxY?: number }A container or specific boundaries. AnimX will bounce off these limits.
onUpdateFunctionA function called every frame. Gives you the exact speed and position of the elements.
onCompleteFunctionA function called when everything comes to a complete stop.
onWallBounceFunctionA function called when the element hits a wall. Tells you which wall it hit and how fast it was going.

Return Instance

MethodDescription
kill()Stops the throw immediately.