Your system asks for reduced motion, so VFX-JS draws nothing. Demos on this site show plain HTML.
Type
EffectContext
vfx-js/src/types.ts:820 ↗import type { EffectContext } from "@vfx-js/core";Context passed to each Effect lifecycle hook. Fields are updated each frame automatically.
Properties
deltaTime
readonly deltaTime: number
dims
readonly dims: EffectDims
Per-stage layout snapshot — same shape as Effect.outputRect's
dims argument. Fresh in update and render; in init it
holds placeholder values until the first frame resolves.
enterProgress
readonly enterProgress: number
Enter transition progress, 0 to 1. Plays backward on reversal.
enterTime
readonly enterTime: number
gl
readonly gl: WebGL2RenderingContext
Raw WebGL2 context, for low-level operations (DataTexture upload, extensions, MRT, etc).
Resources allocated here are the caller's responsibility: free in
dispose(), rebuild in onContextRestored(cb).
Every draw sets its own framebuffer, viewport, program, VAO,
texture bindings and blend state. ctx.draw(), ctx.blit() and
ctx.clear() also turn off SCISSOR_TEST, but the rest of the
frame (other elements, post effects, the per-frame canvas clear)
does not touch scissor.
The rest of the GL state is never set per draw. VFX-JS assumes:
SCISSOR_TEST,DEPTH_TEST,CULL_FACE,STENCIL_TEST,POLYGON_OFFSET_FILL,RASTERIZER_DISCARDandSAMPLE_ALPHA_TO_COVERAGEdisabled.depthMask(true),colorMask(true, true, true, true),frontFace(CCW)andclearColor(0, 0, 0, 0).- No sampler objects,
PIXEL_UNPACK_BUFFERor transform feedback bound. UNPACK_ROW_LENGTH,UNPACK_SKIP_*andUNPACK_IMAGE_HEIGHTat 0, andUNPACK_COLORSPACE_CONVERSION_WEBGLatBROWSER_DEFAULT_WEBGL. Texture uploads setUNPACK_FLIP_Y_WEBGL,UNPACK_PREMULTIPLY_ALPHA_WEBGLandUNPACK_ALIGNMENTthemselves, so don't rely on their values in raw uploads.
If you change any of this, call EffectContext.resetState
when you are done: before the next ctx.draw() / ctx.blit() /
ctx.clear(), and before render() returns.
intersection
readonly intersection: number
leaveProgress
readonly leaveProgress: number
Leave transition progress, 0 to 1. Stays 0 until enter finishes.
leaveTime
readonly leaveTime: number
mouse
readonly mouse: readonly [number, number]
Mouse position on the element (element-local, bottom-left origin).
mouseViewport
readonly mouseViewport: readonly [number, number]
Mouse position on the canvas (canvas-local, bottom-left origin).
pixelRatio
readonly pixelRatio: number
quad
readonly quad: EffectQuad
Default fullscreen quad (NDC -1..1), mapped to the target's viewport.
resolution
readonly resolution: readonly [number, number]
Canvas resolution, physical px.
src
readonly src: EffectTexture
Element capture texture (read-only input for the first stage).
target
readonly target: EffectRenderTarget | null
Destination assigned to this stage. null means the canvas.
time
readonly time: number
uniforms
readonly uniforms: Readonly<Record<string, EffectUniformValue>>
User-defined uniforms from VFXProps.uniforms
Values are re-evaluated every frame efore update().
Built-in uniforms (time etc) are exposed as top-level ctx fields instead.
vfxProps
readonly vfxProps: EffectVFXProps
blit
blit(
source: EffectTexture | EffectRenderTarget,
target?: EffectRenderTarget | null,
opts?: EffectBlitOpts,
): void
Copy a texture / render target into target (the stage's assigned
output, or the canvas, when target is omitted / null).
Samples through the uvSrc varying, so the captured content maps
into the destination buffer exactly like the framework's built-in
passthrough. Use it instead of hand-written texture(src, uvSrc)
copy passes (capture, downsample, source passthrough).
Only valid during Effect.render(); other calls are ignored.
clear
clear(target?: EffectRenderTarget | null): void
Zero a render target with a fast GPU clear, instead of a full-screen draw. Use it to reset accumulation / trail buffers each frame.
Omit target (or pass null) to clear the stage's assigned output.
Clears both sides of a ping-pong (persistent: true) RT.
Only valid during Effect.render(); other calls are ignored.
createRenderTarget
createRenderTarget(opts?: EffectRenderTargetOpts): EffectRenderTarget
Allocate a render target.
draw
draw(opts: EffectDrawOpts): void
Run a draw call.
Only valid during Effect.render(); other calls are ignored.
onContextRestored
onContextRestored(cb: () => void): () => void
Subscribe to webglcontextrestored to rebuild resources allocated
via raw ctx.gl. High-level API resources (createRenderTarget,
wrapTexture, EffectGeometry) are restored automatically.
Returns an unsubscribe function; auto-unsubscribed on dispose.
releaseGeometry
releaseGeometry(geometry: EffectGeometry): void
Free the GPU buffers compiled for a geometry.
Call before dropping or replacing an EffectGeometry (e.g. on a
density change); otherwise its buffers live until the effect
chain is disposed.
resetState
resetState(): void
Put the GL state back to the baseline VFX-JS's pipeline assumes,
whatever raw ctx.gl calls changed. It only writes state; it
never queries it.
Resets:
- Draw and read framebuffer to the canvas,
drawBuffers([BACK]), and the viewport to the whole canvas. DEPTH_TEST,CULL_FACE,STENCIL_TEST,SCISSOR_TEST,BLEND,POLYGON_OFFSET_FILL,RASTERIZER_DISCARD,SAMPLE_ALPHA_TO_COVERAGEandSAMPLE_COVERAGEdisabled.depthMask(true),depthFunc(LESS),colorMask(true × 4),stencilMask(~0),frontFace(CCW),cullFace(BACK),clearColor(0, 0, 0, 0).- Program, VAO and the
ARRAY_BUFFER,PIXEL_PACK_BUFFER,PIXEL_UNPACK_BUFFER,UNIFORM_BUFFER,COPY_READ_BUFFER,COPY_WRITE_BUFFERbindings unbound. Transform feedback unbound. - Sampler objects unbound on every texture unit, and the active
texture unit set to
TEXTURE0. - Pixel store parameters set to the WebGL defaults.
Call it after raw ctx.gl work in render(): before the next
ctx.draw() / ctx.blit() / ctx.clear(), and before render()
returns. Calling it in init() or update() is allowed but rarely
needed, since nothing is drawn there. It does nothing while the
WebGL context is lost, or after the effect is disposed.
If you use transform feedback, call gl.endTransformFeedback()
first. While transform feedback is active, unbinding it and the
program is an INVALID_OPERATION.
Example
render(ctx) {
const gl = ctx.gl;
gl.bindFramebuffer(gl.FRAMEBUFFER, this.fbo);
gl.enable(gl.DEPTH_TEST);
// ... custom drawing ...
ctx.resetState();
ctx.blit(this.result);
}
wrapTexture
wrapTexture(source: EffectTextureSource, opts?: {
autoUpdate?: boolean;
filter?: EffectTextureFilter;
size?: readonly [number, number];
wrap?: EffectTextureWrap | readonly [EffectTextureWrap, EffectTextureWrap];
}): EffectTexture
Wrap an externally-produced texture for use as a uniform.
Each call allocates a new GPU texture (no caching), so call this
once in init() and reuse the result across frames.
- DOM sources: dimensions are read automatically, and the texture is restored after WebGL context loss.
WebGLTexture: you must passopts.size, and you must re-wrap the texture yourself fromonContextRestored(cb).
autoUpdate defaults to true for HTMLVideoElement,
HTMLCanvasElement, and OffscreenCanvas, and false for
everything else.
With autoUpdate: false, call texture.update() after the source changes.