← Back to catalog
shader-transition / flash-through-white
flash-through-white
Transitions through a white flash. Ported from the pinned Hyperframes shader.
Use this effect
VideoML XML
Save this example as example.videoml.xml and place the downloaded asset in an assets/ directory beside it. Run vml pipeline example.videoml.xml with a VideoML installation that supports frame effects.
Download Geist-Latin.woff2 to assets/.
<vml id="catalog-example" width="1280" height="720" fps="30" duration="4s">
<voiceover seed="0"/>
<assets><asset id="font" src="assets/Geist-Latin.woff2" media-type="font/woff2"/></assets>
<scene id="from" start="0s" duration="3s">
<video-background props='{"color":"#224466"}'/>
<frame-effect id="echo" effect-id="videoml/echo-smear" effect-version="1" props='{"parameters":{"length":100,"threshold":40,"color":"#71f5a7"}}' start="0s" duration="3s"/>
</scene>
<transition id="transition" effect="flash-through-white" start="2s" duration="1s" ease="linear" props='{"accent":[1,0.6,0.2],"dark":[0.4,0.15,0],"bright":[1,0.85,0.5]}'/>
<scene id="to" start="2s" duration="2s">
<video-background props='{"color":"#88aa66"}'/>
<frame-effect id="particles" effect-id="videoml/particle-text-dissolve" effect-version="1" props='{"parameters":{"text":"VideoML","density":"med","accent":"green","direction":"in"}}' start="0s" duration="2s"/>
</scene>
</vml>
TypeScript
Requires the frozen stdlib package, GSAP, a page element with id="effect-root", and the referenced local assets. Revoke any generated object URLs when the host disposes the effect.
import { createEffectRegistry, mountEffect } from '@videoml/stdlib/effects';
import { registerEchoSmear } from '@videoml/stdlib/effects/echo-smear';
import { registerParticleEffects } from '@videoml/stdlib/effects/particles';
import { mountSceneCompositor } from '@videoml/stdlib/effects/transitions';
import { gsap } from 'gsap';
const root = document.querySelector<HTMLElement>('#effect-root');
if (!root) throw new Error('Missing #effect-root');
const registry = createEffectRegistry(); registerEchoSmear(registry); registerParticleEffects(registry);
const response = await fetch('./assets/Geist-Latin.woff2');
if (!response.ok) throw new Error('Font unavailable');
const font = URL.createObjectURL(await response.blob());
const context = { width: 1280, height: 720, fps: 30, seed: 0, assets: { font } };
function scene(id: string, parameters: Record<string, unknown>, startFrame: number, endFrame: number, background: string) {
const layer = document.createElement('div'); Object.assign(layer.style, { position: 'absolute', left: '-10000px', top: '0', width: '1280px', height: '720px' }); document.body.append(layer);
const effect = mountEffect(layer, registry, { id, version: '1', parameters, startFrame, endFrame }, context);
const canvas = document.createElement('canvas'); canvas.width = 1280; canvas.height = 720;
const ctx = canvas.getContext('2d'); if (!ctx) throw new Error('Canvas unavailable');
return { seek: (frame: number) => effect.seek(frame), async capture() { const content = layer.querySelector('canvas'); if (!content) throw new Error('Scene unavailable'); ctx.fillStyle = background; ctx.fillRect(0, 0, 1280, 720); ctx.drawImage(content, 0, 0); return canvas; }, dispose() { effect.dispose(); layer.remove(); } };
}
const from = scene('videoml/echo-smear', {"length":100,"threshold":40,"color":"#71f5a7"}, 0, 90, '#224466');
const to = scene('videoml/particle-text-dissolve', {"text":"VideoML","density":"med","accent":"green","direction":"in"}, 60, 120, '#88aa66');
const easeName = "linear";
if (!/^[A-Za-z][A-Za-z0-9]*(?:\.(?:in|out|inOut))?$/.test(easeName)) throw new Error('TRANSITION_INVALID: unknown easing');
const ease = gsap.parseEase(easeName); if (typeof ease !== 'function') throw new Error('TRANSITION_INVALID: unknown easing');
const transition = mountSceneCompositor(root, { from, to, width: 1280, height: 720, startFrame: 60, endFrame: 90, shader: "flash-through-white", parameters: {"accent":[1,0.6,0.2],"dark":[0.4,0.15,0],"bright":[1,0.85,0.5]}, ease });
await transition.seek(75);
// On teardown: transition.dispose(); URL.revokeObjectURL(font);Upstream Apache-2.0 license · GSAP license · Geist font license
implemented · interactive preview
This entry is implemented but not yet verified.