textmode.js 0.2.0-beta.2 → 0.2.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.
@@ -34,6 +34,10 @@ export declare class GLShader {
34
34
  */
35
35
  private _resetState;
36
36
  $setUniforms(uniforms: Record<string, UniformValue>): void;
37
+ /**
38
+ * Check if a uniform exists in this shader
39
+ */
40
+ $hasUniform(name: string): boolean;
37
41
  /**
38
42
  * Set a single uniform value with automatic texture unit management
39
43
  */
@@ -0,0 +1 @@
1
+ export {};
@@ -37,10 +37,12 @@ export declare abstract class BaseGeometry implements IGeometry {
37
37
  ny: number;
38
38
  };
39
39
  protected _setRotationCenter(instanceData: InstanceData, centerX: number, centerY: number): void;
40
- protected _calculateRotationParams(x: number, y: number, width: number, height: number, rotationDegrees: number): {
40
+ protected _calculateRotationParams(x: number, y: number, width: number, height: number, rotationXDegrees: number, rotationYDegrees: number, rotationZDegrees: number): {
41
41
  centerX: number;
42
42
  centerY: number;
43
- radians: number;
43
+ radiansX: number;
44
+ radiansY: number;
45
+ radiansZ: number;
44
46
  aspectRatio: number;
45
47
  };
46
48
  }
@@ -1,6 +1,15 @@
1
1
  import type { GeometryParams, GeometryType } from './GeometryTypes';
2
2
  import type { IRenderState } from '../RenderState';
3
- export type DrawParams = GeometryParams;
3
+ import type { GLShader } from '../Shader';
4
+ export type CustomRectParams = {
5
+ x: number;
6
+ y: number;
7
+ width: number;
8
+ height: number;
9
+ shader: GLShader;
10
+ uniforms: Record<string, any>;
11
+ };
12
+ export type DrawParams = GeometryParams | CustomRectParams;
4
13
  export interface DrawCommand {
5
14
  id: number;
6
15
  type: GeometryType;
@@ -9,4 +9,6 @@ export interface RenderContext {
9
9
  shader: GLShader;
10
10
  gl: WebGL2RenderingContext;
11
11
  viewport: [number, number, number, number];
12
+ cellWidth?: number;
13
+ cellHeight?: number;
12
14
  }
@@ -55,6 +55,7 @@ declare const Textmodifier_base: typeof TextmodifierCore;
55
55
  */
56
56
  export declare class Textmodifier extends Textmodifier_base {
57
57
  private _isDisposed;
58
+ private _setupCallback;
58
59
  private _drawCallback;
59
60
  private _resizedCallback;
60
61
  private _windowResizeListener;
@@ -65,11 +66,10 @@ export declare class Textmodifier extends Textmodifier_base {
65
66
  */
66
67
  constructor(opts?: TextmodeOptions);
67
68
  /**
68
- * Static factory method for creating and initializing a Textmodifier instance.
69
- * @param opts Optional configuration options for the `Textmodifier` instance.
70
- * @ignore
69
+ * Internal async initialization method.
70
+ * @param opts Configuration options
71
71
  */
72
- static create(opts?: TextmodeOptions): Promise<Textmodifier>;
72
+ private _initialize;
73
73
  /**
74
74
  * Setup event listeners for resize handling.
75
75
  * @ignore
@@ -81,6 +81,41 @@ export declare class Textmodifier extends Textmodifier_base {
81
81
  * @ignore
82
82
  */
83
83
  $render(): void;
84
+ /**
85
+ * Set a setup callback function that will be executed once when initialization is complete.
86
+ *
87
+ * This callback is called after font loading and grid initialization, allowing access to
88
+ * properties like `textmodifier.grid.cols` for calculating layout or setup variables.
89
+ *
90
+ * @param callback The function to call when setup is complete
91
+ *
92
+ * @example
93
+ * ```javascript
94
+ * const textmodifier = textmode.create({
95
+ * width: 800,
96
+ * height: 600,
97
+ * fontSize: 16
98
+ * });
99
+ *
100
+ * // Setup callback - called once when ready
101
+ * textmodifier.setup(() => {
102
+ * // Now you can access grid properties
103
+ * const cols = textmodifier.grid.cols;
104
+ * const rows = textmodifier.grid.rows;
105
+ *
106
+ * // Initialize any variables that depend on grid size
107
+ * cellWidth = Math.floor(cols / 3);
108
+ * cellHeight = Math.floor(rows / 2);
109
+ * });
110
+ *
111
+ * // Draw callback - called every frame
112
+ * textmodifier.draw(() => {
113
+ * textmodifier.background(128);
114
+ * textmodifier.rect(0, 0, cellWidth, cellHeight);
115
+ * });
116
+ * ```
117
+ */
118
+ setup(callback: () => void): void;
84
119
  /**
85
120
  * Set a draw callback function that will be executed before each render.
86
121
  *
@@ -1,11 +1,17 @@
1
1
  import type { Mixin } from './TextmodifierMixin';
2
+ import type { GLShader } from '../../rendering/webgl/Shader';
3
+ /**
4
+ * Supported uniform value types for shader parameters
5
+ */
6
+ type UniformValue = number | boolean | number[] | Float32Array | Int32Array | WebGLTexture;
2
7
  /**
3
8
  * Interface for rendering capabilities that will be mixed into Textmodifier
4
9
  */
5
10
  export interface RenderingCapabilities {
6
11
  /**
7
- * Sets the rotation angle for subsequent shape rendering operations
8
- * @param degrees The rotation angle in degrees
12
+ * Set a custom shader for subsequent rendering operations.
13
+ * Pass null to return to the default shader.
14
+ * @param shader The custom shader to use, or null to use the default shader
9
15
  *
10
16
  * @example
11
17
  * ```javascript
@@ -14,14 +20,219 @@ export interface RenderingCapabilities {
14
20
  * height: 600,
15
21
  * })
16
22
  *
23
+ * // Create a custom filter shader
24
+ * const customShader = t.createFilterShader(`
25
+ * // ... fragment shader code ...
26
+ * `);
27
+ *
17
28
  * t.draw(() => {
18
29
  * t.background(0);
19
30
  *
20
- * // todo...
31
+ * // Use custom shader
32
+ * t.shader(customShader);
33
+ * t.setUniform('u_frameCount', t.frameCount);
34
+ * t.rect(0, 0, t.grid.cols, t.grid.rows);
35
+ *
36
+ * // Return to default shader
37
+ * t.shader(null);
38
+ * });
39
+ * ```
40
+ */
41
+ shader(shader: GLShader | null): void;
42
+ /**
43
+ * Set a uniform value for the current custom shader.
44
+ * @param name The name of the uniform variable
45
+ * @param value The value to set
46
+ *
47
+ * @example
48
+ * ```javascript
49
+ * const t = await textmode.create({
50
+ * width: 800,
51
+ * height: 600,
52
+ * })
53
+ *
54
+ * const shader = t.createFilterShader(`
55
+ * uniform float u_time;
56
+ * // ... rest of shader ...
57
+ * `);
58
+ *
59
+ * t.draw(() => {
60
+ * t.shader(shader);
61
+ * t.setUniform('u_time', t.frameCount * 0.02);
62
+ * t.rect(0, 0, t.grid.cols, t.grid.rows);
63
+ * });
64
+ * ```
65
+ */
66
+ setUniform(name: string, value: UniformValue): void;
67
+ /**
68
+ * Set multiple uniform values for the current custom shader.
69
+ * @param uniforms Object containing uniform name-value pairs
70
+ *
71
+ * @example
72
+ * ```javascript
73
+ * const t = await textmode.create({
74
+ * width: 800,
75
+ * height: 600,
76
+ * })
77
+ *
78
+ * const shader = t.createFilterShader(`
79
+ * uniform float u_time;
80
+ * uniform vec2 u_resolution;
81
+ * // ... rest of shader ...
82
+ * `);
83
+ *
84
+ * t.draw(() => {
85
+ * t.shader(shader);
86
+ * t.setUniforms({
87
+ * u_time: t.frameCount * 0.02,
88
+ * u_resolution: [t.grid.cols, t.grid.rows]
89
+ * });
90
+ * t.rect(0, 0, t.grid.cols, t.grid.rows);
91
+ * });
92
+ * ```
93
+ */
94
+ setUniforms(uniforms: Record<string, UniformValue>): void;
95
+ /**
96
+ * Create a custom filter shader from fragment shader source code.
97
+ * The fragment shader will automatically receive the standard vertex shader inputs
98
+ * and must output to all 5 MRT attachments.
99
+ * @param fragmentSource The fragment shader source code
100
+ * @returns A compiled shader ready for use with shader()
101
+ *
102
+ * @example
103
+ * ```javascript
104
+ * const t = await textmode.create({
105
+ * width: 800,
106
+ * height: 600,
107
+ * })
108
+ *
109
+ * const noiseShader = t.createFilterShader(`
110
+ * #version 300 es
111
+ * precision highp float;
112
+ *
113
+ * in vec2 v_uv;
114
+ * in vec3 v_character;
115
+ * in vec4 v_primaryColor;
116
+ * in vec4 v_secondaryColor;
117
+ * in vec2 v_rotation;
118
+ * in vec3 v_transform;
119
+ *
120
+ * uniform float u_frameCount;
121
+ *
122
+ * layout(location = 0) out vec4 o_character;
123
+ * layout(location = 1) out vec4 o_primaryColor;
124
+ * layout(location = 2) out vec4 o_secondaryColor;
125
+ * layout(location = 3) out vec4 o_rotation;
126
+ * layout(location = 4) out vec4 o_transform;
127
+ *
128
+ * float random(vec2 st) {
129
+ * return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * 43758.5453123);
130
+ * }
131
+ *
132
+ * void main() {
133
+ * vec2 gridPos = floor(gl_FragCoord.xy);
134
+ * float noise = random(gridPos + u_frameCount * 0.1);
135
+ *
136
+ * o_character = vec4(noise, 0.0, 0.0, 1.0);
137
+ * o_primaryColor = vec4(vec3(noise), 1.0);
138
+ * o_secondaryColor = vec4(0.0, 0.0, 0.0, 1.0);
139
+ * o_rotation = vec4(0.0, 0.0, 0.0, 1.0);
140
+ * o_transform = vec4(0.0, 0.0, 0.0, 1.0);
141
+ * }
142
+ * `);
143
+ *
144
+ * t.draw(() => {
145
+ * t.shader(noiseShader);
146
+ * t.setUniform('u_frameCount', t.frameCount);
147
+ * t.rect(0, 0, t.grid.cols, t.grid.rows);
148
+ * });
149
+ * ```
150
+ */
151
+ createFilterShader(fragmentSource: string): GLShader;
152
+ /**
153
+ * Sets the rotation angles for subsequent shape rendering operations
154
+ * @param degreesX The rotation angle in degrees around the X-axis (optional, defaults to 0)
155
+ * @param degreesY The rotation angle in degrees around the Y-axis (optional, defaults to 0)
156
+ * @param degreesZ The rotation angle in degrees around the Z-axis (optional, defaults to 0)
157
+ *
158
+ * @example
159
+ * ```javascript
160
+ * const t = await textmode.create({
161
+ * width: 800,
162
+ * height: 600,
163
+ * })
164
+ *
165
+ * t.draw(() => {
166
+ * t.background(0);
167
+ *
168
+ * // Rotate only around Z-axis (backward compatible)
169
+ * t.rotate(0, 0, 45);
170
+ *
171
+ * // Rotate around all three axes
172
+ * t.rotate(30, 45, 60);
173
+ *
174
+ * t.rect(10, 10, 5, 5);
175
+ * });
176
+ * ```
177
+ */
178
+ rotate(degreesX?: number, degreesY?: number, degreesZ?: number): void;
179
+ /**
180
+ * Sets the X-axis rotation angle for subsequent shape rendering operations
181
+ * @param degrees The rotation angle in degrees around the X-axis
182
+ *
183
+ * @example
184
+ * ```javascript
185
+ * const t = await textmode.create({
186
+ * width: 800,
187
+ * height: 600,
188
+ * })
189
+ *
190
+ * t.draw(() => {
191
+ * t.background(0);
192
+ * t.rotateX(45); // Rotate around X-axis
193
+ * t.rect(10, 10, 5, 5);
194
+ * });
195
+ * ```
196
+ */
197
+ rotateX(degrees: number): void;
198
+ /**
199
+ * Sets the Y-axis rotation angle for subsequent shape rendering operations
200
+ * @param degrees The rotation angle in degrees around the Y-axis
201
+ *
202
+ * @example
203
+ * ```javascript
204
+ * const t = await textmode.create({
205
+ * width: 800,
206
+ * height: 600,
207
+ * })
208
+ *
209
+ * t.draw(() => {
210
+ * t.background(0);
211
+ * t.rotateY(45); // Rotate around Y-axis
212
+ * t.rect(10, 10, 5, 5);
213
+ * });
214
+ * ```
215
+ */
216
+ rotateY(degrees: number): void;
217
+ /**
218
+ * Sets the Z-axis rotation angle for subsequent shape rendering operations
219
+ * @param degrees The rotation angle in degrees around the Z-axis
220
+ *
221
+ * @example
222
+ * ```javascript
223
+ * const t = await textmode.create({
224
+ * width: 800,
225
+ * height: 600,
226
+ * })
227
+ *
228
+ * t.draw(() => {
229
+ * t.background(0);
230
+ * t.rotateZ(45); // Rotate around Z-axis
231
+ * t.rect(10, 10, 5, 5);
21
232
  * });
22
233
  * ```
23
234
  */
24
- rotate(degrees: number): void;
235
+ rotateZ(degrees: number): void;
25
236
  /**
26
237
  * Save the current rendering state to the state stack.
27
238
  * Use with {@link pop} to isolate style changes within a block.
@@ -270,12 +481,12 @@ export interface RenderingCapabilities {
270
481
  *
271
482
  * t.draw(() => {
272
483
  * t.background(0);
273
- * t.flipHorizontally(true);
484
+ * t.flipX(true);
274
485
  * t.rect(10, 10, 5, 5);
275
486
  * });
276
487
  * ```
277
488
  */
278
- flipHorizontally(toggle: boolean): void;
489
+ flipX(toggle: boolean): void;
279
490
  /**
280
491
  * Toggle vertical flipping for subsequent character rendering.
281
492
  * @param toggle Whether to flip vertically
@@ -289,12 +500,12 @@ export interface RenderingCapabilities {
289
500
  *
290
501
  * t.draw(() => {
291
502
  * t.background(0);
292
- * t.flipVertically(true);
503
+ * t.flipY(true);
293
504
  * t.rect(10, 10, 5, 5);
294
505
  * });
295
506
  * ```
296
507
  */
297
- flipVertically(toggle: boolean): void;
508
+ flipY(toggle: boolean): void;
298
509
  /**
299
510
  * Set the character rotation angle for subsequent character rendering.
300
511
  * @param degrees The rotation angle in degrees
@@ -407,3 +618,4 @@ export interface RenderingCapabilities {
407
618
  * @returns Extended class with rendering capabilities
408
619
  */
409
620
  export declare const RenderingMixin: Mixin<RenderingCapabilities>;
621
+ export {};
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "textmode.js",
3
- "version": "0.2.0-beta.2",
3
+ "version": "0.2.0-beta.4",
4
4
  "description": "Apply real-time ASCII conversion to any HTML canvas.",
5
5
  "type": "module",
6
6
  "types": "./dist/types/index.d.ts",