Your system asks for reduced motion, so VFX-JS draws nothing. Demos on this site show plain HTML.
Class
VFX
vfx-js/src/vfx.ts:78 ↗import { VFX } from "@vfx-js/core";The main interface of VFX-JS.
Constructors
new VFX()
Accessors
canvas
get canvas(): HTMLCanvasElement
The output canvas VFX renders into.
maxTextureSize
get maxTextureSize(): number
time
get time(): number
Current virtual animation time in seconds (the value behind the
time uniform).
timeScale
get timeScale(): number
Playback rate of the animation clock.
1 is realtime, 0 pauses (frames still render), and negative
values run time backwards. Can be changed at any time.
Note: deltaTime follows this rate, so it goes negative while
rewinding. Time-only effects handle that fine; effects that integrate
motion over deltaTime (particles, fluid, datamosh) are not designed
to run backwards and may behave unexpectedly.
set timeScale(scale: number): void
Methods
add
add(element: HTMLElement, opts: VFXProps): Promise<void>
Register an element to track the position and render visual effects in the area.
addHTML
addHTML(element: HTMLElement, opts: VFXProps): Promise<void>
Register an element using html-in-canvas API.
Wraps the element in a <canvas layoutsubtree content="drawable"> and captures via drawElementImage.
Falls back to add() if html-in-canvas is not supported.
addTransition
addTransition<T extends Transition | TransitionClass>(
element: HTMLElement,
opts?: AddTransitionOpts<T> = {},
): TransitionHandle
Animate an element from its old content to its new content with a
shader. The element is wrapped only while a run is in flight,
unless keepWrapped is set.
const t = vfx.addTransition(main, { duration: 0.6 });
await t.run(() => renderNextPage());
capture
capture(source: HTMLElement, opts?: VFXCaptureOpts = {}): Promise<VFXCapture>
Capture an element as a texture without drawing it. Any effect of this VFX instance can read the texture. Resolves after the first capture is in the texture.
<img>, <video> and <canvas> are uploaded as they are.
Other elements are captured with html-in-canvas when the browser
supports it (like VFX.addHTML), or else with one DOM snapshot
(like VFX.add). Call update() on the snapshot after the
element changes.
const page = await vfx.capture(article, { hide: true });
await vfx.add(minimap, {
effect: myEffect,
uniforms: { page: page.texture },
});
// Later:
page.dispose();
The texture works on the effect path (effect) only, and only in
this VFX instance.
Rejects when the element already has a capture in this instance,
when addHTML or a transition wraps it, when add has it (unless it
is an <img>, <video> or <canvas> captured without hide), or
when the first capture fails. add rejects a captured element under
the same rule.
When the user prefers reduced motion, it resolves to a handle that
leaves the element alone and samples as transparent.
destroy
destroy(): void
Destroy VFX and stop rendering.
play
play(): void
Start rendering VFX.
remove
remove(element: HTMLElement): void
Remove the element from VFX and stop rendering the shader.
render
render(): void
Render the whole scene once, manually.
This is useful when you want to control the rendering timings manually by combining with autoplay: false.
setTime
setTime(time: number): void
Pin the animation clock to an absolute time in seconds.
The next render() uses the value verbatim, so setTime(t); render()
produces a deterministic frame — handy for scrubbing a timeline or
capturing stable snapshots (e.g. visual regression tests):
const vfx = new VFX({ autoplay: false });
await vfx.add(img, { effect });
vfx.setTime(1.5);
vfx.render();
Note: this drives deltaTime too, so a jump produces one large
deltaTime on the next frame. Time-only effects are unaffected, but
effects that integrate motion over deltaTime (particles, fluid,
datamosh) may jump — pause first (timeScale = 0) when scrubbing them.
stop
stop(): void
Stop rendering VFX.
You can restart rendering by calling VFX.play() later.
update
update(element: HTMLElement): Promise<void>
Update the texture for the given element.
For an HTMLImageElement, reloads its currently selected image URL
— call this after changing img.src or when responsive image
selection changes. Videos refresh automatically (no-op).
Otherwise re-snapshots the element's DOM subtree.
For html-in-canvas elements, resolves once the new capture is in
the texture, or after a short timeout.
Useful for elements whose contents change (input, textarea, or an
<img> whose selected source swaps).
updateEffects
updateEffects(
element: HTMLElement,
effect: Effect | readonly Effect[],
): Promise<void>
Replace the effect chain on an already-registered effect-path
element in-place. Effects whose reference is unchanged keep their
init state and GPU resources; only added/removed effects run
init / dispose. The element's source texture is preserved.
Useful for live UIs that reorder or toggle effects without paying
the cost of vfx.remove + vfx.add (which reloads the source).