textmode.js 0.6.0-beta.3 → 0.6.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,13 @@
1
1
  import { Textmode } from './Textmode';
2
2
  export { Textmodifier } from './textmode/Textmodifier';
3
- export { GLFramebuffer as TextmodeFramebuffer } from './rendering';
3
+ export { GLFramebuffer as TextmodeFramebuffer, Shader } from './rendering';
4
4
  export { TextmodeColor } from './textmode/TextmodeColor';
5
5
  export { TextmodeCanvas } from './textmode/Canvas';
6
6
  export { TextmodeGrid } from './textmode/Grid';
7
7
  export type { TextmodeOptions } from './textmode/types';
8
8
  export type { TextmodeFramebufferOptions } from './rendering/webgl';
9
+ export { registerConversionStrategy, unregisterConversionStrategy, getConversionStrategy, } from './textmode/conversion';
10
+ export type { TextmodeConversionStrategy, TextmodeConversionContext, TextmodeConversionMode, } from './textmode/conversion';
9
11
  export type { TextmodePlugin, TextmodePluginAPI, } from './textmode/managers/PluginManager';
10
12
  export { TextmodeErrorLevel } from './errors/ErrorHandler';
11
13
  export { Textmode as textmode } from './Textmode';
@@ -2,8 +2,9 @@ import { GLFramebuffer } from "./Framebuffer";
2
2
  import type { FramebufferOptions } from './Framebuffer';
3
3
  import { GLShader } from "./Shader";
4
4
  import { RenderState } from "../state/RenderState";
5
- import type { TextmodeImage } from "../../../textmode/loadables/TextmodeImage";
5
+ import type { TextmodeSource } from '../../../textmode/loadables/TextmodeSource';
6
6
  import type { IRenderer } from "./interfaces/IRenderer";
7
+ import { MaterialManager } from '../materials/MaterialManager';
7
8
  export declare class GLRenderer implements IRenderer {
8
9
  private _gl;
9
10
  private _currentShader;
@@ -45,7 +46,7 @@ export declare class GLRenderer implements IRenderer {
45
46
  $setUniform(name: string, value: any): void;
46
47
  $setUserUniforms(uniforms: Record<string, any>): void;
47
48
  $createFilterShader(fragmentSource: string): GLShader;
48
- $image(source: GLFramebuffer | TextmodeImage, width?: number, height?: number): void;
49
+ $image(source: GLFramebuffer | TextmodeSource, width?: number, height?: number): void;
49
50
  $quad(x: number, y: number, width: number, height: number): void;
50
51
  $rect(width: number, height: number): void;
51
52
  $line(x1: number, y1: number, x2: number, y2: number): void;
@@ -61,4 +62,5 @@ export declare class GLRenderer implements IRenderer {
61
62
  $dispose(): void;
62
63
  get context(): WebGLRenderingContext;
63
64
  get state(): RenderState;
65
+ get materialManager(): MaterialManager;
64
66
  }
@@ -1,3 +1,6 @@
1
+ type GlyphColor = [number, number, number];
2
+ type GlyphColorResolver = (chars: string) => GlyphColor[];
3
+ type ColorTuple = [number, number, number] | [number, number, number, number];
1
4
  /**
2
5
  * Represents a color in the `textmode.js` rendering system.
3
6
  *
@@ -19,6 +22,13 @@ export declare class TextmodeColor {
19
22
  /** Alpha component *(0-255)* */
20
23
  readonly a: number;
21
24
  private constructor();
25
+ /**
26
+ * Create a color from any supported source.
27
+ * Accepts an existing {@link TextmodeColor}, CSS hex strings, single characters
28
+ * (resolved through a glyph resolver), grayscale values, RGB(A) tuples, or
29
+ * normalized component arrays.
30
+ */
31
+ static $from(value: TextmodeColor | string | number | ColorTuple, gOrResolver?: number | GlyphColorResolver, b?: number, a?: number): TextmodeColor;
22
32
  /**
23
33
  * Create a color from RGB or RGBA components (0-255 range).
24
34
  * @ignore
@@ -48,10 +58,15 @@ export declare class TextmodeColor {
48
58
  get normalized(): [number, number, number, number];
49
59
  /** Returns the character encoding *(0-1 range)* if this color was created from a glyph. */
50
60
  get character(): [number, number, number] | undefined;
61
+ /**
62
+ * Create a copy of this color with a different alpha value.
63
+ */
64
+ withAlpha(alpha: number): TextmodeColor;
51
65
  /**
52
66
  * Runtime type guard.
53
67
  * @ignore
54
68
  */
55
69
  static $isColor(value: unknown): value is TextmodeColor;
56
70
  }
57
- export type ColorLike = TextmodeColor | [number, number, number] | [number, number, number, number];
71
+ export type ColorLike = TextmodeColor | string | number | [number, number, number] | [number, number, number, number];
72
+ export {};
@@ -3,6 +3,7 @@ import { TextmodeFont } from './loadables/font';
3
3
  import { TextmodeGrid } from './Grid';
4
4
  import { TextmodeCanvas } from './Canvas';
5
5
  import { TextmodeImage } from './loadables/TextmodeImage';
6
+ import type { TextmodeSource } from './loadables/TextmodeSource';
6
7
  import { AnimationController } from './AnimationController';
7
8
  import { MouseManager } from './managers/MouseManager';
8
9
  import { KeyboardManager } from './managers/KeyboardManager';
@@ -54,6 +55,7 @@ export declare class Textmodifier extends Textmodifier_base implements ITextmodi
54
55
  private _resizeObserver?;
55
56
  private _isOverlay;
56
57
  private _targetCanvasImage?;
58
+ private _sources;
57
59
  /**
58
60
  * Create a new Textmodifier instance.
59
61
  * @param opts Configuration options for the Textmodifier instance.
@@ -82,6 +84,8 @@ export declare class Textmodifier extends Textmodifier_base implements ITextmodi
82
84
  get isDisposed(): boolean;
83
85
  get overlay(): TextmodeImage | undefined;
84
86
  get loading(): LoadingScreenManager;
87
+ $registerSource(source: TextmodeSource): void;
88
+ $notifyFontChange(): void;
85
89
  }
86
90
  export interface Textmodifier extends IRenderingMixin, IFontMixin, IAnimationMixin, IMouseMixin, ITouchMixin, IKeyboardMixin {
87
91
  }
@@ -0,0 +1,21 @@
1
+ import type { Shader } from '../../rendering';
2
+ import type { GLRenderer } from '../../rendering/webgl/core/Renderer';
3
+ import type { TextmodeFont } from '../loadables/font/TextmodeFont';
4
+ import type { TextmodeSource } from '../loadables/TextmodeSource';
5
+ export type TextmodeConversionMode = 'brightness' | 'accurate' | (string & {});
6
+ export interface TextmodeConversionContext {
7
+ renderer: GLRenderer;
8
+ gl: WebGL2RenderingContext;
9
+ font: TextmodeFont;
10
+ source: TextmodeSource;
11
+ gridWidth: number;
12
+ gridHeight: number;
13
+ }
14
+ export interface TextmodeConversionStrategy {
15
+ readonly id: TextmodeConversionMode;
16
+ createShader(context: TextmodeConversionContext): Shader;
17
+ createUniforms(context: TextmodeConversionContext): Record<string, any>;
18
+ }
19
+ export declare function registerConversionStrategy(strategy: TextmodeConversionStrategy): void;
20
+ export declare function unregisterConversionStrategy(id: TextmodeConversionMode): void;
21
+ export declare function getConversionStrategy(id: TextmodeConversionMode): TextmodeConversionStrategy | undefined;
@@ -0,0 +1 @@
1
+ export * from './ConversionRegistry';
@@ -0,0 +1,2 @@
1
+ import type { TextmodeConversionStrategy } from '../ConversionRegistry';
2
+ export declare const brightnessStrategy: TextmodeConversionStrategy;
@@ -1,6 +1,7 @@
1
1
  import type { TextmodeGrid } from '../Grid';
2
2
  import type { TextmodeFont } from '../loadables/font';
3
3
  import type { TextmodeImage } from '../loadables/TextmodeImage';
4
+ import type { TextmodeSource } from '../loadables/TextmodeSource';
4
5
  import type { TextmodeCanvas } from '../Canvas';
5
6
  import type { AnimationController } from '../AnimationController';
6
7
  import type { GLFramebuffer, Shader } from '../../rendering';
@@ -50,6 +51,10 @@ export interface ITextmodifier extends IRenderingMixin, IFontMixin, IAnimationMi
50
51
  readonly _presentShader: Shader;
51
52
  /** Loading screen manager for boot-time UX @ignore */
52
53
  readonly _loading: LoadingScreenManager;
54
+ /** @ignore */
55
+ $registerSource(source: TextmodeSource): void;
56
+ /** @ignore */
57
+ $notifyFontChange(): void;
53
58
  /** Main render method @ignore */
54
59
  $render(): void;
55
60
  /**
@@ -1,4 +1,5 @@
1
1
  import type { GLRenderer } from '../../rendering/webgl/core/Renderer';
2
+ import type { TextmodeFont } from './font/TextmodeFont';
2
3
  import { TextmodeSource } from './TextmodeSource';
3
4
  /**
4
5
  * Represents an image uploaded for textmode rendering via {@link Textmodifier.loadImage}.
@@ -42,6 +43,6 @@ export declare class TextmodeImage extends TextmodeSource {
42
43
  * Texture parameters use NEAREST and CLAMP to align with grid sampling.
43
44
  * @ignore
44
45
  */
45
- static $fromSource(renderer: GLRenderer, source: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement, gridCols: number, gridRows: number, glyphResolver: (s: string) => ([number, number, number])[]): TextmodeImage;
46
+ static $fromSource(renderer: GLRenderer, font: TextmodeFont, source: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement, gridCols: number, gridRows: number, glyphResolver: (s: string) => ([number, number, number])[]): TextmodeImage;
46
47
  protected $getActiveTexture(): WebGLTexture;
47
48
  }
@@ -1,7 +1,13 @@
1
1
  import type { GLRenderer } from '../../rendering/webgl/core/Renderer';
2
2
  import type { Material } from '../../rendering/webgl/materials/Material';
3
3
  import { TextmodeColor } from '../TextmodeColor';
4
+ import type { TextmodeFont } from './font/TextmodeFont';
5
+ import { type TextmodeConversionMode } from '../conversion';
6
+ export interface TextmodeConversionOptions {
7
+ sampleRate?: number;
8
+ }
4
9
  type GlyphColor = [number, number, number];
10
+ export type TextmodeColorFilterInput = TextmodeColor | string | [number, number, number] | [number, number, number, number];
5
11
  /**
6
12
  * Base class for drawable textmode sources (images, videos, canvas, etc.).
7
13
  * Handles shared WebGL texture state, material creation, and color/character settings.
@@ -15,6 +21,9 @@ export declare abstract class TextmodeSource {
15
21
  protected _width: number;
16
22
  protected _height: number;
17
23
  protected _material: Material | null;
24
+ protected _font: TextmodeFont;
25
+ protected _conversionMode: TextmodeConversionMode;
26
+ private _cachedConversionStrategy;
18
27
  protected _invert: number;
19
28
  protected _flipX: number;
20
29
  protected _flipY: number;
@@ -26,13 +35,23 @@ export declare abstract class TextmodeSource {
26
35
  protected _backgroundColor: [number, number, number, number];
27
36
  protected _glyphColors: GlyphColor[];
28
37
  protected _glyphColorResolver: (s: string) => GlyphColor[];
29
- private static _sharedShader;
30
- protected constructor(gl: WebGL2RenderingContext, renderer: GLRenderer, texture: WebGLTexture, originalWidth: number, originalHeight: number, width: number, height: number);
38
+ private _characterString;
39
+ private _disposeListeners;
40
+ private _colorFilterPalette;
41
+ private _colorFilterSize;
42
+ protected constructor(gl: WebGL2RenderingContext, renderer: GLRenderer, texture: WebGLTexture, font: TextmodeFont, originalWidth: number, originalHeight: number, width: number, height: number);
43
+ /**
44
+ * Select the conversion mode for this source.
45
+ * `'brightness'` uses single-sample conversion, while `'accurate'` performs glyph matching.
46
+ * @param mode Conversion mode to use.
47
+ */
48
+ conversionMode(mode: TextmodeConversionMode): this;
31
49
  /**
32
50
  * Dispose of the underlying WebGL texture. Subclasses may extend for additional cleanup.
33
51
  * @ignore
34
52
  */
35
53
  $dispose(): void;
54
+ $onDispose(callback: () => void): void;
36
55
  /**
37
56
  * Set the invert flag, swapping character and cell colors when enabled.
38
57
  * @param v Invert flag
@@ -96,13 +115,23 @@ export declare abstract class TextmodeSource {
96
115
  * @returns This instance for chaining.
97
116
  */
98
117
  background(colorOrGray: number | TextmodeColor | string, g?: number, b?: number, a?: number): this;
118
+ /**
119
+ * Applies an optional color filter palette before MRT conversion.
120
+ * When a palette is provided, all sampled pixels are quantized to the closest palette color
121
+ * prior to character/color analysis.
122
+ *
123
+ * @param palette A list of colors defined as {@link TextmodeColor} instances, hex strings, or RGBA tuples (0-255).
124
+ * Providing an empty array or `null` disables the filter.
125
+ */
126
+ colorFilter(palette?: TextmodeColorFilterInput[] | null): this;
99
127
  /**
100
128
  * Define the characters to use for brightness mapping as a string.
101
- * Maximum length is 64; excess characters are ignored.
129
+ * Maximum length is 255; excess characters are ignored.
102
130
  * @param chars String of characters to map
103
131
  * @returns This instance for chaining.
104
132
  */
105
133
  characters(chars: string): this;
134
+ $handleFontChange(font: TextmodeFont): void;
106
135
  /** Return the WebGL texture currently backing this source. */
107
136
  get texture(): WebGLTexture;
108
137
  /** Ideal width in grid cells. */
@@ -124,7 +153,9 @@ export declare abstract class TextmodeSource {
124
153
  protected abstract $getActiveTexture(): WebGLTexture;
125
154
  private _updateMaterial;
126
155
  private _setColor;
127
- private _ensureShader;
128
- protected _createUniforms(): Record<string, any>;
156
+ private _applyCharacterPalette;
157
+ createBaseConversionUniforms(): Record<string, any>;
158
+ private _getActiveConversionStrategy;
159
+ private _createConversionContext;
129
160
  }
130
161
  export {};
@@ -1,5 +1,6 @@
1
1
  import type { GLRenderer } from '../../rendering/webgl/core/Renderer';
2
2
  import type { Material } from '../../rendering/webgl/materials/Material';
3
+ import type { TextmodeFont } from './font/TextmodeFont';
3
4
  import { TextmodeSource } from './TextmodeSource';
4
5
  type TextmodeVideoPreloadStrategy = 'captureStream' | 'seeking';
5
6
  export interface TextmodeVideoPreloadProgress {
@@ -97,7 +98,7 @@ export declare class TextmodeVideo extends TextmodeSource {
97
98
  *
98
99
  * @ignore
99
100
  */
100
- constructor(gl: WebGL2RenderingContext, renderer: GLRenderer, texture: WebGLTexture, videoElement: HTMLVideoElement, originalWidth: number, originalHeight: number, gridCols: number, gridRows: number);
101
+ constructor(gl: WebGL2RenderingContext, renderer: GLRenderer, texture: WebGLTexture, font: TextmodeFont, videoElement: HTMLVideoElement, originalWidth: number, originalHeight: number, gridCols: number, gridRows: number);
101
102
  /**
102
103
  * Dispose of GPU resources and cleanup video element.
103
104
  * @ignore
@@ -175,7 +176,7 @@ export declare class TextmodeVideo extends TextmodeSource {
175
176
  * @returns Promise resolving to TextmodeVideo instance
176
177
  * @ignore
177
178
  */
178
- static $fromSource(renderer: GLRenderer, source: string | HTMLVideoElement, gridCols: number, gridRows: number, glyphResolver: (s: string) => ([number, number, number])[], options?: TextmodeVideoOptions): Promise<TextmodeVideo>;
179
+ static $fromSource(renderer: GLRenderer, font: TextmodeFont, source: string | HTMLVideoElement, gridCols: number, gridRows: number, glyphResolver: (s: string) => ([number, number, number])[], options?: TextmodeVideoOptions): Promise<TextmodeVideo>;
179
180
  /**
180
181
  * Play the video.
181
182
  * @returns Promise that resolves when playback starts
@@ -1,5 +1,8 @@
1
1
  export { TextmodeImage } from './TextmodeImage';
2
2
  export { TextmodeVideo } from './TextmodeVideo';
3
+ export { TextmodeSource } from './TextmodeSource';
3
4
  export { TextmodeFont } from './font/TextmodeFont';
4
5
  export type { TextmodeCharacter } from './font/types';
5
6
  export type { TextmodeVideoOptions } from './TextmodeVideo';
7
+ export type { TextmodeConversionOptions } from './TextmodeSource';
8
+ export type { TextmodeConversionMode } from '../conversion';
@@ -1,5 +1,6 @@
1
1
  import type { GLFramebuffer, GLShader, TextmodeFramebufferOptions, UniformValue } from "../../../rendering/webgl";
2
- import type { TextmodeImage } from "../../loadables/TextmodeImage";
2
+ import type { TextmodeSource } from '../../loadables/TextmodeSource';
3
+ import type { TextmodeImage } from '../../loadables/TextmodeImage';
3
4
  import type { TextmodeVideo, TextmodeVideoOptions } from "../../loadables/TextmodeVideo";
4
5
  import type { TextmodeColor } from "../../TextmodeColor";
5
6
  /**
@@ -117,7 +118,7 @@ export interface IRenderingMixin {
117
118
  * });
118
119
  * ```
119
120
  */
120
- image(source: GLFramebuffer | TextmodeImage, width?: number, height?: number): void;
121
+ image(source: GLFramebuffer | TextmodeSource, width?: number, height?: number): void;
121
122
  /**
122
123
  * Load an image and return a TextmodeImage that can be drawn with image().
123
124
  *
@@ -0,0 +1 @@
1
+ export declare function parseHexColor(hexString: string): [number, number, number, number];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "textmode.js",
3
- "version": "0.6.0-beta.3",
3
+ "version": "0.6.0-beta.4",
4
4
  "description": "textmode.js is a lightweight creative coding library for creating real-time ASCII art on the web.",
5
5
  "type": "module",
6
6
  "types": "./dist/types/index.d.ts",
@@ -20,9 +20,8 @@
20
20
  },
21
21
  "scripts": {
22
22
  "dev": "vite --port 5177 --host",
23
- "build": "vite build && vite build --mode min && tsc",
23
+ "build": "vite build && tsc",
24
24
  "build:full": "vite build && tsc",
25
- "build:min": "vite build --mode min && tsc",
26
25
  "build:docs": "typedoc",
27
26
  "dev:docs": "typedoc --watch",
28
27
  "preview": "vite preview",