Layers and compositing
Layers let you build a composition from independent render passes. Each layer has its own draw callback, grid, font, framebuffers, opacity, blend mode, filter sequences, and camera state. (ノ◕ヮ◕)ノ*:・゚✧
Access layers through t.layers, a TextmodeLayerManager.
Base layer
Every sketch has a base layer:
t.layers.base.draw(() => {
t.background(0);
t.char(".");
t.charColor(120);
t.rect(t.grid.cols, t.grid.rows);
});Calling t.draw(...) is the common shorthand for drawing on the base layer.
Add a layer
Create user layers with t.layers.add():
const glow = t.layers.add({
opacity: 0.75,
blendMode: t.BLEND_SCREEN,
fontSize: 8,
});
glow.draw(() => {
t.clear();
t.char("*");
t.charColor(120, 220, 255);
t.rotateZ(t.frameCount);
t.rect(24, 12);
});Layer options include:
visibleopacityblendModeoffsetXandoffsetYrotationZfontSizefontSource
Blend modes
blendMode() controls how a layer is composited over the result below it:
glow.blendMode(t.BLEND_ADDITIVE);Use the LayerBlendMode values exposed through constants such as t.BLEND_NORMAL, t.BLEND_ADDITIVE, t.BLEND_MULTIPLY, t.BLEND_SCREEN, t.BLEND_OVERLAY, and t.BLEND_DIFFERENCE.
Opacity, visibility, and placement
glow.opacity(0.5);
glow.offset(20, 0);
glow.rotateZ(8);
glow.hide();
glow.show();These layer transforms affect compositing placement, not the drawing coordinate system inside the layer.
Manage layer order
Use the layer manager to reorder or remove user layers:
t.layers.move(glow, 0);
t.layers.swap(layerA, layerB);
t.layers.remove(glow);
t.layers.clear();The base layer is always present.
Layer-local resources
Layers can load their own fonts or tilesets:
const labelLayer = t.layers.add({ fontSize: 12 });
await labelLayer.loadFont("./fonts/label.woff");Layer-local font loading lets one sketch mix different glyph systems without changing the base layer.
Filters on layers
Apply filters before a layer is composited (requires textmode.filters.js). Each layer has its own filter queue, and filters run in the order they are requested:
glow.filter("threshold", { cutoff: 0.5 });Calls to layer.filter() made during a layer's draw() callback run after that layer is converted to ASCII. Calls made during layer.postDraw() run after the draw-time filter sequence and still before compositing:
glow.draw(() => {
t.clear();
t.char("*");
t.rect(24, 10);
glow.filter("grayscale");
});
glow.postDraw(() => {
glow.filter("invert");
});The invert filter runs after the layer has already been converted and passed through grayscale, but before glow is composited with other layers.
Apply global filters with t.filter() after all layers are composited. See Filters for the full filtering model.
Final draw
Use finalDraw() for final post-processing operations after layer compositing and before presentation:
t.finalDraw(() => {
t.filter("grayscale");
});Export layered sketches
Use Exporting to choose the right export model:
- canvas exports capture the final composited result, including layers, opacity, blend modes, filters, and
finalDraw(); - TXT and SVG exports read one selected layer through the
layeroption; - JSON exports one selected layer by default, or the full descriptive layer stack with
target: 'all'.