The WebGL rendering context.
The underlying Renderer instance.
The underlying <canvas> element. Append this to the document yourself.
ScrollRendererOptions.overscan — always 0 in fixed layout.
Height of the overscan band above (and below) the viewport, in CSS px.
0 in fixed layout. Useful as a ScrollScene margin.
Whether the render loop is currently running.
Controls the render loop. Setting to true starts requestAnimationFrame;
setting to false stops it.
Registers a scene with the renderer. Scenes are rendered in insertion order.
The ScrollScene to add.
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.
The canvas element.
Removes a previously registered scene from the render loop.
This does not call ScrollScene.destroy — the caller is
responsible for disconnecting the scene's IntersectionObserver by
calling scene.destroy() when it is no longer needed.
The ScrollScene to remove.
The main render loop — called internally via requestAnimationFrame.
Do not call this directly; use the playing setter instead.
Timestamp provided by requestAnimationFrame.
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.
Renders multiple independent WebGL scenes on a single full-viewport canvas, each scissor-tested to a DOM element's exact pixel bounds.
A single
requestAnimationFrameloop drives all registered ScrollScene instances. Scenes outside the viewport are skipped automatically viaIntersectionObserver. The canvas is cleared to transparent once per frame before the scissored passes run.Example
Example: React — pass a canvas ref so React owns the DOM node
Example: Absolute layout — compositor-synced scrolling on touch devices