Move anything on the web.
Gimbal is a small JavaScript library for easing, scroll, layout, drag, physics and timelines. Take only the parts you need.
Scroll to open the lens
The whole kit, in six parts.
Every part of the lens is a module you can import on its own.
FIG. 1 GIMBAL, EXPLODED
01Core
Say what moves. Gimbal does the rest.
One call takes the target, the properties and a curve. The ring reads the move back while it plays.
import { move } from 'gimbal-motion';
move('.square', {
x: 240,
rotate: 180,
radius: '50%',
duration: 1700,
ease: 'spring',
loop: true,
});02easing
Curves with character.
Pick a curve by name, or draw your own. Every property of every move gets its own.
move('.dot', { x: 360, ease: 'out(3)' });
move('.dot', { x: 360, ease: 'spring' });
move('.dot', { x: 360, ease: 'steps(6)' });03scroll
Tie any move to the scroll bar.
Link a move to a scroll position or to a whole pane. Scrub it, pin it, or just trigger it.
import { scroll } from 'gimbal-motion/scroll';
scroll('.pane', {
scrub: true,
animate: { rotate: 360, x: 220 },
});Scroll inside the pane.
04layout
Layouts that glide.
Change the layout and every item travels to its new place, one after another. Click a tile to send it first.
import { layout } from 'gimbal-motion/layout';
const grid = layout('.grid', { stagger: 'center' });
grid.update(() => el.classList.toggle('wide'));05core
Draw it, then bend it.
Draw lines, morph one shape into another and ride a path, all with the same call.
move('.outline', { draw: [0, 1] });
move('.outline', { morph: '#star' });
move('.dot', { along: '.outline', loop: true });06drag + physics
Grab it. Throw it. Watch it settle.
Drag with inertia and release into a spring. Tune the stiffness and the damping, or use the keyboard.
import { drag } from 'gimbal-motion/drag';
import { spring } from 'gimbal-motion/physics';
drag('.handle', {
release: spring({ stiffness: 170, damping: 14 }),
});07timeline
Plan it, then scrub it.
Place moves on one clock. Pause it, reverse it, or drag the playhead to any moment.
const tl = timeline({ loop: true });
tl.add('.a', { x: 200 }, 0)
.add('.b', { x: 200 }, 0.4)
.add('.c', { x: 200 }, 0.8);08core
One move, every screen.
Give a move a media query and it rebuilds itself when the screen changes.
scope({ phone: '(max-width: 600px)' }, ({ matches }) => {
move('.dot', { x: matches.phone ? 80 : 240 });
});Take only the parts you need.
Import a module and you pay for that module. Switch parts on and off to see the weight.
Total, gzipped15.0 kB
import { move } from 'gimbal-motion';
import { easing } from 'gimbal-motion/easing';
import { drag } from 'gimbal-motion/drag';
import { timeline } from 'gimbal-motion/timeline';
import { layout } from 'gimbal-motion/layout';
import { scroll } from 'gimbal-motion/scroll';
import { physics } from 'gimbal-motion/physics';Sizes are invented. Gimbal is a concept.
Our backers
Gimbal is free for everyone. These studios pay for the time.
- Harbour & Co.
- Nine Bolts
- Ledger Moth
- northbound
- QUIET ENGINE
- Folio 24
- Pale Rider
- Lantern Row
Backers are fictional.
This button sends nothing. Gimbal is a concept.