Skip to content

Squash & Stretch Spring Motion

Bouncy, jelly-like motion: things crouch, jump, stretch and land with a squash and wobble, shown on three glossy balls.

Motion, D1 MotionAny rendererSeamless loop, verified103 lines of codev1.1.0

In Food & sweets, Toys, games & parties

Next: Jelly CubeSurprise me

Squash & Stretch Spring Motion preview
Starting live preview…
00:00:00:00 / 00:00:00:01

Live, running the real source.

Your current settings go with it. Combine several clips and hand them over together from your sequence.

Effect controls

Presets

4
1
0.35
9

Lower numbers wobble longer after landing.

The preview runs the same code your AI receives. These settings travel with the hand-off.

Info

What it is

The classic cartoon animation principles as ready-made motion: anything can hop, stretch as it flies, squash when it lands and wobble back into shape. There is also an exact spring (for overshoot-and-settle moves like a pop-in) and a squash helper that keeps the shape's volume believable. Use it to make logos, icons, characters or buttons feel playful.

Reuse it in your own idea

  • Pop a number or label in with spring(t, { from: 0, to: 1 }) as its scale (see Minimal Animated Number Reveal).
  • Make a logo or app icon hop in a product video.
  • Use squashStretch on a Three.js mesh's scale for 3D jelly characters.

Which part is reusable

src/spring-motion.js is the ingredient your AI reuses. demo.js is only the example scene around it, and uses the demo harness only for the demo.

Good to know

  • The hop is stylised animation, not physics. Use Bouncing Balls for real collisions.

Technical details

Technical details
Implementation
Plain JavaScript math — works with any renderer · ES module src/spring-motion.js
Exports
  • spring(t, { from?, to?, velocity?, stiffness?, damping?, mass? }) => number
  • squashStretch(stretch) => [scaleX, scaleY]
  • hop(time, { period?, height?, squash?, airtime?, wobble?, offset? }) => { y, scaleX, scaleY, phase, inAir }
  • cyclePhase(progress, cycles?) => number
Dependencies (exact)
  • apw-runtime@1.0.0 (demo) — Demo harness and colour helpers. src/spring-motion.js has no dependencies.
How it fits a scene

Coordinates: y is height above the ground in your units. Scale around the object's bottom centre so it squashes onto the floor.

Lighting: None.

Timing: Closed-form math: no state, frames can be computed in any order.

Output
1080×1080, 30 fps, 4 s · procedural (computed from the frame number) · seamless loop — The hop is periodic and the clip holds a whole number of hops.
Tested
Rendered 120 frames on 2026-10-03 in Chrome 154.0.8037.97 headless on Linux 7.0.0-38-generic (x64), Node 22.14.0 (Canvas 2D). Same frame twice from fresh pages: identical. Loop: Frame 0 vs end state (progress 1): mean |Δ| 0.0000, max |Δ| 0 of 255.
Performance
A few exp/sin calls per object per frame. None.
Export a video yourself
Download the source, then in the folder: npm install npm run render -- spring-motion/1.1.0 --out my-video.mp4Needs Node 18+, ffmpeg and Chrome/Chromium. Add --params my-settings.json (from Copy settings) for your own settings.
Version
1.1.0 · sha256:6f156d4a1c7e533b… · other versions: 1.0.0
Files
License
MIT. Copyright (c) 2026 AI Pixel Wizard. Released under the MIT License. See LICENSE in this folder. License details
Provenance
Original code written for AI Pixel Wizard in October 2026. Demo rebuilt in October 2026 to the catalog quality bar (docs/QUALITY.md).
BinMore like this

Jelly Cube

3D object3DSeamless loop10 seconds

Coin Stack

3D object3DSeamless loop12 seconds

Marble Run

3D object3DSeamless loop16 seconds