Skip to content

Dynamics.trackVelocity()

Measures the real-time rate of change of any numerical CSS property (such as x, y, opacity, or width). It does not animate elements directly but provides live velocity data.

This is how you connect user interactions (like dragging) to physics (like throwing).

The properties you wish to track can be provided as either a comma-separated string ('x, y') or an array (['x', 'y']).


1. Reading Live Velocity

As you drag the box, the tracker calculates the exact speed (in pixels per second) for x and y.

Drag the box!
VX: 0px/s
VY: 0px/s
60 FPS
js
import { trackVelocity } from 'animx/plugins/Dynamics';
import { Interactable } from 'animx/plugins/Interactable';

const tracker = trackVelocity('.box', 'x,y');

Interactable.create('.box', {
  onDrag() {
    console.log("X Speed:", tracker.get('x'));
    console.log("Y Speed:", tracker.get('y'));
  }
});

2. Velocity-Driven UI

You can use the live speed to dynamically drive other properties, like scale or color. Drag this box left and right-the faster you move it, the larger and redder it gets!

Drag the box at different speeds!
60 FPS
js
const tracker = trackVelocity('.box', 'x');

Interactable.create('.box', {
  onDrag() {
    const vx = Math.abs(tracker.get('x'));
    const progress = Math.min(vx / 1500, 1);
    
    const color = \`hsl(\${217 - (progress * 217)}, 90%, 60%)\`;
    
    // Scale the box and change its color
    animate('.box', {
      scale: 1 + (progress * 1.5),
      backgroundColor: color,
      duration: 0.15
    });
    
    // Fill the speed bar
    animate('.bar', {
      width: \`\${progress * 100}%\`,
      backgroundColor: color,
      duration: 0.15
    });
  },
  onRelease() {
    animate(['.box', '.bar'], { backgroundColor: 'hsl(217, 90%, 60%)', duration: 0.5 });
    animate('.box', { scale: 1, duration: 0.5 });
    animate('.bar', { width: '0%', duration: 0.5 });
  }
});

3. The Handoff (Throwing)

The most common use is capturing the exact speed when the user releases an element, and then passing that speed to throwTo.

Throw the ball around the room!
60 FPS
js
import { trackVelocity, throwTo } from 'animx/plugins/Dynamics';
import { Interactable } from 'animx/plugins/Interactable';

let tracker;
let throwEngine;

Interactable.create('.ball', {
  onPress() {
    if (throwEngine) throwEngine.kill();
    tracker = trackVelocity('.ball', 'x,y');
  },
  onRelease() {
    throwEngine = throwTo('.ball', {
      x: { velocity: tracker.get('x') },
      y: { velocity: tracker.get('y') }
    });
    tracker.kill();
  }
});

4. Tracking Rotation & Scale

You can track spatial properties beyond just X and Y. Here we are measuring the live rotational velocity (degrees/second) and scale velocity (scale units/second) of an animating wheel!

Watch the readouts during the tween!
Rotation Speed: 0 °/s
Scale Speed: 0 units/s
60 FPS
js
const tracker = trackVelocity('.wheel', 'rotation, scale');

animate('.wheel', {
  rotation: 360,
  scale: 1.5,
  duration: 2,
  onUpdate() {
    console.log("Rotate Velocity:", tracker.get('rotation'));
    console.log("Scale Velocity:", tracker.get('scale'));
  }
});

5. Tracking Native CSS Properties

Because the tracker calculates the numeric change per frame, it can track the real-time velocity of any numeric CSS property, not just transforms! Here we track width (pixels/second) and opacity (units/second).

Native CSS velocity tracking
Width Growth: 0 px/s
Opacity Fade: 0 units/s
60 FPS
js
const tracker = trackVelocity('.bar', 'width, opacity');

animate('.bar', {
  width: '240px',
  opacity: 0.2,
  duration: 1.5,
  onUpdate() {
    console.log("Width Velocity:", tracker.get('width'), "px/s");
    console.log("Opacity Velocity:", tracker.get('opacity'), "/s");
  }
});

Properties & Methods

MethodDescription
get(property)Gets the current speed of the property in pixels/sec (or degrees/sec for rotation). Positive means it's moving right/down. Negative means left/up.
kill()Stops tracking. Always call this when you are done (like when the user lets go) to save memory.