The animator's toolbox providing comprehensive animation capabilities including keyframe, spring, and decay animations for numbers, colors, and complex strings
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Comprehensive collection of easing functions for natural motion feel, plus utilities for creating custom easing curves and modifying existing ones.
Pre-defined easing functions for common animation patterns.
type Easing = (v: number) => number;
// Linear easing
const linear: Easing;
// Exponential easing
const easeIn: Easing;
const easeOut: Easing;
const easeInOut: Easing;
// Circular easing
const circIn: Easing;
const circOut: Easing;
const circInOut: Easing;
// Back easing (with overshoot)
const backIn: Easing;
const backOut: Easing;
const backInOut: Easing;
// Bounce easing
const bounceIn: Easing;
const bounceOut: Easing;
const bounceInOut: Easing;
// Special easing
const anticipate: Easing;Usage Examples:
import { animate, easeOut, bounceOut, anticipate } from "popmotion";
// Using pre-defined easing
animate({
from: 0,
to: 100,
duration: 1000,
ease: easeOut,
onUpdate: (value) => element.style.left = value + "px"
});
// Bounce animation
animate({
from: 0,
to: 100,
duration: 800,
ease: bounceOut,
onUpdate: (value) => element.style.transform = `translateY(${value}px)`
});
// Anticipate for UI interactions
animate({
from: 1,
to: 1.2,
duration: 200,
ease: anticipate,
onUpdate: (scale) => button.style.transform = `scale(${scale})`
});Functions for creating custom easing curves with precise control.
/**
* Creates a cubic Bezier easing function
* @param mX1 - First control point X coordinate (0-1)
* @param mY1 - First control point Y coordinate
* @param mX2 - Second control point X coordinate (0-1)
* @param mY2 - Second control point Y coordinate
* @returns Custom cubic Bezier easing function
*/
function cubicBezier(mX1: number, mY1: number, mX2: number, mY2: number): Easing;
/**
* Creates a stepped easing function for discrete animations
* @param steps - Number of steps in the animation
* @param direction - Whether to change at start or end of each step
* @returns Stepped easing function
*/
function steps(steps: number, direction?: "start" | "end"): Easing;Usage Examples:
import { animate, cubicBezier, steps } from "popmotion";
// Custom cubic Bezier (CSS equivalent: cubic-bezier(0.25, 0.46, 0.45, 0.94))
const customEase = cubicBezier(0.25, 0.46, 0.45, 0.94);
animate({
from: 0,
to: 100,
duration: 1000,
ease: customEase,
onUpdate: (value) => element.style.opacity = value / 100
});
// Stepped animation (like frame-by-frame)
const stepEase = steps(8, "end");
animate({
from: 0,
to: 8,
duration: 2000,
ease: stepEase,
onUpdate: (frame) => sprite.style.backgroundPosition = `-${Math.floor(frame) * 64}px 0`
});
// Material Design easing curves
const fastOutSlowIn = cubicBezier(0.4, 0, 0.2, 1);
const fastOutLinearIn = cubicBezier(0.4, 0, 1, 1);
const linearOutSlowIn = cubicBezier(0, 0, 0.2, 1);Advanced utilities for creating and modifying easing functions.
/**
* Mirrors an easing function for the second half of animation
* @param easing - Base easing function to mirror
* @returns Mirrored easing function that mirrors at halfway point
*/
function mirrorEasing(easing: Easing): Easing;
/**
* Reverses the direction of an easing function
* @param easing - Base easing function to reverse
* @returns Reversed easing function (easeIn becomes easeOut)
*/
function reverseEasing(easing: Easing): Easing;
/**
* Creates exponential easing with custom power
* @param power - Exponential power factor (higher = more dramatic)
* @returns Custom exponential easing function using p^power
*/
function createExpoIn(power: number): Easing;
/**
* Creates back easing with custom overshoot
* @param power - Overshoot amount (higher = stronger pullback)
* @returns Custom back easing function with overshoot effect
*/
function createBackIn(power: number): Easing;
/**
* Creates anticipate easing with custom power
* @param power - Anticipation strength (higher = more pullback)
* @returns Custom anticipate easing combining back-in with expo-out
*/
function createAnticipate(power: number): Easing;
type EasingModifier = (easing: Easing) => Easing;Usage Examples:
import {
easeIn,
mirrorEasing,
reverseEasing,
createExpoIn,
createBackIn,
createAnticipate
} from "popmotion";
// Mirror easing for symmetrical motion
const mirroredEase = mirrorEasing(easeIn);
animate({
from: 0,
to: 100,
duration: 2000,
ease: mirroredEase, // Ease in for first half, ease out for second half
onUpdate: (value) => element.style.left = value + "px"
});
// Reversed easing - converts easeIn to easeOut
const reversedEase = reverseEasing(easeIn); // Equivalent to easeOut
animate({
from: 0,
to: 100,
duration: 1000,
ease: reversedEase, // Same curve as easeOut
onUpdate: (value) => element.style.opacity = value / 100
});
// Custom exponential easing with different powers
const quadratic = createExpoIn(2); // p^2 - gentle curve
const cubic = createExpoIn(3); // p^3 - moderate curve
const quartic = createExpoIn(4); // p^4 - dramatic curve
animate({
from: 0,
to: 100,
duration: 1000,
ease: quartic, // Very dramatic ease-in
onUpdate: (value) => element.style.transform = `scale(${1 + value / 100})`
});
// Custom back easing with different overshoot amounts
const subtleBack = createBackIn(2); // Gentle pullback
const normalBack = createBackIn(3); // Standard pullback
const strongBack = createBackIn(4); // Strong pullback
animate({
from: 0,
to: 100,
duration: 800,
ease: strongBack, // Strong overshoot effect
onUpdate: (value) => element.style.left = value + "px"
});
// Custom anticipate easing for UI interactions
const subtleAnticipate = createAnticipate(2);
const strongAnticipate = createAnticipate(4);
// Perfect for button hover effects
button.addEventListener('mouseenter', () => {
animate({
from: 1,
to: 1.1,
duration: 200,
ease: subtleAnticipate, // Subtle pullback then forward
onUpdate: (scale) => button.style.transform = `scale(${scale})`
});
});
// Combining utilities for complex effects
const complexEase = mirrorEasing(createExpoIn(3));
animate({
from: 1,
to: 0,
duration: 1500,
ease: complexEase, // Exponential ease-in-out with power 3
onUpdate: (value) => element.style.opacity = value
});
// Creating custom modifier chains
const customModifier = (easing: Easing) =>
mirrorEasing(reverseEasing(easing));
const uniqueEase = customModifier(createBackIn(2));// Combine multiple easing functions
const complexEase = (t: number) => {
if (t < 0.5) {
return easeIn(t * 2) / 2;
} else {
return (easeOut((t - 0.5) * 2) + 1) / 2;
}
};
// Use with animations
animate({
from: 0,
to: 100,
duration: 1000,
ease: complexEase,
onUpdate: (value) => console.log(value)
});Install with Tessl CLI
npx tessl i tessl/npm-popmotion