Text and glyph ramps
textmode.js can draw individual glyphs with char() and shape primitives, but it also includes native text printing and glyph ramps for value-to-character workflows.
Use printing for labels, captions, terminal-style panels, and typographic compositions. Use glyph ramps when brightness, noise, distance, or audio values should become characters.
Printing text
print() writes a string into the active layer:
t.print("SIGNAL ONLINE", -12, -4);It uses the current drawing state, so charColor(), cellColor(), invert(), flipX(), flipY(), and charRotation() affect printed characters the same way they affect points and shapes.
t.charColor(120, 255, 180);
t.cellColor(10, 18, 28);
t.print("ACTIVE", -3, 0);Print alignment
printAlign() changes how the print position is interpreted:
t.printAlign("center", "middle");
t.print("CENTERED", 0, 0);
t.printAlign("right", "bottom");
t.print("lower right", t.grid.cols / 2 - 2, t.grid.rows / 2 - 2);Horizontal alignment can be "left", "center", or "right". Vertical alignment can be "top", "middle", or "bottom".
Print options
Pass options as the fourth argument:
t.print(
"A\tB\tC\nD\tE\tF",
-12,
-4,
{
leading: 2,
tabSize: 4,
letterSpacing: 1,
markup: false,
}
);leadingcontrols line spacing in cells.tabSizecontrols how many spaces a tab expands to.letterSpacingadds extra cells between printed characters.markupcontrols whether inline formatting tags are parsed.
Inline markup
By default, print() supports BBCode-style tags for local formatting changes:
t.print(
"[fg=lime]READY[/fg] [bg=#102030]BUFFER[/bg] [inv]HOT[/inv]",
-18,
0
);Supported tags include:
[fg=color]...[/fg]for foreground character color.[bg=color]...[/bg]for cell background color.[inv]...[/inv]for inverted character and cell colors.[rot=90]...[/rot]for character rotation in degrees.[fx]...[/fx]for horizontal glyph flip.[fy]...[/fy]for vertical glyph flip.
Tags can be nested for compact HUDs, labels, and annotated visual systems:
t.print(
"status: [fg=yellow][inv]SYNC[/inv][/fg] angle: [rot=90]>[/rot]",
-20,
6
);Disable markup when printing text that should display brackets literally:
t.print("[fg=red]literal tag[/fg]", -10, 0, { markup: false });Glyph ramps
A TextmodeGlyphRamp maps numeric values to characters. Create one with createGlyphRamp():
const ramp = t.createGlyphRamp(" .:-=+*#%@");Characters should be ordered from low intensity to high intensity. Spaces and light punctuation usually work well at the beginning; dense glyphs usually work well at the end.
Mapping values to glyphs
Use at() with normalized values:
const value = t.noise(x * 0.08, y * 0.08, t.secs * 0.2);
t.char(ramp.at(value));You can also pass a source range:
const wave = Math.sin(x * 0.2 + t.secs);
t.char(ramp.at(wave, -1, 1));Values outside the range are clamped to the nearest glyph.
Noise-to-glyph field
Glyph ramps are especially useful when paired with noise():
const ramp = t.createGlyphRamp(" .,:;irsXA253hMHGS#9B&@");
t.draw(() => {
t.background(4, 6, 14);
for (let y = -18; y < 18; y++) {
for (let x = -32; x < 32; x++) {
const value = t.noise(x * 0.07, y * 0.1, t.secs * 0.18);
t.char(ramp.at(value));
t.charColor(90 + value * 140, 150 + value * 80, 255);
t.point(x, y);
}
}
});Shifted ramps
shift(amount) returns a shifted copy of the ramp:
const baseRamp = t.createGlyphRamp("0123456789ABCDEF");
t.draw(() => {
const animatedRamp = baseRamp.shift(t.frameCount * 0.08);
const value = t.noise(t.secs * 0.2);
t.char(animatedRamp.at(value));
t.point();
});This is useful for animated character palettes where the value field stays stable but the glyph vocabulary rotates over time.