Your system asks for reduced motion, so VFX-JS draws nothing. Demos on this site show plain HTML.

Effects

There are two ways to style an element. Pass a preset name to shader, or pass effect objects to effect. Use one or the other, not both.

Shader presets

@vfx-js/core comes with these presets. Pass the name to shader.

main.ts
vfx.add(el, { shader: "rainbow" });

// Some presets draw outside the element. Give them room with overflow.
vfx.add(el, { shader: "glitch", overflow: 100 });
uvGradient
rainbow
glitch
rgbGlitch
rgbShift
shine
blink
spring
sinewave
pixelate
halftone
invert
grayscale
duotone
tritone
hueShift
vignette
chromatic

Scroll reveal presets

These animate in when the element enters the viewport, and out when it leaves. Scroll them in and out to see it again.

slitScanReveal
warpReveal
pixelateReveal
focusReveal

Preset uniforms

Some presets read values from uniforms. They have no defaults, so pass all of them.

Preset Uniforms
duotone color1, color2 (vec4), speed
tritone color1, color2, color3 (vec4), speed
hueShift shift (0 to 1)
vignette intensity, radius, power
chromatic intensity, radius, power
main.ts
vfx.add(video, {
    shader: "duotone",
    uniforms: {
        color1: [0, 0, 1, 1],
        color2: [0, 1, 0, 1],
        speed: 0.2,
    },
});

Chaining

Pass an array to effect. Each effect reads the output of the one before it.

main.ts
import { BloomEffect, PixelateEffect, ScanlineEffect } from "@vfx-js/effects";

await vfx.add(video, {
    effect: [
        new PixelateEffect({ size: 10 }),
        new ScanlineEffect({ spacing: 5 }),
        new BloomEffect({ threshold: 0.01, intensity: 10, pad: 100 }),
    ],
});

// Swap the chain in place. Instances already in it keep their state.
await vfx.updateEffects(video, [new BloomEffect({ intensity: 8 })]);

overflow does not apply to effects. Effects that draw outside the element, like BloomEffect, have their own pad param.

Storybook

The Storybook has every preset and effect with live controls for their params.