Skip to content

textmode.js / loadables / TextmodeSource

Class: abstract TextmodeSource

Abstract base class representing a textmode source asset (image, video, texture).

Extends

  • Disposable

Extended by

Implements

  • ITextmodeSource

Accessors

height

Get Signature

ts
get height(): number;

Ideal height in grid cells.

Returns

number

Implementation of

ts
ITextmodeSource.height

originalHeight

Get Signature

ts
get originalHeight(): number;

Original pixel height.

Returns

number

Implementation of

ts
ITextmodeSource.originalHeight

originalWidth

Get Signature

ts
get originalWidth(): number;

Original pixel width.

Returns

number

Implementation of

ts
ITextmodeSource.originalWidth

texture

Get Signature

ts
get texture(): WebGLTexture;

Return the WebGL texture currently backing this source.

Returns

WebGLTexture

Implementation of

ts
ITextmodeSource.texture

width

Get Signature

ts
get width(): number;

Ideal width in grid cells.

Returns

number

Implementation of

ts
ITextmodeSource.width

Methods

background()

ts
background(
   colorOrGray, 
   g?, 
   b?, 
   a?): this;

Defines the background color used for transparent pixels.

Parameters

ParameterTypeDescription
colorOrGraystring | number | TextmodeColorA grayscale value (0-255), hex string ('#RGB', '#RRGGBB', '#RRGGBBAA'), or TextmodeColor instance
g?numberOptional green component (0-255) if using RGB format, or alpha (0-255) when using grayscale form
b?numberOptional blue component (0-255) if using RGB format
a?numberOptional alpha component (0-255) if using RGBA format

Returns

this

This instance for chaining.

Example

javascript
const t = textmode.create({ width: window.innerWidth, height: window.innerHeight });

let img;

t.setup(async () => {
  // Load an image with transparency (or simulate by setting background)
  // Here we use a standard image but define a background color that would
  // show through if the image had alpha holes.
  img = await t.loadImage('https://images.unsplash.com/photo-1550684848-fac1c5b4e853?w=500&q=80');
  img.characters(' .:-=+*#%@');
});

t.draw(() => {
  t.background(50); // Canvas background
  if (!img) return;

  // Set the image's "background" color (fallback for transparent pixels)
  img.background(255, 0, 0);

  t.image(img, img.width, img.height);
});

t.windowResized(() => {
  t.resizeCanvas(window.innerWidth, window.innerHeight);
});

Implementation of

ts
ITextmodeSource.background

cellColor()

ts
cellColor(
   colorOrGray, 
   g?, 
   b?, 
   a?): this;

Defines the cell color when cellColorMode is 'fixed'.

Parameters

ParameterTypeDescription
colorOrGraystring | number | TextmodeColorA grayscale value (0-255), hex string ('#RGB', '#RRGGBB', '#RRGGBBAA'), or TextmodeColor instance
g?numberOptional green component (0-255) if using RGB format, or alpha (0-255) when using grayscale form
b?numberOptional blue component (0-255) if using RGB format
a?numberOptional alpha component (0-255) if using RGBA format

Returns

this

This instance for chaining.

Example

javascript
const t = textmode.create({ width: window.innerWidth, height: window.innerHeight });

let img;

t.setup(async () => {
  img = await t.loadImage('https://images.unsplash.com/photo-1550684848-fac1c5b4e853?w=500&q=80');
  img.cellColorMode('fixed');
  img.characters(' .:-=+*#%@');
});

t.draw(() => {
  t.background(0);
  if (!img) return;

  // Set a dark blue background for the image cells
  img.cellColor('#000033');
  // Ensure characters are visible
  img.charColorMode('fixed').charColor(255);

  t.image(img, img.width, img.height);
});

t.windowResized(() => {
  t.resizeCanvas(window.innerWidth, window.innerHeight);
});

Implementation of

ts
ITextmodeSource.cellColor

cellColorMode()

ts
cellColorMode(mode): this;

Set cell color mode: 'sampled' (from source) or 'fixed'.

Parameters

ParameterTypeDescription
mode"sampled" | "fixed"The cell color mode

Returns

this

This instance for chaining.

Example

javascript
const t = textmode.create({ width: window.innerWidth, height: window.innerHeight });

let img;

t.setup(async () => {
  img = await t.loadImage('https://images.unsplash.com/photo-1550684848-fac1c5b4e853?w=500&q=80');
  img.characters(' .:-=+*#%@');
});

t.draw(() => {
  t.background(0);
  if (!img) return;

  // Sample character colors from image, but force black background
  // This creates a high-contrast ASCII art look
  img.charColorMode('sampled')
     .cellColorMode('fixed')
     .cellColor(Math.sin(t.frameCount * 0.1) * 127 + 128, 0, 0);

  t.image(img, img.width, img.height);
});

t.windowResized(() => {
  t.resizeCanvas(window.innerWidth, window.innerHeight);
});

Implementation of

ts
ITextmodeSource.cellColorMode

characters()

ts
characters(chars): this;

Define the characters to use for brightness mapping as a string. Maximum length is 255; excess characters are ignored.

Parameters

ParameterTypeDescription
charsstringString of characters to map

Returns

this

This instance for chaining.

Example

javascript
const t = textmode.create({ width: window.innerWidth, height: window.innerHeight });

let tex;

t.setup(() => {
    // Create a gradient pattern to demonstrate character mapping
    const canvas = document.createElement('canvas');
    canvas.width = 200;
    canvas.height = 200;
    const ctx = canvas.getContext('2d');
    if (ctx) {
        const g = ctx.createLinearGradient(0, 0, 200, 200);
        g.addColorStop(0, '#000');
        g.addColorStop(1, '#fff');
        ctx.fillStyle = g;
        ctx.fillRect(0, 0, 200, 200);
    }

    tex = t.createTexture(canvas);

    // Map brightness to a high-density character set
    // Darker pixels become ' ', lighter pixels become '@'
    tex.characters(' .:-=+*#%@');
});

t.draw(() => {
    t.background(0);

    // Render the image filling the entire grid
    // (0,0) is the center of the screen
    if (tex) {
        t.image(tex, tex.width, tex.height);
    }
});

t.windowResized(() => {
  t.resizeCanvas(window.innerWidth, window.innerHeight);
});

Implementation of

ts
ITextmodeSource.characters

charColor()

ts
charColor(
   colorOrGray, 
   g?, 
   b?, 
   a?): this;

Defines the character color when charColorMode is 'fixed'.

Parameters

ParameterTypeDescription
colorOrGraystring | number | TextmodeColorA grayscale value (0-255), hex string ('#RGB', '#RRGGBB', '#RRGGBBAA'), or TextmodeColor instance
g?numberOptional green component (0-255) if using RGB format, or alpha (0-255) when using grayscale form
b?numberOptional blue component (0-255) if using RGB format
a?numberOptional alpha component (0-255) if using RGBA format

Returns

this

This instance for chaining.

Example

javascript
const t = textmode.create({ width: window.innerWidth, height: window.innerHeight });

let img;

t.setup(async () => {
  img = await t.loadImage('https://images.unsplash.com/photo-1550684848-fac1c5b4e853?w=500&q=80');
  img.charColorMode('fixed');
  img.characters(' .:-=+*#%@');
});

t.draw(() => {
  t.background(0);
  if (!img) return;

  // Animate character color
  const r = 150 + 100 * Math.sin(t.frameCount * 0.05);
  const b = 150 + 100 * Math.cos(t.frameCount * 0.05);

  img.charColor(r, 100, b);

  t.image(img, img.width, img.height);
});

t.windowResized(() => {
  t.resizeCanvas(window.innerWidth, window.innerHeight);
});

Implementation of

ts
ITextmodeSource.charColor

charColorMode()

ts
charColorMode(mode): this;

Set character color mode: 'sampled' (from source) or 'fixed'.

Parameters

ParameterTypeDescription
mode"sampled" | "fixed"The character color mode

Returns

this

This instance for chaining.

Example

javascript
const t = textmode.create({ width: window.innerWidth, height: window.innerHeight });

let img;

t.setup(async () => {
  img = await t.loadImage('https://images.unsplash.com/photo-1550684848-fac1c5b4e853?w=500&q=80');
  img.characters(' .:-=+*#%@');
});

t.draw(() => {
  t.background(0);
  if (!img) return;

  // Use fixed color mode for a stylized look
  // Characters will be red, background will be sampled from image
  img.charColorMode('fixed')
     .charColor(255, 50, 50)
     .cellColorMode('sampled');

  t.image(img, img.width, img.height);
});

t.windowResized(() => {
  t.resizeCanvas(window.innerWidth, window.innerHeight);
});

Implementation of

ts
ITextmodeSource.charColorMode

charRotation()

ts
charRotation(degrees): this;

Set the character rotation in degrees (0-360).

Parameters

ParameterTypeDescription
degreesnumberRotation in degrees

Returns

this

This instance for chaining.

Example

javascript
const t = textmode.create({ width: window.innerWidth, height: window.innerHeight });

let tex;

t.setup(() => {
  // Create a procedural texture (checkers pattern)
  const canvas = document.createElement('canvas');
  canvas.width = 64;
  canvas.height = 64;
  const ctx = canvas.getContext('2d');
  if (ctx) {
    ctx.fillStyle = '#fff';
    ctx.fillRect(0, 0, 64, 64);
    ctx.fillStyle = '#000';
    ctx.fillRect(0, 0, 32, 32);
    ctx.fillRect(32, 32, 32, 32);
  }

  tex = t.createTexture(canvas);
  tex.characters(' .:-=+*#%@');
});

t.draw(() => {
  t.background(0);
  if (!tex) return;

  const size = Math.min(tex.width, tex.height) * 0.4;
  const offset = size * 0.6;

  // Original orientation (0 degrees)
  t.push();
  t.translate(-offset, 0);
  tex.charRotation(0);
  t.image(tex, size, size);
  t.pop();

  // Rotated characters (90 degrees)
  t.push();
  t.translate(offset, 0);
  tex.charRotation(90);
  t.image(tex, size, size);
  t.pop();
});

t.windowResized(() => {
  t.resizeCanvas(window.innerWidth, window.innerHeight);
});

Implementation of

ts
ITextmodeSource.charRotation

conversionMode()

ts
conversionMode(mode): this;

Select the conversion mode for this source.

textmode.js includes only a single built-in conversion strategy 'brightness'.

Additional conversion strategies may be provided via add-on libraries.

Parameters

ParameterTypeDescription
modestringConversion mode to use.

Returns

this

This instance for chaining.

Example

javascript
const t = textmode.create({ width: window.innerWidth, height: window.innerHeight });

let img;

t.setup(async () => {
  img = await t.loadImage('https://images.unsplash.com/photo-1550684848-fac1c5b4e853?w=500&q=80');
  img.conversionMode('brightness');
  img.characters(' .:-=+*#%@');
});

t.draw(() => {
  t.background(0);
  if (!img) return;

  // Draw centered
  t.image(img, img.width, img.height);
});

t.windowResized(() => {
  t.resizeCanvas(window.innerWidth, window.innerHeight);
});

Implementation of

ts
ITextmodeSource.conversionMode

dispose()

ts
dispose(): void;

Dispose of the resource and run all registered callbacks. Subclasses should call super.dispose() at the end of their dispose method.

Returns

void

Implementation of

ts
ITextmodeSource.dispose

Overrides

ts
Disposable.dispose

flipX()

ts
flipX(v): this;

Set horizontal flip indicator flag.

Parameters

ParameterTypeDefault valueDescription
vnumber | booleantrueFlip flag

Returns

this

This instance for chaining.

Example

javascript
// Creating symmetry using flipX
const t = textmode.create({ width: window.innerWidth, height: window.innerHeight });

let tex;

t.setup(() => {
  // Create a simple procedural quadrant pattern
  const canvas = document.createElement('canvas');
  canvas.width = 64; canvas.height = 64;
  const ctx = canvas.getContext('2d');
  if (ctx) {
    const g = ctx.createRadialGradient(64, 64, 0, 64, 64, 64);
    g.addColorStop(0, '#fff'); g.addColorStop(1, '#000');
    ctx.fillStyle = g; ctx.fillRect(0, 0, 64, 64);
    ctx.strokeStyle = '#fff'; ctx.lineWidth = 4;
    ctx.strokeRect(0, 0, 64, 64);
  }

  tex = t.createTexture(canvas);
  tex.characters(' .:-=+*#%@');
});

t.draw(() => {
  t.background(5, 5, 15);
  if (!tex) return;

  const size = 30;
  const time = t.frameCount * 0.02;

  // Draw a 2x1 symmetrical composition
  for (let x = 0; x < 2; x++) {
    t.push();
    t.translate((x - 0.5) * size, 0);

    // Flip the right side to create a mirrored effect
    tex.flipX(x === 1);

    t.image(tex, size, size);
    t.pop();
  }
});

t.windowResized(() => {
  t.resizeCanvas(window.innerWidth, window.innerHeight);
});

Implementation of

ts
ITextmodeSource.flipX

flipY()

ts
flipY(v): this;

Set vertical flip indicator flag.

Parameters

ParameterTypeDefault valueDescription
vnumber | booleantrueFlip flag

Returns

this

This instance for chaining.

Example

javascript
const t = textmode.create({ width: window.innerWidth, height: window.innerHeight });

let img;

t.setup(async () => {
  img = await t.loadImage('https://images.unsplash.com/photo-1550684848-fac1c5b4e853?w=500&q=80');
  img.characters(' .:-=+*#%@');
});

t.draw(() => {
  t.background(0);
  if (!img) return;

  const size = Math.min(img.width, img.height) * 0.4;
  const offset = size * 0.6;

  // Draw original
  t.push();
  t.translate(-offset, 0);
  t.image(img, size, size);
  t.pop();

  // Draw flipped vertically
  t.push();
  t.translate(offset, 0);
  img.flipY(true);
  t.image(img, size, size);
  // Reset for next frame
  img.flipY(false);
  t.pop();
});

t.windowResized(() => {
  t.resizeCanvas(window.innerWidth, window.innerHeight);
});

Implementation of

ts
ITextmodeSource.flipY

invert()

ts
invert(v): this;

Set the invert flag, swapping character and cell colors when enabled.

Parameters

ParameterTypeDefault valueDescription
vnumber | booleantrueInvert flag

Returns

this

This instance for chaining.

Example

javascript
const t = textmode.create({ width: window.innerWidth, height: window.innerHeight });

let texNormal, texInverted;

t.setup(() => {
  // Create a procedural texture (gradient)
  const canvas = document.createElement('canvas');
  canvas.width = 64;
  canvas.height = 64;
  const ctx = canvas.getContext('2d');
  if (ctx) {
    const g = ctx.createLinearGradient(0, 0, 64, 64);
    g.addColorStop(0, '#000');
    g.addColorStop(1, '#fff');
    ctx.fillStyle = g;
    ctx.fillRect(0, 0, 64, 64);
  }

  // Create two separate textures from the same source
  texNormal = t.createTexture(canvas);
  texNormal.characters(' .:-=+*#%@');

  texInverted = t.createTexture(canvas);
  texInverted.characters(' .:-=+*#%@');
  texInverted.invert(true);
});

t.draw(() => {
  t.background(0);
  if (!texNormal || !texInverted) return;

  const size = Math.min(texNormal.width, texNormal.height) * 0.4;
  const offset = size * 0.6;

  // Normal
  t.push();
  t.translate(-offset, 0);
  t.image(texNormal, size, size);
  t.pop();

  // Inverted
  t.push();
  t.translate(offset, 0);
  t.image(texInverted, size, size);
  t.pop();
});

t.windowResized(() => {
  t.resizeCanvas(window.innerWidth, window.innerHeight);
});

Implementation of

ts
ITextmodeSource.invert