asciify-engine 4.0.0 → 4.2.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.
@@ -0,0 +1,323 @@
1
+ type ColorMode = 'grayscale' | 'fullcolor' | 'matrix' | 'accent';
2
+ type RenderMode = 'ascii' | 'dots';
3
+ type AnimationStyle = 'none' | 'caustics' | 'current' | 'reform';
4
+ /** Core media draws ASCII/dots; use StudioStyle for the 15 render styles. */
5
+ type ArtStyle = 'classic';
6
+ type HoverEffect = 'spotlight' | 'magnify' | 'repel' | 'glow' | 'colorShift' | 'attract' | 'shatter' | 'trail' | 'glitchText';
7
+ type HoverShape = 'circle' | 'box';
8
+ type HoverPreset = 'none' | 'subtle' | 'flashlight' | 'magnifier' | 'forceField' | 'neon' | 'fire' | 'ice' | 'gravity' | 'shatter' | 'ghost' | 'glitchReveal';
9
+ type SourceCropUnit = 'percent' | 'pixel';
10
+ type SourceCropAnchor = 'center' | 'top' | 'bottom' | 'left' | 'right' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
11
+ interface SourceCrop {
12
+ /** Legacy crop origin on the source media. Percent values use 0–1. Default: centered when cropped */
13
+ x?: number;
14
+ /** Legacy crop origin on the source media. Percent values use 0–1. Default: centered when cropped */
15
+ y?: number;
16
+ /** Legacy crop width on the source media. Percent values use 0–1. Default: mirrors `height` to preserve proportions */
17
+ width?: number;
18
+ /** Legacy crop height on the source media. Percent values use 0–1. Default: mirrors `width` to preserve proportions */
19
+ height?: number;
20
+ /** CSS-like crop inset from the top edge. Percent values use 0–1. */
21
+ top?: number;
22
+ /** CSS-like crop inset from the right edge. Percent values use 0–1. */
23
+ right?: number;
24
+ /** CSS-like crop inset from the bottom edge. Percent values use 0–1. */
25
+ bottom?: number;
26
+ /** CSS-like crop inset from the left edge. Percent values use 0–1. */
27
+ left?: number;
28
+ /**
29
+ * Keep the source aspect ratio when deriving a crop from a single `width` or
30
+ * `height`. CSS-like side insets (`top`, `right`, `bottom`, `left`) already
31
+ * define an exact source view box, and `asciifyVideo` sizes from that crop
32
+ * aspect so the output does not stretch. Default: `true`.
33
+ */
34
+ preserveAspect?: boolean;
35
+ /** Bias auto-centered crops toward an edge or corner. Default: `'center'` */
36
+ anchor?: SourceCropAnchor;
37
+ /** Interpret values as normalized percentages or source pixels. Default: `'percent'` */
38
+ unit?: SourceCropUnit;
39
+ }
40
+ /**
41
+ * Named colour palette presets — pass as `colorMode` for themed rendering.
42
+ * Applied as a post-process colour remap over the standard grayscale output.
43
+ */
44
+ type PaletteTheme = 'dracula' | 'monokai' | 'nord' | 'catppuccin' | 'solarized' | 'gruvbox';
45
+ declare const PALETTE_THEMES: Record<PaletteTheme, {
46
+ name: string;
47
+ accent: string;
48
+ bg: string;
49
+ fg: string;
50
+ }>;
51
+ type SourceType = 'image' | 'video' | 'gif' | null;
52
+ interface AsciiOptions {
53
+ /** Character cell width in pixels. Smaller = more detail, more cells. Default: `7` */
54
+ fontSize: number;
55
+ /** Extra horizontal spacing between characters (pixels). Default: `1` */
56
+ charSpacing: number;
57
+ /**
58
+ * Brightness adjustment applied before luminance mapping.
59
+ * Range −1 (black) → 0 (unchanged) → 1 (white). Default: `0`
60
+ */
61
+ brightness: number;
62
+ /**
63
+ * Contrast boost applied before luminance mapping.
64
+ * `0` = unchanged, positive values increase contrast, negative decrease it.
65
+ * Default: `0`
66
+ */
67
+ contrast: number;
68
+ /**
69
+ * Character density ramp — ordered from lightest to darkest.
70
+ * Use `CHARACTER_SETS.standard.chars` for a curated ramp or supply your own string.
71
+ * Default: `' .:-=+*#%@'`
72
+ */
73
+ charset: string;
74
+ /**
75
+ * Colour output mode.
76
+ * - `'grayscale'` — white-on-black monochrome
77
+ * - `'fullcolor'` — samples pixel colours from the source
78
+ * - `'matrix'` — green phosphor terminal look
79
+ * - `'accent'` — single accent colour with intensity-driven brightness
80
+ * Default: `'grayscale'`
81
+ */
82
+ colorMode: ColorMode;
83
+ /**
84
+ * The accent colour used when `colorMode` is `'accent'` or `'matrix'`.
85
+ * Any CSS colour string. Default: `'#d4ff00'`
86
+ */
87
+ /**
88
+ * Hex color string used when `colorMode` is `'accent'`.
89
+ * Set to `'auto'` to let the engine pick contrasting ink automatically:
90
+ * dark ink (`#0d0d0d`) in light mode, light ink (`#faf9f7`) in dark mode.
91
+ */
92
+ accentColor: string;
93
+ /**
94
+ * Invert luminance mapping (light pixels → dense chars). Default: `false`
95
+ *
96
+ * Set to `'auto'` to let the engine detect the OS color scheme:
97
+ * - Light mode → inverts (bright pixel = dark char = visible on white background)
98
+ * - Dark mode → normal (bright pixel = bright char = visible on dark background)
99
+ */
100
+ invert: boolean | 'auto';
101
+ /**
102
+ * Render mode.
103
+ * - `'ascii'` — characters drawn as text
104
+ * - `'dots'` — each cell rendered as a filled circle (particle look)
105
+ * Default: `'ascii'`
106
+ */
107
+ renderMode: RenderMode;
108
+ /**
109
+ * Per-character animation driven over time.
110
+ * Applies wave, glitch, rain-drop, spiral, and other effects to the rendered text.
111
+ * Default: `'none'`
112
+ */
113
+ animationStyle: AnimationStyle;
114
+ /** Speed multiplier for `animationStyle` effects. Default: `1` */
115
+ animationSpeed: number;
116
+ /**
117
+ * Size of each dot relative to the cell when `renderMode === 'dots'`.
118
+ * `1` fills the whole cell, `0.5` draws half-size circles. Default: `0.8`
119
+ */
120
+ dotSizeRatio: number;
121
+ /**
122
+ * Ordered Bayer (4×4) dither strength applied to the luminance map.
123
+ * `0` = no dithering, `1` = full dithering. Default: `0`
124
+ */
125
+ ditherStrength: number;
126
+ /**
127
+ * Assumed aspect ratio (width ÷ height) of a single output character.
128
+ * Controls how many rows vs columns are generated — must match your rendering
129
+ * environment to preserve the source image's proportions.
130
+ * - `0.55` — browser monospace at `line-height: 1.09` (default)
131
+ * - `0.52` — browser monospace at `line-height: 1.15`
132
+ * - `0.5` — most terminal emulators
133
+ * Default: `0.55`
134
+ */
135
+ charAspect: number;
136
+ /**
137
+ * Auto-stretch the luminance range before charset mapping.
138
+ * When `true`, the darkest pixel in the frame maps to the first charset character
139
+ * and the brightest to the last, maximising perceived detail and contrast.
140
+ * Particularly useful for images with low inherent contrast or muted tones.
141
+ * Default: `false`
142
+ */
143
+ normalize: boolean;
144
+ /**
145
+ * Overall intensity of the hover / cursor interaction effect.
146
+ * `0` disables the effect. Default: `0`
147
+ */
148
+ hoverStrength: number;
149
+ /**
150
+ * Radius of the hover interaction zone as a fraction of the canvas size.
151
+ * `0.1` = 10% of canvas width. Default: `0.2`
152
+ */
153
+ hoverRadius: number;
154
+ /**
155
+ * Which cursor interaction style to apply when `hoverStrength > 0`.
156
+ * See `HoverPreset` or `HOVER_PRESETS` for ready-made configurations.
157
+ * Default: `'spotlight'`
158
+ */
159
+ hoverEffect: HoverEffect;
160
+ /**
161
+ * Tint colour used by hover effects such as spotlight, glow, and colorShift.
162
+ * Any CSS colour string. Default: `'#ffffff'`
163
+ */
164
+ hoverColor: string;
165
+ /**
166
+ * Shape of the hover interaction zone.
167
+ * - `'circle'` — radial falloff (default)
168
+ * - `'box'` — rectangular zone, text fills a block around the cursor
169
+ * Default: `'circle'`
170
+ */
171
+ hoverShape: HoverShape;
172
+ /**
173
+ * Text string revealed by the `'glitchText'` hover effect.
174
+ * Characters around the cursor scramble and resolve into this text.
175
+ * Supports `\n` for multi-line reveals.
176
+ *
177
+ * Pass an **array** of strings to cycle through different words based on
178
+ * the cursor's grid region — the engine picks one via a spatial hash so
179
+ * each area of the canvas shows a different word.
180
+ *
181
+ * Default: `'ASCIIFY'`
182
+ *
183
+ * @example
184
+ * // Single word:
185
+ * options: { hoverEffect: 'glitchText', hoverText: 'HELLO' }
186
+ *
187
+ * // Word pool — different text at different cursor positions:
188
+ * options: { hoverEffect: 'glitchText', hoverText: ['DEPLOY', 'SCALE', 'SHIP', 'BUILD'] }
189
+ */
190
+ hoverText: string | string[];
191
+ /**
192
+ * Core renderer discriminator. No legacy preset lookup is performed.
193
+ * Core rendering uses `classic`; select the current render styles through `/studio`.
194
+ */
195
+ artStyle: ArtStyle;
196
+ /** Explicit fine-dither treatment for the optional hover compositor. */
197
+ fineDither?: boolean;
198
+ /**
199
+ * Custom repeating text used when `artStyle` is `'letters'` or when you set
200
+ * a custom charset. Leave empty to use the selected `charset`. Default: `''`
201
+ */
202
+ customText: string;
203
+ /**
204
+ * Chroma-key colour to remove from the source (green screen / blue screen).
205
+ * Pixels whose RGB distance from this colour is within `chromaKeyTolerance`
206
+ * are keyed out: their character becomes a space and alpha is set to 0,
207
+ * letting the canvas background show through.
208
+ *
209
+ * - `true` — **smart green screen**: heuristic detection (`g > r*1.4 && g > b*1.4`)
210
+ * catches every shade of green screen (lime, broadcast, chroma green) with no
211
+ * config. Works on virtually all studio/streaming footage.
212
+ * - `'blue-screen'` — **smart blue screen**: same heuristic for blue.
213
+ * - `{ r, g, b }` or CSS colour string — custom key colour + `chromaKeyTolerance`
214
+ * - `null` / `false` — disabled (default)
215
+ *
216
+ * @example
217
+ * // Standard green screen — zero config:
218
+ * options: { chromaKey: true }
219
+ *
220
+ * // Blue screen — zero config:
221
+ * options: { chromaKey: 'blue-screen' }
222
+ *
223
+ * // Custom CSS colour:
224
+ * options: { chromaKey: '#00b140', chromaKeyTolerance: 70 }
225
+ */
226
+ chromaKey: {
227
+ r: number;
228
+ g: number;
229
+ b: number;
230
+ } | string | boolean | null;
231
+ /**
232
+ * Euclidean RGB tolerance radius for chroma-key detection.
233
+ * `0` = exact match only, `441` ≈ key out everything.
234
+ * Higher values remove more pixels. Default: `60`
235
+ */
236
+ chromaKeyTolerance: number;
237
+ /**
238
+ * Extra normalized padding kept around the detected chroma-key foreground when
239
+ * `asciifyVideo` auto-trims keyed video content inside `sourceCrop`.
240
+ * `0` hugs the visible foreground. `0.01` keeps 1% safety padding.
241
+ * Default: `0.002`
242
+ */
243
+ chromaKeyTrimPadding: number;
244
+ /**
245
+ * Minimum source-pixel luminance for chroma-key foreground auto-trim.
246
+ * Raise this when faint edge noise is counted as content and prevents a
247
+ * keyed subject from filling a preserved-ratio layout. Range `0–255`.
248
+ * Default: `0`
249
+ */
250
+ chromaKeyTrimLuminanceThreshold: number;
251
+ /**
252
+ * How keyed video foreground trimming is applied when `chromaKey` and
253
+ * `sourceCrop` are enabled.
254
+ *
255
+ * - `'range'` samples the video/scroll range once and keeps a stable union
256
+ * crop. Best default for consistent framing.
257
+ * - `'frame'` remeasures each rendered frame and expands the crop to the
258
+ * render aspect. Best for scroll-scrubbed hero footage where foreground
259
+ * position changes and pure contain leaves empty edges.
260
+ * - `'off'` disables automatic keyed foreground trimming.
261
+ *
262
+ * Default: `'range'`
263
+ */
264
+ chromaKeyTrimMode: 'range' | 'frame' | 'off';
265
+ /**
266
+ * Optional source crop applied before ASCII sampling.
267
+ *
268
+ * Use this when the media has empty edges or a subject that should be framed
269
+ * tighter without changing the destination canvas size.
270
+ *
271
+ * @example
272
+ * // Remove 15% from the top and 15% from the bottom, preserving proportions:
273
+ * options: { sourceCrop: { top: 0.15, bottom: 0.15 } }
274
+ *
275
+ * @example
276
+ * // Keep 70% of the source, preserve proportions, and center it:
277
+ * options: { sourceCrop: { height: 0.7 } }
278
+ *
279
+ * @example
280
+ * // Use an exact source window when manual framing should override proportions:
281
+ * options: { sourceCrop: { x: 0.05, y: 0.08, width: 0.9, height: 0.9, preserveAspect: false } }
282
+ */
283
+ sourceCrop?: SourceCrop | null;
284
+ /**
285
+ * Array of charset strings to cycle through over time.
286
+ * The engine picks `charsetFrames[Math.floor(time * charsetFps) % length]` on each
287
+ * render tick, re-mapping characters from stored cell luminance.
288
+ * Pairs beautifully with `animationStyle` and `asciiBackground`.
289
+ *
290
+ * Supply your own array of character ramps:
291
+ * @example
292
+ * options: { charsetFrames: [CHARACTER_SETS.standard.chars, CHARACTER_SETS.blocks.chars] }
293
+ */
294
+ charsetFrames?: string[];
295
+ /** Cycle rate for `charsetFrames` in frames-per-second. Default: `2` */
296
+ charsetFps?: number;
297
+ }
298
+ interface AsciiCell {
299
+ char: string;
300
+ r: number;
301
+ g: number;
302
+ b: number;
303
+ a: number;
304
+ /** 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`. */
305
+ lum?: number;
306
+ }
307
+ type AsciiFrame = AsciiCell[][];
308
+ interface AsciiResult {
309
+ frames: AsciiFrame[];
310
+ cols: number;
311
+ rows: number;
312
+ fps: number;
313
+ }
314
+ declare const DEFAULT_OPTIONS: AsciiOptions;
315
+ /**
316
+ * Hover presets — one-click configurations for the hover system.
317
+ */
318
+ declare const HOVER_PRESETS: Record<HoverPreset, {
319
+ label: string;
320
+ options: Partial<AsciiOptions>;
321
+ }>;
322
+
323
+ export { type AsciiFrame as A, type ColorMode as C, DEFAULT_OPTIONS as D, type HoverEffect as H, PALETTE_THEMES as P, type RenderMode as R, type SourceType as S, type AsciiOptions as a, type ArtStyle as b, type AnimationStyle as c, type AsciiCell as d, type AsciiResult as e, HOVER_PRESETS as f, type HoverPreset as g, type HoverShape as h, type PaletteTheme as i };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "asciify-engine",
3
- "version": "4.0.0",
3
+ "version": "4.2.0",
4
4
  "description": "Framework-agnostic ASCII art engine. Convert images, videos, and GIFs into ASCII art rendered on canvas.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -2,13 +2,13 @@
2
2
  name: asciify-engine
3
3
  description: Build and tune browser ASCII images, video, GIFs, text, and interactive heroes with asciify-engine. Use for media conversion, character and color choices, hover integration, layered HTML typography, scroll-synced video, and rendering performance in apps using this package.
4
4
  metadata:
5
- tested-engine: "4.0.0"
6
- updated: "2026-09-09"
5
+ tested-engine: "4.2.0"
6
+ updated: "2026-10-07"
7
7
  ---
8
8
 
9
9
  # Asciify Engine
10
10
 
11
- Use the published `asciify-engine` npm package for browser canvas rendering. Tested against **4.0.0**. Check the application's installed version and its public types before using newer options; a local checkout can contain unpublished changes.
11
+ Use the published `asciify-engine` npm package for browser canvas rendering. Tested against **4.2.0**. Check the application's installed version and its public types before using newer options; a local checkout can contain unpublished changes.
12
12
 
13
13
  - Agent entry: https://asciify.org/skill (redirects to this Markdown document).
14
14
  - Playground: https://asciify.org/editor
@@ -83,7 +83,7 @@ const letters = [...new Set('ASCIIFY'.toUpperCase().replace(/[^A-Z]/g, ''))].joi
83
83
  const charset = ` .:-=+${letters}#%@`;
84
84
  ```
85
85
 
86
- Preview it: letter glyph densities differ, so arbitrary words are not automatically an evenly ordered ramp. Keep the leading space and the light/dense symbols. Use `CHARSETS.standard`, `dense`, `blocks`, or `braille` when they better suit the subject.
86
+ Preview it: letter glyph densities differ, so arbitrary words are not automatically an evenly ordered ramp. Keep the leading space and the light/dense symbols. Use the curated `CHARACTER_SETS.standard.chars`, `detailed.chars`, `blocks.chars`, or `braille.chars` from `/core` when appropriate.
87
87
 
88
88
  ## Engine effects versus studio effects
89
89
 
@@ -136,6 +136,11 @@ Version 1.3.0 adds text-shaped charcoal cutouts (`textMask`), peripheral scanlin
136
136
 
137
137
  For optional wallpaper/backdrops, alternate renderers, palettes, masks, saved looks, text fonts, or deterministic MP4/GIF export, read [references/studio-workspace.md](references/studio-workspace.md). The new `/studio` API is separate from `/hover` and `AsciiOptions`; do not replace an existing hero pipeline just to add a backdrop. Use version 1.4.0 or newer for these APIs after verifying the installed package.
138
138
 
139
- ## Standard catalogs in 2.0
139
+ ## Current catalogs (4.2)
140
140
 
141
- `CHARSETS` and `ART_STYLE_PRESETS` no longer include `emoji`, `musical` or `starfield`. Do not recommend or generate those names. For character selection in a Studio integration, use `STUDIO_CHARACTER_SETS` from `asciify-engine/studio` and assign an entry's `chars` to `settings.charset`. These ramps apply to the `ascii` style; other styles define their own marks. Custom Unicode strings remain supported. Read the upgrade reference when migrating 1.x preset names. The site now opens its primary workspace at `/editor`; `/editor/classic` preserves earlier workflows. Keep the engine imports modular: new editor defaults do not require importing Studio into an existing hero.
141
+ Legacy `CHARSETS`, `ART_STYLE_PRESETS`, `CHARSET_SEQUENCES`, `LIVING_STYLE_PRESETS` and their key types are removed. Do not import them or generate old names such as Katakana, Binary, Waves or Smoke. Use the 18 `STUDIO_STYLES` for render-style selectors and `/studio` rendering. For ASCII-only character ramps use `CHARACTER_SETS` from `/core` or `STUDIO_CHARACTER_SETS` from `/studio`; custom Unicode and user-provided frame arrays remain supported. Core `artStyle` only accepts `classic`; use explicit options instead of preset shortcuts. Despite the requested 4.1.0 version number, migrating these removed APIs is a breaking change.
142
+
143
+
144
+ ## Fine dither and creative controls (4.2)
145
+
146
+ Studio adds `hex`, `led`, and `cmyk` render styles, directional/radial dither patterns, additional palettes, luminance mapping, RGB split, sharpening, and adjustable still-image motion strength. Read [studio-workspace.md](references/studio-workspace.md#fine-detail-and-controls-42) for exact options, density budgets and preview/export consistency. These are local Canvas/WebGL effects, not AI generation or a claim of parity with every competing catalog.
@@ -105,7 +105,7 @@ Do not promise a 120 FPS minimum on every mobile device or arbitrary character c
105
105
 
106
106
  ### Hero character catalog
107
107
 
108
- Hero → Customize → Character set exposes every preset from the published engine `CHARSETS` catalog, plus the Asciify brand set. Selecting a set clears a custom-letter override; Apply letters modifies only the selected set, and Reset set restores it. Selection works while paused or with reduced motion. The hero remains gray; these are character ramps, not the playground’s Halftone/Dither rendering modes. Prism at 95% with 35% edge softness is the default hero finish: red/cyan separation with short soft shoulders at the perimeter, a clear center, and no blur on HTML text or controls. The same Prism shader is used by the playground and optional engine hover surface.
108
+ Hero → Customize → Characters uses the same 15 render-style tiles as the editor, with six primary styles and nine under More render styles. Custom letters are available under ASCII. Alternate styles use the published Studio renderer and share the hero's video; they are not aliases for old alphabets. Default ASCII retains its GPU hover and Prism finish. Selecting styles works while paused or with reduced motion.
109
109
 
110
110
  The default Trail radius is now `0.45` in the hero, playground preset and optional engine mount. This widens the nominal fluid impulse by about 51% versus `0.2`, while preserving the same strength, bounded flow field. Pass `radius: 0.2` explicitly for the previous narrower reach. Other hover presets keep their existing sizes.
111
111
 
@@ -125,3 +125,35 @@ Studio defaults to a 6-unit cell size. Separate the sampling grid from canvas ba
125
125
  Start with `cellSize: 6`; the editor remembers each style's size. A Retina preview uses `resize(width, height, pixelRatio)` on a `mountStudioMedia` handle to keep logical cells independent of physical raster resolution. Its `setBudget(maxCells)` changes the upper sampling budget; automatic adaptation may reduce it when frames are slow. At a 960×540 logical canvas, 32,768 cells permit Lego size 4, and 65,536 permit dither scale 3. Keep ASCII at a measured budget such as 12,000 cells. Smaller requested cells cannot bypass the active budget; show `studioGrid`'s actual minimum in controls. Fine grids cost more, so profile hover and motion on target devices. Studio caches Lego stud artwork.
126
126
 
127
127
  For menus shared with a media hero, import the eight `CHARACTER_SETS` from `asciify-engine/core`; `STUDIO_CHARACTER_SETS` is the identical catalog through `/studio`. A hero need not load the Studio runtime.
128
+
129
+
130
+ ## Fine detail and controls (4.2)
131
+
132
+ - The style catalog adds `hex` (hexagonal tiles), `led` (circular emitters), and `cmyk` (offset cyan/magenta/yellow/black ink dots on white paper). CMYK uses source channel coverage. These remain in the optional `/studio` entry; `/core` does not import them.
133
+ - Tile styles accept `cellSize: 1`; glyph styles retain a minimum of 3. Dither uses `dither.scale` from 1 to 12, independent of `cellSize`. Values are logical pixels in the reference frame, not device pixels.
134
+ - `studioGrid(width, height, settings, maxCells, pixelRatio)` reports the actual grid, `minimum`, and `limited`. Explain a limit in the UI rather than presenting a requested 1px value as an actual 1px grid.
135
+ - `maxCells` can be explicitly raised to 1,048,576. Defaults remain bounded. For a 960 × 540 reference, `maxCells: 1048576` allows one-pixel dithering. This is a detail option, not a promise of real-time performance at that density. Larger reference frames can still be limited.
136
+ - Mounts expose `setAdaptive(boolean)` and `setBudget(cells)`. The budget cannot exceed the mount's original `maxCells`. Adaptive mode can reduce the grid during animation/hover; disable it deliberately when exact density is more important. Static dither is cached until its source/settings/grid change.
137
+ - New dither algorithms: `vertical-lines`, `diagonal-lines`, `radial`. `lines` remains horizontal; `noise` remains deterministic white noise, not blue noise. New palettes: `gray4`, `gray8`, `rgb8`, `cyberpunk`, `pastel`.
138
+ - `dither.colorSpace` is `rgb` (nearest palette color) or `luminance` (nearest perceived brightness); default `rgb`. `dither.direction` is degrees from −180 to 180, with 0 toward positive X and 90 toward positive Y. It controls drift, with `motion: 'drift'` and `speed: 0.1–3`. Radial drift travels through concentric thresholds, so direction does not apply. Diffusion has no ordered matrix to translate; choose an ordered algorithm for drift.
139
+ - `effects.rgbSplit` and `effects.sharpen` are 0–1, default 0. RGB split is uniform channel separation; `prism` remains peripheral separation. Both need WebGL finishing. Do not silently claim unsupported effects were rendered.
140
+ - `motion.amount` is 0–2, default 1. It changes displacement/light/dissolve strength without changing phase or speed. Zero retains the stationary image. Caustics, Slow Current, and Reveal & Reform remain the supported motion types.
141
+
142
+ ```ts
143
+ const studio = await mountStudio(canvas, file, {
144
+ width: 960, height: 540, maxDimension: 960,
145
+ maxCells: 1048576, adaptive: false,
146
+ settings: {
147
+ style: 'dither',
148
+ dither: { scale: 1, algorithm: 'bayer8', palette: 'gray4',
149
+ colorSpace: 'luminance', motion: 'drift', direction: 90, speed: .5 },
150
+ motion: { type: 'current', speed: .4, amount: .35 },
151
+ effects: { sharpen: .15 },
152
+ },
153
+ });
154
+ // Return to an interactive budget without remounting:
155
+ studio.setAdaptive(true);
156
+ studio.setBudget(65536);
157
+ ```
158
+
159
+ When exporting, pass the same `maxCells` and logical `referenceWidth` as the preview to retain cell density. Increasing output resolution alone should not invent a different composition. Older projects normalize new fields to neutral defaults.
@@ -30,7 +30,7 @@ After updating, read the installed SKILL.md and its linked references, confirm i
30
30
 
31
31
  ## 2.0 catalog migration
32
32
 
33
- 2.0.0 removes the `emoji`, `musical`, and `starfield` keys from `CHARSETS`, `ArtStyle`, and `ART_STYLE_PRESETS`. Before upgrading, search application settings and saved presets for those names. Use `classic` plus a custom `charset` to retain an application-owned alphabet, or use `circles`, `braille`, or `geometric` for structural alternatives. The existing cosmic sequence now uses sparse marks/circles/shadows, and angular uses geometry/shards/blocks. Other core options and renderers retain their behavior. Do not pass retired keys or tell users that custom Unicode has been removed.
33
+ 2.0.0 removes the `emoji`, `musical`, and `starfield` keys from `CHARSETS`, `ArtStyle`, and `ART_STYLE_PRESETS`. Before upgrading, search application settings and saved presets for those names. For current releases, use a custom `charset` or a current StudioStyle. The existing cosmic sequence now uses sparse marks/circles/shadows, and angular uses geometry/shards/blocks. Other core options and renderers retain their behavior. Do not pass retired keys or tell users that custom Unicode has been removed.
34
34
 
35
35
  The curated `STUDIO_CHARACTER_SETS` export is available from `/studio` in 2.0.0. Its values contain `label` and `chars`; assign `chars` to Studio settings only for `style: 'ascii'`. The primary editor at `/editor` uses Studio; earlier webcam and classic-editor workflows remain at `/editor/classic`.
36
36
 
@@ -48,4 +48,9 @@ Use one motion owner: `animationStyle` for core, `motion` for `/hover`, or `moti
48
48
 
49
49
  Remove imports from `asciify-engine/backgrounds` and generator imports from the root package. Download the chosen `.js` template from https://asciify.org/backgrounds and change the import to `./wave.js` (or your selected file). The template exports `asciiBackground`; keep calling `destroy()` on unmount. It handles resizing, hidden/offscreen suspension, reduced motion, and cleanup. A selected template contains only that generator; backgrounds.js is the optional full collection. Application-owned source templates are separate from npm updates. Existing installations can stay on 3.x while migrating. Text and media rendering remain supported, including text backgrounds.
50
50
 
51
- Use `CHARACTER_SETS` from root or `/core` for the same eight choices as the editor's `STUDIO_CHARACTER_SETS`. This data-only import does not load Studio. Keep custom characters available separately; do not populate standard UI choices from the larger legacy `CHARSETS` object.
51
+ Use `CHARACTER_SETS` from root or `/core` for the same eight choices as the editor's `STUDIO_CHARACTER_SETS`. This data-only import does not load Studio. Keep custom characters available separately; do not import the removed `CHARSETS` object.
52
+
53
+
54
+ ## 4.1.0 — remove legacy catalogs
55
+
56
+ This requested minor version contains breaking API removals: `CHARSETS`, `ART_STYLE_PRESETS`, `CHARSET_SEQUENCES`, `LIVING_STYLE_PRESETS`, `CharsetKey`, `CharsetSequenceKey`, and `LivingStylePresetKey`. Search source, saved settings, generated snippets, and documentation before upgrading. Use `/studio`'s 15 `STUDIO_STYLES` for render styles; use `/core`'s curated `CHARACTER_SETS` for ASCII alphabets. Replace old shorthand `artStyle` names with actual Studio rendering or explicit core charset/renderMode/colorMode options. Core only accepts `artStyle: 'classic'`. Custom `charset` and `charsetFrames` remain supported. Fine-dither hover integration uses explicit `fineDither: true`, not the removed terminal preset.
@@ -1,71 +0,0 @@
1
- /** Curated ASCII ramps. Use custom text to supply a different alphabet. */
2
- declare const CHARACTER_SETS: {
3
- readonly standard: {
4
- readonly label: "Classic ASCII";
5
- readonly chars: " .:-=+*#%@";
6
- };
7
- readonly asciify: {
8
- readonly label: "Asciify";
9
- readonly chars: " .:-=+ASCIIFY#@";
10
- };
11
- readonly minimal: {
12
- readonly label: "Minimal";
13
- readonly chars: " .:+";
14
- };
15
- readonly detailed: {
16
- readonly label: "Detailed";
17
- readonly chars: " .,:;i1tfLCG08@";
18
- };
19
- readonly letters: {
20
- readonly label: "Letters";
21
- readonly chars: " .ilLCFTYASMW";
22
- };
23
- readonly technical: {
24
- readonly label: "Technical";
25
- readonly chars: " .:;>_/[{}]=+*#@$";
26
- };
27
- readonly blocks: {
28
- readonly label: "Tonal blocks";
29
- readonly chars: " ░▒▓█";
30
- };
31
- readonly braille: {
32
- readonly label: "Braille";
33
- readonly chars: " ⠁⠃⠇⡇⣇⣧⣷⣿";
34
- };
35
- };
36
- declare const STUDIO_CHARACTER_SETS: {
37
- readonly standard: {
38
- readonly label: "Classic ASCII";
39
- readonly chars: " .:-=+*#%@";
40
- };
41
- readonly asciify: {
42
- readonly label: "Asciify";
43
- readonly chars: " .:-=+ASCIIFY#@";
44
- };
45
- readonly minimal: {
46
- readonly label: "Minimal";
47
- readonly chars: " .:+";
48
- };
49
- readonly detailed: {
50
- readonly label: "Detailed";
51
- readonly chars: " .,:;i1tfLCG08@";
52
- };
53
- readonly letters: {
54
- readonly label: "Letters";
55
- readonly chars: " .ilLCFTYASMW";
56
- };
57
- readonly technical: {
58
- readonly label: "Technical";
59
- readonly chars: " .:;>_/[{}]=+*#@$";
60
- };
61
- readonly blocks: {
62
- readonly label: "Tonal blocks";
63
- readonly chars: " ░▒▓█";
64
- };
65
- readonly braille: {
66
- readonly label: "Braille";
67
- readonly chars: " ⠁⠃⠇⡇⣇⣧⣷⣿";
68
- };
69
- };
70
-
71
- export { CHARACTER_SETS as C, STUDIO_CHARACTER_SETS as S };
@@ -1,71 +0,0 @@
1
- /** Curated ASCII ramps. Use custom text to supply a different alphabet. */
2
- declare const CHARACTER_SETS: {
3
- readonly standard: {
4
- readonly label: "Classic ASCII";
5
- readonly chars: " .:-=+*#%@";
6
- };
7
- readonly asciify: {
8
- readonly label: "Asciify";
9
- readonly chars: " .:-=+ASCIIFY#@";
10
- };
11
- readonly minimal: {
12
- readonly label: "Minimal";
13
- readonly chars: " .:+";
14
- };
15
- readonly detailed: {
16
- readonly label: "Detailed";
17
- readonly chars: " .,:;i1tfLCG08@";
18
- };
19
- readonly letters: {
20
- readonly label: "Letters";
21
- readonly chars: " .ilLCFTYASMW";
22
- };
23
- readonly technical: {
24
- readonly label: "Technical";
25
- readonly chars: " .:;>_/[{}]=+*#@$";
26
- };
27
- readonly blocks: {
28
- readonly label: "Tonal blocks";
29
- readonly chars: " ░▒▓█";
30
- };
31
- readonly braille: {
32
- readonly label: "Braille";
33
- readonly chars: " ⠁⠃⠇⡇⣇⣧⣷⣿";
34
- };
35
- };
36
- declare const STUDIO_CHARACTER_SETS: {
37
- readonly standard: {
38
- readonly label: "Classic ASCII";
39
- readonly chars: " .:-=+*#%@";
40
- };
41
- readonly asciify: {
42
- readonly label: "Asciify";
43
- readonly chars: " .:-=+ASCIIFY#@";
44
- };
45
- readonly minimal: {
46
- readonly label: "Minimal";
47
- readonly chars: " .:+";
48
- };
49
- readonly detailed: {
50
- readonly label: "Detailed";
51
- readonly chars: " .,:;i1tfLCG08@";
52
- };
53
- readonly letters: {
54
- readonly label: "Letters";
55
- readonly chars: " .ilLCFTYASMW";
56
- };
57
- readonly technical: {
58
- readonly label: "Technical";
59
- readonly chars: " .:;>_/[{}]=+*#@$";
60
- };
61
- readonly blocks: {
62
- readonly label: "Tonal blocks";
63
- readonly chars: " ░▒▓█";
64
- };
65
- readonly braille: {
66
- readonly label: "Braille";
67
- readonly chars: " ⠁⠃⠇⡇⣇⣧⣷⣿";
68
- };
69
- };
70
-
71
- export { CHARACTER_SETS as C, STUDIO_CHARACTER_SETS as S };