CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-popmotion

The animator's toolbox providing comprehensive animation capabilities including keyframe, spring, and decay animations for numbers, colors, and complex strings

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

animation-generators.mddocs/

Animation Generators

Animation generators are specialized functions that create different types of motion patterns with precise control over physics parameters and timing. They return Animation objects that can be used directly or with the core animate function.

Capabilities

Spring Animation Generator

Creates physics-based spring animations with natural motion characteristics.

/**
 * Creates a spring animation generator
 * @param options - Spring configuration including physics parameters
 * @returns Animation generator for spring motion
 */
function spring(options: SpringOptions): Animation<number>;

interface SpringOptions extends PhysicsSpringOptions {
  /** Starting value */
  from?: number;
  /** Target value */
  to?: number;
  /** Duration in milliseconds (alternative to physics params) */
  duration?: number;
  /** Bounce factor (0-1, alternative to damping) */
  bounce?: number;
  /** Speed threshold for completion detection */
  restSpeed?: number;
  /** Distance threshold for completion detection */
  restDelta?: number;
}

interface PhysicsSpringOptions {
  /** Initial velocity */
  velocity?: number;
  /** Spring stiffness (higher = stiffer) */
  stiffness?: number;
  /** Spring damping (higher = less oscillation) */
  damping?: number;
  /** Mass of the animated object */
  mass?: number;
}

Usage Examples:

import { spring, animate } from "popmotion";

// Direct spring generator usage
const springGen = spring({
  from: 0,
  to: 100,
  stiffness: 400,
  damping: 40
});

// Manual stepping
let time = 0;
const step = () => {
  const { value, done } = springGen.next(time);
  console.log(value);
  time += 16;
  if (!done) requestAnimationFrame(step);
};
step();

// With animate function (recommended)
animate({
  from: 0,
  to: 100,
  type: "spring",
  stiffness: 400,
  damping: 40,
  onUpdate: (value) => element.style.left = value + "px"
});

// Duration-based spring (easier tuning)
animate({
  from: 0,
  to: 100,
  type: "spring",
  duration: 800,
  bounce: 0.25
});

Decay Animation Generator

Creates exponential decay animations typically used for momentum scrolling and drag interactions.

/**
 * Creates a decay animation generator
 * @param options - Decay configuration including velocity and physics
 * @returns Animation generator for decay motion
 */
function decay(options: DecayOptions): Animation<number>;

interface DecayOptions {
  /** Starting value */
  from?: number;
  /** Target value (optional, not used in decay calculation) */
  to?: number;
  /** Initial velocity */
  velocity?: number;
  /** Decay power factor (default: 0.8) */
  power?: number;
  /** Time constant for decay rate */
  timeConstant?: number;
  /** Function to modify calculated target */
  modifyTarget?: (target: number) => number;
  /** Distance threshold for completion */
  restDelta?: number;
}

Usage Examples:

import { decay, animate } from "popmotion";

// Momentum scrolling effect
let scrollY = 0;
animate({
  from: scrollY,
  velocity: -500, // Initial upward velocity
  type: "decay",
  power: 0.8,
  timeConstant: 325,
  onUpdate: (value) => {
    scrollY = value;
    element.scrollTop = Math.max(0, value);
  }
});

// Drag release with boundaries
animate({
  from: currentX,
  velocity: dragVelocity,
  type: "decay",
  modifyTarget: (target) => Math.max(0, Math.min(maxX, target)),
  onUpdate: (x) => element.style.transform = `translateX(${x}px)`
});

// Custom decay with direct generator
const decayGen = decay({
  from: 100,
  velocity: -200,
  power: 0.9
});

Keyframes Animation Generator

Creates keyframe-based animations with support for multiple values, custom easing per segment, and time offsets.

/**
 * Creates a keyframe animation generator
 * @param options - Keyframe configuration including values and timing
 * @returns Animation generator for keyframe motion
 */
function keyframes<V = number>(options: KeyframeOptions<V>): Animation<V>;

interface KeyframeOptions<V = number> {
  /** Target values (array creates keyframes, single value creates simple tween) */
  to: V | V[];
  /** Starting value */
  from?: V;
  /** Total duration in milliseconds */
  duration?: number;
  /** Easing function(s) - single for all segments or array per segment */
  ease?: Easing | Easing[];
  /** Time offsets for each keyframe (0-1, length must match values) */
  offset?: number[];
}

Usage Examples:

import { keyframes, animate } from "popmotion";

// Simple keyframes
animate({
  from: 0,
  to: [25, 50, 75, 100],
  duration: 2000,
  onUpdate: (value) => element.style.left = value + "px"
});

// Complex keyframes with different easing per segment
animate({
  from: 0,
  to: [50, 100, 0],
  duration: 3000,
  ease: ["easeOut", "linear", "easeIn"],
  onUpdate: (value) => element.style.opacity = value / 100
});

// Custom timing with offsets
animate({
  from: 0,
  to: [20, 80, 100],
  duration: 2000,
  offset: [0, 0.1, 1], // 20% at 10% through, 80% at 100%
  ease: "easeInOut",
  onUpdate: (value) => element.style.transform = `scale(${value / 100})`
});

// Color keyframes
animate({
  from: "#ff0000",
  to: ["#00ff00", "#0000ff", "#ff0000"],
  duration: 3000,
  onUpdate: (color) => element.style.backgroundColor = color
});

Animation Object Interface

All generators return Animation objects with a consistent interface:

interface Animation<V> {
  /**
   * Calculate animation state at given time
   * @param t - Elapsed time in milliseconds
   * @returns Current value and completion status
   */
  next: (t: number) => {
    value: V;
    done: boolean;
  };
  
  /** Flip target for mirror-type repeat animations */
  flipTarget: () => void;
}

Physics Parameter Guidelines

Spring Parameters

  • Stiffness: 100-1000 (higher = faster, snappier)
  • Damping: 10-100 (higher = less bounce)
  • Mass: 0.1-10 (higher = slower, more momentum)
  • Duration: 300-2000ms (alternative to physics params)
  • Bounce: 0-1 (0 = no bounce, 1 = maximum bounce)

Decay Parameters

  • Power: 0.6-0.9 (higher = slower decay)
  • TimeConstant: 100-500ms (higher = longer decay)
  • Velocity: Depends on interaction (pixels/second)

Keyframe Parameters

  • Duration: 500-5000ms typical range
  • Offset: Must sum to 1.0 if provided
  • Ease: Can be different for each segment

Install with Tessl CLI

npx tessl i tessl/npm-popmotion

docs

animation-generators.md

core-animation.md

easing.md

index.md

inertia.md

utilities.md

tile.json