class · blotter.ts
Blotter
The orchestrator: packs its texts into one atlas, renders them through the material in a single draw call, and hands each text its own canvas.
extends Emitter<BlotterEvents>
import { Blotter } from "blotter.ts"; Whenever you want a material applied to some texts, you make a Blotter. It measures the texts, bin-packs them into a shared texture, compiles the material into a shader that reads that texture, and runs a render loop on requestAnimationFrame. Every Blotter on the page draws through one shared WebGL context, so the cost of a second instance is a render target, not a context.
The constructor throws where WebGL is unavailable; check isWebGLSupported() first when you need a plain-text fallback.
import { Blotter, Text } from "blotter.ts";
import { ChannelSplitMaterial } from "blotter.ts/materials";
const text = new Text("Hello", { family: "serif", size: 96 });
const blotter = new Blotter(new ChannelSplitMaterial(), { texts: text });
blotter.forText(text)?.appendTo(document.body);
await blotter.ready; Members #
constructor constructor
Takes the material to draw with and an optional BlotterOptions: the texts, the pixel ratio, and the three auto* switches. With the defaults the instance builds and starts rendering immediately.
ratio property
The pixel ratio the atlas is drawn at. Defaults to the device pixel ratio so text is crisp on high-density screens; read-only after construction.
autoplay property
Whether new render scopes start in the playing state. Set through the options; read-only afterwards.
ready property
A promise that resolves with the instance after its first successful build, and rejects if the material fails to compile. The ready event fires at the same moment; awaiting the promise is the usual way to wait.
autostart property
Whether the render loop is running. start() and stop() flip it, so it doubles as a "is this instance animating" check.
autobuild property
Whether the instance builds itself on construction and after changes. Set it to false in the options when you intend to add texts or swap the material before the first build, then call update() yourself.
material get / set
The material the texts are drawn with. Assigning a new one is the same as calling setMaterial(): it takes effect after the next update().
texts get
The texts this instance draws, as a read-only array. Change the set with addTexts() and removeTexts().
imageData get
The whole back buffer from the most recent frame as ImageData, or undefined before the first render. Each render scope copies its own rectangle out of this; you rarely need it directly.
setMaterial method
Replaces the material. The shader is recompiled on the next update(), which you call yourself.
addText method
Adds one text. An alias for addTexts(text).
addTexts method
Adds one or more texts to be drawn. They join the atlas on the next update(), which you call yourself.
blotter.addTexts([a, b]);
await blotter.update();
blotter.forText(a)?.appendTo(el); removeText method
Removes one text. An alias for removeTexts(text).
removeTexts method
Removes one or more texts. Their canvases stop updating after the next update(); remove the elements from the DOM yourself.
update method
Rebuilds the atlas and the shader from the current texts and material, and resolves when the rebuild has settled. Concurrent calls coalesce: one build runs at a time with at most one more queued, so calling it in a burst is safe. Changing a text’s value or properties, or a material’s uniforms declaration, calls this for you; you only need it after setMaterial, addTexts, removeTexts, or when autobuild is off.
start method
Starts the render loop. Each frame updates the built-in uniforms, draws the atlas, and emits render.
stop method
Stops the render loop. The canvases keep their last frame. Uniform changes made while stopped are not visible until the loop runs again.
teardown method
Disposes the instance’s render target and removes every listener it registered on its texts and material. Call stop() first. The shared WebGL context stays alive for other instances.
forText method
The RenderScope for a text this instance draws, or undefined for a text it does not know. The scope is where the canvas and the per-text uniforms live.
See also RenderScope
boundsForText method
The rectangle a text occupies in the back buffer, as TextBounds. Width and height are the size of the text’s canvas; the offsets are an implementation detail of the atlas.
Inherited #
on method inherited from Emitter
Subscribes to an event and returns a function that unsubscribes. ready fires once after the first build, update after every later rebuild, render after every frame. Every emitter in Blotter shares this shape.
const off = blotter.on("render", (frame) => {
if (frame > 600) off();
}); off method inherited from Emitter
Removes a handler added with on.