Skip to content

@ilovevideoeditor/renderer-browser — API reference

Encode VideoJSON to an MP4 Blob inside the browser via WebCodecs.

Classes

BrowserRenderer

Properties

  • currentFrame: number — Frame being rendered right now (for dedup / cancellation).
  • layers: RuntimeBaseLayer[] — Runtime layer wrappers.
  • loadedFonts: Record<string, string> — Cache of loaded Google Fonts — maps font name → stylesheet URL.

Methods

  • constructor(videoJSON: VideoJSON): BrowserRenderer
  • captureFrame(frame: number): Promise<OffscreenCanvas> — Capture a single frame onto the shared render canvas.
  1. Ensure all layer DOMs reflect this frame (via renderFrame).
  2. For each enabled, in-range layer, pick the cheapest path:
    • Fast path (tier-1 + no effects): paint the layer's $element directly onto the final canvas via drawDirectInto — skips the per-layer surface copy entirely.
    • Normal path: ask the LayerRasterizer for a project-sized bitmap (cached when the layer's final props match the previous render), pipe through the WebGL effect compositor if the layer declares effects, then drawImage onto the final canvas.
  • compositeLayerInto(ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D, layer: RuntimeBaseLayer, frame?: number): Promise<void> — Composite one layer onto ctx (the group's flatten canvas, or any other caller-owned target sized to the project).

  • Fast path: when the layer is tier-1 and has no effects, paints the layer's $element straight onto ctx via drawDirectInto — no per-layer surface, no extra blit.

  • Normal path: rasterizes the layer (cached when possible), runs the WebGL effect compositor if effects are declared, then drawImages the result onto ctx.

Used by RuntimeGroupLayer.renderFrame to flatten each child onto the group's canvas — the same path that captureFrame uses for top-level layers.

  • destroy(): void — Tear down the renderer: destroy every runtime layer (releases media elements, decoders, audio buffers), remove the hidden <div data-renderer> from the DOM, drop the shared render canvas, and dispose the rasterizer's per-layer surfaces and the WebGL effect compositor's GL context. Call this after the last captureFrame / exportVideo to avoid leaking GL contexts across repeated renders.
  • exportVideo(options: RenderOptions): Promise<Blob> — Export the full video as an MP4 blob using MediaBunny.

When options.worker is not false (the default), SVG rasterisation and MediaBunny encoding are offloaded to a dedicated Web Worker so that the main thread stays responsive. Set worker: false to encode entirely on the main thread (useful when Workers are unavailable).

  • getPropertyDefinition(layerType: string): Record<string, PropertyDefinition> | undefined — Look up the full property definitions for a layer type, or a single property. Used by runtime layers to determine CSS mapping and defaults.
  • getVirtualLayerHost(): Node — Where group layers should park their hidden child host. For the export renderer we use document.body directly so the children's CSS resolves against the page's layout context (the same context the main $canvas uses).
  • loadFont(fontName: string): Promise<void> — Load a Google Font by name.

Constructs the exact CSS2 URL for the font using the bundled Google Fonts registry (axis ranges, italic support, weight variants) so the request always matches what the API expects — preventing 400 errors that arise from requesting unsupported axis combinations.

  • renderAudio(): Promise<AudioBuffer | null> — Render all audio layers into a single AudioBuffer using OfflineAudioContext.

Each audio/video layer creates a buffer source node with volume and pan keyframe automation, connected to the context's destination.

  • renderFrame(frame: number, force: boolean): Promise<void> — Render a single frame to the DOM.

Each enabled layer computes its interpolated properties at the given frame and applies them to its DOM element.

  • registerEffect(name: string, glsl: string, params: Record<string, EffectParamDefinition>): void — Register a GLSL effect. glsl is the fragment-shader body implementing vec4 effect(sampler2D tex, vec2 uv, vec2 resolution); each entry in params becomes a u_<name> uniform. Like transitions, the registry is shared with DomRenderer.
  • registerTransition(name: string, fn: TransitionFn): void — Register a transition preset. The same registry backs both BrowserRenderer and DomRenderer, so a transition registered here is immediately usable in live preview too.
  • render(videoJSON: VideoJSON, options: RenderOptions): Promise<Blob | ArrayBuffer> — Render a VideoJSON to a video Blob or ArrayBuffer.

This is the primary public API. It creates a BrowserRenderer instance, initialises all layers, renders every frame, encodes the result via MediaBunny, and returns the output.

Functions

getEffect

Retrieve a registered effect.

ts
getEffect(name: string): EffectDefinition | undefined

Parameters

  • namestring

Returns EffectDefinition | undefined

getTransition

Look up a previously registered transition's function.

ts
getTransition(name: string): TransitionFn | undefined

Parameters

  • namestring

Returns TransitionFn | undefined

listEffects

List registered effect names.

ts
listEffects(): string[]

Returns string[]

listTransitions

List registered transition names.

ts
listTransitions(): string[]

Returns string[]

registerEffect

Register an effect. Pass either:

  • a string glsl body for single-pass effects, or
  • an array of EffectPass for multi-pass effects.

Last registration wins.

ts
registerEffect(name: string, glslOrPasses: string | EffectPass[], params: Record<string, EffectParamDefinition>): void

Parameters

  • namestring
  • glslOrPassesstring | EffectPass[]
  • paramsRecord<string, EffectParamDefinition>

registerTransition

Register a transition preset under name. Last registration wins.

options.defaultEasing sets the easing applied to p when the layer's transitionIn / transitionOut spec does not specify one. Layers can always override it via the easing field of their transition spec.

ts
registerTransition(name: string, fn: TransitionFn, options: RegisterTransitionOptions): void

Parameters

  • namestring
  • fnTransitionFn
  • optionsRegisterTransitionOptions

Type aliases

EffectDefinition

A registered effect. Has either glsl (single-pass) or passes.

EffectParamDefinition

Metadata describing a single effect parameter.

default is used when the layer's JSON does not override it. For color, the value is a CSS colour string ("#rrggbb" / "rgba(..)"), converted to a vec4 by the compositor at draw time. For option, the value is one of the keys of fieldConfig.options; the compositor resolves it to its index and binds it as an int u_<name> uniform.

fieldConfig carries all editor UI hints — step, integer coercion, unit, option labels — and also drives runtime unit conversion (unit: 'em' → pixels). See EffectParamFieldConfig.

EffectParamType

Supported GL uniform types for effect parameters.

ts
EffectParamType: "float" | "int" | "bool" | "vec2" | "vec3" | "vec4" | "color" | "option"

RegisterTransitionOptions

Options accepted by registerTransition.

TransitionDefinition

Full transition entry as stored in the registry.

TransitionFn

A transition implementation.

  • p — signed progress, -1..+1 as described above (already eased).
  • properties — the layer's resolved, unit-ized properties at this frame. Mutate in place or return a new object; either works.
  • params — free-form per-preset parameters from LayerTransitionJSON.params.
  • context — per-call context (e.g. seed for deterministic randomness).
ts
TransitionFn: (p: number, properties: Record<string, any>, params: Record<string, any>, context: TransitionContext) => Record<string, any>

Released under the MIT License.