asciify-engine 1.0.117 → 1.1.0

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.ts CHANGED
@@ -1,1668 +1,2 @@
1
- type ColorMode = 'grayscale' | 'fullcolor' | 'matrix' | 'accent';
2
- type RenderMode = 'ascii' | 'dots';
3
- type AnimationStyle = 'none' | 'wave' | 'pulse' | 'rain' | 'breathe' | 'sparkle' | 'glitch' | 'spiral' | 'typewriter' | 'scatter' | 'waveField' | 'ripple' | 'melt' | 'orbit' | 'cellular';
4
- type ArtStyle = 'classic' | 'particles' | 'letters' | 'claudeCode' | 'art' | 'terminal' | 'box' | 'lines' | 'braille' | 'katakana' | 'musical' | 'emoji' | 'circles' | 'shadows' | 'starfield' | 'geometric' | 'pipes' | 'waves' | 'shards' | 'smoke' | 'ascii' | 'interface' | 'prompt' | 'data' | 'humanist' | 'mesh';
5
- type HoverEffect = 'spotlight' | 'magnify' | 'repel' | 'glow' | 'colorShift' | 'attract' | 'shatter' | 'trail' | 'glitchText';
6
- type HoverShape = 'circle' | 'box';
7
- type HoverPreset = 'none' | 'subtle' | 'flashlight' | 'magnifier' | 'forceField' | 'neon' | 'fire' | 'ice' | 'gravity' | 'shatter' | 'ghost' | 'glitchReveal';
8
- type SourceCropUnit = 'percent' | 'pixel';
9
- type SourceCropAnchor = 'center' | 'top' | 'bottom' | 'left' | 'right' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
10
- interface SourceCrop {
11
- /** Legacy crop origin on the source media. Percent values use 0–1. Default: centered when cropped */
12
- x?: number;
13
- /** Legacy crop origin on the source media. Percent values use 0–1. Default: centered when cropped */
14
- y?: number;
15
- /** Legacy crop width on the source media. Percent values use 0–1. Default: mirrors `height` to preserve proportions */
16
- width?: number;
17
- /** Legacy crop height on the source media. Percent values use 0–1. Default: mirrors `width` to preserve proportions */
18
- height?: number;
19
- /** CSS-like crop inset from the top edge. Percent values use 0–1. */
20
- top?: number;
21
- /** CSS-like crop inset from the right edge. Percent values use 0–1. */
22
- right?: number;
23
- /** CSS-like crop inset from the bottom edge. Percent values use 0–1. */
24
- bottom?: number;
25
- /** CSS-like crop inset from the left edge. Percent values use 0–1. */
26
- left?: number;
27
- /**
28
- * Keep the source aspect ratio when deriving a crop from a single `width` or
29
- * `height`. CSS-like side insets (`top`, `right`, `bottom`, `left`) already
30
- * define an exact source view box, and `asciifyVideo` sizes from that crop
31
- * aspect so the output does not stretch. Default: `true`.
32
- */
33
- preserveAspect?: boolean;
34
- /** Bias auto-centered crops toward an edge or corner. Default: `'center'` */
35
- anchor?: SourceCropAnchor;
36
- /** Interpret values as normalized percentages or source pixels. Default: `'percent'` */
37
- unit?: SourceCropUnit;
38
- }
39
- /**
40
- * Named colour palette presets — pass as `colorMode` for themed rendering.
41
- * Applied as a post-process colour remap over the standard grayscale output.
42
- */
43
- type PaletteTheme = 'dracula' | 'monokai' | 'nord' | 'catppuccin' | 'solarized' | 'gruvbox';
44
- declare const PALETTE_THEMES: Record<PaletteTheme, {
45
- name: string;
46
- accent: string;
47
- bg: string;
48
- fg: string;
49
- }>;
50
- type SourceType = 'image' | 'video' | 'gif' | null;
51
- interface AsciiOptions {
52
- /** Character cell size in pixels. Smaller = more detail, more cells. Default: `10` */
53
- fontSize: number;
54
- /** Extra horizontal spacing between characters (pixels). Default: `1` */
55
- charSpacing: number;
56
- /**
57
- * Brightness adjustment applied before luminance mapping.
58
- * Range −1 (black) → 0 (unchanged) → 1 (white). Default: `0`
59
- */
60
- brightness: number;
61
- /**
62
- * Contrast boost applied before luminance mapping.
63
- * `0` = unchanged, positive values increase contrast, negative decrease it.
64
- * Default: `0`
65
- */
66
- contrast: number;
67
- /**
68
- * Character density ramp — ordered from lightest to darkest.
69
- * Use `CHARSETS` for pre-built ramps or supply your own string.
70
- * Default: `' .:-=+*#%@'`
71
- */
72
- charset: string;
73
- /**
74
- * Colour output mode.
75
- * - `'grayscale'` — white-on-black monochrome
76
- * - `'fullcolor'` — samples pixel colours from the source
77
- * - `'matrix'` — green phosphor terminal look
78
- * - `'accent'` — single accent colour with intensity-driven brightness
79
- * Default: `'grayscale'`
80
- */
81
- colorMode: ColorMode;
82
- /**
83
- * The accent colour used when `colorMode` is `'accent'` or `'matrix'`.
84
- * Any CSS colour string. Default: `'#d4ff00'`
85
- */
86
- /**
87
- * Hex color string used when `colorMode` is `'accent'`.
88
- * Set to `'auto'` to let the engine pick contrasting ink automatically:
89
- * dark ink (`#0d0d0d`) in light mode, light ink (`#faf9f7`) in dark mode.
90
- */
91
- accentColor: string;
92
- /**
93
- * Invert luminance mapping (light pixels → dense chars). Default: `false`
94
- *
95
- * Set to `'auto'` to let the engine detect the OS color scheme:
96
- * - Light mode → inverts (bright pixel = dark char = visible on white background)
97
- * - Dark mode → normal (bright pixel = bright char = visible on dark background)
98
- */
99
- invert: boolean | 'auto';
100
- /**
101
- * Render mode.
102
- * - `'ascii'` — characters drawn as text
103
- * - `'dots'` — each cell rendered as a filled circle (particle look)
104
- * Default: `'ascii'`
105
- */
106
- renderMode: RenderMode;
107
- /**
108
- * Per-character animation driven over time.
109
- * Applies wave, glitch, rain-drop, spiral, and other effects to the rendered text.
110
- * Default: `'none'`
111
- */
112
- animationStyle: AnimationStyle;
113
- /** Speed multiplier for `animationStyle` effects. Default: `1` */
114
- animationSpeed: number;
115
- /**
116
- * Size of each dot relative to the cell when `renderMode === 'dots'`.
117
- * `1` fills the whole cell, `0.5` draws half-size circles. Default: `0.8`
118
- */
119
- dotSizeRatio: number;
120
- /**
121
- * Floyd-Steinberg dither strength applied to the luminance map.
122
- * `0` = no dithering, `1` = full dithering. Default: `0`
123
- */
124
- ditherStrength: number;
125
- /**
126
- * Assumed aspect ratio (width ÷ height) of a single output character.
127
- * Controls how many rows vs columns are generated — must match your rendering
128
- * environment to preserve the source image's proportions.
129
- * - `0.55` — browser monospace at `line-height: 1.09` (default)
130
- * - `0.52` — browser monospace at `line-height: 1.15`
131
- * - `0.5` — most terminal emulators
132
- * Default: `0.55`
133
- */
134
- charAspect: number;
135
- /**
136
- * Auto-stretch the luminance range before charset mapping.
137
- * When `true`, the darkest pixel in the frame maps to the first charset character
138
- * and the brightest to the last, maximising perceived detail and contrast.
139
- * Particularly useful for images with low inherent contrast or muted tones.
140
- * Default: `false`
141
- */
142
- normalize: boolean;
143
- /**
144
- * Overall intensity of the hover / cursor interaction effect.
145
- * `0` disables the effect. Default: `0`
146
- */
147
- hoverStrength: number;
148
- /**
149
- * Radius of the hover interaction zone as a fraction of the canvas size.
150
- * `0.1` = 10% of canvas width. Default: `0.2`
151
- */
152
- hoverRadius: number;
153
- /**
154
- * Which cursor interaction style to apply when `hoverStrength > 0`.
155
- * See `HoverPreset` or `HOVER_PRESETS` for ready-made configurations.
156
- * Default: `'spotlight'`
157
- */
158
- hoverEffect: HoverEffect;
159
- /**
160
- * Tint colour used by hover effects such as spotlight, glow, and colorShift.
161
- * Any CSS colour string. Default: `'#ffffff'`
162
- */
163
- hoverColor: string;
164
- /**
165
- * Shape of the hover interaction zone.
166
- * - `'circle'` — radial falloff (default)
167
- * - `'box'` — rectangular zone, text fills a block around the cursor
168
- * Default: `'circle'`
169
- */
170
- hoverShape: HoverShape;
171
- /**
172
- * Text string revealed by the `'glitchText'` hover effect.
173
- * Characters around the cursor scramble and resolve into this text.
174
- * Supports `\n` for multi-line reveals.
175
- *
176
- * Pass an **array** of strings to cycle through different words based on
177
- * the cursor's grid region — the engine picks one via a spatial hash so
178
- * each area of the canvas shows a different word.
179
- *
180
- * Default: `'ASCIIFY'`
181
- *
182
- * @example
183
- * // Single word:
184
- * options: { hoverEffect: 'glitchText', hoverText: 'HELLO' }
185
- *
186
- * // Word pool — different text at different cursor positions:
187
- * options: { hoverEffect: 'glitchText', hoverText: ['DEPLOY', 'SCALE', 'SHIP', 'BUILD'] }
188
- */
189
- hoverText: string | string[];
190
- /**
191
- * Art style preset applied at render time.
192
- * Shorthand for a specific combination of `charset`, `renderMode`, and `colorMode`.
193
- * See `ART_STYLE_PRESETS` for the full list. Default: `'classic'`
194
- */
195
- artStyle: ArtStyle;
196
- /**
197
- * Custom repeating text used when `artStyle` is `'letters'` or when you set
198
- * a custom charset. Leave empty to use the selected `charset`. Default: `''`
199
- */
200
- customText: string;
201
- /**
202
- * Chroma-key colour to remove from the source (green screen / blue screen).
203
- * Pixels whose RGB distance from this colour is within `chromaKeyTolerance`
204
- * are keyed out: their character becomes a space and alpha is set to 0,
205
- * letting the canvas background show through.
206
- *
207
- * - `true` — **smart green screen**: heuristic detection (`g > r*1.4 && g > b*1.4`)
208
- * catches every shade of green screen (lime, broadcast, chroma green) with no
209
- * config. Works on virtually all studio/streaming footage.
210
- * - `'blue-screen'` — **smart blue screen**: same heuristic for blue.
211
- * - `{ r, g, b }` or CSS colour string — custom key colour + `chromaKeyTolerance`
212
- * - `null` / `false` — disabled (default)
213
- *
214
- * @example
215
- * // Standard green screen — zero config:
216
- * options: { chromaKey: true }
217
- *
218
- * // Blue screen — zero config:
219
- * options: { chromaKey: 'blue-screen' }
220
- *
221
- * // Custom CSS colour:
222
- * options: { chromaKey: '#00b140', chromaKeyTolerance: 70 }
223
- */
224
- chromaKey: {
225
- r: number;
226
- g: number;
227
- b: number;
228
- } | string | boolean | null;
229
- /**
230
- * Euclidean RGB tolerance radius for chroma-key detection.
231
- * `0` = exact match only, `441` ≈ key out everything.
232
- * Higher values remove more pixels. Default: `60`
233
- */
234
- chromaKeyTolerance: number;
235
- /**
236
- * Extra normalized padding kept around the detected chroma-key foreground when
237
- * `asciifyVideo` auto-trims keyed video content inside `sourceCrop`.
238
- * `0` hugs the visible foreground. `0.01` keeps 1% safety padding.
239
- * Default: `0.002`
240
- */
241
- chromaKeyTrimPadding: number;
242
- /**
243
- * Minimum source-pixel luminance for chroma-key foreground auto-trim.
244
- * Raise this when faint edge noise is counted as content and prevents a
245
- * keyed subject from filling a preserved-ratio layout. Range `0–255`.
246
- * Default: `0`
247
- */
248
- chromaKeyTrimLuminanceThreshold: number;
249
- /**
250
- * How keyed video foreground trimming is applied when `chromaKey` and
251
- * `sourceCrop` are enabled.
252
- *
253
- * - `'range'` samples the video/scroll range once and keeps a stable union
254
- * crop. Best default for consistent framing.
255
- * - `'frame'` remeasures each rendered frame and expands the crop to the
256
- * render aspect. Best for scroll-scrubbed hero footage where foreground
257
- * position changes and pure contain leaves empty edges.
258
- * - `'off'` disables automatic keyed foreground trimming.
259
- *
260
- * Default: `'range'`
261
- */
262
- chromaKeyTrimMode: 'range' | 'frame' | 'off';
263
- /**
264
- * Optional source crop applied before ASCII sampling.
265
- *
266
- * Use this when the media has empty edges or a subject that should be framed
267
- * tighter without changing the destination canvas size.
268
- *
269
- * @example
270
- * // Remove 15% from the top and 15% from the bottom, preserving proportions:
271
- * options: { sourceCrop: { top: 0.15, bottom: 0.15 } }
272
- *
273
- * @example
274
- * // Keep 70% of the source, preserve proportions, and center it:
275
- * options: { sourceCrop: { height: 0.7 } }
276
- *
277
- * @example
278
- * // Use an exact source window when manual framing should override proportions:
279
- * options: { sourceCrop: { x: 0.05, y: 0.08, width: 0.9, height: 0.9, preserveAspect: false } }
280
- */
281
- sourceCrop?: SourceCrop | null;
282
- /**
283
- * Array of charset strings to cycle through over time.
284
- * The engine picks `charsetFrames[Math.floor(time * charsetFps) % length]` on each
285
- * render tick, re-mapping characters from stored cell luminance.
286
- * Pairs beautifully with `animationStyle` and `asciiBackground`.
287
- *
288
- * Use `CHARSET_SEQUENCES` for curated combinations or build your own:
289
- * @example
290
- * options: { charsetFrames: CHARSET_SEQUENCES.cosmic }
291
- * options: { charsetFrames: [CHARSETS.standard, CHARSETS.blocks, CHARSETS.circles] }
292
- */
293
- charsetFrames?: string[];
294
- /** Cycle rate for `charsetFrames` in frames-per-second. Default: `2` */
295
- charsetFps?: number;
296
- }
297
- interface AsciiCell {
298
- char: string;
299
- r: number;
300
- g: number;
301
- b: number;
302
- a: number;
303
- /** Stored dithered luminance (0–255). Present when the frame was generated by the engine. Used for dynamic charset re-selection at render time via `charsetFrames`. */
304
- lum?: number;
305
- }
306
- type AsciiFrame = AsciiCell[][];
307
- interface AsciiResult {
308
- frames: AsciiFrame[];
309
- cols: number;
310
- rows: number;
311
- fps: number;
312
- }
313
- declare const CHARSETS: {
314
- readonly standard: " .:-=+*#%@";
315
- readonly blocks: " ░▒▓█";
316
- readonly minimal: " .:+";
317
- readonly dense: " .'`^\",:;Il!i><~+_-?][}{1)(|/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$";
318
- readonly binary: "01";
319
- readonly dots: " ⠁⠃⠇⡇⣇⣧⣷⣿";
320
- readonly letters: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
321
- readonly claudeCode: " ╔╗╚╝║═╠╣╦╩╬░▒▓█│─┌┐└┘├┤┬┴┼";
322
- readonly box: " ▪◾◼■█";
323
- readonly lines: " ˗‐–—―━";
324
- readonly braille: " ⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿⡀⡁⡂⡃⡄⡅⡆⡇⣀⣁⣂⣃⣄⣅⣆⣇⣈⣉⣊⣋⣌⣍⣎⣏⣐⣑⣒⣓⣔⣕⣖⣗⣘⣙⣚⣛⣜⣝⣞⣟⣠⣡⣢⣣⣤⣥⣦⣧⣨⣩⣪⣫⣬⣭⣮⣯⣰⣱⣲⣳⣴⣵⣶⣷⣸⣹⣺⣻⣼⣽⣾⣿";
325
- readonly katakana: " ヲァィゥェォャュョッアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン";
326
- readonly musical: " ♩♪♫♬♭♮♯";
327
- readonly emoji: " ⬛🟫🟥🟧🟨🟩🟦🟪⬜";
328
- readonly circles: " .·:∘○◦°•∙";
329
- readonly shadows: " ·∘◦○◎⊙●◉";
330
- readonly starfield: " ˙·∘∗✦✧★◆●";
331
- readonly geometric: " ·△▷◇◈◆▣■█";
332
- readonly pipes: " ╶─┐└├┤┬┴┼╬▒▓█";
333
- readonly waves: " ˜∼≈〰≋∿∾∭∫";
334
- readonly shards: " ╱╲╳◤◥◣◢△▲◆◼█";
335
- readonly smoke: " ·˙⁚⁖∶∷⋮⋰⋱∴∵";
336
- /** All printable ASCII characters ordered from airy punctuation to dense symbols. */
337
- readonly ascii: " .'`^\",:;~-_+<>i!lI?/\\|()[]{}1tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$";
338
- /** Clean product UI glyphs inspired by command palettes, panes, controls, and focus rings. */
339
- readonly interface: " ·•-–—+=:;<>[]{}()⌘⌥⇧⌃↵↗↘◇◆◈□■";
340
- /** Prompt, shell, and assistant transcript glyphs for modern AI/dev surfaces. */
341
- readonly prompt: " .:;>_`/\\|{}[]()=+*#@$";
342
- /** Analytical/data-viz glyphs: sparse dots into nodes, diamonds, and dense blocks. */
343
- readonly data: " ·∙•◦○●◇◆◈▱▰▣█";
344
- /** Warm editorial/math symbols for quieter Claude-like and research-oriented pages. */
345
- readonly humanist: " ·˙,:;∴∵∷∶⁚⋮⋯∼≈≋∞";
346
- /** Dense network/mesh characters for agent maps, model graphs, and infrastructure visuals. */
347
- readonly mesh: " ·╶╴╷╵─│┌┐└┘├┤┬┴┼╬░▒▓█";
348
- };
349
- /**
350
- * Curated charset sequences for use with `charsetFrames`.
351
- * Each sequence morphs between 2–3 complementary charsets over time,
352
- * creating a living texture effect.
353
- *
354
- * @example
355
- * asciiBackground('#hero', { charsetFrames: CHARSET_SEQUENCES.cosmic })
356
- */
357
- declare const CHARSET_SEQUENCES: {
358
- /** Stars → softcircles → orbs — dreamy space feel */
359
- readonly cosmic: string[];
360
- /** Katakana → braille dots → binary — hacker rain */
361
- readonly rain: string[];
362
- /** Box pipes → Claude glyphs → classic — terminal morph */
363
- readonly terminal: string[];
364
- /** Shards → blocks → squares — shattering crystal */
365
- readonly crystal: string[];
366
- /** Wave glyphs → smoke dots → circles — fluid / organic */
367
- readonly fluid: string[];
368
- /** Dense classic → art → blocks — maximum detail pulse */
369
- readonly pulse: string[];
370
- /** Braille → shadows → smoke — ethereal / dream-like */
371
- readonly dream: string[];
372
- /** Geometric shapes → shards → starfield — sci-fi angular */
373
- readonly angular: string[];
374
- /** Interface controls → prompts → data nodes — clean assistant/product motion */
375
- readonly assistant: string[];
376
- /** Mesh → data → ASCII — alive network signal with readable texture */
377
- readonly signal: string[];
378
- /** Humanist symbols → waves → smoke — soft research/editorial motion */
379
- readonly editorial: string[];
380
- };
381
- type CharsetSequenceKey = keyof typeof CHARSET_SEQUENCES;
382
- type CharsetKey = keyof typeof CHARSETS;
383
- /**
384
- * Art Style presets — each one sets render mode, charset, color mode, etc.
385
- */
386
- declare const ART_STYLE_PRESETS: Record<ArtStyle, Partial<AsciiOptions>>;
387
- /**
388
- * Higher-level living presets for output that should feel active immediately.
389
- * They intentionally compose existing primitives so renderers and integrations
390
- * can consume them as a normal `Partial<AsciiOptions>`.
391
- */
392
- declare const LIVING_STYLE_PRESETS: {
393
- readonly agentField: {
394
- readonly charsetFrames: string[];
395
- readonly charsetFps: 1.6;
396
- readonly animationStyle: "breathe";
397
- readonly animationSpeed: 0.75;
398
- readonly ditherStrength: 0.12;
399
- readonly hoverEffect: "glow";
400
- readonly hoverStrength: 0.42;
401
- readonly hoverRadius: 0.18;
402
- readonly hoverColor: "#f4f1ea";
403
- readonly normalize: true;
404
- readonly fontSize?: number | undefined;
405
- readonly charSpacing?: number | undefined;
406
- readonly brightness?: number | undefined;
407
- readonly contrast?: number | undefined;
408
- readonly charset?: string | undefined;
409
- readonly colorMode?: ColorMode | undefined;
410
- readonly accentColor?: string | undefined;
411
- readonly invert?: boolean | "auto" | undefined;
412
- readonly renderMode?: RenderMode | undefined;
413
- readonly dotSizeRatio?: number | undefined;
414
- readonly charAspect?: number | undefined;
415
- readonly hoverShape?: HoverShape | undefined;
416
- readonly hoverText?: string | string[] | undefined;
417
- readonly artStyle?: ArtStyle | undefined;
418
- readonly customText?: string | undefined;
419
- readonly chromaKey?: string | boolean | {
420
- r: number;
421
- g: number;
422
- b: number;
423
- } | null | undefined;
424
- readonly chromaKeyTolerance?: number | undefined;
425
- readonly chromaKeyTrimPadding?: number | undefined;
426
- readonly chromaKeyTrimLuminanceThreshold?: number | undefined;
427
- readonly chromaKeyTrimMode?: "range" | "frame" | "off" | undefined;
428
- readonly sourceCrop?: SourceCrop | null;
429
- };
430
- readonly liquidSignal: {
431
- readonly charsetFrames: string[];
432
- readonly charsetFps: 2.4;
433
- readonly animationStyle: "melt";
434
- readonly animationSpeed: 0.65;
435
- readonly ditherStrength: 0.45;
436
- readonly hoverEffect: "repel";
437
- readonly hoverStrength: 0.55;
438
- readonly hoverRadius: 0.22;
439
- readonly hoverColor: "#8fd3ff";
440
- readonly normalize: true;
441
- readonly fontSize?: number | undefined;
442
- readonly charSpacing?: number | undefined;
443
- readonly brightness?: number | undefined;
444
- readonly contrast?: number | undefined;
445
- readonly charset?: string | undefined;
446
- readonly colorMode?: ColorMode | undefined;
447
- readonly accentColor?: string | undefined;
448
- readonly invert?: boolean | "auto" | undefined;
449
- readonly renderMode?: RenderMode | undefined;
450
- readonly dotSizeRatio?: number | undefined;
451
- readonly charAspect?: number | undefined;
452
- readonly hoverShape?: HoverShape | undefined;
453
- readonly hoverText?: string | string[] | undefined;
454
- readonly artStyle?: ArtStyle | undefined;
455
- readonly customText?: string | undefined;
456
- readonly chromaKey?: string | boolean | {
457
- r: number;
458
- g: number;
459
- b: number;
460
- } | null | undefined;
461
- readonly chromaKeyTolerance?: number | undefined;
462
- readonly chromaKeyTrimPadding?: number | undefined;
463
- readonly chromaKeyTrimLuminanceThreshold?: number | undefined;
464
- readonly chromaKeyTrimMode?: "range" | "frame" | "off" | undefined;
465
- readonly sourceCrop?: SourceCrop | null;
466
- };
467
- readonly cursorGravity: {
468
- readonly charsetFrames: string[];
469
- readonly charsetFps: 1.2;
470
- readonly animationStyle: "orbit";
471
- readonly animationSpeed: 0.9;
472
- readonly ditherStrength: 0.2;
473
- readonly hoverEffect: "attract";
474
- readonly hoverStrength: 0.82;
475
- readonly hoverRadius: 0.24;
476
- readonly hoverColor: "#ffffff";
477
- readonly normalize: true;
478
- readonly fontSize?: number | undefined;
479
- readonly charSpacing?: number | undefined;
480
- readonly brightness?: number | undefined;
481
- readonly contrast?: number | undefined;
482
- readonly charset?: string | undefined;
483
- readonly colorMode?: ColorMode | undefined;
484
- readonly accentColor?: string | undefined;
485
- readonly invert?: boolean | "auto" | undefined;
486
- readonly renderMode?: RenderMode | undefined;
487
- readonly dotSizeRatio?: number | undefined;
488
- readonly charAspect?: number | undefined;
489
- readonly hoverShape?: HoverShape | undefined;
490
- readonly hoverText?: string | string[] | undefined;
491
- readonly artStyle?: ArtStyle | undefined;
492
- readonly customText?: string | undefined;
493
- readonly chromaKey?: string | boolean | {
494
- r: number;
495
- g: number;
496
- b: number;
497
- } | null | undefined;
498
- readonly chromaKeyTolerance?: number | undefined;
499
- readonly chromaKeyTrimPadding?: number | undefined;
500
- readonly chromaKeyTrimLuminanceThreshold?: number | undefined;
501
- readonly chromaKeyTrimMode?: "range" | "frame" | "off" | undefined;
502
- readonly sourceCrop?: SourceCrop | null;
503
- };
504
- readonly editorialPulse: {
505
- readonly charsetFrames: string[];
506
- readonly charsetFps: 0.9;
507
- readonly animationStyle: "ripple";
508
- readonly animationSpeed: 0.55;
509
- readonly ditherStrength: 0.18;
510
- readonly hoverEffect: "spotlight";
511
- readonly hoverStrength: 0.35;
512
- readonly hoverRadius: 0.2;
513
- readonly hoverColor: "#fff8ea";
514
- readonly normalize: true;
515
- readonly fontSize?: number | undefined;
516
- readonly charSpacing?: number | undefined;
517
- readonly brightness?: number | undefined;
518
- readonly contrast?: number | undefined;
519
- readonly charset?: string | undefined;
520
- readonly colorMode?: ColorMode | undefined;
521
- readonly accentColor?: string | undefined;
522
- readonly invert?: boolean | "auto" | undefined;
523
- readonly renderMode?: RenderMode | undefined;
524
- readonly dotSizeRatio?: number | undefined;
525
- readonly charAspect?: number | undefined;
526
- readonly hoverShape?: HoverShape | undefined;
527
- readonly hoverText?: string | string[] | undefined;
528
- readonly artStyle?: ArtStyle | undefined;
529
- readonly customText?: string | undefined;
530
- readonly chromaKey?: string | boolean | {
531
- r: number;
532
- g: number;
533
- b: number;
534
- } | null | undefined;
535
- readonly chromaKeyTolerance?: number | undefined;
536
- readonly chromaKeyTrimPadding?: number | undefined;
537
- readonly chromaKeyTrimLuminanceThreshold?: number | undefined;
538
- readonly chromaKeyTrimMode?: "range" | "frame" | "off" | undefined;
539
- readonly sourceCrop?: SourceCrop | null;
540
- };
541
- readonly terminalFlow: {
542
- readonly charsetFrames: string[];
543
- readonly charsetFps: 3;
544
- readonly animationStyle: "rain";
545
- readonly animationSpeed: 1.1;
546
- readonly ditherStrength: 0.22;
547
- readonly hoverEffect: "glitchText";
548
- readonly hoverStrength: 0.65;
549
- readonly hoverRadius: 0.16;
550
- readonly hoverColor: "#d4ff00";
551
- readonly hoverText: ["BUILD", "SHIP", "RUN", "ASK", "MODEL"];
552
- readonly normalize: true;
553
- readonly fontSize?: number | undefined;
554
- readonly charSpacing?: number | undefined;
555
- readonly brightness?: number | undefined;
556
- readonly contrast?: number | undefined;
557
- readonly charset?: string | undefined;
558
- readonly colorMode?: ColorMode | undefined;
559
- readonly accentColor?: string | undefined;
560
- readonly invert?: boolean | "auto" | undefined;
561
- readonly renderMode?: RenderMode | undefined;
562
- readonly dotSizeRatio?: number | undefined;
563
- readonly charAspect?: number | undefined;
564
- readonly hoverShape?: HoverShape | undefined;
565
- readonly artStyle?: ArtStyle | undefined;
566
- readonly customText?: string | undefined;
567
- readonly chromaKey?: string | boolean | {
568
- r: number;
569
- g: number;
570
- b: number;
571
- } | null | undefined;
572
- readonly chromaKeyTolerance?: number | undefined;
573
- readonly chromaKeyTrimPadding?: number | undefined;
574
- readonly chromaKeyTrimLuminanceThreshold?: number | undefined;
575
- readonly chromaKeyTrimMode?: "range" | "frame" | "off" | undefined;
576
- readonly sourceCrop?: SourceCrop | null;
577
- };
578
- };
579
- type LivingStylePresetKey = keyof typeof LIVING_STYLE_PRESETS;
580
- declare const DEFAULT_OPTIONS: AsciiOptions;
581
- /**
582
- * Hover presets — one-click configurations for the hover system.
583
- */
584
- declare const HOVER_PRESETS: Record<HoverPreset, {
585
- label: string;
586
- options: Partial<AsciiOptions>;
587
- }>;
588
-
589
- /**
590
- * Core frame-to-canvas renderer and source-to-frame converters.
591
- */
592
-
593
- interface AsciiTextFrame {
594
- rows: string[];
595
- cols: number;
596
- rowCount: number;
597
- colors?: Uint8ClampedArray;
598
- }
599
- /** Clear shared renderer caches. Useful for long-lived editors that cycle many fonts/charsets. */
600
- declare function clearAsciifyCaches(): void;
601
- /**
602
- * Convert an image element or canvas to a single ASCII frame.
603
- */
604
- declare function imageToAsciiFrame(source: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement, options: AsciiOptions, targetWidth?: number, targetHeight?: number): {
605
- frame: AsciiFrame;
606
- cols: number;
607
- rows: number;
608
- };
609
- /**
610
- * Convert a source into pre-shaped text rows for fast monochrome/accent ASCII.
611
- *
612
- * This is the high-performance path for dense video scrubbers. It keeps the
613
- * expensive pixel sampling work, but avoids allocating one object per cell and
614
- * lets the renderer draw one string per row instead of one `fillText` per cell.
615
- */
616
- declare function imageToAsciiTextFrame(source: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement, options: AsciiOptions, targetWidth?: number, targetHeight?: number): AsciiTextFrame;
617
- declare function renderTextFrameToCanvas(ctx: CanvasRenderingContext2D, textFrame: AsciiTextFrame, options: AsciiOptions, canvasWidth: number, canvasHeight: number): void;
618
- /**
619
- * Extract frames from a video element for ASCII animation.
620
- */
621
- declare function videoToAsciiFrames(video: HTMLVideoElement, options: AsciiOptions, targetWidth: number, targetHeight: number, targetFps?: number, maxDuration?: number, onProgress?: (progress: number) => void, startTime?: number): Promise<{
622
- frames: AsciiFrame[];
623
- cols: number;
624
- rows: number;
625
- fps: number;
626
- }>;
627
- /**
628
- * Extract video frames into compact text rows for high-density monochrome/accent
629
- * animations. This mirrors videoToAsciiFrames but avoids object-per-cell frames.
630
- */
631
- declare function videoToAsciiTextFrames(video: HTMLVideoElement, options: AsciiOptions, targetWidth: number, targetHeight: number, targetFps?: number, maxDuration?: number, onProgress?: (progress: number) => void, startTime?: number): Promise<{
632
- frames: AsciiTextFrame[];
633
- cols: number;
634
- rows: number;
635
- fps: number;
636
- }>;
637
- /**
638
- * Extract frames from an animated GIF file buffer.
639
- */
640
- declare function gifToAsciiFrames(buffer: ArrayBuffer, options: AsciiOptions, targetWidth: number, targetHeight: number, onProgress?: (progress: number) => void): Promise<{
641
- frames: AsciiFrame[];
642
- cols: number;
643
- rows: number;
644
- fps: number;
645
- }>;
646
- /**
647
- * Extract animated GIF frames into compact text rows for high-density
648
- * monochrome/accent playback. Keeps the legacy object-frame extractor intact
649
- * for full-color and interactive modes.
650
- */
651
- declare function gifToAsciiTextFrames(buffer: ArrayBuffer, options: AsciiOptions, targetWidth: number, targetHeight: number, onProgress?: (progress: number) => void): Promise<{
652
- frames: AsciiTextFrame[];
653
- cols: number;
654
- rows: number;
655
- fps: number;
656
- }>;
657
- /**
658
- * Render an ASCII frame to a canvas context.
659
- * Supports both ASCII text mode and Dots mode.
660
- */
661
- declare function renderFrameToCanvas(ctx: CanvasRenderingContext2D, frame: AsciiFrame, options: AsciiOptions, canvasWidth: number, canvasHeight: number, time?: number, hoverPos?: {
662
- x: number;
663
- y: number;
664
- intensity?: number;
665
- } | null): void;
666
-
667
- /**
668
- * Simple one-call asciify API.
669
- * Wraps imageToAsciiFrame + renderFrameToCanvas behind easy-to-use helpers.
670
- */
671
-
672
- interface AsciifySimpleOptions {
673
- /** Character size in pixels. Default: 10 */
674
- fontSize?: number;
675
- /**
676
- * Art style preset — controls charset, render mode, and color mode together.
677
- * Shorthand for spreading `ART_STYLE_PRESETS[artStyle]` into options.
678
- * Default: `'classic'`
679
- */
680
- artStyle?: ArtStyle;
681
- /** Extra options to merge on top of the preset */
682
- options?: Partial<AsciiOptions>;
683
- }
684
- type ScrollTriggerInstance = {
685
- kill?: () => void;
686
- };
687
- type ScrollTriggerLike = {
688
- create: (vars: Record<string, unknown>) => ScrollTriggerInstance;
689
- };
690
- type GsapLike = {
691
- registerPlugin?: (...plugins: unknown[]) => void;
692
- ScrollTrigger?: ScrollTriggerLike;
693
- };
694
- interface VideoScrollScrubOptions {
695
- /**
696
- * Element that controls scroll progress. Accepts an HTMLElement or selector.
697
- * When used through `asciifyVideo`, defaults to `fitTo` or the canvas.
698
- */
699
- trigger?: HTMLElement | string | null;
700
- /**
701
- * GSAP instance. Pass this with ScrollTrigger for native GSAP scrub support.
702
- *
703
- * @example
704
- * asciifyVideo('/hero.mp4', canvas, {
705
- * fitTo: '#hero',
706
- * scroll: { gsap, ScrollTrigger }
707
- * });
708
- */
709
- gsap?: GsapLike;
710
- /** GSAP ScrollTrigger plugin. Optional when available as `gsap.ScrollTrigger`. */
711
- ScrollTrigger?: ScrollTriggerLike;
712
- /** GSAP start value. Native fallback ignores this and uses viewport progress. */
713
- start?: string;
714
- /** GSAP end value. Native fallback ignores this and uses viewport progress. */
715
- end?: string;
716
- /** GSAP scrub value. Default: `true`. Native fallback always scrubs. */
717
- scrub?: boolean | number;
718
- /**
719
- * Multiply scroll progress before mapping it to video time.
720
- * `2` reaches the end of the clip in half the scroll distance, `0.5` makes it
721
- * take twice as much scroll. Default: `1`.
722
- */
723
- speed?: number;
724
- /** Video time to map from. Defaults to trim start or `0`. */
725
- from?: number;
726
- /** Video time to map to. Defaults to trim end or video duration. */
727
- to?: number;
728
- /** Optional progress transform before mapping to video time. */
729
- ease?: (progress: number) => number;
730
- /** Called whenever scroll progress updates. */
731
- onUpdate?: (progress: number, video: HTMLVideoElement) => void;
732
- }
733
- type CanvasObjectFit = 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
734
- type CanvasBleed = number | string | {
735
- x?: number | string;
736
- y?: number | string;
737
- };
738
- interface AsciifyVideoOptions extends AsciifySimpleOptions {
739
- /**
740
- * Fit the canvas to a container element, maintaining the video's aspect ratio.
741
- * Accepts an HTMLElement or a CSS selector string. The canvas is resized on
742
- * load and again whenever the container resizes (via ResizeObserver).
743
- * `stop()` automatically disconnects the observer.
744
- *
745
- * @example
746
- * // Fill the hero div, re-size on window resize automatically:
747
- * asciifyVideo('/clip.mp4', canvas, { fitTo: '#hero' });
748
- */
749
- fitTo?: HTMLElement | string | null;
750
- /**
751
- * CSS object-fit behavior for the visible canvas when `fitTo` or explicit
752
- * `width`/`height` is used. This controls visual framing only; ASCII sampling
753
- * resolution remains independent. When `options.sourceCrop` is present, the
754
- * engine sizes from the resolved crop aspect to avoid stretch.
755
- *
756
- * Use `'cover'` for full-bleed heroes and `'contain'` for previews.
757
- * Default: `'contain'`.
758
- */
759
- objectFit?: CanvasObjectFit;
760
- /**
761
- * CSS object-position for the visible canvas, e.g. `'center bottom'` or
762
- * `'50% 62%'`. Useful with `objectFit: 'cover'`.
763
- */
764
- objectPosition?: string;
765
- /**
766
- * Visual scale applied with the CSS individual `scale` property. This is a
767
- * layout-safe way to overfill a container without changing source proportions
768
- * or overriding an app's `transform` styles.
769
- */
770
- scale?: number;
771
- /**
772
- * Visible CSS width for the canvas. Numbers are pixels; strings are used as
773
- * provided (`'100%'`, `'100vw'`, `min(100vw, 1200px)`, etc.).
774
- */
775
- width?: number | string;
776
- /**
777
- * Visible CSS height for the canvas. Numbers are pixels; strings are used as
778
- * provided.
779
- */
780
- height?: number | string;
781
- /**
782
- * Extra visible overfill added around the fitted canvas box before
783
- * object-fit sizing. Useful for full-bleed ASCII heroes where glyph side
784
- * bearings or character-cell quantization can leave a small edge gap even
785
- * when the source media and canvas are full width.
786
- *
787
- * Numbers are pixels. Strings support `%`, `px`, `vw`, and `vh`. Pass an
788
- * object to control axes independently, e.g. `{ x: '2vw', y: 0 }`.
789
- */
790
- bleed?: CanvasBleed;
791
- /**
792
- * Pre-extract all video frames into memory before starting playback.
793
- * Useful for short clips where you need frame-perfect control.
794
- *
795
- * Default: `false` — streams live directly from the playing video (instant
796
- * start, constant memory, unlimited duration).
797
- *
798
- * ⚠️ Memory-intensive. Capped at 10 s / 300 frames.
799
- */
800
- preExtract?: boolean;
801
- /**
802
- * Target render FPS.
803
- * - In pre-extracted mode, this controls how many frames are decoded into memory.
804
- * - In live mode, this throttles expensive ASCII frame rendering while the
805
- * backing video continues decoding normally.
806
- *
807
- * Lower values use less CPU/memory and make scroll scrubbing cheaper.
808
- * Defaults to `18` for pre-extracted scroll scrub and unthrottled rendering
809
- * for normal live playback.
810
- */
811
- fps?: number;
812
- /**
813
- * Maximum long-edge render dimension for video frame extraction.
814
- * Raise this for full-width or 4K heroes so the canvas is not upscaled by CSS.
815
- * Default: `2048`.
816
- */
817
- maxRenderDimension?: number;
818
- /**
819
- * Trim the video to a specific time range (in seconds).
820
- * - `start` — seek to this time before playback begins. Default: `0`
821
- * - `end` — loop back to `start` when this time is reached.
822
- * In `preExtract` mode, only frames up to `end` are extracted.
823
- *
824
- * @example
825
- * // Play only seconds 2–8, looping:
826
- * asciifyVideo('/clip.mp4', canvas, { trim: { start: 2, end: 8 } });
827
- */
828
- trim?: {
829
- start?: number;
830
- end?: number;
831
- };
832
- /**
833
- * Sync video time to scroll progress.
834
- *
835
- * - `true` uses native scroll scrubbing with `fitTo`/canvas as the trigger.
836
- * - Passing `gsap` + `ScrollTrigger` uses GSAP ScrollTrigger.
837
- *
838
- * @example
839
- * await asciifyVideo('/hero.mp4', canvas, {
840
- * fitTo: '#hero',
841
- * scroll: true
842
- * });
843
- *
844
- * @example
845
- * await asciifyVideo('/hero.mp4', canvas, {
846
- * fitTo: '#hero',
847
- * scroll: { gsap, ScrollTrigger, start: 'top bottom', end: 'bottom top', scrub: 1 }
848
- * });
849
- */
850
- scroll?: boolean | VideoScrollScrubOptions;
851
- /**
852
- * Called once when the video metadata is loaded and playback has started.
853
- * Receives the backing video element.
854
- */
855
- onReady?: (video: HTMLVideoElement) => void;
856
- /**
857
- * Maximum number of decoded text frames kept in memory for live scroll scrub.
858
- * The cache is nearest-frame and bounded; lower values reduce memory for long
859
- * clips while preserving smooth scrubbing around the current scroll position.
860
- * Default: `90`.
861
- */
862
- maxCachedFrames?: number;
863
- /** Called after every rendered frame. */
864
- onFrame?: () => void;
865
- }
866
- /** @deprecated Use {@link AsciifyVideoOptions} */
867
- type AsciifyLiveVideoOptions = AsciifyVideoOptions;
868
- /**
869
- * Sync an HTMLVideoElement's currentTime to scroll progress.
870
- *
871
- * If `gsap` and `ScrollTrigger` are supplied, the helper uses GSAP. Otherwise
872
- * it falls back to a tiny native scroll listener. Returns a cleanup function.
873
- */
874
- declare function createVideoScrollScrub(video: HTMLVideoElement, opts?: VideoScrollScrubOptions): () => void;
875
- interface CanvasRenderSizeInput {
876
- sourceWidth: number;
877
- sourceHeight: number;
878
- cssWidth?: number;
879
- cssHeight?: number;
880
- /** Accepted for callers that pass complete display context; DPR is applied separately by the canvas backing buffer. */
881
- dpr?: number;
882
- maxRenderDimension?: number;
883
- }
884
- declare function computeCanvasRenderSize({ sourceWidth, sourceHeight, cssWidth, cssHeight, maxRenderDimension, }: CanvasRenderSizeInput): {
885
- renderW: number;
886
- renderH: number;
887
- };
888
- /**
889
- * Convert an image/video/canvas element to ASCII art and render it onto a canvas.
890
- *
891
- * When hover options are active (`hoverStrength > 0` in `options`), the engine
892
- * automatically sets up mouse tracking and a `requestAnimationFrame` loop so
893
- * the hover effect works out of the box. In that case, a `stop()` function is
894
- * returned to tear down the loop and listeners.
895
- *
896
- * @example
897
- * // Static (no hover):
898
- * await asciify('/photo.jpg', canvas);
899
- *
900
- * // With hover — returns a cleanup handle:
901
- * const stop = await asciify('/photo.jpg', canvas, {
902
- * options: { hoverEffect: 'glitchText', hoverStrength: 0.8, hoverText: 'HI' }
903
- * });
904
- * // later: stop?.();
905
- */
906
- declare function asciify(source: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | string, canvas: HTMLCanvasElement, { fontSize, artStyle, options }?: AsciifySimpleOptions): Promise<(() => void) | void>;
907
- /**
908
- * Fetch a GIF, convert it to ASCII, and start an animation loop on a canvas.
909
- * Returns a `stop()` function that cancels the loop.
910
- *
911
- * @example
912
- * const stop = await asciifyGif('animation.gif', canvas);
913
- * // later: stop();
914
- */
915
- declare function asciifyGif(source: string | ArrayBuffer, canvas: HTMLCanvasElement, { fontSize, artStyle, options }?: AsciifySimpleOptions): Promise<() => void>;
916
- /**
917
- * Render a video as ASCII art on a canvas. Defaults to live streaming —
918
- * instant start, constant memory, unlimited duration.
919
- *
920
- * Pass `{ preExtract: true }` to pre-decode all frames before playback starts
921
- * (useful for short clips that need frame-perfect looping).
922
- *
923
- * Pass `{ fitTo: '#container' }` to automatically size and re-size the canvas
924
- * to fill a container element, maintaining the video's aspect ratio.
925
- *
926
- * Returns a `stop()` function that cancels the loop and cleans up.
927
- *
928
- * ⚠️ Never set the backing `<video>` to `display: none` — browsers skip GPU
929
- * frame decoding for hidden elements. When given a URL string, this function
930
- * handles that automatically.
931
- *
932
- * @example
933
- * // Minimal
934
- * const stop = await asciifyVideo('/clip.mp4', canvas);
935
- *
936
- * // Fit to container, re-size on window resize:
937
- * const stop = await asciifyVideo('/clip.mp4', canvas, { fitTo: '#hero' });
938
- *
939
- * // Pre-extract frames (old behavior):
940
- * const stop = await asciifyVideo('/clip.mp4', canvas, { preExtract: true });
941
- */
942
- declare function asciifyVideo(source: HTMLVideoElement | string, canvas: HTMLCanvasElement, { fontSize, artStyle, options, fitTo, objectFit, objectPosition, scale, width, height, bleed, preExtract, fps, maxRenderDimension, trim, scroll, maxCachedFrames, onReady, onFrame, }?: AsciifyVideoOptions): Promise<() => void>;
943
- /**
944
- * @deprecated Use {@link asciifyVideo} instead — it now defaults to live streaming
945
- * and accepts the same options including `fitTo` and `preExtract`.
946
- */
947
- declare function asciifyLiveVideo(source: HTMLVideoElement | string, canvas: HTMLCanvasElement, opts?: AsciifyVideoOptions): Promise<() => void>;
948
-
949
- interface WaveBackgroundOptions {
950
- /** Font size in CSS pixels (default: 13) */
951
- fontSize?: number;
952
- /** Character aspect ratio width/height (default: 0.62) */
953
- charAspect?: number;
954
- /** Line height multiplier (default: 1.4) */
955
- lineHeightRatio?: number;
956
- /** Character set from dark→bright (default: ' .:-=+*#%@') */
957
- chars?: string;
958
- /** Base colour — use '{a}' as alpha placeholder */
959
- baseColor?: string;
960
- /** Accent colour applied near the cursor and on wave peaks (default: '#d4ff00') */
961
- accentColor?: string;
962
- /** Accent threshold: normalised intensity above which accent kicks in (default: 0.52) */
963
- accentThreshold?: number;
964
- /** How strongly the mouse influences local intensity (default: 0.55) */
965
- mouseInfluence?: number;
966
- /** Radial falloff for mouse influence (default: 2.8) */
967
- mouseFalloff?: number;
968
- /** Base wave animation speed (default: 1) */
969
- speed?: number;
970
- /** Enable vortex swirl effect around cursor (default: true) */
971
- vortex?: boolean;
972
- /** Enable sparkle / pop flicker (default: true) */
973
- sparkles?: boolean;
974
- /** Enable a slow global breathe pulse (default: true) */
975
- breathe?: boolean;
976
- /** Light mode: swap fill colours to dark-on-light (default: false) */
977
- lightMode?: boolean;
978
- }
979
- declare function renderWaveBackground(ctx: CanvasRenderingContext2D, width: number, height: number, time: number, mousePos?: {
980
- x: number;
981
- y: number;
982
- }, options?: WaveBackgroundOptions): void;
983
-
984
- interface RainBackgroundOptions {
985
- fontSize?: number;
986
- /** Characters drawn in columns */
987
- chars?: string;
988
- /** Head / accent colour (default: '#d4ff00') */
989
- accentColor?: string;
990
- /** Custom character colour */
991
- color?: string;
992
- /** Global speed multiplier (default: 1) */
993
- speed?: number;
994
- /** Fraction of columns active at once 0-1 (default: 0.55) */
995
- density?: number;
996
- /** Number of cells in the fading tail (default: 14) */
997
- tailLength?: number;
998
- /** Light mode (default: false) */
999
- lightMode?: boolean;
1000
- }
1001
- declare function renderRainBackground(ctx: CanvasRenderingContext2D, width: number, height: number, time: number, options?: RainBackgroundOptions): void;
1002
-
1003
- interface StarsBackgroundOptions {
1004
- fontSize?: number;
1005
- /** Characters used as stars */
1006
- chars?: string;
1007
- /** Accent/trail colour for fast near-edge stars (default: '#d4ff00') */
1008
- accentColor?: string;
1009
- /** Custom base colour */
1010
- color?: string;
1011
- /** Global speed multiplier (default: 1) */
1012
- speed?: number;
1013
- /** Number of star particles (default: 180) */
1014
- count?: number;
1015
- /** Light mode (default: false) */
1016
- lightMode?: boolean;
1017
- }
1018
- declare function renderStarsBackground(ctx: CanvasRenderingContext2D, width: number, height: number, time: number, mousePos?: {
1019
- x: number;
1020
- y: number;
1021
- }, options?: StarsBackgroundOptions): void;
1022
-
1023
- interface PulseBackgroundOptions {
1024
- fontSize?: number;
1025
- /** Characters to tile (default: '. · ○ ◎ ●') */
1026
- chars?: string;
1027
- /** Ring peak colour (default: '#00ffcc') */
1028
- accentColor?: string;
1029
- /** Custom base colour */
1030
- color?: string;
1031
- /** Number of simultaneous rings (default: 5) */
1032
- rings?: number;
1033
- /** Animation speed (default: 1) */
1034
- speed?: number;
1035
- /** Ring edge sharpness 1–10 (default: 4) */
1036
- sharpness?: number;
1037
- /** Light mode (default: false) */
1038
- lightMode?: boolean;
1039
- }
1040
- declare function renderPulseBackground(ctx: CanvasRenderingContext2D, width: number, height: number, time: number, mousePos?: {
1041
- x: number;
1042
- y: number;
1043
- }, options?: PulseBackgroundOptions): void;
1044
-
1045
- interface NoiseBackgroundOptions {
1046
- /** Font size in CSS pixels (default: 14). */
1047
- fontSize?: number;
1048
- /** Character ramp dark → bright (default: ' .·:;=+*#%@░▒▓'). */
1049
- chars?: string;
1050
- /** Accent colour on intensity peaks (default: '#d4ff00'). */
1051
- accentColor?: string;
1052
- /** Custom base character colour (any CSS colour string). */
1053
- color?: string;
1054
- /** Number of noise octaves for FBM detail (default: 4, max: 6). */
1055
- octaves?: number;
1056
- /** Drift / scroll speed (default: 1). */
1057
- speed?: number;
1058
- /** Noise scale — lower = larger blobs (default: 1). */
1059
- scale?: number;
1060
- /** Accent threshold 0-1 (default: 0.78). */
1061
- accentThreshold?: number;
1062
- /** Mouse warp radius 0-1 (default: 0.3). */
1063
- mouseWarp?: number;
1064
- /** Light mode (default: false). */
1065
- lightMode?: boolean;
1066
- }
1067
- declare function renderNoiseBackground(ctx: CanvasRenderingContext2D, width: number, height: number, time: number, mousePos?: {
1068
- x: number;
1069
- y: number;
1070
- }, options?: NoiseBackgroundOptions): void;
1071
-
1072
- interface GridBackgroundOptions {
1073
- /** Font size in CSS pixels (default: 12). */
1074
- fontSize?: number;
1075
- /** Character set (default: '·-=+|/'). */
1076
- chars?: string;
1077
- /** Accent / scan-band colour (default: '#d4ff00'). */
1078
- accentColor?: string;
1079
- /** Custom base character colour (any CSS colour string). */
1080
- color?: string;
1081
- /** Number of scan bands visible at once (default: 3). */
1082
- bands?: number;
1083
- /** Band travel speed (default: 1). */
1084
- speed?: number;
1085
- /** Band width as fraction of canvas height (default: 0.12). */
1086
- bandWidth?: number;
1087
- /** Enable cursor disruption glitch zone (default: true). */
1088
- glitch?: boolean;
1089
- /** Light mode (default: false). */
1090
- lightMode?: boolean;
1091
- }
1092
- declare function renderGridBackground(ctx: CanvasRenderingContext2D, width: number, height: number, time: number, mousePos?: {
1093
- x: number;
1094
- y: number;
1095
- }, options?: GridBackgroundOptions): void;
1096
-
1097
- interface AuroraBackgroundOptions {
1098
- /** Character grid density. Default 14. */
1099
- fontSize?: number;
1100
- /** Character ramp from sparse to dense. */
1101
- chars?: string;
1102
- /** Base character color. Default theme-aware white/black. */
1103
- color?: string;
1104
- /** Accent color for intensity peaks. Default '#d4ff00'. */
1105
- accentColor?: string;
1106
- /** Animation speed multiplier. Default 1. */
1107
- speed?: number;
1108
- /** Number of wave layers stacked. More = richer interference. Default 5. */
1109
- layers?: number;
1110
- /** Wave spread/softness — higher = broader, more diffuse bands. Default 1.2. */
1111
- softness?: number;
1112
- /** Mouse distortion radius (0–1). Elegant ripple that follows the cursor. Default 0.2. */
1113
- mouseRipple?: number;
1114
- /** Force light mode (dark chars on light bg). Default false. */
1115
- lightMode?: boolean;
1116
- }
1117
- declare function renderAuroraBackground(ctx: CanvasRenderingContext2D, width: number, height: number, time: number, mousePos?: {
1118
- x: number;
1119
- y: number;
1120
- }, options?: AuroraBackgroundOptions): void;
1121
-
1122
- interface SilkBackgroundOptions {
1123
- /** Character grid density. Default 13. */
1124
- fontSize?: number;
1125
- /** Base character color. Default theme-aware white/black. */
1126
- color?: string;
1127
- /** Accent color for intensity peaks. Default '#d4ff00'. */
1128
- accentColor?: string;
1129
- /** Animation speed multiplier. Default 0.4 (intentionally slow). */
1130
- speed?: number;
1131
- /** Number of flow-field layers. More = richer ribbons. Default 4. */
1132
- layers?: number;
1133
- /** Flow turbulence (0–2). Higher = more folded, tangled ribbons. Default 0.8. */
1134
- turbulence?: number;
1135
- /** Force light mode. Default false. */
1136
- lightMode?: boolean;
1137
- }
1138
- declare function renderSilkBackground(ctx: CanvasRenderingContext2D, width: number, height: number, time: number, options?: SilkBackgroundOptions): void;
1139
-
1140
- interface VoidBackgroundOptions {
1141
- /** Character grid density. Default 13. */
1142
- fontSize?: number;
1143
- /** Character ramp. Default space-to-dense. */
1144
- chars?: string;
1145
- /** Base character color. Default theme-aware. */
1146
- color?: string;
1147
- /** Accent color for the inner singularity ring. Default '#d4ff00'. */
1148
- accentColor?: string;
1149
- /** Animation speed multiplier. Default 1. */
1150
- speed?: number;
1151
- /** Gravity well radius (fraction of canvas width). Default 0.38. */
1152
- radius?: number;
1153
- /** Spiral tightness — higher = more rotation per unit distance. Default 3. */
1154
- swirl?: number;
1155
- /** Force light mode. Default false. */
1156
- lightMode?: boolean;
1157
- }
1158
- declare function renderVoidBackground(ctx: CanvasRenderingContext2D, width: number, height: number, time: number, mousePos?: {
1159
- x: number;
1160
- y: number;
1161
- }, options?: VoidBackgroundOptions): void;
1162
-
1163
- interface MorphBackgroundOptions {
1164
- /** Character grid density. Default 14. */
1165
- fontSize?: number;
1166
- /** Character ramp. Default clean gradient. */
1167
- chars?: string;
1168
- /** Base character color. Default theme-aware. */
1169
- color?: string;
1170
- /** Accent color for intensity peaks. Default '#d4ff00'. */
1171
- accentColor?: string;
1172
- /** Animation speed multiplier. Default 0.5 (intentionally slow). */
1173
- speed?: number;
1174
- /** How many frequency harmonics per cell. More = richer shimmer. Default 3. */
1175
- harmonics?: number;
1176
- /** Force light mode. Default false. */
1177
- lightMode?: boolean;
1178
- }
1179
- declare function renderMorphBackground(ctx: CanvasRenderingContext2D, width: number, height: number, time: number, options?: MorphBackgroundOptions): void;
1180
-
1181
- interface FireBackgroundOptions {
1182
- /** Font size in CSS pixels (default: 13) */
1183
- fontSize?: number;
1184
- /** Characters mapped from cool→hot (default: ' .,:;i+xX#&@') */
1185
- chars?: string;
1186
- /** Base flame colour (default: '#ff4500') */
1187
- color?: string;
1188
- /** Secondary hot-tip colour (default: '#ffe066') */
1189
- hotColor?: string;
1190
- /** Flame intensity 0–1 (default: 0.85) */
1191
- intensity?: number;
1192
- /** Horizontal wind force -1..1 (default: 0) */
1193
- wind?: number;
1194
- /** Global speed multiplier (default: 1) */
1195
- speed?: number;
1196
- /** Light mode: invert text colours (default: false) */
1197
- lightMode?: boolean;
1198
- }
1199
- declare function renderFireBackground(ctx: CanvasRenderingContext2D, width: number, height: number, time: number, options?: FireBackgroundOptions): void;
1200
-
1201
- interface DnaBackgroundOptions {
1202
- /** Font size in CSS pixels (default: 13) */
1203
- fontSize?: number;
1204
- /** Characters for strand nodes (default: 'ATCG') */
1205
- baseChars?: string;
1206
- /** Characters for the connectors between strands (default: '-=≡') */
1207
- bridgeChars?: string;
1208
- /** Primary strand colour (default: '#00e5ff') */
1209
- color?: string;
1210
- /** Secondary strand colour (default: '#ff4081') */
1211
- color2?: string;
1212
- /** Bridge / connector colour (default: '#88ffcc') */
1213
- bridgeColor?: string;
1214
- /** Speed multiplier (default: 1) */
1215
- speed?: number;
1216
- /** Number of helix columns (default: auto, ~1 per 80px) */
1217
- helixCount?: number;
1218
- /** Light mode (default: false) */
1219
- lightMode?: boolean;
1220
- }
1221
- declare function renderDnaBackground(ctx: CanvasRenderingContext2D, width: number, height: number, time: number, options?: DnaBackgroundOptions): void;
1222
-
1223
- interface TerrainBackgroundOptions {
1224
- /** Font size in CSS pixels (default: 13) */
1225
- fontSize?: number;
1226
- /** Characters for terrain density (default: ' .,:;+*#@') */
1227
- chars?: string;
1228
- /** Foreground ground colour (default: '#4caf50') */
1229
- color?: string;
1230
- /** Sky / star colour (default: '#1a237e') */
1231
- skyColor?: string;
1232
- /** Peak / snow-cap colour (default: '#e0e0e0') */
1233
- peakColor?: string;
1234
- /** Horizontal scroll speed (default: 1) */
1235
- speed?: number;
1236
- /** Terrain roughness 0.1–1 (default: 0.55) */
1237
- roughness?: number;
1238
- /** Mountain height fraction 0–1 (default: 0.55) */
1239
- heightScale?: number;
1240
- /** Show faint background stars (default: true) */
1241
- stars?: boolean;
1242
- /** Light mode (default: false) */
1243
- lightMode?: boolean;
1244
- }
1245
- declare function renderTerrainBackground(ctx: CanvasRenderingContext2D, width: number, height: number, time: number, options?: TerrainBackgroundOptions): void;
1246
-
1247
- interface CircuitBackgroundOptions {
1248
- /** Font size in CSS pixels (default: 13) */
1249
- fontSize?: number;
1250
- /** Trace characters (default: '─│┌┐└┘├┤┬┴┼') */
1251
- chars?: string;
1252
- /** Trace colour (default: '#00ff88') */
1253
- color?: string;
1254
- /** Signal pulse colour (default: '#ffffff') */
1255
- pulseColor?: string;
1256
- /** Fraction of cells that have a trace (default: 0.38) */
1257
- density?: number;
1258
- /** Signal pulse speed (default: 1) */
1259
- speed?: number;
1260
- /** Light mode (default: false) */
1261
- lightMode?: boolean;
1262
- }
1263
- declare function renderCircuitBackground(ctx: CanvasRenderingContext2D, width: number, height: number, time: number, options?: CircuitBackgroundOptions): void;
1264
-
1265
- /**
1266
- * ASCII Background — public entry point for the backgrounds sub-system.
1267
- *
1268
- * Exports:
1269
- * - All 10 render functions
1270
- * - All 10 option interfaces
1271
- * - `AsciiBackgroundOptions` — combined union type + mount options
1272
- * - `asciiBackground()` — the drop-in mount helper
1273
- * - `mountWaveBackground` / `MountWaveOptions` — deprecated aliases
1274
- */
1275
-
1276
- /**
1277
- * Combined options for `asciiBackground()`. Extends all 10 background option
1278
- * interfaces so every background's options can be passed through one object.
1279
- */
1280
- interface AsciiBackgroundOptions extends WaveBackgroundOptions, RainBackgroundOptions, StarsBackgroundOptions, PulseBackgroundOptions, NoiseBackgroundOptions, GridBackgroundOptions, AuroraBackgroundOptions, SilkBackgroundOptions, VoidBackgroundOptions, MorphBackgroundOptions, FireBackgroundOptions, DnaBackgroundOptions, TerrainBackgroundOptions, CircuitBackgroundOptions {
1281
- /**
1282
- * Which background to render (default: 'wave').
1283
- * - 'wave' — interactive ASCII field with vortex, sparkles, breathe
1284
- * - 'rain' — digital column rain (Matrix-style falling characters)
1285
- * - 'stars' — 3D star-warp / hyperspace chars fly toward the viewer
1286
- * - 'pulse' — concentric ASCII ripples radiating from the mouse
1287
- * - 'noise' — slow-drifting organic fractal noise field
1288
- * - 'grid' — CRT-style horizontal scan bands with cursor glitch zone
1289
- * - 'aurora' — premium slow-drifting light bands
1290
- * - 'silk' — smooth directional flow-field ribbons
1291
- * - 'void' — gravitational singularity follows the cursor
1292
- * - 'morph' — per-cell multi-frequency shimmer
1293
- * - 'fire' — upward cellular-automata flame simulation
1294
- * - 'dna' — double-helix strand scrolling with base-pair chars
1295
- * - 'terrain' — scrolling ASCII side-scroll heightmap landscape
1296
- * - 'circuit' — procedural PCB traces with traveling signal pulses
1297
- */
1298
- type?: 'wave' | 'rain' | 'stars' | 'pulse' | 'noise' | 'grid' | 'aurora' | 'silk' | 'void' | 'morph' | 'fire' | 'dna' | 'terrain' | 'circuit';
1299
- /** CSS opacity applied to the canvas element (default: 0.2) */
1300
- opacity?: number;
1301
- /** Extra CSS class names added to the injected canvas */
1302
- className?: string;
1303
- /** z-index of the canvas (default: 0) */
1304
- zIndex?: number;
1305
- /**
1306
- * Colour scheme handling (default: 'auto').
1307
- * - 'auto' — follows system prefers-color-scheme and updates live
1308
- * - 'dark' — always render bright chars on dark background
1309
- * - 'light' — always render dark chars on light background
1310
- */
1311
- colorScheme?: 'auto' | 'light' | 'dark';
1312
- /**
1313
- * Custom character colour. Accepts any CSS colour string: hex, rgb(), hsl().
1314
- * Overrides the default white/black for ASCII chars.
1315
- * @example '#6b8700'
1316
- */
1317
- color?: string;
1318
- }
1319
- /**
1320
- * All supported background type identifiers — single source of truth for
1321
- * counts, type-safe option values, and documentation.
1322
- */
1323
- declare const BACKGROUND_TYPES: readonly ["wave", "rain", "stars", "pulse", "noise", "grid", "aurora", "silk", "void", "morph", "fire", "dna", "terrain", "circuit"];
1324
- type BackgroundType = typeof BACKGROUND_TYPES[number];
1325
- /**
1326
- * Drop-in helper that mounts an interactive ASCII background onto any element.
1327
- * Injects a canvas, wires DPR resize, mouse tracking, and the RAF loop.
1328
- * Auto-detects light/dark mode and stays in sync if the system theme changes.
1329
- *
1330
- * Returns a `destroy()` function to clean everything up.
1331
- *
1332
- * @example
1333
- * ```ts
1334
- * // 1 line:
1335
- * const { destroy } = asciiBackground('#hero', { opacity: 0.2 });
1336
- *
1337
- * // React — return destroy as cleanup:
1338
- * useEffect(() => asciiBackground(ref.current).destroy, []);
1339
- * ```
1340
- */
1341
- declare function asciiBackground(target: string | HTMLElement | null, options?: AsciiBackgroundOptions): {
1342
- destroy: () => void;
1343
- };
1344
- /** @deprecated Use `asciiBackground` instead. */
1345
- declare const mountWaveBackground: typeof asciiBackground;
1346
- /** @deprecated Use `AsciiBackgroundOptions` instead. */
1347
- type MountWaveOptions = AsciiBackgroundOptions;
1348
-
1349
- /**
1350
- * asciiText — pure string output (no canvas required).
1351
- * Converts an image/video/canvas element to a plain-text ASCII string
1352
- * suitable for server-side rendering, clipboard export, or terminal output.
1353
- */
1354
-
1355
- /**
1356
- * Convert any image/video/canvas source to a plain multi-line string of ASCII.
1357
- *
1358
- * @example
1359
- * ```ts
1360
- * const text = asciiText(imgEl, { fontSize: 8, colorMode: 'grayscale' });
1361
- * console.log(text);
1362
- * ```
1363
- *
1364
- * @example SSR (Node/JSDOM)
1365
- * ```ts
1366
- * const { createCanvas, loadImage } = require('@napi-rs/canvas');
1367
- * const img = await loadImage('./photo.jpg');
1368
- * const canvas = createCanvas(img.width, img.height);
1369
- * const ctx = canvas.getContext('2d');
1370
- * ctx.drawImage(img, 0, 0);
1371
- * const text = asciiText(canvas as unknown as HTMLCanvasElement, { fontSize: 10 });
1372
- * ```
1373
- */
1374
- declare function asciiText(source: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement, options?: Partial<AsciiOptions>, targetWidth?: number, targetHeight?: number): string;
1375
- /**
1376
- * Convert any source to an ASCII string with ANSI 256-colour escape codes.
1377
- * Works in any terminal that supports ANSI colours.
1378
- *
1379
- * @example
1380
- * ```ts
1381
- * process.stdout.write(asciiTextAnsi(imgEl, { fontSize: 8 }));
1382
- * ```
1383
- */
1384
- declare function asciiTextAnsi(source: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement, options?: Partial<AsciiOptions>, targetWidth?: number, targetHeight?: number): string;
1385
-
1386
- /**
1387
- * text-frame.ts — Build and render ASCII frames from tiling text patterns.
1388
- *
1389
- * Enables interactive text backgrounds with the full hover-effect system
1390
- * (spotlight, magnify, repel, glow, colorShift, …) without needing an image
1391
- * source.
1392
- *
1393
- * @example — basic usage
1394
- * ```ts
1395
- * import { renderTextBackground } from 'asciify-engine';
1396
- *
1397
- * function tick(ctx, w, h, mousePos) {
1398
- * renderTextBackground(ctx, w, h, 'asciify·engine·v1·', {
1399
- * hoverEffect: 'spotlight',
1400
- * hoverColor: '#d4ff00',
1401
- * }, mousePos);
1402
- * requestAnimationFrame(() => tick(ctx, w, h, mousePos));
1403
- * }
1404
- * ```
1405
- *
1406
- * @example — build the frame yourself and pass it to renderFrameToCanvas
1407
- * ```ts
1408
- * import { buildTextFrame, renderFrameToCanvas, DEFAULT_OPTIONS } from 'asciify-engine';
1409
- *
1410
- * const frame = buildTextFrame('hello world · ', 80, 24);
1411
- * renderFrameToCanvas(ctx, frame, {
1412
- * ...DEFAULT_OPTIONS,
1413
- * hoverEffect: 'repel',
1414
- * hoverStrength: 0.9,
1415
- * hoverColor: '#a0e8ff',
1416
- * }, width, height, 0, mousePos);
1417
- * ```
1418
- */
1419
-
1420
- interface TextBackgroundOptions {
1421
- /**
1422
- * Character size in pixels.
1423
- * Controls the grid density: smaller → more cells, finer text.
1424
- * @default 10
1425
- */
1426
- fontSize?: number;
1427
- /**
1428
- * Line-height multiplier applied on top of `fontSize` to derive row height.
1429
- * Matches the default monospace aspect ratio used by the renderer.
1430
- * @default 1.6
1431
- */
1432
- lineHeight?: number;
1433
- /**
1434
- * Base colour for the text cells (inactive state).
1435
- * Accepts any CSS hex or rgb string.
1436
- * @default '#505050'
1437
- */
1438
- color?: string;
1439
- /**
1440
- * Base alpha for the text cells, 0–255.
1441
- * @default 100
1442
- */
1443
- opacity?: number;
1444
- /**
1445
- * Which hover effect to activate when `hoverPos` is supplied.
1446
- * @default 'spotlight'
1447
- */
1448
- hoverEffect?: HoverEffect;
1449
- /**
1450
- * Intensity of the hover distortion / glow, 0–1.
1451
- * @default 0.85
1452
- */
1453
- hoverStrength?: number;
1454
- /**
1455
- * Normalised radius of the hover influence zone, 0–1.
1456
- * @default 0.18
1457
- */
1458
- hoverRadius?: number;
1459
- /**
1460
- * Accent colour applied by the hover effect.
1461
- * @default '#d4ff00'
1462
- */
1463
- hoverColor?: string;
1464
- }
1465
- /**
1466
- * Build an `AsciiFrame` filled with a tiling text pattern.
1467
- *
1468
- * The `text` string is repeated (wrapping at column boundaries) across every
1469
- * cell of the `cols × rows` grid. Each cell carries the supplied base colour
1470
- * and opacity as `{r, g, b, a}` values.
1471
- *
1472
- * The returned frame can be passed directly to `renderFrameToCanvas` with any
1473
- * `AsciiOptions` including hover effects.
1474
- *
1475
- * @param text - Pattern string to tile across the grid (e.g. `'hello · '`)
1476
- * @param cols - Number of character columns
1477
- * @param rows - Number of character rows
1478
- * @param color - Base RGB colour string for the cells (default: `'#505050'`)
1479
- * @param opacity - Base alpha 0–255 (default: `100`)
1480
- */
1481
- declare function buildTextFrame(text: string, cols: number, rows: number, color?: string, opacity?: number): AsciiFrame;
1482
- /**
1483
- * All-in-one: build a tiling text grid and render it to a canvas with the
1484
- * full hover-effect system (spotlight, magnify, repel, glow, colorShift, …).
1485
- *
1486
- * Call this inside a `requestAnimationFrame` loop, passing updated `hoverPos`
1487
- * each frame to get smooth interactive effects.
1488
- *
1489
- * @param ctx - 2D rendering context of the target canvas
1490
- * @param width - Canvas logical width in pixels
1491
- * @param height - Canvas logical height in pixels
1492
- * @param text - Pattern string to tile (e.g. `'asciify·engine·v1·'`)
1493
- * @param options - {@link TextBackgroundOptions}
1494
- * @param hoverPos - Normalised mouse position `{x, y}` in 0–1 range,
1495
- * optionally with an `intensity` multiplier (0–1).
1496
- * Pass `null` or omit to render without hover.
1497
- */
1498
- declare function renderTextBackground(ctx: CanvasRenderingContext2D, width: number, height: number, text: string, options?: TextBackgroundOptions, hoverPos?: {
1499
- x: number;
1500
- y: number;
1501
- intensity?: number;
1502
- } | null): void;
1503
-
1504
- interface SnapshotOptions {
1505
- /**
1506
- * Image format.
1507
- * - 'png' — lossless (default)
1508
- * - 'jpeg' — smaller, no transparency
1509
- * - 'webp' — best compression with transparency
1510
- */
1511
- format?: 'png' | 'jpeg' | 'webp';
1512
- /** 0–1 quality for jpeg/webp. Default: 0.92 */
1513
- quality?: number;
1514
- /**
1515
- * Scale factor applied before capture. Default: 1.
1516
- * Use 2 for a high-resolution export at 2× the canvas size.
1517
- */
1518
- scale?: number;
1519
- }
1520
- /**
1521
- * Capture a single frame from a canvas as a Blob.
1522
- *
1523
- * @example
1524
- * ```ts
1525
- * const blob = await captureSnapshot(canvas);
1526
- * const url = URL.createObjectURL(blob);
1527
- * ```
1528
- */
1529
- declare function captureSnapshot(canvas: HTMLCanvasElement, { format, quality, scale }?: SnapshotOptions): Promise<Blob>;
1530
- /**
1531
- * Capture a single frame and immediately trigger a browser download.
1532
- *
1533
- * @example
1534
- * ```ts
1535
- * await snapshotAndDownload(canvas);
1536
- * await snapshotAndDownload(canvas, { format: 'jpeg', filename: 'my-art' });
1537
- * ```
1538
- */
1539
- declare function snapshotAndDownload(canvas: HTMLCanvasElement, options?: SnapshotOptions & {
1540
- filename?: string;
1541
- }): Promise<void>;
1542
-
1543
- /**
1544
- * asciifyWebcam — live webcam → ASCII art on canvas.
1545
- *
1546
- * Requests camera access, attaches the stream to a hidden video element, and
1547
- * runs a rAF loop that converts each frame to ASCII and renders it onto a
1548
- * supplied canvas.
1549
- *
1550
- * @example
1551
- * const stop = await asciifyWebcam(canvas);
1552
- * // later: stop();
1553
- *
1554
- * @example
1555
- * const stop = await asciifyWebcam(canvas, {
1556
- * fontSize: 8,
1557
- * style: 'terminal',
1558
- * mirror: true, // horizontal flip (selfie mode)
1559
- * constraints: { facingMode: 'user' },
1560
- * });
1561
- */
1562
-
1563
- interface WebcamOptions {
1564
- /** Character size in pixels. Default: 10 */
1565
- fontSize?: number;
1566
- /** Art style preset. Default: 'classic' */
1567
- style?: ArtStyle;
1568
- /** Extra AsciiOptions merged on top of the preset */
1569
- options?: Partial<AsciiOptions>;
1570
- /**
1571
- * Called every frame to get the latest options. Takes priority over `options`.
1572
- * Use this to keep the rendering in sync with live UI controls without
1573
- * restarting the camera.
1574
- *
1575
- * @example
1576
- * const optionsRef = useRef(currentOptions);
1577
- * optionsRef.current = currentOptions;
1578
- * asciifyWebcam(canvas, { liveOptions: () => optionsRef.current });
1579
- */
1580
- liveOptions?: () => Partial<AsciiOptions>;
1581
- /**
1582
- * Flip the output horizontally so it reads like a mirror / selfie camera.
1583
- * Default: true
1584
- */
1585
- mirror?: boolean;
1586
- /**
1587
- * Passed directly to `getUserMedia({ video: constraints })`.
1588
- * Defaults to `{ facingMode: 'user' }`.
1589
- */
1590
- constraints?: MediaTrackConstraints;
1591
- /**
1592
- * Device pixel ratio used to compute logical render dimensions from the
1593
- * canvas's physical pixel size. Defaults to `window.devicePixelRatio ?? 1`.
1594
- * Set this when you size the canvas at physical resolution (e.g. width × dpr)
1595
- * so that ASCII column/row counts are based on CSS pixels, not physical ones.
1596
- */
1597
- dpr?: number;
1598
- }
1599
- /**
1600
- * Start a live webcam ASCII-art loop and render it onto `canvas`.
1601
- * Returns a `stop()` function that cancels the loop and releases the camera.
1602
- *
1603
- * Throws if the browser doesn't support `getUserMedia` or the user denies
1604
- * camera permission.
1605
- */
1606
- declare function asciifyWebcam(canvas: HTMLCanvasElement, { fontSize, style, options, liveOptions, mirror, constraints, dpr: dprOverride, }?: WebcamOptions): Promise<() => void>;
1607
-
1608
- /**
1609
- * big-text.ts — ASCII text rendering via an embedded 7×7 bitmap font.
1610
- *
1611
- * Each character is defined as 7 rows × 7 pixels stored as compact bit-patterns.
1612
- * No canvas, no font files, no pixel-sampling — output is always crisp and readable.
1613
- *
1614
- * @example
1615
- * ```ts
1616
- * import { asciifyText } from 'asciify-engine';
1617
- * console.log(asciifyText('Hello!'));
1618
- * console.log(asciifyText('v2', { scale: 2, char: '#' }));
1619
- * ```
1620
- */
1621
- interface BigTextOptions {
1622
- /**
1623
- * Character used for ink pixels. Any single grapheme — emoji work too.
1624
- * @default '█'
1625
- */
1626
- char?: string;
1627
- /**
1628
- * Pixel scale factor.
1629
- * `1` = each font pixel → 1 char (output is 7 rows tall).
1630
- * `2` = each pixel → 2×2 chars (14 rows tall), etc.
1631
- * @default 1
1632
- */
1633
- scale?: number;
1634
- /** Foreground colour (canvas output only). @default '#d4ff00' */
1635
- color?: string;
1636
- /** Background colour (canvas output only). @default transparent */
1637
- bgColor?: string;
1638
- /** Physical character cell size in px (canvas output only). @default 10 */
1639
- fontSize?: number;
1640
- }
1641
- /**
1642
- * Convert a string to multi-line ASCII text art.
1643
- *
1644
- * Uses an embedded 7×7 pixel bitmap font — no font files, no install step,
1645
- * works in every JS environment (browser, Node, Deno, Bun).
1646
- *
1647
- * @example
1648
- * ```ts
1649
- * import { asciifyText } from 'asciify-engine';
1650
- * console.log(asciifyText('Hello!'));
1651
- * console.log(asciifyText('v2.0', { char: '#' }));
1652
- * console.log(asciifyText('WOW', { scale: 2, char: '▓' }));
1653
- * ```
1654
- */
1655
- declare function asciifyText(text: string, options?: BigTextOptions): string;
1656
- /**
1657
- * Render ASCII text directly onto an HTMLCanvasElement.
1658
- * The canvas is automatically resized to fit the output.
1659
- *
1660
- * @example
1661
- * ```ts
1662
- * import { renderTextToCanvas } from 'asciify-engine';
1663
- * renderTextToCanvas(canvas, 'Hello!', { color: '#d4ff00', scale: 2 });
1664
- * ```
1665
- */
1666
- declare function renderTextToCanvas(canvas: HTMLCanvasElement, text: string, options?: BigTextOptions): void;
1667
-
1668
- export { ART_STYLE_PRESETS, type AnimationStyle, type ArtStyle, type AsciiBackgroundOptions, type AsciiCell, type AsciiFrame, type AsciiOptions, type AsciiResult, type AsciiTextFrame, type AsciifyLiveVideoOptions, type AsciifySimpleOptions, type AsciifyVideoOptions, type AuroraBackgroundOptions, BACKGROUND_TYPES, type BackgroundType, type BigTextOptions, CHARSETS, CHARSET_SEQUENCES, type CanvasBleed, type CanvasObjectFit, type CanvasRenderSizeInput, type CharsetKey, type CharsetSequenceKey, type CircuitBackgroundOptions, type ColorMode, DEFAULT_OPTIONS, type DnaBackgroundOptions, type FireBackgroundOptions, type GridBackgroundOptions, HOVER_PRESETS, type HoverEffect, type HoverPreset, type HoverShape, LIVING_STYLE_PRESETS, type LivingStylePresetKey, type MorphBackgroundOptions, type MountWaveOptions, type NoiseBackgroundOptions, PALETTE_THEMES, type PaletteTheme, type PulseBackgroundOptions, type RainBackgroundOptions, type RenderMode, type SilkBackgroundOptions, type SnapshotOptions, type SourceType, type StarsBackgroundOptions, type TerrainBackgroundOptions, type TextBackgroundOptions, type VideoScrollScrubOptions, type VoidBackgroundOptions, type WaveBackgroundOptions, type WebcamOptions, asciiBackground, asciiText, asciiTextAnsi, asciify, asciifyGif, asciifyLiveVideo, asciifyText, asciifyVideo, asciifyWebcam, buildTextFrame, captureSnapshot, clearAsciifyCaches, computeCanvasRenderSize, createVideoScrollScrub, gifToAsciiFrames, gifToAsciiTextFrames, imageToAsciiFrame, imageToAsciiTextFrame, mountWaveBackground, renderAuroraBackground, renderCircuitBackground, renderDnaBackground, renderFireBackground, renderFrameToCanvas, renderGridBackground, renderMorphBackground, renderNoiseBackground, renderPulseBackground, renderRainBackground, renderSilkBackground, renderStarsBackground, renderTerrainBackground, renderTextBackground, renderTextFrameToCanvas, renderTextToCanvas, renderVoidBackground, renderWaveBackground, snapshotAndDownload, videoToAsciiFrames, videoToAsciiTextFrames };
1
+ export { ART_STYLE_PRESETS, AnimationStyle, ArtStyle, AsciiCell, AsciiFrame, AsciiOptions, AsciiResult, AsciiTextFrame, AsciifyLiveVideoOptions, AsciifySimpleOptions, AsciifyVideoOptions, BigTextOptions, CHARSETS, CHARSET_SEQUENCES, CanvasBleed, CanvasObjectFit, CanvasRenderSizeInput, CharsetKey, CharsetSequenceKey, ColorMode, DEFAULT_OPTIONS, HOVER_PRESETS, HoverEffect, HoverPreset, HoverShape, LIVING_STYLE_PRESETS, LivingStylePresetKey, PALETTE_THEMES, PaletteTheme, RenderMode, SnapshotOptions, SourceType, TextBackgroundOptions, VideoScrollScrubOptions, WebcamOptions, asciiText, asciiTextAnsi, asciify, asciifyGif, asciifyLiveVideo, asciifyText, asciifyVideo, asciifyWebcam, buildTextFrame, captureSnapshot, clearAsciifyCaches, computeCanvasRenderSize, createVideoScrollScrub, gifToAsciiFrames, gifToAsciiTextFrames, imageToAsciiFrame, imageToAsciiTextFrame, renderFrameToCanvas, renderTextBackground, renderTextFrameToCanvas, renderTextToCanvas, snapshotAndDownload, videoToAsciiFrames, videoToAsciiTextFrames } from './core.js';
2
+ export { AsciiBackgroundOptions, AuroraBackgroundOptions, BACKGROUND_TYPES, BackgroundType, CircuitBackgroundOptions, DnaBackgroundOptions, FireBackgroundOptions, GridBackgroundOptions, MorphBackgroundOptions, MountWaveOptions, NoiseBackgroundOptions, PulseBackgroundOptions, RainBackgroundOptions, SilkBackgroundOptions, StarsBackgroundOptions, TerrainBackgroundOptions, VoidBackgroundOptions, WaveBackgroundOptions, asciiBackground, mountWaveBackground, renderAuroraBackground, renderCircuitBackground, renderDnaBackground, renderFireBackground, renderGridBackground, renderMorphBackground, renderNoiseBackground, renderPulseBackground, renderRainBackground, renderSilkBackground, renderStarsBackground, renderTerrainBackground, renderVoidBackground, renderWaveBackground } from './backgrounds.js';