Created by Pavel Klavík
A high-level explanation of how physics-based motion makes a spatial canvas feel continuous, responsive, and understandable.
For and
, the roots are
So the solution is for some
.
For the initial conditions and
, we find
and
by solving this linear system
This gives and
, so the full spring trajectory is
For fixed parameters and
, we get a family of possible solutions, one for each choice of
.
A particular solution is obtained by computing and
from the initial position
and velocity
. This requires solving a
system of linear equations.
This lets an animation continue smoothly when its target changes mid-motion. The engine takes the current position and velocity, and uses them as the starting point for the next spring animation.
Usually calm, monotone movement with no repeated overshoot. It is useful when an animation should feel stable and restrained.
The fastest calm movement that settles without repeated wobbling. It is useful when the interface should feel direct but not jumpy.
Spring animations make OrgPad feel natural. Objects move in ways we recognize from everyday life. The animation stays out of the way and helps you follow what changed in the document.
OrgPad uses a custom animation library with roughly 5,000 lines of ClojureScript to orchestrate detailed animations throughout the app.
The differential equation for spring motion is:
Depending on the value of , the solution takes one of three forms.
Lively movement that can cross the target repeatedly before settling. Used sparingly in the OrgPad interface.
OrgPad’s animation layer works more like a small game engine than a traditional document redraw system. While objects move, it runs a fast render loop: each frame advances the animation state, updates what's visible, and renders the result.
During each frame, OrgPad:
The loop is driven by browser animation frames:
(when start-playing
(.requestAnimationFrame js/window
#(dispatch! [:frame-anim/set-frame %])))
Profiles are named choices of stiffness and damping
. The animation engine computes the motion type and eigenvalues from these numbers.
{:spring/id :spring/canvas-camera
:spring/stiffness 55
:spring/damping 25
:spring/type :spring/overdamped
:spring/eigenvalues [-2.437694101250946 -22.562305898749052]}
{:spring/id :spring/unit-drag
:spring/stiffness 850
:spring/damping 98
:spring/type :spring/overdamped
:spring/eigenvalues [-9.617262664969566 -88.38273733503044]}
{:spring/id :spring/unit-pulse
:spring/stiffness 150
:spring/damping 6
:spring/type :spring/underdamped
:spring/eigenvalues [-3 11.874342087037917]}
{:spring/id :spring/panel-opacity
:spring/stiffness 64
:spring/damping 16
:spring/type :spring/critically-damped
:spring/eigenvalues [-8]}Dragging, camera movement, feedback pulses, and opening content should not all move the same way.
Spring physics lets OrgPad tune motion with two meaningful quantities: