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/README.md +217 -124
- package/dist/index.cjs +12 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +85 -6
- package/dist/index.d.ts +85 -6
- package/dist/index.js +12 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
-
/**
|
|
134
|
-
|
|
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,
|
|
222
|
+
* await asciify(img, canvas, { fontSize: 8, artStyle: 'letters' });
|
|
144
223
|
*/
|
|
145
|
-
declare function asciify(source: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | string, canvas: HTMLCanvasElement, { fontSize,
|
|
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,
|
|
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,
|
|
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
|
-
/**
|
|
134
|
-
|
|
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,
|
|
222
|
+
* await asciify(img, canvas, { fontSize: 8, artStyle: 'letters' });
|
|
144
223
|
*/
|
|
145
|
-
declare function asciify(source: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | string, canvas: HTMLCanvasElement, { fontSize,
|
|
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,
|
|
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,
|
|
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,
|
|
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[
|
|
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,
|
|
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[
|
|
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,
|
|
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
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
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[
|
|
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);
|