//

Physics Model

Core Concept

Material + Weight + Force = Motion Profile

Objects have physical properties that determine how they move. Express these through timing, deformation, and easing curves.

Quick Reference

Context Base Durations

  • Social media (mobile): 200-400ms (fast-paced, attention-grabbing)
  • Explainer videos: 500-800ms (clear, readable)
  • Cinematic: 1000-1600ms (dramatic, luxurious)
  • Transitions: 300-600ms (context-dependent)

Frame Rate Considerations

At 24fps: 1 frame = ~42ms (round to multiples of 42ms)
At 30fps: 1 frame = ~33ms (round to multiples of 33ms)
At 60fps: 1 frame = ~17ms (round to multiples of 17ms)

Use frame-aligned timing for smooth motion.

Weight Multipliers

  • Heavy: 1.5-2.0× base duration (large text blocks, full-screen graphics)
  • Medium: 1.0× base duration (title cards, standard elements)
  • Light: 0.5-0.7× base duration (small icons, decorative elements)

Duration Calculation Formula

Duration = Material.base × WeightMultiplier × DistanceFactor
Example:
Paper title card (800ms base) × Medium weight (1.0×) × 200px movement (2.0×)
= 800 × 1.0 × 2.0 = 1600ms
At 30fps: 1600ms ÷ 33ms = ~48 frames
At 24fps: 1600ms ÷ 42ms = ~38 frames

Material Properties (Source of Truth)

Every animation chooses a material metaphor. The material determines all motion characteristics.

Complete Material Matrix

MaterialBase DurationDeformationBounceFrictionDensity
Feather2000ms80%0%LowVery low
Paper800ms30-40%10%MediumLow
Leather500ms20-30%15%HighMedium
Rubber600ms60-80%80%HighMedium
Wood500ms5-10%20%MediumMedium
Plastic350ms10-20%30%LowMedium
Glass400ms0%25%LowMedium-high
Metal300ms0-5%5%MediumHigh
Stone600ms0%5%HighVery high
Liquid1400ms100%0%VariableLow

Deriving Motion from Material

Material determines timing:

Playful logo (rubber):
Duration: 600ms (rubber base)
Deformation: scaleY(0.7) scaleX(1.3)
Bounce: Returns past resting point by 80%
Use: Fun brands, celebration moments
Professional title card (glass):
Duration: 400ms (glass base)
Deformation: None (rigid)
Bounce: Minimal overshoot (5%)
Use: Corporate, technical content

Consistency rule: All elements of the same material move similarly throughout the composition.

Weight Scaling

Weight multiplies base duration and affects deformation:

Weight Categories

Light (0.5-0.7× base):

  • Small tooltips, badges, chips
  • Fast start, floaty motion
  • Minimal deformation (barely compresses)
  • Example: Paper badge = 800ms × 0.6 = 480ms

Medium (1.0× base):

  • Standard UI elements, cards, buttons
  • Balanced motion
  • Standard material deformation
  • Example: Paper card = 800ms × 1.0 = 800ms

Heavy (1.5-2.0× base):

  • Large modals, full-page transitions
  • Slow start (inertia), momentum carries
  • Increased deformation (more impact)
  • Example: Paper modal = 800ms × 1.8 = 1440ms

Volume Conservation

When objects deform, volume stays constant:

Volume = Width × Height = constant
Normal: scaleX(1.0) × scaleY(1.0) = 1.0
Squashed: scaleX(1.25) × scaleY(0.8) = 1.0
Stretched: scaleX(0.85) × scaleY(1.3) = 1.1 (close enough)

Compress one axis → expand the other proportionally.

Force Applied (Easing)

Easing curves represent forces acting on objects:

Gravity

Falling (ease-in - accelerating):

Object falls, gravity pulls harder over time
cubic-bezier(0.55, 0, 1, 0.45)

Rising (ease-out - decelerating):

Object thrown upward, gravity slows it
cubic-bezier(0, 0.55, 0.45, 1)

Entrances vs Exits

Entrance (ease-out): Object enters viewport, needs to decelerate to stop

Starting with momentum, slowing to rest
0% → fast → slow → 100%

Exit (ease-in): Object accelerates away, doesn't need to stop

Starting at rest, speeding up to leave
0% → slow → fast → 100%

Within-screen (ease-in-out): Object moves from A to B on screen, must start and stop

Starting at rest, accelerating, then decelerating
0% → slow → fast → slow → 100%

Spring Physics

For elastic materials (rubber, plastic):

// Tight spring (professional UI)
stiffness: 300
damping: 30
= Quick snap, 1-2 oscillations
// Loose spring (playful UI)
stiffness: 100
damping: 15
= Gentle motion, 3-4 oscillations
// Critically damped (precise)
stiffness: 200
damping: 28 (2 × √stiffness)
= Fastest approach without overshoot

Maps to cubic-bezier:

Tight spring: cubic-bezier(0.68, -0.1, 0.265, 1.1)
Loose spring: cubic-bezier(0.68, -0.55, 0.265, 1.55)
Critically damped: cubic-bezier(0.36, 0, 0.66, 1)

Distance Scaling

Duration scales with distance traveled:

Base distance: 100px
Base duration: Material.base
Distance factor = actualDistance / 100px
Final duration = Material.base × Weight × DistanceFactor

Example:

Paper card (800ms base)
Medium weight (1.0×)
Moving 250px (2.5×)
= 800 × 1.0 × 2.5 = 2000ms

Practical limits:

  • Don't scale linearly beyond 3× distance (feels too slow)
  • Use √distance for very long movements
  • Example: 400px → use √4 = 2× instead of 4×

Friction and Drag

High friction (rough surfaces):

Slow, constant deceleration
Longer timing
cubic-bezier(0.4, 0.1, 0.6, 0.9)
Use for: Dragging, scrubbing, sliders

Low friction (smooth surfaces):

Maintains speed, sharp stop
Faster timing
cubic-bezier(0.1, 0.7, 0.3, 1)
Use for: Swipes, throws, momentum scroll

Bounce Dynamics

Realistic bounce sequence:

Drop from height H, duration D
Bounce 1: H × 100%, D × 100%
Bounce 2: H × 70%, D × 70%
Bounce 3: H × 49%, D × 49%
Bounce 4: H × 34%, D × 34%

Each bounce is ~70% of previous height and duration.

Simplified UI bounce (single overshoot):

// Button scale bounce
element.animate([
{ transform: 'scale(0)' },
{ transform: 'scale(1.08)' }, // 8% overshoot
{ transform: 'scale(1)' }
], {
duration: 400,
easing: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)'
});

Inertia and Momentum

Heavy objects resist changes:

Phase 1: Overcome inertia (slow start)
Duration: 40% of total
Easing: Slow at start
Phase 2: Momentum builds (constant speed)
Duration: 30% of total
Easing: Linear
Phase 3: Decelerate to stop (slow end)
Duration: 30% of total
Easing: Slow at end

Direction changes require momentum decay:

Moving right → stop → move left
Cannot change instantly. Must:
1. Decelerate to stop (200ms, ease-in)
2. Pause (50-100ms, shows momentum lost)
3. Accelerate new direction (250ms, ease-out)

Implementation Pattern

Determine material, weight, distance:

1. Material (from intent): Glass
2. Weight: Medium (standard button)
3. Distance: 50px
4. Force: Gravity (falling in)
Calculation:
Base: 400ms (glass)
Weight: 1.0× (medium)
Distance: 0.5× (50px vs 100px base)
= 400 × 1.0 × 0.5 = 200ms
Easing: ease-in (falling)
Deformation: 0% (glass doesn't compress)
Bounce: 25% overshoot
Result:
duration: 200ms
transform: translateY(-50px) → translateY(0) → translateY(-12.5px) → translateY(0)
easing: cubic-bezier(0.55, 0, 1, 0.45) for fall, then bounce

Common Animation Patterns for Video

Title Card Entrance (400-600ms, ease-out)

At 30fps (12-18 frames):
opacity: 0 → 1
translateY: 40px → 0
scale: 0.95 → 1

Title Card Exit (300-400ms, ease-in, 30% faster)

At 30fps (9-12 frames):
opacity: 1 → 0
translateY: 0 → -30px

Logo Animation (800ms, bounce)

At 30fps (24 frames):
scale: 0 → 1.15 → 0.95 → 1
rotation: 0 → 5 → -3 → 0
easing: bounce/elastic

Scene Transition - Wipe (500ms)

At 30fps (15 frames):
clipPath: inset(0 0 0 100%) → inset(0 0 0 0%)
easing: ease-in-out

Scene Transition - Cross-dissolve (800ms)

At 30fps (24 frames):
Outgoing scene opacity: 1 → 0
Incoming scene opacity: 0 → 1
Overlap: 100% (simultaneous)

Text Reveal - Typewriter

Per character: 50ms (1-2 frames at 30fps)
Total for 20 characters: ~1000ms

Emphasis Pulse (600ms)

At 30fps (18 frames):
scale: 1 → 1.1 → 1
opacity: 1 → 1 → 1 (maintain)
Used for: Drawing attention to key information

Common Physics Errors

Error: Ignoring weight

Bad: Full-screen graphic animates in 300ms (too fast for size)
Fix: Apply heavy multiplier: 300ms × 1.8 = 540ms

Error: Violating volume conservation

Bad: scaleX(1.5) scaleY(1.5) on squash (volume increases unnaturally)
Fix: scaleX(1.5) scaleY(0.67) (volume stays constant)

Error: Wrong easing direction

Bad: Title entrance with ease-in (feels like accelerating into wall)
Fix: Title entrance with ease-out (decelerating to rest)

Error: Inconsistent material

Bad: Title card has paper timing (800ms) but metal deformation (2%)
Fix: Use paper deformation (35%) to match timing

Error: Not frame-aligned

Bad: 347ms animation at 30fps (10.4 frames - fractional)
Fix: 330ms (10 frames) or 363ms (11 frames) - whole frame counts