textmode.js 0.8.0-beta.3 → 0.8.1-beta.1

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.
Files changed (28) hide show
  1. package/README.md +179 -179
  2. package/dist/textmode.esm.js +457 -450
  3. package/dist/textmode.umd.js +15 -15
  4. package/dist/types/Textmode.d.ts +14 -2
  5. package/dist/types/errors/ErrorHandler.d.ts +1 -1
  6. package/dist/types/index.d.ts +10 -2
  7. package/dist/types/rendering/webgl/utils/hash.d.ts +6 -6
  8. package/dist/types/textmode/Textmodifier.d.ts +8 -0
  9. package/dist/types/textmode/conversion/ConversionManager.d.ts +2 -2
  10. package/dist/types/textmode/conversion/ConversionRegistry.d.ts +2 -2
  11. package/dist/types/textmode/filters/FilterManager.d.ts +2 -7
  12. package/dist/types/textmode/filters/FilterRegistry.d.ts +2 -2
  13. package/dist/types/textmode/interfaces/ITextmodifier.d.ts +57 -9
  14. package/dist/types/textmode/layers/LayerManager.d.ts +4 -3
  15. package/dist/types/textmode/layers/TextmodeLayer.d.ts +2 -2
  16. package/dist/types/textmode/layers/interfaces/ILayerManager.d.ts +1 -1
  17. package/dist/types/textmode/layers/interfaces/ITextmodeLayer.d.ts +7 -9
  18. package/dist/types/textmode/layers/types.d.ts +2 -2
  19. package/dist/types/textmode/loadables/TextmodeImage.d.ts +2 -4
  20. package/dist/types/textmode/loadables/font/TextmodeFont.d.ts +3 -3
  21. package/dist/types/textmode/loadables/video/TextmodeVideo.d.ts +2 -4
  22. package/dist/types/textmode/loading/LoadingPhase.d.ts +6 -4
  23. package/dist/types/textmode/loading/LoadingScreenManager.d.ts +4 -4
  24. package/dist/types/textmode/loading/types.d.ts +10 -6
  25. package/dist/types/textmode/mixins/interfaces/IAnimationMixin.d.ts +1 -1
  26. package/dist/types/textmode/mixins/interfaces/IRenderingMixin.d.ts +15 -15
  27. package/dist/types/textmode/mixins/interfaces/ITouchMixin.d.ts +11 -11
  28. package/package.json +72 -72
@@ -24,6 +24,18 @@ export declare class Textmode {
24
24
  * t.rect(10, 10);
25
25
  * });
26
26
  * ```
27
+ * @exampleAuthor
28
+ * <div style="display:flex;align-items:center;gap:0.75rem;flex-wrap:wrap;">
29
+ * <img src="https://github.com/humanbydefinition.png" alt="@humanbydefinition avatar" width="72" height="72" style="border-radius:12px;box-shadow:0 2px 6px rgba(0,0,0,0.35);" />
30
+ * <div style="display:flex;flex-direction:column;gap:0.25rem;">
31
+ * <strong><a href="https://github.com/humanbydefinition">@humanbydefinition</a></strong>
32
+ * <span style="font-size:0.95em;">
33
+ * 📷 <a href="https://instagram.com/humanbydefinition">Instagram</a>
34
+ * &nbsp;•&nbsp; 🐘 <a href="https://mastodon.social/@humanbydefinition">Mastodon</a>
35
+ * &nbsp;•&nbsp; 🦋 <a href="https://bsky.app/profile/humanbydefinition.bsky.social">BlueSky</a>
36
+ * </span>
37
+ * </div>
38
+ * </div>
27
39
  */
28
40
  static create(opts?: TextmodeOptions): Textmodifier;
29
41
  /**
@@ -32,7 +44,7 @@ export declare class Textmode {
32
44
  * @param level The error handling level to set.
33
45
  *
34
46
  * @example
35
- * ```javascript
47
+ * ```js
36
48
  * // Set error level to WARNING
37
49
  * textmode.setErrorLevel(TextmodeErrorLevel.WARNING);
38
50
  * ```
@@ -42,7 +54,7 @@ export declare class Textmode {
42
54
  * Returns the version of `textmode.js` being used.
43
55
  *
44
56
  * @example
45
- * ```javascript
57
+ * ```js
46
58
  * console.log(textmode.version); // "1.0.0"
47
59
  * ```
48
60
  */
@@ -9,7 +9,7 @@
9
9
  * and most `textmode.js` functions will still throw errors if used incorrectly.
10
10
  *
11
11
  * @example
12
- * ```javascript
12
+ * ```js
13
13
  * // Set to `WARNING` level to log errors without stopping execution
14
14
  * textmode.setErrorLevel(TextmodeErrorLevel.WARNING);
15
15
  * ```
@@ -9,7 +9,7 @@ export type { TextmodeFramebufferOptions } from './rendering/webgl';
9
9
  /**
10
10
  * All media conversion related modules and types.
11
11
  *
12
- * Responsible for converting images and videos into textmode-renderable formats,
12
+ * Responsible for converting images and videos into textmode-renderable formats
13
13
  * using various conversion strategies, like brightness- or edge-detection-based conversion.
14
14
  *
15
15
  * `textmode.js` only comes with a built-in `'brightness'`-based conversion strategy,
@@ -17,7 +17,15 @@ export type { TextmodeFramebufferOptions } from './rendering/webgl';
17
17
  */
18
18
  export * as conversion from './textmode/conversion';
19
19
  export type { TextmodePlugin, TextmodePluginAPI } from './textmode/managers/PluginManager';
20
- /** All filter related modules and types. */
20
+ /**
21
+ * All filter related modules and types.
22
+ *
23
+ * Provides various image processing filters that can be applied in sequence on a layer's textmode-converted output,
24
+ * such as blur, sharpen, edge detection, and color adjustments. Filters can also be applied globally to all layers as post-processing effects.
25
+ *
26
+ * While `textmode.js` only offers a basic set of filters, additional filters can be implemented and registered via the {@link TextmodeFilterManager},
27
+ * which is accessible through {@link Textmodifier.filters}.
28
+ */
21
29
  export * as filters from './textmode/filters';
22
30
  export { TextmodeErrorLevel } from './errors/ErrorHandler';
23
31
  export { Textmode as textmode } from './Textmode';
@@ -17,7 +17,7 @@
17
17
  * @returns 32-bit integer hash
18
18
  *
19
19
  * @example
20
- * ```typescript
20
+ * ```ts
21
21
  * hashString("hello") // → 99162322
22
22
  * hashString("world") // → 113318802
23
23
  * ```
@@ -31,7 +31,7 @@ export declare function hashString(str: string): number;
31
31
  * @returns Integer hash
32
32
  *
33
33
  * @example
34
- * ```typescript
34
+ * ```ts
35
35
  * hashNumber(42) // → 42
36
36
  * hashNumber(3.14) // → 3
37
37
  * hashNumber(true) // → 1
@@ -47,7 +47,7 @@ export declare function hashNumber(value: number | boolean): number;
47
47
  * @returns Combined hash of all elements
48
48
  *
49
49
  * @example
50
- * ```typescript
50
+ * ```ts
51
51
  * hashArray([1, 2, 3]) // → computed hash
52
52
  * hashArray([[1, 2], [3, 4]]) // → computed hash (flattened)
53
53
  * ```
@@ -61,7 +61,7 @@ export declare function hashArray(arr: number[] | number[][]): number;
61
61
  * @returns Combined hash
62
62
  *
63
63
  * @example
64
- * ```typescript
64
+ * ```ts
65
65
  * const arr = new Float32Array([1.0, 2.0, 3.0]);
66
66
  * hashTypedArray(arr) // → computed hash
67
67
  * ```
@@ -77,7 +77,7 @@ export declare function hashObject(obj: any): number;
77
77
  * @returns Combined hash
78
78
  *
79
79
  * @example
80
- * ```typescript
80
+ * ```ts
81
81
  * const h1 = hashString("hello");
82
82
  * const h2 = hashString("world");
83
83
  * const combined = combineHashes(h1, h2);
@@ -93,7 +93,7 @@ export declare function combineHashes(hash1: number, hash2: number): number;
93
93
  * @returns Combined hash of all key-value pairs
94
94
  *
95
95
  * @example
96
- * ```typescript
96
+ * ```ts
97
97
  * const obj = { b: 2, a: 1, c: 3 };
98
98
  * const hash = hashRecord(obj, hashNumber);
99
99
  * // Keys are sorted: a, b, c → consistent hash
@@ -62,6 +62,7 @@ export declare class Textmodifier extends Textmodifier_base implements ITextmodi
62
62
  private _resizeObserver?;
63
63
  private _isOverlay;
64
64
  private _targetCanvasImage?;
65
+ private _inputGridOverride?;
65
66
  /**
66
67
  * Create a new Textmodifier instance.
67
68
  * @param opts Configuration options for the Textmodifier instance.
@@ -82,6 +83,13 @@ export declare class Textmodifier extends Textmodifier_base implements ITextmodi
82
83
  filter(name: FilterName, params?: unknown): void;
83
84
  loadFont(fontSource: string): Promise<TextmodeFont>;
84
85
  fontSize(size: number): void;
86
+ inputGrid(target?: 'topmost' | TextmodeGrid): 'topmost' | TextmodeGrid | void;
87
+ /**
88
+ * Get the grid used for input coordinate mapping.
89
+ * Returns the override grid/layer's grid if set, otherwise the topmost visible layer's grid.
90
+ * @ignore
91
+ */
92
+ private _getInputGrid;
85
93
  setup(callback: () => void | Promise<void>): Promise<void>;
86
94
  draw(callback: () => void): void;
87
95
  windowResized(callback: () => void): void;
@@ -9,7 +9,7 @@ import type { TextmodeConversionMode, TextmodeConversionStrategy } from './Conve
9
9
  * Used for image-to-ASCII conversion modes.
10
10
  *
11
11
  * @example
12
- * ```typescript
12
+ * ```ts
13
13
  * // Register a custom conversion strategy
14
14
  * t.conversions.register({
15
15
  * id: 'custom',
@@ -35,7 +35,7 @@ export declare class TextmodeConversionManager {
35
35
  * @param strategy The conversion strategy to register
36
36
  *
37
37
  * @example
38
- * ```typescript
38
+ * ```ts
39
39
  * t.conversions.register({
40
40
  * id: 'custom',
41
41
  * createShader: (ctx) => shader,
@@ -9,7 +9,7 @@ export type BuiltInConversionMode = 'brightness';
9
9
  /**
10
10
  * Type representing the available textmode conversion modes
11
11
  */
12
- export type TextmodeConversionMode = BuiltInConversionMode | (string & {});
12
+ export type TextmodeConversionMode = BuiltInConversionMode | string;
13
13
  /**
14
14
  * Interface for the context provided to conversion strategies
15
15
  * @ignore
@@ -38,7 +38,7 @@ export interface TextmodeConversionStrategy {
38
38
  * conversion strategies to be scoped to a specific Textmodifier instance rather than registered globally.
39
39
  *
40
40
  * @example
41
- * ```typescript
41
+ * ```ts
42
42
  * // Register a custom conversion strategy
43
43
  * t.conversions.register(myCustomStrategy);
44
44
  *
@@ -3,15 +3,10 @@ import type { QueuedFilter, FilterName } from './types';
3
3
  /**
4
4
  * Manages filter registration, shader compilation, and filter chain application.
5
5
  *
6
- * This class provides:
7
- * - A registry for custom and built-in filter strategies
8
- * - Lazy shader compilation and caching
9
- * - Ping-pong rendering for efficient multi-filter chains
10
- *
11
6
  * Used both for layer-level filters and global post-processing filters.
12
7
  *
13
8
  * @example
14
- * ```typescript
9
+ * ```ts
15
10
  * // Register a custom filter
16
11
  * await t.filters.register('brightness', brightnessShader, {
17
12
  * u_amount: ['amount', 1.0]
@@ -45,7 +40,7 @@ export declare class TextmodeFilterManager {
45
40
  * @param uniformDefs Maps uniform names to [paramName, defaultValue] tuples
46
41
  *
47
42
  * @example
48
- * ```typescript
43
+ * ```ts
49
44
  * // Register with inline shader source
50
45
  * await t.filters.register('blur', blurFragSource, {
51
46
  * u_radius: ['radius', 5.0],
@@ -7,7 +7,7 @@ import type { TextmodeFilterStrategy, FilterName } from './types';
7
7
  * filters to be scoped to a specific context rather than registered globally.
8
8
  *
9
9
  * @example
10
- * ```typescript
10
+ * ```ts
11
11
  * // Define a simple filter with the declarative API
12
12
  * t.filters.register('blur', blurShader, { radius: 5.0 });
13
13
  *
@@ -37,7 +37,7 @@ export declare class FilterRegistry {
37
37
  * @param uniforms Default uniform values. Keys map uniform names to [paramName, defaultValue] tuples.
38
38
  *
39
39
  * @example
40
- * ```typescript
40
+ * ```ts
41
41
  * // With pre-compiled shader (recommended for add-ons)
42
42
  * const shader = await t.createShader(vertSrc, fragSrc);
43
43
  * t.filters.register('brightness', shader, { u_amount: ['amount', 1.0] });
@@ -71,6 +71,7 @@ export interface ITextmodifier extends IRenderingMixin, IAnimationMixin, IMouseM
71
71
  * t.setup(async () => {
72
72
  * // Load font for the base layer
73
73
  * const font = await t.loadFont('./fonts/myfont.ttf');
74
+ * // const font = await t.layers.base.loadFont('./fonts/myfont.ttf'); // Equivalent
74
75
  *
75
76
  * // Use the same font on another layer
76
77
  * const layer = t.layers.add();
@@ -104,6 +105,43 @@ export interface ITextmodifier extends IRenderingMixin, IAnimationMixin, IMouseM
104
105
  * ```
105
106
  */
106
107
  fontSize(size: number): void;
108
+ /**
109
+ * Get or set the grid used for mouse and touch input coordinate mapping.
110
+ *
111
+ * By default, input coordinates are mapped to the topmost visible layer's grid,
112
+ * which changes dynamically as layers are shown/hidden. Use this method to lock
113
+ * input mapping to a specific grid or layer, or to return to responsive mode.
114
+ *
115
+ * When called without arguments, returns the current input grid mode:<br/>
116
+ * - `'topmost'` if using responsive mode (default)<br/>
117
+ * - The specific `TextmodeGrid` if locked
118
+ *
119
+ * @example
120
+ * ```javascript
121
+ * const t = textmode.create();
122
+ *
123
+ * // Add a UI layer on top
124
+ * const uiLayer = t.layers.add({ fontSize: 16 });
125
+ *
126
+ * t.setup(() => {
127
+ * // Lock input to the base layer's grid for game controls
128
+ * // even though the UI layer is rendered on top
129
+ * t.inputGrid(t.layers.base.grid);
130
+ * });
131
+ *
132
+ * t.draw(() => {
133
+ * // Mouse positions now always use base layer's grid
134
+ * t.text(`Mouse: ${t.mouseX}, ${t.mouseY}`, 0, 0);
135
+ * });
136
+ *
137
+ * // Switch back to responsive mode
138
+ * // t.inputGrid('topmost');
139
+ *
140
+ * // Or check current mode
141
+ * // const current = t.inputGrid(); // 'topmost' or the locked grid
142
+ * ```
143
+ */
144
+ inputGrid(target?: 'topmost' | TextmodeGrid): 'topmost' | TextmodeGrid | void;
107
145
  /**
108
146
  * Set a setup callback function that will be executed once when initialization is complete.
109
147
  *
@@ -146,9 +184,15 @@ export interface ITextmodifier extends IRenderingMixin, IAnimationMixin, IMouseM
146
184
  *
147
185
  * This callback function is where all drawing commands should be placed for textmode rendering on the main layer.
148
186
  *
149
- * If multiple layers are added via {@link Textmodifier.layers}, each layer can have its own draw callback set via {@link TextmodeLayer.draw}.
187
+ * If multiple layers are added via {@link Textmodifier.layers}, each layer has its own draw callback set via {@link TextmodeLayer.draw}.
150
188
  * This allows for complex multi-layered compositions with independent rendering logic per layer.
151
189
  *
190
+ * Calling this method is equivalent to setting the draw callback on the base layer,
191
+ * while the direct layer callback has precedence if both are set.
192
+ * ```js
193
+ * textmodifier.layers.base.draw(callback);
194
+ * ```
195
+ *
152
196
  * @param callback The function to call before each render
153
197
  *
154
198
  * @example
@@ -238,7 +282,7 @@ export interface ITextmodifier extends IRenderingMixin, IAnimationMixin, IMouseM
238
282
  * After calling this method, the instance should not be used and will be eligible for garbage collection.
239
283
  *
240
284
  * @example
241
- * ```javascript
285
+ * ```js
242
286
  * // Create a textmodifier instance
243
287
  * const textmodifier = textmode.create();
244
288
  *
@@ -262,7 +306,7 @@ export interface ITextmodifier extends IRenderingMixin, IAnimationMixin, IMouseM
262
306
  * @param params Optional parameters for the filter
263
307
  *
264
308
  * @example
265
- * ```typescript
309
+ * ```ts
266
310
  * t.draw(() => {
267
311
  * t.background(0);
268
312
  * t.charColor(255);
@@ -282,7 +326,12 @@ export interface ITextmodifier extends IRenderingMixin, IAnimationMixin, IMouseM
282
326
  filter<T extends BuiltInFilterName>(name: T, params?: BuiltInFilterParams[T]): void;
283
327
  filter(name: FilterName, params?: unknown): void;
284
328
  filter(name: FilterName, params?: unknown): void;
285
- /** Get the grid object used for rendering the base layer. */
329
+ /**
330
+ * Get the grid whose layer is currently being drawn to.
331
+ * If called outside of a layers draw callback, returns the base layer's grid.
332
+ *
333
+ * If no grid is set (e.g., before user setup()), returns `undefined`.
334
+ */
286
335
  readonly grid: TextmodeGrid | undefined;
287
336
  /** Get the current font object used for rendering the base layer. */
288
337
  readonly font: TextmodeFont;
@@ -299,10 +348,9 @@ export interface ITextmodifier extends IRenderingMixin, IAnimationMixin, IMouseM
299
348
  *
300
349
  * Use this to register custom filters that can be applied both globally
301
350
  * (via {@link filter}) and on individual layers (via {@link TextmodeLayer.filter}).
302
- * Filters only need to be registered once and are available everywhere.
303
351
  *
304
352
  * @example
305
- * ```typescript
353
+ * ```ts
306
354
  * // Register a custom filter once
307
355
  * await t.filters.register('vignette', vignetteShader, {
308
356
  * u_intensity: ['intensity', 0.5]
@@ -326,7 +374,7 @@ export interface ITextmodifier extends IRenderingMixin, IAnimationMixin, IMouseM
326
374
  * Access the layer manager for this Textmodifier instance.
327
375
  *
328
376
  * Use this to create and manage multiple layers within the textmode rendering context.
329
- * Each layer can have its own grid, font, draw callback, and filters.
377
+ * Each layer has its own grid, font, draw callback, and filters.
330
378
  */
331
379
  readonly layers: TextmodeLayerManager;
332
380
  /**
@@ -341,7 +389,7 @@ export interface ITextmodifier extends IRenderingMixin, IAnimationMixin, IMouseM
341
389
  * allowing further configuration of the conversion parameters.
342
390
  *
343
391
  * @example
344
- * ```javascript
392
+ * ```js
345
393
  * // Create the textmode instance using the p5 canvas as input overlay
346
394
  * const t = textmode.create({ fontSize: 16, canvas: p.canvas, overlay: true });
347
395
  *
@@ -379,7 +427,7 @@ export interface ITextmodifier extends IRenderingMixin, IAnimationMixin, IMouseM
379
427
  * await phase1.track(async () => {
380
428
  * for (let i = 0; i <= 5; i++) {
381
429
  * phase1.report(i / 5);
382
- * // Small delay increases visibility of the loading animation
430
+ * // Small delay - increases visibility of the loading animation
383
431
  * await new Promise((r) => setTimeout(r, 200));
384
432
  * }
385
433
  * });
@@ -6,8 +6,8 @@ import type { ILayerManager } from './interfaces/ILayerManager';
6
6
  import type { TextmodeOptions } from '../types';
7
7
  import type { TextmodeGrid } from '../Grid';
8
8
  /**
9
- * Manages all user-defined layers within a Textmodifier in *
10
- * Th *
9
+ * Manages all user-defined layers within a Textmodifier in addition to the base layer.
10
+ *
11
11
  * This manager is responsible for:
12
12
  * - Managing the collection of user layers (add, remove, move, swap)
13
13
  * - Coordinating layer rendering and compositing
@@ -73,8 +73,9 @@ export declare class LayerManager implements ILayerManager {
73
73
  * Get the grid of the topmost visible layer.
74
74
  * Returns the topmost user layer's grid if any are visible, otherwise returns the base layer's grid.
75
75
  * This is useful for input managers that need to map coordinates to the layer the user sees on top.
76
+ * @ignore
76
77
  */
77
- getTopmostGrid(): TextmodeGrid | undefined;
78
+ $getTopmostGrid(): TextmodeGrid | undefined;
78
79
  /**
79
80
  * Register a callback to be invoked whenever ANY layer's grid dimensions change.
80
81
  * This includes the base layer and all user layers.
@@ -10,7 +10,7 @@ import type { ITextmodeLayer } from './interfaces/ITextmodeLayer';
10
10
  *
11
11
  * Layers are composited together using various blend modes
12
12
  * to create complex visual effects. Each layer can be independently
13
- * manipulated in terms of visibility, opacity, blend mode, and position.
13
+ * manipulated in terms of visibility, {@link opacity}, {@link blendMode}, {@link offset}, rotation, {@link TextmodeGrid}, and {@link TextmodeFont}.
14
14
  *
15
15
  * You can draw on each layer by providing a draw callback function,
16
16
  * like you would with the base layer's {@link Textmodifier.draw} method.
@@ -88,7 +88,7 @@ export declare class TextmodeLayer implements ITextmodeLayer {
88
88
  * @returns The loaded TextmodeFont instance.
89
89
  *
90
90
  * @example
91
- * ```javascript
91
+ * ```js
92
92
  * const layer = t.layers.add();
93
93
  *
94
94
  * t.setup(async () => {
@@ -46,5 +46,5 @@ export interface ILayerManager {
46
46
  * Returns the topmost user layer's grid if any are visible, otherwise returns the base layer's grid.
47
47
  * This is useful for input managers that need to map coordinates to the layer the user sees on top.
48
48
  */
49
- getTopmostGrid(): TextmodeGrid | undefined;
49
+ $getTopmostGrid(): TextmodeGrid | undefined;
50
50
  }
@@ -51,7 +51,7 @@ export interface ITextmodeLayer {
51
51
  * @param callback The function to call when drawing this layer.
52
52
  *
53
53
  * @example
54
- * ```typescript
54
+ * ```javascript
55
55
  * const t = textmode.create();
56
56
  *
57
57
  * // Create layers with different blend modes
@@ -130,7 +130,7 @@ export interface ITextmodeLayer {
130
130
  * @returns The loaded TextmodeFont instance.
131
131
  *
132
132
  * @example
133
- * ```javascript
133
+ * ```js
134
134
  * const layer = t.layers.add();
135
135
  *
136
136
  * t.setup(async () => {
@@ -176,7 +176,7 @@ export interface ITextmodeLayer {
176
176
  * - `'exclusion'` - Softer difference effect
177
177
  *
178
178
  * @example
179
- * ```typescript
179
+ * ```javascript
180
180
  * const t = textmode.create();
181
181
  *
182
182
  * // Create 5 layers with different blend modes
@@ -219,7 +219,7 @@ export interface ITextmodeLayer {
219
219
  * @returns The current offset if no parameters are provided.
220
220
  *
221
221
  * @example
222
- * ```typescript
222
+ * ```javascript
223
223
  * const t = textmode.create();
224
224
  *
225
225
  * const LAYER_COUNT = 32;
@@ -301,9 +301,7 @@ export interface ITextmodeLayer {
301
301
  * @returns The current rotation in degrees if no parameter is provided.
302
302
  *
303
303
  * @example
304
- * ```typescript
305
- * import { textmode } from 'textmode.js';
306
- *
304
+ * ```javascript
307
305
  * const t = textmode.create();
308
306
  *
309
307
  * const rotatingLayer = t.layers.add({ blendMode: 'difference', opacity: 1.0 });
@@ -334,7 +332,7 @@ export interface ITextmodeLayer {
334
332
  * Filters are applied after ASCII conversion in the order they are called.
335
333
  * Call this method within your layer's draw callback to apply effects.
336
334
  *
337
- * **Built-in Filters:**
335
+ * **Built-in filters:**
338
336
  * - `'invert'` - Inverts all colors
339
337
  * - `'grayscale'` - Converts to grayscale (param: amount 0-1, default 1)
340
338
  * - `'sepia'` - Applies sepia tone (param: amount 0-1, default 1)
@@ -344,7 +342,7 @@ export interface ITextmodeLayer {
344
342
  * @param params Optional parameters for the filter
345
343
  *
346
344
  * @example
347
- * ```typescript
345
+ * ```javascript
348
346
  * const t = textmode.create();
349
347
  *
350
348
  * // Create a layer with filters applied
@@ -47,9 +47,9 @@ export interface TextmodeLayerOptions {
47
47
  */
48
48
  offsetY?: number;
49
49
  /**
50
- * The rotation of the layer in degrees around its center. Default is `0`.
50
+ * The z-rotation of the layer in degrees around its center. Default is `0`.
51
51
  */
52
- rotation?: number;
52
+ rotationZ?: number;
53
53
  /**
54
54
  * The font size for the layer's text. Default is `16`.
55
55
  */
@@ -29,10 +29,8 @@ import type { TextmodeConversionManager } from '../conversion';
29
29
  * t.draw(() => {
30
30
  * t.background(0);
31
31
  *
32
- * if (img) {
33
- * // Draw the loaded image
34
- * t.image(img);
35
- * }
32
+ * // Draw the loaded image
33
+ * t.image(img);
36
34
  * });
37
35
  * ```
38
36
  */
@@ -3,13 +3,13 @@ import type { GLFramebuffer } from '../../../rendering/webgl/core/Framebuffer.ts
3
3
  import type { TextmodeCharacter } from './types.ts';
4
4
  import type { TyprFont } from './typr/types.ts';
5
5
  /**
6
- * Manages the font used for rendering characters via {@link Textmodifier.loadFont}.
6
+ * Manages the font used for rendering characters via {@link TextmodeLayer.loadFont}.
7
7
  *
8
8
  * This class coordinates font loading, character extraction, texture atlas creation,
9
9
  * and provides character information.
10
10
  *
11
- * The font used by your {@link Textmodifier} instance is accessible via
12
- * the {@link Textmodifier.font} property.
11
+ * Each {@link TextmodeLayer} has its own instance of this class to allow for
12
+ * layer-specific font configurations.
13
13
  */
14
14
  export declare class TextmodeFont {
15
15
  private _font;
@@ -33,10 +33,8 @@ import type { TextmodeConversionManager } from '../../conversion';
33
33
  * t.draw(() => {
34
34
  * t.background(0);
35
35
  *
36
- * if (video) {
37
- * // Draw the loaded video
38
- * t.image(video);
39
- * }
36
+ * // Draw the loaded video
37
+ * t.image(video);
40
38
  * });
41
39
  * ```
42
40
  */
@@ -1,5 +1,5 @@
1
- import type { LoadingPhaseTracker } from "./LoadingPhaseTracker";
2
- import type { ILoadingPhase } from "./types";
1
+ import type { LoadingPhaseTracker } from './LoadingPhaseTracker';
2
+ import type { ILoadingPhase } from './types';
3
3
  /**
4
4
  * Represents a loading phase tracked by a LoadingPhaseTracker.
5
5
  *
@@ -11,16 +11,18 @@ export declare class LoadingPhase implements ILoadingPhase {
11
11
  private readonly _phaseTracker;
12
12
  readonly id: string;
13
13
  readonly label: string;
14
+ private readonly _onError?;
14
15
  /**
15
16
  * Creates a new LoadingPhase.
16
17
  * @param _phaseTracker The LoadingPhaseTracker managing this phase
17
18
  * @param id The unique identifier for this loading phase
18
19
  * @param label The human-readable label for this loading phase
20
+ * @param _onError Callback to invoke when the phase fails
19
21
  * @ignore
20
22
  */
21
- constructor(_phaseTracker: LoadingPhaseTracker, id: string, label: string);
23
+ constructor(_phaseTracker: LoadingPhaseTracker, id: string, label: string, _onError?: ((error: Error | string) => void) | undefined);
22
24
  report(progress: number): void;
23
25
  complete(): void;
24
- fail(_error?: Error): void;
26
+ fail(error?: Error | string): void;
25
27
  track<T>(task: Promise<T> | (() => Promise<T> | T)): Promise<T>;
26
28
  }
@@ -75,7 +75,7 @@ export declare class LoadingScreenManager {
75
75
  *
76
76
  * // In setup we can start a phase and read the overall progress
77
77
  * t.setup(async () => {
78
- * const phase = t.loading.beginPhase('assets', 1);
78
+ * const phase = t.loading.addPhase('assets', 1);
79
79
  * phase.report(0.5); // half complete for the phase
80
80
  *
81
81
  * // The `progress` accessor reports the global progress across all phases
@@ -101,7 +101,7 @@ export declare class LoadingScreenManager {
101
101
  * // Update the message visible on the loading screen
102
102
  * t.loading.message('preloading video...');
103
103
  *
104
- * // Read the current message (useful in custom renderers)
104
+ * // Read the current message (useful in custom loading screen implementations)
105
105
  * const msg = t.loading.message();
106
106
  * console.log(msg);
107
107
  * });
@@ -128,7 +128,7 @@ export declare class LoadingScreenManager {
128
128
  *
129
129
  * // In setup we start a phase and then track work in that phase
130
130
  * t.setup(async () => {
131
- * const phase = t.loading.beginPhase('video preload', 2);
131
+ * const phase = t.loading.addPhase('video preload', 2);
132
132
  *
133
133
  * // Example: report progress from a loader callback
134
134
  * await phase.track(async () => {
@@ -168,7 +168,7 @@ export declare class LoadingScreenManager {
168
168
  * });
169
169
  *
170
170
  * t.setup(async () => {
171
- * const phase = t.loading.beginPhase('remote fetch', 1);
171
+ * const phase = t.loading.addPhase('remote fetch', 1);
172
172
  * try {
173
173
  * await phase.track(async () => {
174
174
  * // Failing call
@@ -164,7 +164,7 @@ export interface ILoadingPhase {
164
164
  *
165
165
  * // Create a phase and report progress as work proceeds
166
166
  * t.setup(async () => {
167
- * const phase = t.loading.beginPhase('assets', 1);
167
+ * const phase = t.loading.addPhase('assets', 1);
168
168
  * phase.report(0.25);
169
169
  * // ...load assets...
170
170
  * phase.report(0.75);
@@ -181,7 +181,7 @@ export interface ILoadingPhase {
181
181
  * const t = textmode.create({ width: 800, height: 600, loadingScreen: { message: 'prepping...' } });
182
182
  *
183
183
  * t.setup(() => {
184
- * const phase = t.loading.beginPhase('init', 1);
184
+ * const phase = t.loading.addPhase('init', 1);
185
185
  * // Finish phase when work is done
186
186
  * phase.complete();
187
187
  * });
@@ -190,14 +190,18 @@ export interface ILoadingPhase {
190
190
  complete(): void;
191
191
  /**
192
192
  * Mark the loading phase as failed.
193
- * @param error An optional error object describing the failure.
193
+ *
194
+ * This will put the loading manager into an error state, displaying the
195
+ * error on the loading screen.
196
+ *
197
+ * @param error An optional error object or message describing the failure.
194
198
  *
195
199
  * @example
196
200
  * ```ts
197
201
  * const t = textmode.create({ width: 800, height: 600 });
198
202
  *
199
203
  * t.setup(async () => {
200
- * const phase = t.loading.beginPhase('fetch', 1);
204
+ * const phase = t.loading.addPhase('fetch', 1);
201
205
  * try {
202
206
  * // simulate failure
203
207
  * throw new Error('network error');
@@ -207,7 +211,7 @@ export interface ILoadingPhase {
207
211
  * });
208
212
  * ```
209
213
  */
210
- fail(error?: Error): void;
214
+ fail(error?: Error | string): void;
211
215
  /**
212
216
  * Track a task within this loading phase.
213
217
  * @param task A promise or function representing the task to track.
@@ -218,7 +222,7 @@ export interface ILoadingPhase {
218
222
  * const t = textmode.create({ width: 800, height: 600, loadingScreen: { message: 'loading...' } });
219
223
  *
220
224
  * t.setup(async () => {
221
- * const phase = t.loading.beginPhase('video', 2);
225
+ * const phase = t.loading.addPhase('video', 2);
222
226
  * await phase.track(async () => {
223
227
  * // do async work and report updates
224
228
  * for (let i = 0; i <= 10; i++) {