wtc-gl
    Preparing search index...

    Class ScrollRenderer

    Renders multiple independent WebGL scenes on a single full-viewport canvas, each scissor-tested to a DOM element's exact pixel bounds.

    A single requestAnimationFrame loop drives all registered ScrollScene instances. Scenes outside the viewport are skipped automatically via IntersectionObserver. The canvas is cleared to transparent once per frame before the scissored passes run.

    const renderer = new ScrollRenderer()
    Object.assign(renderer.canvas.style, {
    position: 'fixed', inset: '0', width: '100%', height: '100%',
    pointerEvents: 'none', zIndex: '0',
    })
    document.body.appendChild(renderer.canvas)

    const scene = new ScrollScene({ element: document.querySelector('.hero'), scene: drawable })
    renderer.addScene(scene)
    renderer.playing = true
    // In your component:
    const canvasRef = useRef<HTMLCanvasElement>(null)
    useEffect(() => {
    const renderer = new ScrollRenderer({ rendererProps: { canvas: canvasRef.current! } })
    renderer.playing = true
    return () => { renderer.destroy() } // canvas stays in the DOM; React removes it
    }, [])
    // In JSX:
    <canvas ref={canvasRef} style={{ position: 'fixed', inset: 0, width: '100%', height: '100%', pointerEvents: 'none' }} />
    const renderer = new ScrollRenderer({ layout: 'absolute' })
    Object.assign(renderer.canvas.style, {
    position: 'absolute', top: '0', left: '0', width: '100%',
    pointerEvents: 'none', zIndex: '0',
    })
    // body (or another non-positioned ancestor) so the canvas is document-relative
    document.body.appendChild(renderer.canvas)
    renderer.addScene(new ScrollScene({ element, scene, margin: renderer.overscanPx }))
    Index

    Constructors

    Properties

    The WebGL rendering context.

    onAfterRender: (delta: number) => void
    onBeforeRender: (delta: number) => void
    renderer: Renderer

    The underlying Renderer instance.

    Accessors

    Methods

    • Stops the render loop, disconnects the resize observer, and destroys all registered scenes (disconnecting their IntersectionObservers).

      When the renderer created its own canvas, the WebGL context is also released immediately (via WEBGL_lose_context) rather than lingering until garbage collection — browsers cap the number of live contexts per page and drop the oldest when the cap is hit. A caller-supplied canvas (via rendererProps.canvas) is left untouched: a canvas can only ever hold one context, so losing it would break callers that keep the element and construct a new ScrollRenderer against it (React StrictMode does exactly this).

      Returns the underlying <canvas> element so callers can remove it from the DOM if they own it. When using a React-managed canvas you don't need the return value — React will remove the element itself on unmount.

      Returns HTMLCanvasElement

      The canvas element.

    • Synchronises the GL canvas buffer size with the viewport.

      In fixed layout, measures the canvas (clientWidth/clientHeight) so the buffer can never disagree with how the element is laid out. Falls back to the document's client size when the canvas isn't in the DOM yet (or has no layout size), which also avoids the scrollbar-gutter offset that window.innerWidth/innerHeight would introduce.

      In absolute layout, the viewport height is read from the document and the canvas is sized to viewport * (1 + 2 * overscan) — the renderer sets the canvas height style itself.

      Called automatically on construction, when the canvas ResizeObserver triggers, and at the start of every rendered frame.

      Returns void