asciify-engine 1.0.34 → 1.0.36

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.
package/dist/index.d.cts CHANGED
@@ -17,24 +17,99 @@ declare const PALETTE_THEMES: Record<PaletteTheme, {
17
17
  }>;
18
18
  type SourceType = 'image' | 'video' | 'gif' | null;
19
19
  interface AsciiOptions {
20
+ /** Character cell size in pixels. Smaller = more detail, more cells. Default: `10` */
20
21
  fontSize: number;
22
+ /** Extra horizontal spacing between characters (pixels). Default: `1` */
21
23
  charSpacing: number;
24
+ /**
25
+ * Brightness adjustment applied before luminance mapping.
26
+ * Range −1 (black) → 0 (unchanged) → 1 (white). Default: `0`
27
+ */
22
28
  brightness: number;
29
+ /**
30
+ * Contrast boost applied before luminance mapping.
31
+ * `0` = unchanged, positive values increase contrast, negative decrease it.
32
+ * Default: `0`
33
+ */
23
34
  contrast: number;
35
+ /**
36
+ * Character density ramp — ordered from lightest to darkest.
37
+ * Use `CHARSETS` for pre-built ramps or supply your own string.
38
+ * Default: `' .:-=+*#%@'`
39
+ */
24
40
  charset: string;
41
+ /**
42
+ * Colour output mode.
43
+ * - `'grayscale'` — white-on-black monochrome
44
+ * - `'fullcolor'` — samples pixel colours from the source
45
+ * - `'matrix'` — green phosphor terminal look
46
+ * - `'accent'` — single accent colour with intensity-driven brightness
47
+ * Default: `'grayscale'`
48
+ */
25
49
  colorMode: ColorMode;
50
+ /**
51
+ * The accent colour used when `colorMode` is `'accent'` or `'matrix'`.
52
+ * Any CSS colour string. Default: `'#d4ff00'`
53
+ */
26
54
  accentColor: string;
55
+ /** Invert luminance mapping (light pixels → dense chars). Default: `false` */
27
56
  invert: boolean;
57
+ /**
58
+ * Render mode.
59
+ * - `'ascii'` — characters drawn as text
60
+ * - `'dots'` — each cell rendered as a filled circle (particle look)
61
+ * Default: `'ascii'`
62
+ */
28
63
  renderMode: RenderMode;
64
+ /**
65
+ * Per-character animation driven over time.
66
+ * Applies wave, glitch, rain-drop, spiral, and other effects to the rendered text.
67
+ * Default: `'none'`
68
+ */
29
69
  animationStyle: AnimationStyle;
70
+ /** Speed multiplier for `animationStyle` effects. Default: `1` */
30
71
  animationSpeed: number;
72
+ /**
73
+ * Size of each dot relative to the cell when `renderMode === 'dots'`.
74
+ * `1` fills the whole cell, `0.5` draws half-size circles. Default: `0.8`
75
+ */
31
76
  dotSizeRatio: number;
77
+ /**
78
+ * Floyd-Steinberg dither strength applied to the luminance map.
79
+ * `0` = no dithering, `1` = full dithering. Default: `0`
80
+ */
32
81
  ditherStrength: number;
82
+ /**
83
+ * Overall intensity of the hover / cursor interaction effect.
84
+ * `0` disables the effect. Default: `0`
85
+ */
33
86
  hoverStrength: number;
87
+ /**
88
+ * Radius of the hover interaction zone as a fraction of the canvas size.
89
+ * `0.1` = 10% of canvas width. Default: `0.2`
90
+ */
34
91
  hoverRadius: number;
92
+ /**
93
+ * Which cursor interaction style to apply when `hoverStrength > 0`.
94
+ * See `HoverPreset` or `HOVER_PRESETS` for ready-made configurations.
95
+ * Default: `'spotlight'`
96
+ */
35
97
  hoverEffect: HoverEffect;
98
+ /**
99
+ * Tint colour used by hover effects such as spotlight, glow, and colorShift.
100
+ * Any CSS colour string. Default: `'#ffffff'`
101
+ */
36
102
  hoverColor: string;
103
+ /**
104
+ * Art style preset applied at render time.
105
+ * Shorthand for a specific combination of `charset`, `renderMode`, and `colorMode`.
106
+ * See `ART_STYLE_PRESETS` for the full list. Default: `'classic'`
107
+ */
37
108
  artStyle: ArtStyle;
109
+ /**
110
+ * Custom repeating text used when `artStyle` is `'letters'` or when you set
111
+ * a custom charset. Leave empty to use the selected `charset`. Default: `''`
112
+ */
38
113
  customText: string;
39
114
  }
40
115
  interface AsciiCell {
@@ -130,8 +205,12 @@ declare function renderFrameToCanvas(ctx: CanvasRenderingContext2D, frame: Ascii
130
205
  interface AsciifySimpleOptions {
131
206
  /** Character size in pixels. Default: 10 */
132
207
  fontSize?: number;
133
- /** Art style preset. Default: 'classic' */
134
- style?: ArtStyle;
208
+ /**
209
+ * Art style preset — controls charset, render mode, and color mode together.
210
+ * Shorthand for spreading `ART_STYLE_PRESETS[artStyle]` into options.
211
+ * Default: `'classic'`
212
+ */
213
+ artStyle?: ArtStyle;
135
214
  /** Extra options to merge on top of the preset */
136
215
  options?: Partial<AsciiOptions>;
137
216
  }
@@ -140,9 +219,9 @@ interface AsciifySimpleOptions {
140
219
  *
141
220
  * @example
142
221
  * await asciify(document.querySelector('img'), canvas);
143
- * await asciify(img, canvas, { fontSize: 8, style: 'letters' });
222
+ * await asciify(img, canvas, { fontSize: 8, artStyle: 'letters' });
144
223
  */
145
- declare function asciify(source: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | string, canvas: HTMLCanvasElement, { fontSize, style, options }?: AsciifySimpleOptions): Promise<void>;
224
+ declare function asciify(source: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | string, canvas: HTMLCanvasElement, { fontSize, artStyle, options }?: AsciifySimpleOptions): Promise<void>;
146
225
  /**
147
226
  * Fetch a GIF, convert it to ASCII, and start an animation loop on a canvas.
148
227
  * Returns a `stop()` function that cancels the loop.
@@ -151,7 +230,7 @@ declare function asciify(source: HTMLImageElement | HTMLVideoElement | HTMLCanva
151
230
  * const stop = await asciifyGif('animation.gif', canvas);
152
231
  * // later: stop();
153
232
  */
154
- declare function asciifyGif(source: string | ArrayBuffer, canvas: HTMLCanvasElement, { fontSize, style, options }?: AsciifySimpleOptions): Promise<() => void>;
233
+ declare function asciifyGif(source: string | ArrayBuffer, canvas: HTMLCanvasElement, { fontSize, artStyle, options }?: AsciifySimpleOptions): Promise<() => void>;
155
234
  /**
156
235
  * Convert a video element to ASCII art and start an animation loop on a canvas.
157
236
  * Returns a `stop()` function that cancels the loop.
@@ -160,7 +239,7 @@ declare function asciifyGif(source: string | ArrayBuffer, canvas: HTMLCanvasElem
160
239
  * const stop = await asciifyVideo(video, canvas);
161
240
  * // later: stop();
162
241
  */
163
- declare function asciifyVideo(source: HTMLVideoElement | string, canvas: HTMLCanvasElement, { fontSize, style, options }?: AsciifySimpleOptions): Promise<() => void>;
242
+ declare function asciifyVideo(source: HTMLVideoElement | string, canvas: HTMLCanvasElement, { fontSize, artStyle, options }?: AsciifySimpleOptions): Promise<() => void>;
164
243
 
165
244
  interface WaveBackgroundOptions {
166
245
  /** Font size in CSS pixels (default: 13) */
package/dist/index.d.ts CHANGED
@@ -17,24 +17,99 @@ declare const PALETTE_THEMES: Record<PaletteTheme, {
17
17
  }>;
18
18
  type SourceType = 'image' | 'video' | 'gif' | null;
19
19
  interface AsciiOptions {
20
+ /** Character cell size in pixels. Smaller = more detail, more cells. Default: `10` */
20
21
  fontSize: number;
22
+ /** Extra horizontal spacing between characters (pixels). Default: `1` */
21
23
  charSpacing: number;
24
+ /**
25
+ * Brightness adjustment applied before luminance mapping.
26
+ * Range −1 (black) → 0 (unchanged) → 1 (white). Default: `0`
27
+ */
22
28
  brightness: number;
29
+ /**
30
+ * Contrast boost applied before luminance mapping.
31
+ * `0` = unchanged, positive values increase contrast, negative decrease it.
32
+ * Default: `0`
33
+ */
23
34
  contrast: number;
35
+ /**
36
+ * Character density ramp — ordered from lightest to darkest.
37
+ * Use `CHARSETS` for pre-built ramps or supply your own string.
38
+ * Default: `' .:-=+*#%@'`
39
+ */
24
40
  charset: string;
41
+ /**
42
+ * Colour output mode.
43
+ * - `'grayscale'` — white-on-black monochrome
44
+ * - `'fullcolor'` — samples pixel colours from the source
45
+ * - `'matrix'` — green phosphor terminal look
46
+ * - `'accent'` — single accent colour with intensity-driven brightness
47
+ * Default: `'grayscale'`
48
+ */
25
49
  colorMode: ColorMode;
50
+ /**
51
+ * The accent colour used when `colorMode` is `'accent'` or `'matrix'`.
52
+ * Any CSS colour string. Default: `'#d4ff00'`
53
+ */
26
54
  accentColor: string;
55
+ /** Invert luminance mapping (light pixels → dense chars). Default: `false` */
27
56
  invert: boolean;
57
+ /**
58
+ * Render mode.
59
+ * - `'ascii'` — characters drawn as text
60
+ * - `'dots'` — each cell rendered as a filled circle (particle look)
61
+ * Default: `'ascii'`
62
+ */
28
63
  renderMode: RenderMode;
64
+ /**
65
+ * Per-character animation driven over time.
66
+ * Applies wave, glitch, rain-drop, spiral, and other effects to the rendered text.
67
+ * Default: `'none'`
68
+ */
29
69
  animationStyle: AnimationStyle;
70
+ /** Speed multiplier for `animationStyle` effects. Default: `1` */
30
71
  animationSpeed: number;
72
+ /**
73
+ * Size of each dot relative to the cell when `renderMode === 'dots'`.
74
+ * `1` fills the whole cell, `0.5` draws half-size circles. Default: `0.8`
75
+ */
31
76
  dotSizeRatio: number;
77
+ /**
78
+ * Floyd-Steinberg dither strength applied to the luminance map.
79
+ * `0` = no dithering, `1` = full dithering. Default: `0`
80
+ */
32
81
  ditherStrength: number;
82
+ /**
83
+ * Overall intensity of the hover / cursor interaction effect.
84
+ * `0` disables the effect. Default: `0`
85
+ */
33
86
  hoverStrength: number;
87
+ /**
88
+ * Radius of the hover interaction zone as a fraction of the canvas size.
89
+ * `0.1` = 10% of canvas width. Default: `0.2`
90
+ */
34
91
  hoverRadius: number;
92
+ /**
93
+ * Which cursor interaction style to apply when `hoverStrength > 0`.
94
+ * See `HoverPreset` or `HOVER_PRESETS` for ready-made configurations.
95
+ * Default: `'spotlight'`
96
+ */
35
97
  hoverEffect: HoverEffect;
98
+ /**
99
+ * Tint colour used by hover effects such as spotlight, glow, and colorShift.
100
+ * Any CSS colour string. Default: `'#ffffff'`
101
+ */
36
102
  hoverColor: string;
103
+ /**
104
+ * Art style preset applied at render time.
105
+ * Shorthand for a specific combination of `charset`, `renderMode`, and `colorMode`.
106
+ * See `ART_STYLE_PRESETS` for the full list. Default: `'classic'`
107
+ */
37
108
  artStyle: ArtStyle;
109
+ /**
110
+ * Custom repeating text used when `artStyle` is `'letters'` or when you set
111
+ * a custom charset. Leave empty to use the selected `charset`. Default: `''`
112
+ */
38
113
  customText: string;
39
114
  }
40
115
  interface AsciiCell {
@@ -130,8 +205,12 @@ declare function renderFrameToCanvas(ctx: CanvasRenderingContext2D, frame: Ascii
130
205
  interface AsciifySimpleOptions {
131
206
  /** Character size in pixels. Default: 10 */
132
207
  fontSize?: number;
133
- /** Art style preset. Default: 'classic' */
134
- style?: ArtStyle;
208
+ /**
209
+ * Art style preset — controls charset, render mode, and color mode together.
210
+ * Shorthand for spreading `ART_STYLE_PRESETS[artStyle]` into options.
211
+ * Default: `'classic'`
212
+ */
213
+ artStyle?: ArtStyle;
135
214
  /** Extra options to merge on top of the preset */
136
215
  options?: Partial<AsciiOptions>;
137
216
  }
@@ -140,9 +219,9 @@ interface AsciifySimpleOptions {
140
219
  *
141
220
  * @example
142
221
  * await asciify(document.querySelector('img'), canvas);
143
- * await asciify(img, canvas, { fontSize: 8, style: 'letters' });
222
+ * await asciify(img, canvas, { fontSize: 8, artStyle: 'letters' });
144
223
  */
145
- declare function asciify(source: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | string, canvas: HTMLCanvasElement, { fontSize, style, options }?: AsciifySimpleOptions): Promise<void>;
224
+ declare function asciify(source: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | string, canvas: HTMLCanvasElement, { fontSize, artStyle, options }?: AsciifySimpleOptions): Promise<void>;
146
225
  /**
147
226
  * Fetch a GIF, convert it to ASCII, and start an animation loop on a canvas.
148
227
  * Returns a `stop()` function that cancels the loop.
@@ -151,7 +230,7 @@ declare function asciify(source: HTMLImageElement | HTMLVideoElement | HTMLCanva
151
230
  * const stop = await asciifyGif('animation.gif', canvas);
152
231
  * // later: stop();
153
232
  */
154
- declare function asciifyGif(source: string | ArrayBuffer, canvas: HTMLCanvasElement, { fontSize, style, options }?: AsciifySimpleOptions): Promise<() => void>;
233
+ declare function asciifyGif(source: string | ArrayBuffer, canvas: HTMLCanvasElement, { fontSize, artStyle, options }?: AsciifySimpleOptions): Promise<() => void>;
155
234
  /**
156
235
  * Convert a video element to ASCII art and start an animation loop on a canvas.
157
236
  * Returns a `stop()` function that cancels the loop.
@@ -160,7 +239,7 @@ declare function asciifyGif(source: string | ArrayBuffer, canvas: HTMLCanvasElem
160
239
  * const stop = await asciifyVideo(video, canvas);
161
240
  * // later: stop();
162
241
  */
163
- declare function asciifyVideo(source: HTMLVideoElement | string, canvas: HTMLCanvasElement, { fontSize, style, options }?: AsciifySimpleOptions): Promise<() => void>;
242
+ declare function asciifyVideo(source: HTMLVideoElement | string, canvas: HTMLCanvasElement, { fontSize, artStyle, options }?: AsciifySimpleOptions): Promise<() => void>;
164
243
 
165
244
  interface WaveBackgroundOptions {
166
245
  /** Font size in CSS pixels (default: 13) */
package/dist/index.js CHANGED
@@ -968,7 +968,7 @@ function renderFrameToCanvas(ctx, frame, options, canvasWidth, canvasHeight, tim
968
968
  }
969
969
 
970
970
  // src/core/simple-api.ts
971
- async function asciify(source, canvas, { fontSize = 10, style = "classic", options = {} } = {}) {
971
+ async function asciify(source, canvas, { fontSize = 10, artStyle = "classic", options = {} } = {}) {
972
972
  let el;
973
973
  if (typeof source === "string") {
974
974
  const img = new Image();
@@ -988,16 +988,16 @@ async function asciify(source, canvas, { fontSize = 10, style = "classic", optio
988
988
  } else {
989
989
  el = source;
990
990
  }
991
- const preset = ART_STYLE_PRESETS[style];
991
+ const preset = ART_STYLE_PRESETS[artStyle];
992
992
  const merged = { ...DEFAULT_OPTIONS, ...preset, ...options, fontSize };
993
993
  const ctx = canvas.getContext("2d");
994
994
  if (!ctx) throw new Error("Could not get 2d context from canvas");
995
995
  const { frame } = imageToAsciiFrame(el, merged, canvas.width, canvas.height);
996
996
  renderFrameToCanvas(ctx, frame, merged, canvas.width, canvas.height);
997
997
  }
998
- async function asciifyGif(source, canvas, { fontSize = 10, style = "classic", options = {} } = {}) {
998
+ async function asciifyGif(source, canvas, { fontSize = 10, artStyle = "classic", options = {} } = {}) {
999
999
  const buffer = typeof source === "string" ? await fetch(source).then((r) => r.arrayBuffer()) : source;
1000
- const merged = { ...DEFAULT_OPTIONS, ...ART_STYLE_PRESETS[style], ...options, fontSize };
1000
+ const merged = { ...DEFAULT_OPTIONS, ...ART_STYLE_PRESETS[artStyle], ...options, fontSize };
1001
1001
  const ctx = canvas.getContext("2d");
1002
1002
  if (!ctx) throw new Error("Could not get 2d context from canvas");
1003
1003
  const { frames, fps } = await gifToAsciiFrames(buffer, merged, canvas.width, canvas.height);
@@ -1021,20 +1021,22 @@ async function asciifyGif(source, canvas, { fontSize = 10, style = "classic", op
1021
1021
  cancelAnimationFrame(animId);
1022
1022
  };
1023
1023
  }
1024
- async function asciifyVideo(source, canvas, { fontSize = 10, style = "classic", options = {} } = {}) {
1024
+ async function asciifyVideo(source, canvas, { fontSize = 10, artStyle = "classic", options = {} } = {}) {
1025
1025
  let video;
1026
1026
  if (typeof source === "string") {
1027
1027
  video = document.createElement("video");
1028
1028
  video.crossOrigin = "anonymous";
1029
1029
  video.src = source;
1030
- await new Promise((resolve, reject) => {
1031
- video.onloadeddata = () => resolve();
1032
- video.onerror = () => reject(new Error(`Failed to load video: ${source}`));
1033
- });
1030
+ if (video.readyState < 2) {
1031
+ await new Promise((resolve, reject) => {
1032
+ video.onloadeddata = () => resolve();
1033
+ video.onerror = () => reject(new Error(`Failed to load video: ${source}`));
1034
+ });
1035
+ }
1034
1036
  } else {
1035
1037
  video = source;
1036
1038
  }
1037
- const merged = { ...DEFAULT_OPTIONS, ...ART_STYLE_PRESETS[style], ...options, fontSize };
1039
+ const merged = { ...DEFAULT_OPTIONS, ...ART_STYLE_PRESETS[artStyle], ...options, fontSize };
1038
1040
  const ctx = canvas.getContext("2d");
1039
1041
  if (!ctx) throw new Error("Could not get 2d context from canvas");
1040
1042
  const { frames, fps } = await videoToAsciiFrames(video, merged, canvas.width, canvas.height);