Visual computing primitives
for the web.
WebGL transitions and filter effects, easing curves, choreographed text, scroll bindings, and the headless components built on top.
- MIT
- TypeScript-native
- Tree-shakable
- SSR-safe
- Zero runtime deps
WebGL2 shaders, defined as plain data.
Mesh-based geometry. Multi-pass HDR pipelines. Endpoint-correct by construction. Every transition is pixel-pure from at progress 0 and pixel-pure to at progress 1.
- Tiny. A few KB for the runner plus the transitions you import.
- Zero runtime deps. Plain data + GLSL, no framework opinions.
- Author your own.
defineTransitioninfers types from defaults.
Drop a transition between two images.
Construct a Runner, hand it a transition and two
source images, and call render with a progress
value in [0,1]. That’s the entire API
surface for the common case. The runner caches compiled
programs per shader; subsequent renders skip compilation and
only update uniforms.
import { Runner, ripple } from "@vysmo/transitions";
const runner = new Runner({ canvas });
runner.render(ripple, {
from: imageA,
to: imageB,
progress: 0.5,
}); Choreographed text, on one master clock.
splitText shatters a heading into characters, words, or lines (grapheme-safe via Intl.Segmenter). animateText drives the parts on a single timeline with back-fill and repeat. No chained-tween glitches at preset boundaries.
- Generous preset library across enter, exit, emphasis modes.
- Multi-property choreography on a single timeline.
- Authoring studio for tuning and saving custom presets.
Filter primitives with one Runner, one render call.
Blur, bloom, glow, color grade, sharpen, halftone, tilt-shift, scanlines, lens distortion, oil paint, wave, swirl, motion blur, VHS, datamosh, ASCII, dither and more. Multi-pass effects auto-allocate HDR ping-pong targets.
- Same authoring model as transitions, with
defineEffect. - HDR-aware. Bloom and glow use four-pass
RGBA16Fpipelines. - Tree-shakable. Import only the effects you ship.
A curated catalog of curves, plus parametric builders.
Standards (cubic, expo, back, elastic, bounce…) and parametrics (spring, bezier, rough, wiggle, smooth, gravity, breathe). Modifiers compose: reverse, mirror, yoyo. Pure math, zero platform assumptions.
- CSS export.
toCSSLinear()returns a CSSlinear()from any function. - Reduced-motion helper via
respectReducedMotion. - Reads like prose:
backOut,elasticOut,spring(...).
Bind scroll progress to the rest of the ecosystem.
createScrollProgress for raw 0–1 emission. createScrollTransition drives any @vysmo/transitions render. createScrollEffect drives any @vysmo/effects params. One shared rAF-throttled observer underneath.
- Headless. You own the canvas. Scroll provides the clock.
- Zone helpers. Plateau, bathtub, ramp envelopes for typical reveals.
- Composable. Any number of subscribers, one observer, one rAF batch.
import { Runner, paintBleed } from "@vysmo/transitions";
import { createScrollTransition } from "@vysmo/scroll";
import { animateText } from "@vysmo/text";
// Two photos that morph as the visitor scrolls past the section.
const runner = new Runner({ canvas });
createScrollTransition({
section,
runner,
transition: paintBleed,
from, to,
});
// And the headline animates in once, on entry.
animateText(headline, {
preset: "enter/depth-zoom",
split: "word",
stagger: 28,
}); Three libraries, one moment.
The libraries don’t just live next to each other; they
plug in. @vysmo/scroll drives any
@vysmo/transitions render off scroll progress.
@vysmo/text animates a headline as it enters.
One coherent ecosystem, not a grab-bag.
Headless components, built on the libraries.
Every component below has a feature only the underlying libraries can give it: drag-scrub mid-flip, shader transitions between slides. Drop in, configure, ship.
A real WebGL flipbook. Drag corners to scrub mid-flip.
Composes @vysmo/transitions (the page-curl mesh shader), @vysmo/animations (commit / revert tweens), and @vysmo/easings. Three small libraries, one drop-in component.
- Drag-scrub maps pointer-drag to the curl shader's
progress. - Headless core. Click halves, arrow keys, drag corners, all wired by default.
- Scroll-driven seek. Pipe scroll progress into
seek().
Slideshow driven by any transition shader.
Single transition or per-slide function. Chrome is fully opt-in: arrows, dots, counter, progress bar, captions, each themeable via CSS custom properties. Set every chrome option to false for pure-headless mode.
- Click halves, keyboard, swipe, autoplay, wired by default.
- Pause-on-hidden and pause-on-hover built in.
- Composes the whole stack: transitions, animations, easings.