asciify-engine 4.3.0 → 4.4.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.
@@ -33,18 +33,23 @@ The positioned host must fit the displayed source canvas. The surface appends a
33
33
  | Module `effect` | Behavior |
34
34
  | --- | --- |
35
35
  | `trail` | Density wake with a fading tail; glyph grid remains fixed. |
36
- | `water` | Local refraction with aligned outer boundaries. |
36
+ | `water` | Local refraction; opt into protected boundaries with `edgeSafe: true`. |
37
37
  | `contour` | Expanding ring echoes along the pointer path. |
38
38
  | `dissolve` | Fading/reforming density trace with a lingering tail. |
39
39
  | `silk` | Directional folds following the stroke. |
40
40
  | `vortex` | Local rotational wake. |
41
+ | `magnetic` | Attracts the field toward a stroke, then relaxes. |
42
+ | `scatter` | Spatially varied radial scatter with a decaying wake. |
43
+ | `etch` | Signed light-and-shadow impression; the glyph grid stays fixed. |
44
+ | `elastic` | Directional momentum, damped recoil and a return to rest. |
45
+ | `rake` | Alternating strips shear with the pointer, then align again. |
41
46
  | `none` | No hover effect. |
42
47
 
43
48
  These are `/hover` module `effect` IDs, not the root engine’s legacy `HoverEffect` values. For example, passing `hoverEffect: 'water'` to the published engine is invalid.
44
49
 
45
50
  ## Still-image motion and dither
46
51
 
47
- The module's `motion` IDs are `none`, `caustics` (traveling light on a fixed grid), `current` (Slow Current), and `reform` (Reveal & Reform). Keep source-video motion alone unless the user intentionally wants another animation layered onto it. For a still, select one motion and a restrained `motionSpeed`, rather than stacking effects.
52
+ The module's `motion` IDs are `none`, `caustics` (traveling light on a fixed grid), `current` (Slow Current), `reform` (Reveal & Reform), `sheen` (diagonal light sweep), `tidal` (Tidal Rings), and `grain` (Living Grain). 4.4 adds `parallax` (shallow drift), `weave` (interlaced flow), `print` (staggered row registration), and `trace` (light that follows source-image tonal contours). Sheen, Living Grain and Contour Light keep the grid anchored. Contour Light uses source luminance; pass `getFrame` for exact source tones when layering a surface over an existing canvas. Keep source-video motion alone unless the user intentionally wants another animation layered onto it. For a still, select one motion and a restrained `motionSpeed`, rather than stacking effects.
48
53
 
49
54
  For the website's fine-dither treatment, use the module's `fineDither: true` and `ditherStrength` after matching the backing canvas's character settings. This is separate from the core renderer’s built-in dither behavior. Check a still and a moving scene for flicker before choosing the default.
50
55
 
@@ -60,3 +65,13 @@ When using the low-level object-frame API, pass `getFrame: () => currentFrame` t
60
65
  ## Hero finish
61
66
 
62
67
  Version 1.3.0 adds text-shaped charcoal cutouts (`textMask`), peripheral scanline/fringe control (`edgeEffect`), fixed accent ink, Prism edge softness (`edgeSoftness`), and fixed-grid fluid Trail. These additions ship in **npm 1.3.0**. Upgrade older applications before using them. See the [complete API, layering example, lifecycle, and fallback limits](hero-finish.md).
68
+
69
+ ## Catalogs and useful combinations (4.4)
70
+
71
+ Build controls from `STUDIO_HOVERS` and `STUDIO_MOTIONS`, exported by `/studio` and `/hover`. Each entry includes `value`, `label`, `group`, and `description`. Use the `value` as the API ID; “Emboss” is `etch` and “Contour Light” is `trace`. Do not maintain a second hard-coded menu or use the legacy core hover IDs for these interactions.
72
+
73
+ For a fixed grid, try Contour Light with Emboss. For continuous spatial movement, try Parallax with Elastic. For a fabric-like treatment, try Woven Flow with Rake. These are combinations of two independent settings, not additional art styles. Keep strength restrained until you have checked the source at actual display size.
74
+
75
+ All ambient modes repeat after `12 / speed` seconds. Looping the motion does not guarantee that a source video, film grain, dust, glitch or animated dither has the same boundary. Exported PNG/JPEG captures one frame; MP4/WebM/GIF carries autonomous motion, not live pointer movement. For complete composition export, use `/studio` rather than capturing the hover overlay.
76
+
77
+ The pointer simulations have bounded storage. Elastic allocates its two velocity buffers only when first selected; idle effects stop. This is not a device-independent FPS promise. Test dense grids, fast reversal and the actual finish stack on the target device.
@@ -45,7 +45,7 @@ Start with `normalizeStudioSettings({ ... })`, `DEFAULT_STUDIO_SETTINGS`, or `st
45
45
  - `mask`: enable/invert and a list of rectangle, ellipse, or brush shapes. Coordinates are normalized to the output canvas. Masks are bounded to 64 shapes and 2,048 total brush points. Masking affects the artwork; the backdrop remains visible.
46
46
  - `lights`: at most four colored radial lights with normalized position, radius, and intensity. This is 2D illumination, not physically based material lighting.
47
47
  - `effects`: independent character bloom and whole-composition bloom, prism, grain, dust, scanlines, CRT, vignette, glitch, pixelation, halftone, and Gaussian/directional/radial/progressive blur. Optical effects use an optional WebGL pass. Check `capabilities.gpuFinish` after an effect renders; unavailable GPU effects must not be described as applied.
48
- - `hover`: Trail, Water, Contour, Dissolve, Silk, Vortex, or none; strength, normalized radius, optional `edgeSafe`. Hover is live interaction; it is not recorded into offline exports.
48
+ - `hover`: Trail, Water, Contour, Dissolve, Silk, Vortex, Magnetic Pull, Scatter, or none; strength, normalized radius, optional `edgeSafe`. Hover is live interaction; it is not recorded into offline exports.
49
49
 
50
50
  `serializeStudioSettings` and `parseStudioSettings` round-trip validated, versioned state. Media URLs/files are excluded. Unknown fields are discarded, values are bounded, future schema versions and oversized imports are rejected. Share source files separately. `restyleStudio` chooses another curated look while preserving crop, ratio, and mask.
51
51
 
@@ -109,7 +109,7 @@ Other renderer styles define their own marks, so character controls only apply t
109
109
 
110
110
  Use `studioGrid(width, height, settings, maxCells, pixelRatio)` to inspect `minimum`, `cell`, `columns`, `rows`, and `limited` at the actual preview resolution. ASCII/tile renderers use `cellSize`; Dither uses `dither.scale`. Respect the returned minimum in a size picker instead of offering a range that the performance budget silently clamps. Use the same budget and reference width for export to retain density.
111
111
 
112
- For PNG/JPEG, pass `time: player.time` to `exportStudio` to save the selected frame. Default time is zero; animation exports start at zero. Snapshot the time/settings/preview size before asynchronous loading. The editor's Export tab separates Image and Animation, shows validated pixel sizes and keeps website code in an expandable section.
112
+ For PNG/JPEG, pass `time: player.time` and `motionTime: player.motionTime` to `exportStudio` to save the selected frame. Default time is zero; animation exports start at zero. Snapshot the time/settings/preview size before asynchronous loading. The editor's Export tab separates Image and Animation, shows validated pixel sizes and keeps website code in an expandable section.
113
113
 
114
114
  ## Still-image motion (3.0)
115
115
 
@@ -129,7 +129,7 @@ For menus shared with a media hero, import the eight `CHARACTER_SETS` from `asci
129
129
 
130
130
  ## Fine detail and controls (4.2)
131
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.
132
+ - The style catalog adds `hex` (hexagonal tiles), `led` (circular emitters), and `cmyk` (offset cyan/magenta/yellow/black ink dots on white paper). CMYK derives channel coverage from the selected color mode and tonal hover/motion. These remain in the optional `/studio` entry; `/core` does not import them.
133
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
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
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.
@@ -137,7 +137,7 @@ For menus shared with a media hero, import the eight `CHARACTER_SETS` from `asci
137
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
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
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.
140
+ - `motion.amount` is 0–2, default 1. It changes displacement/light/dissolve strength without changing phase or speed. Zero retains the stationary image. Enumerate `STUDIO_MOTIONS` for all supported motion types, including the 4.3 additions below.
141
141
 
142
142
  ```ts
143
143
  const studio = await mountStudio(canvas, file, {
@@ -175,3 +175,13 @@ Base cycles last 12 seconds; speed scales duration. Studio amount scales strengt
175
175
  Keep automatic motion off for source video unless requested. Respect reduced motion.
176
176
  These are local effects, not AI-generated frames. Frame rate depends on device,
177
177
  resolution and other effects; no universal FPS guarantee.
178
+
179
+ ## Performance fixes (4.3.1)
180
+
181
+ Stationary artwork, masks, lights, backdrops and character bloom are cached while finishing grain/dust/glitch continue. Source/settings/layout edits invalidate the composition; pointer motion redraws until the field settles and restores a clean final frame. Unused dither motion on other styles and zero-strength ambient motion no longer keep a still preview awake. Ordered Bayer threshold tables avoid per-pixel recurrence without changing quantized output. CMYK now honors tonal hover/motion and gray/accent color modes. Still exports accept `motionTime` from the mounted preview to preserve the selected phase after speed edits; animation exports still start at zero.
182
+
183
+ ## Expanded motion library (4.4)
184
+
185
+ Use `STUDIO_HOVERS` and `STUDIO_MOTIONS` to show all eleven hovers and ten still-image motions, plus Off, grouped by behavior. New hover IDs are `etch`, `elastic`, `rake`; new motion IDs are `parallax`, `weave`, `print`, `trace`. `hover.radius` and `hover.strength` are independent of `motion.speed` and `motion.amount`. All remain serialized in look links and saved projects. A static photo needs no video input or AI service to animate.
186
+
187
+ Example: `player.update({ motion: { type: 'trace', speed: 1, amount: .7 }, hover: { effect: 'etch', radius: .45, strength: .65 } })`. Tone and character choices remain yours. See [effect behaviors and combinations](studio-effects.md#catalogs-and-useful-combinations-44). Do not run several looping thumbnail canvases just to display this catalog; apply the selected treatment to one shared preview.
@@ -54,3 +54,11 @@ Use `CHARACTER_SETS` from root or `/core` for the same eight choices as the edit
54
54
  ## 4.1.0 — remove legacy catalogs
55
55
 
56
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.
57
+
58
+ ## 4.3 and 4.3.1
59
+
60
+ 4.3 adds Magnetic Pull and Scatter hover (`magnetic`, `scatter`) and Sheen, Tidal Rings and Living Grain motion (`sheen`, `tidal`, `grain`). Old defaults remain. 4.3.1 fixes CMYK tonal interactions and idle-frame work, caches stationary compositions, and accelerates ordered dithering without changing its output. Read [project-integration.md](project-integration.md) for one-owner live integration and independent PNG/video export.
61
+
62
+ ## 4.4
63
+
64
+ Adds Emboss, Elastic and Rake hover; Parallax, Woven Flow, Print Shift and Contour Light motion. Existing IDs, defaults, saved projects and v1 settings remain valid. `STUDIO_HOVERS` and `STUDIO_MOTIONS` are now shared public catalogs in `/studio` and `/hover`; generate selection controls from them. The four new ambient IDs are also accepted by core `animationStyle`. Keep only one owner for motion.
@@ -1,39 +0,0 @@
1
- type AmbientMotion = 'none' | 'caustics' | 'current' | 'reform' | 'sheen' | 'tidal' | 'grain';
2
- declare const MOTION_STYLES: readonly [{
3
- readonly value: "none";
4
- readonly mode: "none";
5
- readonly label: "Off";
6
- readonly description: "Keep the image still. Hover stays available.";
7
- }, {
8
- readonly value: "caustics";
9
- readonly mode: "caustics";
10
- readonly label: "Caustics";
11
- readonly description: "Soft ribbons of light travel across a stationary character grid.";
12
- }, {
13
- readonly value: "current";
14
- readonly mode: "current";
15
- readonly label: "Slow Current";
16
- readonly description: "A gentle flow through the image, with steady edges.";
17
- }, {
18
- readonly value: "reform";
19
- readonly mode: "reform";
20
- readonly label: "Reveal & Reform";
21
- readonly description: "Disperse, gather, then hold the complete image.";
22
- }, {
23
- readonly value: "sheen";
24
- readonly mode: "sheen";
25
- readonly label: "Sheen";
26
- readonly description: "A broad diagonal light sweep; characters stay anchored.";
27
- }, {
28
- readonly value: "tidal";
29
- readonly mode: "tidal";
30
- readonly label: "Tidal Rings";
31
- readonly description: "Concentric currents travel outward, with protected edges.";
32
- }, {
33
- readonly value: "grain";
34
- readonly mode: "grain";
35
- readonly label: "Living Grain";
36
- readonly description: "Slow, individually phased tonal changes on a stationary grid.";
37
- }];
38
-
39
- export { type AmbientMotion as A, MOTION_STYLES as M };
@@ -1,39 +0,0 @@
1
- type AmbientMotion = 'none' | 'caustics' | 'current' | 'reform' | 'sheen' | 'tidal' | 'grain';
2
- declare const MOTION_STYLES: readonly [{
3
- readonly value: "none";
4
- readonly mode: "none";
5
- readonly label: "Off";
6
- readonly description: "Keep the image still. Hover stays available.";
7
- }, {
8
- readonly value: "caustics";
9
- readonly mode: "caustics";
10
- readonly label: "Caustics";
11
- readonly description: "Soft ribbons of light travel across a stationary character grid.";
12
- }, {
13
- readonly value: "current";
14
- readonly mode: "current";
15
- readonly label: "Slow Current";
16
- readonly description: "A gentle flow through the image, with steady edges.";
17
- }, {
18
- readonly value: "reform";
19
- readonly mode: "reform";
20
- readonly label: "Reveal & Reform";
21
- readonly description: "Disperse, gather, then hold the complete image.";
22
- }, {
23
- readonly value: "sheen";
24
- readonly mode: "sheen";
25
- readonly label: "Sheen";
26
- readonly description: "A broad diagonal light sweep; characters stay anchored.";
27
- }, {
28
- readonly value: "tidal";
29
- readonly mode: "tidal";
30
- readonly label: "Tidal Rings";
31
- readonly description: "Concentric currents travel outward, with protected edges.";
32
- }, {
33
- readonly value: "grain";
34
- readonly mode: "grain";
35
- readonly label: "Living Grain";
36
- readonly description: "Slow, individually phased tonal changes on a stationary grid.";
37
- }];
38
-
39
- export { type AmbientMotion as A, MOTION_STYLES as M };