Skip to main content
Impact: HIGH - Creates natural, organic motion instead of mechanical animations
This skill covers using Remotion’s spring() function to create physics-based animations that feel organic and alive, rather than robotic and linear.

Prefer spring() Over interpolate()

Use spring() for natural motion, interpolate() only for linear progress.
const scale = interpolate(frame, [0, 30], [0, 1], {
  extrapolateRight: "clamp",
});
Springs create subtle overshoot and settling that makes animations feel more natural and less “computed”. This small detail makes a huge difference in perceived quality.

Spring Config Parameters

spring({
  frame,
  fps,
  config: {
    damping: 10, // Higher = less bounce (10-200)
    stiffness: 100, // Higher = faster snap (50-200)
    mass: 1, // Higher = more inertia (0.5-3)
  },
});
Controls how quickly the spring settles.
  • Low (8-12): Bouncy, playful, overshoots significantly
  • Medium (15-20): Balanced, subtle bounce
  • High (100-200): Smooth, minimal overshoot
damping: 12  // Playful bounce
damping: 200 // Almost no bounce
Controls how quickly the spring accelerates.
  • Low (50-80): Slow, gentle acceleration
  • Medium (100-150): Balanced snap
  • High (170-200): Fast, snappy motion
stiffness: 80  // Gentle
stiffness: 200 // Snappy
Controls the “weight” of the animated object.
  • Low (0.5-1): Light, responsive
  • Medium (1-1.5): Natural weight
  • High (2-3): Heavy, sluggish
mass: 0.5  // Light object
mass: 2    // Heavy object

Common Spring Presets

// Snappy, minimal bounce (UI elements)
const snappy = { damping: 20, stiffness: 200 };

// Bouncy entrance (playful animations)
const bouncy = { damping: 8, stiffness: 100 };

// Smooth, no bounce (subtle reveals)
const smooth = { damping: 200, stiffness: 100 };

// Heavy, slow (large objects)
const heavy = { damping: 15, stiffness: 80, mass: 2 };
config: { damping: 20, stiffness: 200 }
Best for: UI elements, buttons, toggles, quick interactionsFast and responsive with minimal overshoot.

Delayed Spring Start

Offset the frame for delayed spring animations:
const entrance = spring({ frame, fps, config: { damping: 12 } });
When frame - ENTRANCE_DELAY is negative, spring() automatically returns 0. This makes delayed starts very simple.

Spring for Scale with Overshoot

For bouncy scale animations that overshoot:
const bounce = spring({
  frame,
  fps,
  config: { damping: 8, stiffness: 150 },
});
// Will overshoot past 1.0 before settling

<div style={{ transform: `scale(${bounce})` }}>{content}</div>;
Low damping (8-12) creates overshoot above 1.0. Be aware that elements may temporarily grow larger than their final size.

Combining Spring with Interpolate

Map spring output (0-1) to custom ranges:
const springProgress = spring({ frame, fps, config: { damping: 15 } });

// Map to rotation
const rotation = interpolate(springProgress, [0, 1], [0, 360]);

// Map to position
const translateY = interpolate(springProgress, [0, 1], [50, 0]);

<div style={{ transform: `translateY(${translateY}px) rotate(${rotation}deg)` }}>
This pattern is powerful: use spring for the timing/easing, then map its output to whatever range you need.

Chained Springs for Sequential Motion

const PHASE_1_END = 30;
const PHASE_2_START = 25; // Slight overlap

const phase1 = spring({ frame, fps, config: { damping: 15 } });
const phase2 = spring({
  frame: frame - PHASE_2_START,
  fps,
  config: { damping: 12 },
});

// phase1 controls entrance, phase2 controls secondary motion
Starting phase 2 before phase 1 completes creates fluid, continuous motion rather than start-stop-start animation.

Key Patterns

1

Choose Spring Config

Match the config to the desired feel:
  • Playful: Low damping (8-12)
  • Professional: Medium damping (15-20)
  • Elegant: High damping (100-200)
2

Delay with Frame Offset

spring({ frame: frame - delay, fps })
Automatically handles negative values.
3

Map to Custom Range

const s = spring({ frame, fps });
const custom = interpolate(s, [0, 1], [start, end]);

Spring vs Interpolate Decision Tree

Common Mistakes to Avoid

Don’t use interpolate for organic animations - Linear motion looks robotic. Use spring() instead.
Don’t use extreme config values - Damping over 300 or under 5 creates unnatural motion.
Don’t forget to delay springs - For staggered animations, offset the frame: frame - delay
Don’t mix presets inconsistently - Stick to one “feel” throughout a video (all bouncy OR all smooth).

Visualizing Spring Behavior

Spring damping comparison

Sequencing

Delay spring animations

Charts

Use springs in bar animations

Messaging

Bounce chat bubbles

Build docs developers (and LLMs) love