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

core-animation.mddocs/

Core Animation

The core animation system provides a unified interface for creating different types of animations with comprehensive playback controls and lifecycle management.

Capabilities

Animate Function

The primary animation function that detects animation type from options and provides unified control interface.

/**
 * Creates an animation from the provided options
 * @param options - Animation configuration including type, timing, and callbacks
 * @returns PlaybackControls interface for stopping the animation
 */
function animate<V = number>(options: AnimationOptions<V>): PlaybackControls;

interface PlaybackControls {
  /** Stop the animation immediately */
  stop: () => void;
}

type AnimationOptions<V> = PlaybackOptions<V> & 
  (DecayOptions | KeyframeOptions<V> | SpringOptions);

interface PlaybackOptions<V> {
  /** Whether to start animation immediately (default: true) */
  autoplay?: boolean;
  /** Custom driver for animation timing (default: framesync) */
  driver?: Driver;
  /** Starting elapsed time in milliseconds */
  elapsed?: number;
  /** Starting value for animation */
  from?: V;
  /** Number of times to repeat animation (0 = no repeat) */
  repeat?: number;
  /** How to handle repeats: loop, reverse, or mirror */
  repeatType?: "loop" | "reverse" | "mirror";
  /** Delay between repeats in milliseconds */
  repeatDelay?: number;
  /** Animation type hint (auto-detected if not provided) */
  type?: "spring" | "decay" | "keyframes";
  /** Called with latest value on each frame */
  onUpdate?: (latest: V) => void;
  /** Called when animation starts playing */
  onPlay?: () => void;
  /** Called when animation completes (not on stop) */
  onComplete?: () => void;
  /** Called each time animation repeats */
  onRepeat?: () => void;
  /** Called when animation is stopped */
  onStop?: () => void;
}

Usage Examples:

import { animate } from "popmotion";

// Basic keyframe animation
animate({
  from: 0,
  to: 100,
  duration: 1000,
  onUpdate: (value) => element.style.opacity = value / 100
});

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

// Repeating animation with callbacks
const controls = animate({
  from: 0,
  to: 360,
  duration: 2000,
  repeat: Infinity,
  repeatType: "loop",
  onUpdate: (degrees) => element.style.transform = `rotate(${degrees}deg)`,
  onComplete: () => console.log("Animation complete"),
  onRepeat: () => console.log("Animation repeating")
});

// Stop animation later
setTimeout(() => controls.stop(), 5000);

Driver System

The driver system allows custom timing mechanisms for animations, with framesync as the default.

/**
 * Animation driver interface for custom timing control
 * @param update - Function to call with elapsed time
 * @returns Controls for starting and stopping the driver
 */
type Driver = (update: (timestamp: number) => void) => DriverControls;

interface DriverControls {
  /** Start the driver timing loop */
  start: () => void;
  /** Stop the driver timing loop */
  stop: () => void;
}

Usage Examples:

import { animate } from "popmotion";

// Custom driver using setInterval
const intervalDriver = (update) => {
  let intervalId;
  let startTime = Date.now();
  
  return {
    start: () => {
      intervalId = setInterval(() => {
        update(Date.now() - startTime);
      }, 16); // ~60fps
    },
    stop: () => clearInterval(intervalId)
  };
};

animate({
  from: 0,
  to: 100,
  duration: 1000,
  driver: intervalDriver,
  onUpdate: (value) => console.log(value)
});

Animation State

The animation state interface defines the structure returned by animation generators.

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

interface AnimationState<V> {
  /** Current animated value */
  value: V;
  /** Whether animation has completed */
  done: boolean;
}

Repeat Modes

Loop Mode

Restarts animation from beginning on each repeat.

animate({
  from: 0,
  to: 100,
  duration: 1000,
  repeat: 3,
  repeatType: "loop" // 0→100, 0→100, 0→100, 0→100
});

Reverse Mode

Alternates direction on each repeat.

animate({
  from: 0,
  to: 100,
  duration: 1000,
  repeat: 3,
  repeatType: "reverse" // 0→100, 100→0, 0→100, 100→0
});

Mirror Mode

Flips the target value on each repeat while maintaining direction.

animate({
  from: 0,
  to: 100,
  duration: 1000,
  repeat: 3,
  repeatType: "mirror" // 0→100, 100→0, 0→100, 100→0
});

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