Skip to main content
Springs are the foundation of Wave’s animation system. The Spring class determines the timing curve and settling duration of animations using real spring physics.

Creating springs

Wave provides two ways to create springs: using response (frequency-based) or stiffness (force-based).
Response and stiffness are interchangeable - Wave automatically converts between them using the formula: stiffness = (2π / response)² × mass

Spring parameters

Damping ratio

The dampingRatio controls the amount of oscillation (“springiness”) in your animation:
  • 1.0 (critically damped): Smoothly reaches the target value without any oscillation or overshoot
  • < 1.0 (underdamped): Increases oscillation and overshoots the target before settling
  • > 1.0 (overdamped): Slower animation with no oscillation
// Smooth, no bounce
let criticalSpring = Spring(dampingRatio: 1.0, response: 0.82)

// Slight bounce, feels more playful
let bouncySpring = Spring(dampingRatio: 0.6, response: 0.8)
When dampingRatio = 1.0, the spring is critically damped - it reaches equilibrium as quickly as possible without oscillating.Values below 1.0 are underdamped and will overshoot the target, creating a bouncy effect. The lower the damping ratio, the more oscillation cycles occur before settling.The damping coefficient c is derived from the damping ratio using:
c = 4π × dampingRatio × mass / response

Response

The response affects how quickly the spring animation reaches its target:
// Fast, tight spring (200ms response)
let tightSpring = Spring(dampingRatio: 1.0, response: 0.2)

// Slower, looser spring (800ms response)
let looseSpring = Spring(dampingRatio: 1.0, response: 0.8)
For interactive animations (like dragging), use lower response values (0.2-0.3) for tight tracking. For non-interactive animations, higher values (0.6-1.0) feel more natural.

Mass

The mass parameter represents the mass “attached” to the spring. The default value of 1.0 rarely needs modification:
let spring = Spring(dampingRatio: 0.8, response: 0.3, mass: 1.0)
Increasing mass makes the spring feel “heavier” and take longer to settle.

Derived properties

Wave automatically calculates additional properties from your spring configuration:
let spring = Spring(dampingRatio: 0.6, response: 0.8)

// Automatically calculated:
spring.stiffness          // 61.685
spring.dampingCoefficient // 9.425
spring.settlingDuration   // 1.954 seconds

Default springs

Wave provides three pre-configured springs for common scenarios:
// Slightly underdamped spring for interactive animations
// Great for dragging, swiping, or gesture-driven animations
let spring = Spring.defaultInteractive
// dampingRatio: 0.8, response: 0.20

Settling duration

The settlingDuration tells you how long the spring will take to complete. This is automatically calculated based on your spring parameters:
let spring = Spring(dampingRatio: 0.6, response: 0.8)
print(spring.settlingDuration) // 1.954 seconds
Wave uses a settling threshold of 0.0001 (0.01%) to determine when the animation has “settled” close enough to the target value.
The settlingDuration is useful for debugging, but don’t use it to determine animation progress. Wave handles timing internally.

Real-world examples

Here are spring configurations from Wave’s sample app:
// From GridViewController.swift:60
let interactiveSpring = Spring(dampingRatio: 1.0, response: 0.3)

Wave.animate(withSpring: interactiveSpring) {
    draggedView.animator.center = touchLocation
    draggedView.animator.scale = CGPoint(x: scale, y: scale)
}

Choosing spring values

1

Start with defaults

Use Spring.defaultInteractive for gesture-driven animations or Spring.defaultAnimated for triggered animations.
2

Adjust damping ratio

Set to 1.0 for smooth animations without bounce, or 0.6-0.8 for slight bounciness.
3

Tune response

Lower values (0.2-0.3) for tight, responsive animations. Higher values (0.6-1.0) for more relaxed motion.
4

Test and iterate

Run your animation and adjust parameters until it feels right. Small changes make a big difference.

Advanced: Spring physics formulas

For those interested in the underlying physics, Wave uses these formulas:
// Stiffness from response
stiffness = ( / response)² × mass

// Response from stiffness  
response = /(stiffness / mass)

// Damping coefficient
dampingCoefficient = × dampingRatio × mass / response

// Undamped natural frequency
ωn =(stiffness / mass)

// Settling time (for underdamped springs)
settlingTime = -ln(0.0001) / (dampingRatio × ωn)
These formulas are defined in Spring.swift:128-156 and ensure physically accurate spring behavior.

Build docs developers (and LLMs) love