textmode.js 0.6.0-beta.1 → 0.6.0-beta.2

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 (25) hide show
  1. package/dist/textmode.esm.js +2496 -2472
  2. package/dist/textmode.esm.min.js +2579 -2555
  3. package/dist/textmode.umd.js +11 -11
  4. package/dist/textmode.umd.min.js +11 -11
  5. package/dist/types/errors/ErrorHandler.d.ts +6 -1
  6. package/dist/types/rendering/webgl/batching/InstanceAttributeBinder.d.ts +6 -6
  7. package/dist/types/rendering/webgl/batching/InstanceBatch.d.ts +3 -3
  8. package/dist/types/rendering/webgl/batching/InstanceBuffer.d.ts +9 -9
  9. package/dist/types/rendering/webgl/batching/InstanceWriter.d.ts +2 -2
  10. package/dist/types/rendering/webgl/core/Framebuffer.d.ts +3 -3
  11. package/dist/types/textmode/Textmodifier.d.ts +1 -6
  12. package/dist/types/textmode/interfaces/ITextmodifier.d.ts +13 -10
  13. package/dist/types/textmode/loadables/TextmodeImage.d.ts +26 -0
  14. package/dist/types/textmode/loadables/TextmodeSource.d.ts +14 -14
  15. package/dist/types/textmode/loadables/TextmodeVideo.d.ts +29 -1
  16. package/dist/types/textmode/loadables/font/TextmodeFont.d.ts +3 -0
  17. package/dist/types/textmode/loading/LoadingPhaseTracker.d.ts +8 -8
  18. package/dist/types/textmode/loading/LoadingScreenManager.d.ts +49 -8
  19. package/dist/types/textmode/loading/LoadingScreenState.d.ts +11 -11
  20. package/dist/types/textmode/loading/LoadingScreenTheme.d.ts +3 -3
  21. package/dist/types/textmode/loading/LoadingScreenTransition.d.ts +5 -5
  22. package/dist/types/textmode/loading/index.d.ts +1 -1
  23. package/dist/types/textmode/managers/PluginManager.d.ts +6 -1
  24. package/dist/types/textmode/mixins/interfaces/IRenderingMixin.d.ts +218 -179
  25. package/package.json +1 -1
@@ -12,23 +12,30 @@ export interface IRenderingMixin {
12
12
  *
13
13
  * @example
14
14
  * ```javascript
15
- * const t = textmode.create({
16
- * width: 800,
17
- * height: 600,
18
- * })
19
- *
20
- * // Create a custom filter shader
21
- * const customShader = t.createFilterShader('
22
- * // ... fragment shader code ...
23
- * ');
15
+ * const t = textmode.create({ width: 800, height: 600 });
16
+ *
17
+ * const glitchShader = t.createFilterShader(`#version 300 es
18
+ * precision highp float;
19
+ * in vec2 v_uv;
20
+ * uniform float u_intensity;
21
+ * layout(location = 0) out vec4 o_character;
22
+ * layout(location = 1) out vec4 o_primaryColor;
23
+ * layout(location = 2) out vec4 o_secondaryColor;
24
+ *
25
+ * void main() {
26
+ * vec2 offset = vec2(sin(v_uv.y * 50.0) * u_intensity, 0.0);
27
+ * float pattern = fract(v_uv.x * 20.0 + offset.x);
28
+ * vec3 color = vec3(pattern, 1.0 - pattern, 0.5);
29
+ * o_character = vec4(pattern, 0.0, 0.0, 0.0);
30
+ * o_primaryColor = vec4(color, 1.0);
31
+ * o_secondaryColor = vec4(color * 0.5, 1.0);
32
+ * }
33
+ * `);
24
34
  *
25
35
  * t.draw(() => {
26
- * t.background(0);
27
- *
28
- * // Use custom shader
29
- * t.shader(customShader);
30
- * t.setUniform('u_frameCount', t.frameCount);
31
- * t.rect(0, 0, t.grid.cols, t.grid.rows);
36
+ * t.shader(glitchShader);
37
+ * t.setUniform('u_intensity', Math.sin(t.frameCount * 0.1) * 0.02);
38
+ * t.rect(t.grid.cols, t.grid.rows);
32
39
  * });
33
40
  * ```
34
41
  */
@@ -186,20 +193,29 @@ export interface IRenderingMixin {
186
193
  *
187
194
  * @example
188
195
  * ```javascript
189
- * const t = textmode.create({
190
- * width: 800,
191
- * height: 600,
192
- * })
196
+ * const t = textmode.create({ width: 800, height: 600 });
193
197
  *
194
- * const shader = t.createFilterShader(`
198
+ * const pulseShader = t.createFilterShader(`#version 300 es
199
+ * precision highp float;
200
+ * in vec2 v_uv;
195
201
  * uniform float u_time;
196
- * // ... rest of shader ...
202
+ * layout(location = 0) out vec4 o_character;
203
+ * layout(location = 1) out vec4 o_primaryColor;
204
+ * layout(location = 2) out vec4 o_secondaryColor;
205
+ *
206
+ * void main() {
207
+ * float pulse = 0.5 + 0.5 * sin(u_time + length(v_uv - 0.5) * 8.0);
208
+ * vec3 color = vec3(pulse * 0.3, pulse * 0.8, pulse);
209
+ * o_character = vec4(pulse, 0.0, 0.0, 0.0);
210
+ * o_primaryColor = vec4(color, 1.0);
211
+ * o_secondaryColor = vec4(color * 0.3, 1.0);
212
+ * }
197
213
  * `);
198
214
  *
199
215
  * t.draw(() => {
200
- * t.shader(shader);
201
- * t.setUniform('u_time', t.frameCount * 0.02);
202
- * t.rect(0, 0, t.grid.cols, t.grid.rows);
216
+ * t.shader(pulseShader);
217
+ * t.setUniform('u_time', t.frameCount * 0.005);
218
+ * t.rect(t.grid.cols, t.grid.rows);
203
219
  * });
204
220
  * ```
205
221
  */
@@ -210,34 +226,44 @@ export interface IRenderingMixin {
210
226
  *
211
227
  * @example
212
228
  * ```javascript
213
- * const t = textmode.create({
214
- * width: 800,
215
- * height: 600,
216
- * })
229
+ * const t = textmode.create({ width: 800, height: 600 });
217
230
  *
218
- * const shader = t.createFilterShader(`
231
+ * const rippleShader = t.createFilterShader(`#version 300 es
232
+ * precision highp float;
233
+ * in vec2 v_uv;
219
234
  * uniform float u_time;
220
- * uniform vec2 u_resolution;
221
- * // ... rest of shader ...
235
+ * uniform vec2 u_center;
236
+ * layout(location = 0) out vec4 o_character;
237
+ * layout(location = 1) out vec4 o_primaryColor;
238
+ * layout(location = 2) out vec4 o_secondaryColor;
239
+ *
240
+ * void main() {
241
+ * float dist = length(v_uv - u_center);
242
+ * float wave = sin(dist * 20.0 - u_time * 2.0) * 0.5 + 0.5;
243
+ * vec3 color = mix(vec3(0.2, 0.4, 0.8), vec3(0.9, 0.6, 0.3), wave);
244
+ * o_character = vec4(wave, 0.0, 0.0, 0.0);
245
+ * o_primaryColor = vec4(color, 1.0);
246
+ * o_secondaryColor = vec4(color * 0.4, 1.0);
247
+ * }
222
248
  * `);
223
249
  *
224
250
  * t.draw(() => {
225
- * t.shader(shader);
251
+ * t.shader(rippleShader);
226
252
  * t.setUniforms({
227
- * u_time: t.frameCount * 0.02,
228
- * u_resolution: [t.grid.cols, t.grid.rows]
253
+ * u_time: t.frameCount * 0.0005,
254
+ * u_center: [0.5, 0.5]
229
255
  * });
230
- * t.rect(0, 0, t.grid.cols, t.grid.rows);
256
+ * t.rect(t.grid.cols, t.grid.rows);
231
257
  * });
232
258
  * ```
233
259
  */
234
260
  setUniforms(uniforms: Record<string, UniformValue>): void;
235
261
  /**
236
- * Create a custom filter shader from fragment shader source code.
262
+ * Create a custom filter shader from fragment shader source code or a file path.
237
263
  * The fragment shader automatically receives the standard vertex shader inputs
238
264
  * and must output to the 3 MRT attachments (character/transform, primary color, secondary color).
239
- * @param fragmentSource The fragment shader source code
240
- * @returns A compiled shader ready for use with {@link shader}
265
+ * @param fragmentSource The fragment shader source code or a file path (e.g., './shader.frag')
266
+ * @returns A Promise that resolves to a compiled shader ready for use with {@link shader}
241
267
  *
242
268
  * @example
243
269
  * ```javascript
@@ -246,57 +272,43 @@ export interface IRenderingMixin {
246
272
  * height: 600,
247
273
  * })
248
274
  *
249
- * const waveShader = t.createFilterShader(`#version 300 es
250
- * precision highp float;
251
- *
252
- * in vec2 v_uv;
253
- * in vec3 v_character;
254
- * in vec4 v_primaryColor;
255
- * in vec4 v_secondaryColor;
256
- *
257
- * uniform float u_time;
258
- *
259
- * layout(location = 0) out vec4 o_character;
260
- * layout(location = 1) out vec4 o_primaryColor;
261
- * layout(location = 2) out vec4 o_secondaryColor;
262
- *
263
- * float luma(vec3 c) {
264
- * return dot(c, vec3(0.2126, 0.7152, 0.0722));
265
- * }
266
- *
267
- * void main() {
268
- * vec2 uv = v_uv * 2.0 - 1.0;
269
- * float time = u_time * 0.4;
270
- * float radial = length(uv);
271
- * float swirl = sin(radial * 9.0 - time) + cos(uv.x * 6.0 + time * 1.3);
272
- * float ripple = sin((uv.x + uv.y) * 10.0 + time * 2.0) * 0.5;
275
+ * let waveShader;
273
276
  *
274
- * // Palette that shifts through warm→cool hues
275
- * vec3 color = vec3(
276
- * 0.55 + 0.45 * sin(time + radial * 4.0),
277
- * 0.55 + 0.45 * sin(time * 1.3 + uv.y * 5.0 + ripple),
278
- * 0.55 + 0.45 * sin(time * 0.9 + uv.x * 5.0 - ripple)
279
- * );
280
- *
281
- * float glyphIndex = fract(0.5 + 0.5 * swirl);
282
- * float rotation = fract(0.5 + swirl * 0.25);
283
- * int invertFlag = luma(color) > 0.6 ? 1 : 0;
284
- * float packedFlags = float(invertFlag) / 255.0;
277
+ * t.setup(async () => {
278
+ * // Load shader from file
279
+ * waveShader = await t.createFilterShader('./shader.frag');
285
280
  *
286
- * o_character = vec4(glyphIndex, 0.0, packedFlags, 0.0);
287
- * o_primaryColor = vec4(color, 1.0);
288
- * o_secondaryColor = vec4(mix(vec3(0.1), color, 0.35), 1.0);
289
- * }
290
- * `);
281
+ * // Or create from inline source
282
+ * // waveShader = await t.createFilterShader(`#version 300 es
283
+ * // precision highp float;
284
+ * //
285
+ * // in vec2 v_uv;
286
+ * // in vec3 v_character;
287
+ * // in vec4 v_primaryColor;
288
+ * // in vec4 v_secondaryColor;
289
+ * //
290
+ * // uniform float u_time;
291
+ * //
292
+ * // layout(location = 0) out vec4 o_character;
293
+ * // layout(location = 1) out vec4 o_primaryColor;
294
+ * // layout(location = 2) out vec4 o_secondaryColor;
295
+ * //
296
+ * // void main() {
297
+ * // // Shader code here
298
+ * // }
299
+ * // `);
300
+ * });
291
301
  *
292
302
  * t.draw(() => {
293
- * t.shader(waveShader);
294
- * t.setUniform('u_time', t.frameCount * 0.003);
295
- * t.rect(t.grid.cols, t.grid.rows);
303
+ * if (waveShader) {
304
+ * t.shader(waveShader);
305
+ * t.setUniform('u_time', t.frameCount * 0.003);
306
+ * t.rect(t.grid.cols, t.grid.rows);
307
+ * }
296
308
  * });
297
309
  * ```
298
310
  */
299
- createFilterShader(fragmentSource: string): GLShader;
311
+ createFilterShader(fragmentSource: string): Promise<GLShader>;
300
312
  /**
301
313
  * Sets the rotation angles for subsequent shape rendering operations.
302
314
  *
@@ -308,21 +320,25 @@ export interface IRenderingMixin {
308
320
  *
309
321
  * @example
310
322
  * ```javascript
311
- * const t = textmode.create({
312
- * width: 800,
313
- * height: 600,
314
- * })
323
+ * const t = textmode.create({ width: 800, height: 600 });
315
324
  *
316
325
  * t.draw(() => {
317
326
  * t.background(0);
318
327
  *
319
- * // Rotate only around Z-axis (backward compatible)
320
- * t.rotate(0, 0, 45);
328
+ * // Draw three rectangles rotating in 3D space with different axes
329
+ * for (let i = 0; i < 3; i++) {
330
+ * t.push();
331
+ * t.translate(i * 15 - 15, 0, 0);
321
332
  *
322
- * // Rotate around all three axes
323
- * t.rotate(30, 45, 60);
333
+ * const angle = t.frameCount * (1.5 + i * 0.5);
334
+ * // Each shape rotates around different combinations of axes
335
+ * t.rotate(angle * 0.7, angle * 0.5, angle);
324
336
  *
325
- * t.rect(10, 10, 5, 5);
337
+ * t.char(['T', 'X', 'T'][i]);
338
+ * t.charColor(100 + i * 60, 200 - i * 40, 255);
339
+ * t.rect(10, 10);
340
+ * t.pop();
341
+ * }
326
342
  * });
327
343
  * ```
328
344
  */
@@ -336,15 +352,14 @@ export interface IRenderingMixin {
336
352
  *
337
353
  * @example
338
354
  * ```javascript
339
- * const t = textmode.create({
340
- * width: 800,
341
- * height: 600,
342
- * })
355
+ * const t = textmode.create({ width: 800, height: 600 });
343
356
  *
344
357
  * t.draw(() => {
345
358
  * t.background(0);
346
- * t.rotateX(45); // Rotate around X-axis
347
- * t.rect(10, 10, 5, 5);
359
+ * t.char('A');
360
+ * t.charColor(255, 150, 100);
361
+ * t.rotateX(t.frameCount * 2); // Flip forward/backward
362
+ * t.rect(12, 12);
348
363
  * });
349
364
  * ```
350
365
  */
@@ -358,15 +373,14 @@ export interface IRenderingMixin {
358
373
  *
359
374
  * @example
360
375
  * ```javascript
361
- * const t = textmode.create({
362
- * width: 800,
363
- * height: 600,
364
- * })
376
+ * const t = textmode.create({ width: 800, height: 600 });
365
377
  *
366
378
  * t.draw(() => {
367
379
  * t.background(0);
368
- * t.rotateY(45); // Rotate around Y-axis
369
- * t.rect(10, 10, 5, 5);
380
+ * t.char('B');
381
+ * t.charColor(100, 255, 200);
382
+ * t.rotateY(t.frameCount * 2); // Spin left/right
383
+ * t.rect(12, 12);
370
384
  * });
371
385
  * ```
372
386
  */
@@ -380,15 +394,14 @@ export interface IRenderingMixin {
380
394
  *
381
395
  * @example
382
396
  * ```javascript
383
- * const t = textmode.create({
384
- * width: 800,
385
- * height: 600,
386
- * })
397
+ * const t = textmode.create({ width: 800, height: 600 });
387
398
  *
388
399
  * t.draw(() => {
389
400
  * t.background(0);
390
- * t.rotateZ(45); // Rotate around Z-axis
391
- * t.rect(10, 10, 5, 5);
401
+ * t.char('C');
402
+ * t.charColor(255, 220, 100);
403
+ * t.rotateZ(t.frameCount * 2); // Spin clockwise
404
+ * t.rect(12, 12);
392
405
  * });
393
406
  * ```
394
407
  */
@@ -404,21 +417,20 @@ export interface IRenderingMixin {
404
417
  *
405
418
  * @example
406
419
  * ```javascript
407
- * const t = textmode.create({
408
- * width: 800,
409
- * height: 600,
410
- * })
420
+ * const t = textmode.create({ width: 800, height: 600 });
411
421
  *
412
422
  * t.draw(() => {
413
423
  * t.background(0);
414
424
  *
415
- * // Translate in 2D
416
- * t.translate(10, 5);
417
- *
418
- * // Translate in 3D
419
- * t.translate(10, 5, 2);
420
- *
421
- * t.rect(0, 0, 5, 5); // Drawn at (10, 5) with Z offset
425
+ * // Draw a grid of shapes with different translations
426
+ * for (let i = 0; i < 3; i++) {
427
+ * t.push();
428
+ * t.translate(i * 12 - 12, Math.sin(t.frameCount * 0.05 + i) * 3);
429
+ * t.char('A');
430
+ * t.charColor(100 + i * 70, 150, 255 - i * 50);
431
+ * t.rect(8, 8);
432
+ * t.pop();
433
+ * }
422
434
  * });
423
435
  * ```
424
436
  */
@@ -430,15 +442,14 @@ export interface IRenderingMixin {
430
442
  *
431
443
  * @example
432
444
  * ```javascript
433
- * const t = textmode.create({
434
- * width: 800,
435
- * height: 600,
436
- * })
445
+ * const t = textmode.create({ width: 800, height: 600 });
437
446
  *
438
447
  * t.draw(() => {
439
448
  * t.background(0);
440
- * t.translateX(10); // Translate 10 pixels to the right
441
- * t.rect(0, 0, 5, 5); // Drawn at (10, 0)
449
+ * t.char('→');
450
+ * t.charColor(255, 180, 100);
451
+ * t.translateX(Math.sin(t.frameCount * 0.05) * 15); // Slide left/right
452
+ * t.rect(10, 10);
442
453
  * });
443
454
  * ```
444
455
  */
@@ -450,15 +461,14 @@ export interface IRenderingMixin {
450
461
  *
451
462
  * @example
452
463
  * ```javascript
453
- * const t = textmode.create({
454
- * width: 800,
455
- * height: 600,
456
- * })
464
+ * const t = textmode.create({ width: 800, height: 600 });
457
465
  *
458
466
  * t.draw(() => {
459
467
  * t.background(0);
460
- * t.translateY(10); // Translate 10 pixels down
461
- * t.rect(0, 0, 5, 5); // Drawn at (0, 10)
468
+ * t.char('↓');
469
+ * t.charColor(100, 255, 180);
470
+ * t.translateY(Math.sin(t.frameCount * 0.05) * 10); // Bounce up/down
471
+ * t.rect(10, 10);
462
472
  * });
463
473
  * ```
464
474
  */
@@ -470,15 +480,14 @@ export interface IRenderingMixin {
470
480
  *
471
481
  * @example
472
482
  * ```javascript
473
- * const t = textmode.create({
474
- * width: 800,
475
- * height: 600,
476
- * })
483
+ * const t = textmode.create({ width: 800, height: 600 });
477
484
  *
478
485
  * t.draw(() => {
479
486
  * t.background(0);
480
- * t.translateZ(5); // Move 5 pixels forward in 3D space
481
- * t.rect(10, 10, 5, 5);
487
+ * t.char('O');
488
+ * t.charColor(180, 120, 255);
489
+ * t.translateZ(Math.sin(t.frameCount * 0.05) * 20); // Pulse in/out
490
+ * t.rect(12, 12);
482
491
  * });
483
492
  * ```
484
493
  */
@@ -489,20 +498,21 @@ export interface IRenderingMixin {
489
498
  *
490
499
  * @example
491
500
  * ```javascript
492
- * const t = textmode.create({
493
- * width: 800,
494
- * height: 600,
495
- * })
501
+ * const t = textmode.create({ width: 800, height: 600 });
496
502
  *
497
503
  * t.draw(() => {
498
504
  * t.background(0);
499
505
  *
500
- * t.push(); // Save current state
501
- * t.charColor(255, 0, 0); // Red characters
502
- * t.rotateZ(t.frameCount * 2);
503
- * t.char('A');
504
- * t.rect(16, 16);
505
- * t.pop(); // Restore previous state
506
+ * // Draw three rotating shapes with isolated transformations and colors
507
+ * for (let i = 0; i < 3; i++) {
508
+ * t.push(); // Save state
509
+ * t.translate(i * 12 - 12, 0);
510
+ * t.rotateZ(t.frameCount * (1 + i * 0.5));
511
+ * t.charColor(100 + i * 70, 255 - i * 50, 150);
512
+ * t.char(['*', '@', '#'][i]);
513
+ * t.rect(8, 8);
514
+ * t.pop(); // Restore state - next iteration starts fresh
515
+ * }
506
516
  * });
507
517
  * ```
508
518
  */
@@ -513,20 +523,21 @@ export interface IRenderingMixin {
513
523
  *
514
524
  * @example
515
525
  * ```javascript
516
- * const t = textmode.create({
517
- * width: 800,
518
- * height: 600,
519
- * })
526
+ * const t = textmode.create({ width: 800, height: 600 });
520
527
  *
521
528
  * t.draw(() => {
522
529
  * t.background(0);
523
530
  *
524
- * t.push(); // Save current state
525
- * t.charColor(0, 255, 0); // Green characters
526
- * t.rotateZ(t.frameCount * 2);
527
- * t.char('A');
528
- * t.rect(16, 16);
529
- * t.pop(); // Restore previous state
531
+ * // Draw three rotating shapes with isolated transformations and colors
532
+ * for (let i = 0; i < 3; i++) {
533
+ * t.push(); // Save state
534
+ * t.translate(i * 12 - 12, 0);
535
+ * t.rotateZ(t.frameCount * (1 + i * 0.5));
536
+ * t.charColor(100 + i * 70, 255 - i * 50, 150);
537
+ * t.char(['*', '@', '#'][i]);
538
+ * t.rect(8, 8);
539
+ * t.pop(); // Restore state - next iteration starts fresh
540
+ * }
530
541
  * });
531
542
  * ```
532
543
  */
@@ -616,26 +627,48 @@ export interface IRenderingMixin {
616
627
  */
617
628
  rect(width?: number, height?: number): void;
618
629
  /**
619
- * Draw a single point at (x, y) with the current settings.
620
- * @param x X-coordinate of the point
621
- * @param y Y-coordinate of the point
630
+ * Draw a 1x1 rectangle with the current settings.
622
631
  *
623
632
  * @example
624
- * ```javascript
625
- * const t = textmode.create({
626
- * width: 800,
627
- * height: 600,
628
- * })
629
- *
630
- * t.draw(() => {
631
- * t.background(0);
632
- *
633
- * t.char('*');
634
- * t.point();
635
- * });
633
+ * ```javascript
634
+ * const t = textmode.create({ width: 800, height: 600 });
635
+ *
636
+ * t.draw(() => {
637
+ * t.background(0);
638
+ *
639
+ * const angle = t.frameCount * 0.06;
640
+ * const radius = Math.min(t.grid.cols, t.grid.rows) * 0.35;
641
+ *
642
+ * // Draw a short trail of points behind the leading point
643
+ * for (let i = 0; i < 10; i++) {
644
+ * const a = angle - i * 0.18;
645
+ * const r = radius * (1 - i * 0.08);
646
+ * const x = Math.round(Math.cos(a) * r);
647
+ * const y = Math.round(Math.sin(a) * r);
648
+ *
649
+ * // Color and brightness fade across the trail
650
+ * const brightness = Math.max(40, 255 - i * 20);
651
+ * const blue = Math.max(60, 255 - i * 25);
652
+ * const green = 120 + i * 8;
653
+ *
654
+ * t.push();
655
+ * t.translate(x, y);
656
+ * t.char('*');
657
+ * t.charColor(brightness, green, blue);
658
+ * t.point();
659
+ *
660
+ * t.pop();
661
+ * }
662
+ *
663
+ * // Leading point drawn with highest brightness
664
+ * t.char('@');
665
+ * t.charColor(255, 255, 160);
666
+ * t.translate(Math.round(Math.cos(angle) * radius), Math.round(Math.sin(angle) * radius));
667
+ * t.point();
668
+ * });
636
669
  * ```
637
670
  */
638
- point(x: number, y: number): void;
671
+ point(): void;
639
672
  /**
640
673
  * Draw a line from point (x1, y1) to point (x2, y2) with the settings.
641
674
  * @param x1 X-coordinate of the line start point
@@ -995,14 +1028,20 @@ export interface IRenderingMixin {
995
1028
  *
996
1029
  * @example
997
1030
  * ```javascript
998
- * const t = textmode.create({
999
- * width: 800,
1000
- * height: 600,
1001
- * })
1031
+ * const t = textmode.create({ width: 800, height: 600 });
1002
1032
  *
1003
1033
  * t.draw(() => {
1004
1034
  * t.background(0);
1005
- * t.triangle(10, 10, 20, 10, 15, 20);
1035
+ * t.char('*');
1036
+ * t.charColor(255, 100, 150);
1037
+ *
1038
+ * const angle = t.frameCount * 0.02;
1039
+ * const size = 15;
1040
+ * t.triangle(
1041
+ * Math.cos(angle) * size, Math.sin(angle) * size,
1042
+ * Math.cos(angle + 2.09) * size, Math.sin(angle + 2.09) * size,
1043
+ * Math.cos(angle + 4.19) * size, Math.sin(angle + 4.19) * size
1044
+ * );
1006
1045
  * });
1007
1046
  * ```
1008
1047
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "textmode.js",
3
- "version": "0.6.0-beta.1",
3
+ "version": "0.6.0-beta.2",
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",