makeHtmlInCanvasPresentation()v4.0.456
Allows you to pass a shader to create a HTML-in-canvas-based @remotion/transitions presentation.
For a step-by-step walkthrough, see Custom HTML-in-canvas presentations.
Minimal crossfade exampleconstmyPresentation =makeHtmlInCanvasPresentation (myShader );
Show myShader implementation
Minimal crossfade shaderimport 'remotion'; import {makeHtmlInCanvasPresentation , typeHtmlInCanvasShader } from '@remotion/transitions'; constVERTEX = `#version 300 es in vec2 a_pos; out vec2 v_uv; void main() { v_uv = vec2(a_pos.x * 0.5 + 0.5, 0.5 - a_pos.y * 0.5); gl_Position = vec4(a_pos, 0.0, 1.0); }`; constFRAGMENT = `#version 300 es precision highp float; uniform sampler2D u_prev; uniform sampler2D u_next; uniform float u_time; in vec2 v_uv; out vec4 outColor; void main() { outColor = mix(texture(u_next, v_uv), texture(u_prev, v_uv), u_time); }`; constmyShader :HtmlInCanvasShader <{}> = (canvas ) => { constgl =canvas .getContext ('webgl2', {premultipliedAlpha : true})!; constcompile = (src : string,type : number) => { constsh =gl .createShader (type )!;gl .shaderSource (sh ,src );gl .compileShader (sh ); returnsh ; }; constprogram =gl .createProgram ()!;gl .attachShader (program ,compile (VERTEX ,gl .VERTEX_SHADER ));gl .attachShader (program ,compile (FRAGMENT ,gl .FRAGMENT_SHADER ));gl .linkProgram (program ); constbuffer =gl .createBuffer ();gl .bindBuffer (gl .ARRAY_BUFFER ,buffer );gl .bufferData (gl .ARRAY_BUFFER , newFloat32Array ([-1, -1, 1, -1, -1, 1, 1, 1]),gl .STATIC_DRAW , ); constaPos =gl .getAttribLocation (program , 'a_pos');gl .enableVertexAttribArray (aPos );gl .vertexAttribPointer (aPos , 2,gl .FLOAT , false, 0, 0); constprevTex =gl .createTexture (); constnextTex =gl .createTexture (); return {clear : () => {gl .clearColor (0, 0, 0, 0);gl .clear (gl .COLOR_BUFFER_BIT ); },cleanup : () => {gl .deleteProgram (program );gl .deleteTexture (prevTex );gl .deleteTexture (nextTex );gl .deleteBuffer (buffer ); },draw : ({prevImage ,nextImage ,width ,height ,time }) => {gl .viewport (0, 0,width ,height );gl .useProgram (program );gl .activeTexture (gl .TEXTURE0 );gl .bindTexture (gl .TEXTURE_2D ,prevTex ); if (prevImage ) {gl .texElementImage2D (gl .TEXTURE_2D , 0,gl .RGBA ,gl .RGBA ,gl .UNSIGNED_BYTE ,prevImage , ); }gl .uniform1i (gl .getUniformLocation (program , 'u_prev'), 0);gl .activeTexture (gl .TEXTURE1 );gl .bindTexture (gl .TEXTURE_2D ,nextTex ); if (nextImage ) {gl .texElementImage2D (gl .TEXTURE_2D , 0,gl .RGBA ,gl .RGBA ,gl .UNSIGNED_BYTE ,nextImage , ); }gl .uniform1i (gl .getUniformLocation (program , 'u_next'), 1); constt = !prevImage ? 0 : !nextImage ? 1 :time ;gl .uniform1f (gl .getUniformLocation (program , 'u_time'),t );gl .drawArrays (gl .TRIANGLE_STRIP , 0, 4); }, }; }; constmyPresentation =makeHtmlInCanvasPresentation (myShader );
HTML-in-canvas requires Chrome Canary with chrome://flags/#canvas-draw-element enabled.
Arguments
shader
A function of type HtmlInCanvasShader<Props>. Called once per transition mount with a shared OffscreenCanvas. Must return an object with three callbacks: clear, cleanup and draw.
import type {HtmlInCanvasShader } from '@remotion/transitions';clear()
Called when there is nothing to draw (both scenes are unmounted). Typically clears the WebGL color buffer.
cleanup()
Called once when the transition unmounts. Release any GL resources you allocated (programs, textures, buffers, VAOs).
draw()
Called every frame the transition is active. Has the type HtmlInCanvasShaderDraw<Props>:
import type {HtmlInCanvasShaderDraw } from '@remotion/transitions';The argument has the type HtmlInCanvasShaderDrawParams<Props>:
import type {HtmlInCanvasShaderDrawParams } from '@remotion/transitions';prevImage
ElementImage | null — the captured exiting scene. null while it has not yet rendered (e.g. at the very start).
nextImage
ElementImage | null — the captured entering scene. null after the entering scene has unmounted.
width / height
The pixel size of the canvas to draw into.
time
A number between 0 and 1.
time = 0 means the shader should output the entering scene fully (i.e. transition end), and time = 1 means the shader should output the exiting scene fully (i.e. transition start).
When one image is missing, treat it as the boundary case: if !prevImage, force time = 0 so the shader falls back to nextImage only; if !nextImage, force time = 1 so the shader falls back to prevImage only.
passedProps
Whatever you typed your Props as. Use this for runtime knobs like rotation, intensity, direction, etc.
Return value
A function (props: Props) => TransitionPresentation<Props> that you call with your runtime props and pass to presentation on a <TransitionSeries.Transition>.
See also
- Custom HTML-in-canvas presentations — full walkthrough and example
- HTML-in-canvas
- Custom presentations — the CSS-based path