Plushie.Animation.Spring (Plushie v0.6.0)

Copy Markdown View Source

Renderer-side physics-based spring descriptor.

Springs animate using a damped harmonic oscillator simulation. Unlike timed transitions, springs have no fixed duration -- they settle naturally based on stiffness, damping, and mass. This makes them ideal for interactive animations where the target changes frequently (drag, scroll, hover) because interruption preserves velocity for smooth redirection.

Usage

# Custom parameters
scale: spring(to: 1.05, stiffness: 200, damping: 20)

# Named presets
scale: spring(to: 1.05, preset: :bouncy)

# Pipeline
alias Plushie.Animation.Spring
scale: Spring.new(to: 1.05) |> Spring.stiffness(200) |> Spring.damping(20)

# Do-block
scale: spring do
  to 1.05
  stiffness 200
  damping 20
end

Presets

  • :gentle -- slow, smooth, no overshoot
  • :snappy -- quick, minimal overshoot
  • :bouncy -- quick with visible overshoot
  • :stiff -- very quick, crisp stop
  • :molasses -- slow, heavy, deliberate

When to use springs vs transitions

Use springs when:

  • The target changes frequently (interactive elements)
  • You want natural-feeling motion with momentum
  • Overshoot/bounce is desirable

Use transitions when:

  • You need precise timing (fade exactly 300ms)
  • You need specific easing curves
  • The animation is fire-and-forget (not interactive)

Summary

Functions

Sets the spring damping (higher = less oscillation).

Sets the explicit start value.

Sets the spring mass (higher = slower, heavier).

Creates a new spring descriptor.

Sets the completion event tag.

Returns the map of available spring presets.

Sets the spring stiffness (higher = faster, snappier).

Sets the target value.

Sets the initial velocity.

Applies keyword options to an existing spring.

Types

preset()

@type preset() :: :gentle | :bouncy | :stiff | :snappy | :molasses

t()

@type t() :: %Plushie.Animation.Spring{
  damping: number(),
  from: term() | nil,
  mass: number(),
  on_complete: atom() | nil,
  stiffness: number(),
  to: term(),
  velocity: number()
}

Functions

damping(s, v)

@spec damping(spring :: t(), damping :: number()) :: t()

Sets the spring damping (higher = less oscillation).

from(s, from)

@spec from(spring :: t(), from :: term()) :: t()

Sets the explicit start value.

mass(s, v)

@spec mass(spring :: t(), mass :: number()) :: t()

Sets the spring mass (higher = slower, heavier).

new(opts)

@spec new(opts :: keyword()) :: t()

Creates a new spring descriptor.

to: is required. Use preset: for named configurations or set stiffness: and damping: directly.

Spring.new(to: 1.05, preset: :bouncy)
Spring.new(to: 1.05, stiffness: 200, damping: 20)

on_complete(s, tag)

@spec on_complete(spring :: t(), tag :: atom()) :: t()

Sets the completion event tag.

presets()

@spec presets() :: %{required(preset()) => keyword()}

Returns the map of available spring presets.

stiffness(s, v)

@spec stiffness(spring :: t(), stiffness :: number()) :: t()

Sets the spring stiffness (higher = faster, snappier).

to(s, to)

@spec to(spring :: t(), to :: term()) :: t()

Sets the target value.

velocity(s, v)

@spec velocity(spring :: t(), velocity :: number()) :: t()

Sets the initial velocity.

with_options(s, opts)

@spec with_options(spring :: t(), opts :: keyword()) :: t()

Applies keyword options to an existing spring.