Guide
Migrating from Blotter.js
Same renderer, new API. What changed, what stayed, and the classic example before and after.
What stayed the same #
Everything you liked about the rendering. Texts sharing a material are still bin-packed into
one atlas and drawn in a single call; each text still gets its own canvas; the loop still
runs on requestAnimationFrame; the five materials are the same shaders with the
same uniforms. If a Blotter.js effect looked right, it looks the same here.
What changed #
The API. Blotter.js was a script tag that put a namespace on window;
blotter.ts is a typed ES module with two entry points and no globals.
| Blotter.js | blotter.ts |
|---|---|
<script> tags and window.Blotter.* globals | Named ESM imports from blotter.ts |
A separate <script> per material | import { ChannelSplitMaterial } from "blotter.ts/materials" |
new Blotter.Text(…), new Blotter.Material() | new Text(…), new Material() |
thing.needsUpdate = true | blotter.update(), material.update(), or nothing: text.value = rebuilds by itself |
blotter.on("ready", …) | await blotter.ready; the event still fires |
Blotter.Assets.Shaders.PI | import { shaders } from "blotter.ts", then shaders.pi |
Blotter._extendWithGettersSetters subclass protocol | class MyMaterial extends Material |
| Bundled underscore, EventEmitter and a custom Three build | Gone. three is a peer dependency |
Before and after #
The first example from the original documentation, as written for Blotter.js:
<script src="./path/to/blotter.js"></script>
<script src="./path/to/materials/liquidDistortMaterial.js"></script>
<script>
var text = new Blotter.Text("observation", {
family : "'EB Garamond', serif",
size : 27,
fill : "#202020"
});
var material = new Blotter.LiquidDistortMaterial();
var blotter = new Blotter(material, {
texts : text
});
blotter.on("ready", function () {
var elem = document.getElementById("plain-text");
var scope = blotter.forText(text);
scope.appendTo(elem);
});
</script> The same example against blotter.ts:
import { Blotter, Text } from "blotter.ts";
import { LiquidDistortMaterial } from "blotter.ts/materials";
const text = new Text("observation", {
family: "'EB Garamond', serif",
size: 27,
fill: "#202020",
});
const material = new LiquidDistortMaterial();
const blotter = new Blotter(material, { texts: text });
const elem = document.getElementById("plain-text");
if (elem) blotter.forText(text)?.appendTo(elem);
await blotter.ready; Behaviour notes #
-
forTextreturnsundefinedfor a text the instance does not know, so TypeScript users want the optional chain. -
Changing a text’s
valueorpropertiesrebuilds automatically. The explicitupdate()is still there forsetMaterial,addTextsandremoveTexts, and returns a promise. - There is no UMD build. Bundle it, or load it from an ESM-aware CDN with an import map.
-
The constructor throws where WebGL is unavailable. Check
isWebGLSupported()first and fall back to plain text.
Credits #
Blotter was created by Bradley Griffith. Shader helpers are adapted from Reza Ali’s Fragment, and atlas packing from Jake Gordon’s bin-packing. See the upstream project for the full original credits.