Skip to content
blotter

Guide

Migrating from Blotter.js

Same renderer, new API. What changed, what stayed, and the classic example before and after.

On this page

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.jsblotter.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 #

  • forText returns undefined for a text the instance does not know, so TypeScript users want the optional chain.
  • Changing a text’s value or properties rebuilds automatically. The explicit update() is still there for setMaterial, addTexts and removeTexts, 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.