asciify-engine 4.17.0 → 4.19.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/README.md +18 -0
- package/dist/{characters-BgG9AZQl.d.cts → characters-BgECi5Lf.d.cts} +2 -2
- package/dist/{characters-BgG9AZQl.d.ts → characters-BgECi5Lf.d.ts} +2 -2
- package/dist/core.cjs +1 -1
- package/dist/core.d.cts +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.js +1 -1
- package/dist/field.cjs +1 -1
- package/dist/field.d.cts +18 -5
- package/dist/field.d.ts +18 -5
- package/dist/field.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/kit.cjs +1 -1
- package/dist/kit.d.cts +267 -69
- package/dist/kit.d.ts +267 -69
- package/dist/kit.js +1 -1
- package/dist/studio.cjs +1 -1
- package/dist/studio.d.cts +1 -1
- package/dist/studio.d.ts +1 -1
- package/dist/studio.js +1 -1
- package/package.json +1 -1
- package/skills/asciify-engine/SKILL.md +14 -16
- package/skills/asciify-engine/references/applying-asciify.md +11 -13
- package/skills/asciify-engine/references/components.md +38 -42
- package/skills/asciify-engine/references/design-matching.md +1 -1
- package/skills/asciify-engine/references/glyph-field.md +2 -1
- package/skills/asciify-engine/references/kit.md +73 -66
- package/skills/asciify-engine/references/looks.md +1043 -0
- package/skills/asciify-engine/references/media-api.md +4 -6
- package/skills/asciify-engine/references/upgrading.md +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "asciify-engine",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.19.0",
|
|
4
4
|
"description": "Framework-agnostic ASCII art engine. Convert images, videos, and GIFs into ASCII art rendered on canvas, or run full-bleed GPU character fields with a fluid cursor wake.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: asciify-engine
|
|
3
|
-
description: Apply Asciify the way asciify.org does - ASCII components and backgrounds that belong in a real interface, inked from the theme, clear around text, inside the page's radii and motion. Use for UI components in characters (loading, status, toasts, tabs, AI states, charts, transitions, pages), animated ASCII backgrounds, and also photo, video and GIF conversion, GPU character fields, art styles and export, hover and motion, layered typography and rendering performance.
|
|
3
|
+
description: Apply Asciify the way asciify.org does - ASCII components and backgrounds that belong in a real interface, inked from the theme, clear around text, inside the page's radii and motion. Use for UI components in characters (loading, status, toasts, tabs, AI states, charts, transitions, pages), animated ASCII backgrounds, and also photo, video and GIF conversion, GPU character fields, artwork looks for wallpapers, posters and prints, art styles and export, hover and motion, layered typography and rendering performance.
|
|
4
4
|
metadata:
|
|
5
|
-
tested-engine: "4.
|
|
5
|
+
tested-engine: "4.19.0"
|
|
6
6
|
updated: "2026-10-17"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Asciify Engine
|
|
10
10
|
|
|
11
|
-
Use the published `asciify-engine` npm package. Tested against **4.
|
|
11
|
+
Use the published `asciify-engine` npm package. Tested against **4.19.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
|
-
- Components: https://asciify.org/components · Backgrounds: https://asciify.org/backgrounds
|
|
14
|
+
- Components: https://asciify.org/components · Looks: https://asciify.org/looks · Backgrounds: https://asciify.org/backgrounds
|
|
15
15
|
- Playground: https://asciify.org/editor · API documentation: https://asciify.org/docs/api
|
|
16
16
|
- Repository: https://github.com/ayangabryl/asciify-engine
|
|
17
17
|
|
|
@@ -36,11 +36,12 @@ Most requests are a feeling ("make the loading state feel alive", "a calm backgr
|
|
|
36
36
|
| The user wants | Use |
|
|
37
37
|
| --- | --- |
|
|
38
38
|
| A UI component in characters: button loading, status, toasts, tabs, pills, odometer, chart, AI thinking and streaming, transitions, sign-in, pricing, 404 | `asciify-engine/kit` ([applying-asciify.md](references/applying-asciify.md), [components.md](references/components.md), [kit.md](references/kit.md)) |
|
|
39
|
-
| A background behind a hero, pricing, docs or a section, light or dark | Kit `fieldBackground(el, { preset: 'hero', clear })` (asciify.org's hero) or `background(el, { preset, clear })` with one of the
|
|
39
|
+
| A background behind a hero, pricing, docs or a section, light or dark | Kit `fieldBackground(el, { preset: 'hero', clear })` (asciify.org's hero) or `background(el, { preset, clear })` with one of the 13 curated presets below |
|
|
40
40
|
| Their word or brand in characters | Kit `wordmark`, or `background()` with `wordField` |
|
|
41
41
|
| Their video in characters on the page | Kit `asciiVideo` |
|
|
42
42
|
| Their photo, video or GIF converted, optionally answering the cursor | Advanced: `asciify` / `asciifyVideo` / `asciifyGif`, plus `mountHover` from `/hover` |
|
|
43
43
|
| A full-bleed field with a look the kit has no option for | Advanced: `mountGlyphField` from `/field` ([glyph-field.md](references/glyph-field.md)) |
|
|
44
|
+
| Their photo or video as finished artwork in a named look: a wallpaper, poster, cover, print or hero artwork ("newsprint", "riso", "phosphor", "engraving", "Lego") | `mountStudio` / `exportStudio` from `/studio` with a look from [looks.md](references/looks.md) |
|
|
44
45
|
| Art styles, saved looks, masks, effects, PNG/MP4/GIF export | Advanced: `mountStudio` from `/studio` ([studio-workspace.md](references/studio-workspace.md)) |
|
|
45
46
|
| Several media and text layers in one artwork | Advanced: `mountStudioProject` from `/studio` ([layered-projects.md](references/layered-projects.md)) |
|
|
46
47
|
| A text banner or lettering | Advanced: `asciifyText` / `renderTextToCanvas` |
|
|
@@ -56,25 +57,22 @@ const b = beam(card, { palette: 'mono', mode: 'pulse' });
|
|
|
56
57
|
// On unmount: b.destroy();
|
|
57
58
|
```
|
|
58
59
|
|
|
59
|
-
`background()`,
|
|
60
|
+
`background()`, its presets, `lazy`, `poster`, `setFieldBudget` and `setGlobalLook` are new in 4.14.0; `halo`, `ripple`, `mesh`, `interference`, `constellation`, `cascade`, the GPU `caustics`, `contour` and `aurora`, and the `mark` option are new in 4.19.0. Check that the installed `asciify-engine/kit` exports them; if not, upgrade ([upgrading.md](references/upgrading.md)).
|
|
60
61
|
|
|
61
62
|
## Backgrounds
|
|
62
63
|
|
|
63
|
-
`background(element, { preset })` draws every background on asciify.org/backgrounds
|
|
64
|
+
`background(element, { preset })` draws every background on asciify.org/backgrounds as a scene of the GPU glyph field, in the site's graphite inks and following the global look. Import presets by name; a page pays only for those it imports. `cursor: false` turns the pointer response off for any of them. Which one suits which surface, and how to keep it calm, is in [applying-asciify.md](references/applying-asciify.md#9-backgrounds).
|
|
64
65
|
|
|
65
66
|
```ts
|
|
66
|
-
import { background,
|
|
67
|
-
const bg = background(pricing, { preset:
|
|
67
|
+
import { background, swell } from 'asciify-engine/kit';
|
|
68
|
+
const bg = background(pricing, { preset: swell, clear: pricingCopy });
|
|
68
69
|
```
|
|
69
70
|
|
|
70
|
-
The
|
|
71
|
+
The 13 curated presets, as export → `id` (name), all on the GPU glyph field (WebGL2, sharing the context budget): `swell` (Swell, dots or characters), `drift` (Drift), `halo` (Halo), `caustics` (Caustics), `contour` (Contour), `aurora` (Aurora), `ripple` (Ripple), `mesh` (Mesh), `interference` (Interference), `constellation` (Constellation), `cascade` (Cascade), `wordField` → `field` (Field), `fluid` (Fluid).
|
|
71
72
|
|
|
72
|
-
|
|
73
|
-
- 2D canvas (no WebGL): `caustics` → `caustics` (Caustics), `contour` → `contour` (Contour), `facet` → `facet` (Facet), `etch` → `etch` (Etch), `moire` → `moire` (Moiré), `weave` → `weave` (Weave), `veil` → `veil` (Veil), `dune` → `dune` (Dune), `wave` → `wave` (Wave), `aurora` → `aurora` (Aurora), `noise` → `noise` (Noise), `silk` → `silk` (Silk), `rain` → `rain` (Rain), `stars` → `stars` (Stars), `pulse` → `pulse` (Pulse), `grid` → `grid` (Grid), `voidWell` → `void` (Void), `morph` → `morph` (Morph), `fire` → `fire` (Fire), `dna` → `dna` (DNA), `terrain` → `terrain` (Terrain), `circuit` → `circuit` (Circuit).
|
|
73
|
+
The retired presets (`halftone`, `dna`, `circuit`, `fire`, `grid`, `morph`, `noise`, `pulse`, `rain`, `silk`, `stars`, `terrain`, `veil`, `voidWell`, `wave`, `weave`, `dune`, `etch`, `facet`, `moire`) are still exported and marked `@deprecated` so old code runs; do not reach for them in new work. [kit.md](references/kit.md#backgrounds) maps each to its replacement. `fieldBackground` is separate: its `hero`, `brand` and `notFound` presets are the asciify.org hero ground, the same ground in the brand colour, and the 404.
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
Downloaded templates from asciify.org/backgrounds (`asciiBackground` from a local `./wave.js`) still work in apps that already use them; new work uses `background()`.
|
|
75
|
+
Templates already downloaded from asciify.org/backgrounds (`asciiBackground` from a local `./wave.js`) keep working in apps that ship them, but the site no longer offers them; move those apps to `background()` with the closest preset (kit.md maps each).
|
|
78
76
|
|
|
79
77
|
## Install the agent skill
|
|
80
78
|
|
|
@@ -191,7 +189,7 @@ Keep these as sibling layers. A transformed or isolated content wrapper can trap
|
|
|
191
189
|
|
|
192
190
|
## Studio composition and export
|
|
193
191
|
|
|
194
|
-
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). `/studio` is separate from `/hover` and `AsciiOptions`; do not replace an existing hero pipeline just to add a backdrop.
|
|
192
|
+
For a finished artwork in a ready look (wallpaper, poster, cover, print), start from [references/looks.md](references/looks.md): 22 looks, each with the prompt, exact settings, and wallpaper/poster/loop export sizes. 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). `/studio` is separate from `/hover` and `AsciiOptions`; do not replace an existing hero pipeline just to add a backdrop.
|
|
195
193
|
|
|
196
194
|
## GPU glyph fields
|
|
197
195
|
|
|
@@ -57,9 +57,9 @@ Rules:
|
|
|
57
57
|
- **Never a new colour.** No hex that is not a token (map to the app's tokens as above), no black canvas on a light page, no white glow on a coloured image.
|
|
58
58
|
|
|
59
59
|
```ts
|
|
60
|
-
import { background,
|
|
60
|
+
import { background, swell, statusOrb, beam } from 'asciify-engine/kit';
|
|
61
61
|
|
|
62
|
-
background(pricing, { preset:
|
|
62
|
+
background(pricing, { preset: swell, clear: pricingCopy, ink: '--ascii-ink' }); // the token, re-read per theme
|
|
63
63
|
const orb = statusOrb(orbSlot); // strong ink at rest; outcomes read --ascii-success, --ascii-warning, --ascii-error
|
|
64
64
|
beam(planCard, { palette: 'mono', mode: 'pulse' }); // the quiet beam; 'colorful' only when asked for
|
|
65
65
|
orb.loading();
|
|
@@ -93,8 +93,8 @@ Text never sits on raw characters, and never in a box. Two layers do the work:
|
|
|
93
93
|
|
|
94
94
|
| Surface | Cell size | Characters | Site reference |
|
|
95
95
|
| --- | --- | --- | --- |
|
|
96
|
-
| Page hero ground | 10–12px, broad shapes | Sparse: `' .:+*#'` in the mono face | `fieldBackground` `hero` (10px), `drift` (11px), `
|
|
97
|
-
| Section band or card stage | 7–10px | Fuller ramp for images (`' .:-=+*#%@'`), quiet ramp for grounds | images 7px, character fields 10px,
|
|
96
|
+
| Page hero ground | 10–12px, broad shapes | Sparse: `' .:+*#'` in the mono face | `fieldBackground` `hero` (10px), `drift` (11px), `swell` (10px dot spacing), the scene presets (11px) |
|
|
97
|
+
| Section band or card stage | 7–10px | Fuller ramp for images (`' .:-=+*#%@'`), quiet ramp for grounds | images 7px, character fields 10px, dots 9px |
|
|
98
98
|
| Control: button, pill, tabs, code input, odometer | Leave it to the kit | The kit fits cells to the element's text | Use a monospaced label for `buttonLoading` |
|
|
99
99
|
|
|
100
100
|
- One density per surface: a stage does not mix a 7px image and a 12px ground.
|
|
@@ -187,29 +187,27 @@ publishButton.addEventListener('click', async () => {
|
|
|
187
187
|
|
|
188
188
|
## 9. Backgrounds
|
|
189
189
|
|
|
190
|
-
`background(element, { preset })` draws any of the
|
|
190
|
+
`background(element, { preset })` draws any of the 13 curated presets from asciify.org/backgrounds under the element's content. Choose by surface:
|
|
191
191
|
|
|
192
192
|
| Surface | Presets | Notes |
|
|
193
193
|
| --- | --- | --- |
|
|
194
|
-
| Product hero, pricing, docs landing, behind copy | `drift`, `
|
|
194
|
+
| Product hero, pricing, docs landing, behind copy | `swell`, `drift`, `halo`, or `fieldBackground` `hero` | Grounds that clear around `clear`. `swell` is the finest, a grid in slow waves (dots, or characters with `mark: 'glyph'`) quiet in the middle even without `clear`; `halo` frames a single headline; `fieldBackground` `hero` is asciify.org's own hero, with ripples and `pulse()`. |
|
|
195
195
|
| A brand or name moment | `wordField` (id `field`), `fieldBackground` `brand` | Your word in the field; keep copy off its centre. |
|
|
196
|
-
| Art-first hero with little copy | `fluid` |
|
|
197
|
-
| Quiet texture: section bands, footers, empty states, side panels | `caustics`, `contour`, `
|
|
198
|
-
| An interactive moment
|
|
199
|
-
| A themed subject the page is about | `rain`, `grid`, `morph`, `fire`, `dna`, `terrain`, `circuit` | Loud. Use only when the subject matches (DNA for a biotech page), with low opacity and copy beside, not over. |
|
|
196
|
+
| Art-first hero with little copy | `fluid`, `mesh` | `fluid` is the original Asciify hero, 7px cells at 0.7 opacity; `mesh` is a soft gradient in characters. Not behind reading text. |
|
|
197
|
+
| Quiet texture: section bands, footers, empty states, side panels | `caustics`, `contour`, `interference`, `constellation` | Fine lines, slow. Safe behind text with `clear`. |
|
|
198
|
+
| An ambient or interactive moment | `aurora`, `ripple`, `cascade` | `aurora` sits above the copy; `ripple` drops rings where the pointer moves; `cascade` falls in three depths. Keep them away from forms and body copy. |
|
|
200
199
|
|
|
201
200
|
Keep them calm:
|
|
202
201
|
|
|
203
202
|
- `speed` at or below the preset's default; `cursor: false` near forms and copy.
|
|
204
|
-
-
|
|
205
|
-
- Always `clear` the copy and add the veil from section 3; on the /backgrounds page the copy also sits on the side the field fades toward.
|
|
203
|
+
- Every preset keeps a quiet zone; still `clear` the copy and add the veil from section 3.
|
|
206
204
|
- One background per page section, under one `isolation: isolate` host with its own background colour.
|
|
207
205
|
- `setPreset()` cross-fades in place for a picker; do not mount a second background.
|
|
208
206
|
|
|
209
207
|
```ts
|
|
210
208
|
import { background, contour, caustics } from 'asciify-engine/kit';
|
|
211
209
|
|
|
212
|
-
const section = background(features, { preset: contour, clear: featuresCopy, opacity: 0.
|
|
210
|
+
const section = background(features, { preset: contour, clear: featuresCopy, opacity: 0.8, cursor: false });
|
|
213
211
|
themePicker.addEventListener('change', () => section.setPreset(caustics)); // keeps clear, opacity and cursor
|
|
214
212
|
```
|
|
215
213
|
|
|
@@ -38,14 +38,14 @@ reply.then(() => orb.done());
|
|
|
38
38
|
Category: AI
|
|
39
39
|
|
|
40
40
|
Prompt:
|
|
41
|
-
“Make a ⌘K command palette for [our app] with Asciify: it opens by condensing out of characters at the trigger,
|
|
41
|
+
“Make a ⌘K command palette for [our app] with Asciify: it opens by condensing out of characters at the trigger, a soft highlight glides between rows, rows a search brings in resolve out of characters, and the AI row shimmers as a crest turns its letters to characters and back. Enter runs the action with a pulse.”
|
|
42
42
|
|
|
43
43
|
```ts
|
|
44
44
|
import { commandPalette } from 'asciify-engine/kit';
|
|
45
45
|
|
|
46
|
-
// ⌘K or the trigger opens it; arrows, Enter and Escape are wired; rows are [role="option"] with an id
|
|
46
|
+
// ⌘K or the trigger opens it; arrows, Enter and Escape are wired; rows are [role="option"] with an id, AI rows carry data-ai
|
|
47
47
|
commandPalette(palettePanel, { trigger: paletteTrigger, onRun: (i, row) => commands[row.dataset.id!].run() });
|
|
48
|
-
searchInput.oninput = () => renderRows(searchInput.value); // the kit re-selects the first row
|
|
48
|
+
searchInput.oninput = () => renderRows(searchInput.value); // the kit re-selects the first row; new rows resolve out of characters
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
## button-loading: Button loading
|
|
@@ -68,15 +68,16 @@ deployButton.onclick = async () => {
|
|
|
68
68
|
Category: Components
|
|
69
69
|
|
|
70
70
|
Prompt:
|
|
71
|
-
“Make [our status badges] Asciify pills: tinted pills
|
|
71
|
+
“Make [our status badges] Asciify pills: soft tinted pills with one glyph before the label, a dot in the status tone that breathes while live, turns as a half-filled spinner while syncing and blinks when a job fails; a solid ink New pill whose sparkle twinkles on hover; and a count that rolls through glyphs. Keep every character inside its pill and off the text.”
|
|
72
72
|
|
|
73
73
|
```ts
|
|
74
74
|
import { pill } from 'asciify-engine/kit';
|
|
75
75
|
|
|
76
|
-
// <span class="pill" data-tone="green" data-live><span data-dot></span>Live</span
|
|
76
|
+
// <span class="pill" data-tone="green" data-live><span data-dot></span><span>Live</span></span>
|
|
77
|
+
// <span class="pill" data-tone="new"><span data-dot></span><span>New</span></span>, <span class="pill" data-count>12</span>
|
|
77
78
|
const pills = pill(document.querySelectorAll<HTMLElement>('.pill'));
|
|
78
|
-
statusPill.dataset.tone = '
|
|
79
|
-
pills.refresh(); // tone changes ease over 240ms
|
|
79
|
+
statusPill.dataset.tone = 'red';
|
|
80
|
+
pills.refresh(); // tone changes ease over 240ms; red blinks the dot
|
|
80
81
|
pills.count(14); // only the changed digits roll
|
|
81
82
|
```
|
|
82
83
|
|
|
@@ -84,13 +85,14 @@ pills.count(14); // only the changed digits roll
|
|
|
84
85
|
Category: Components
|
|
85
86
|
|
|
86
87
|
Prompt:
|
|
87
|
-
“Make [our segmented tabs] Asciify tabs: the active
|
|
88
|
+
“Make [our segmented tabs] Asciify tabs: a crisp pill glides to the active tab, its leading end first, with a row of characters along its foot that streaks toward the new tab and settles into a tapered line. The panel's figure rolls like an odometer and its text slides in from the direction of travel; arrow keys, Home and End switch tabs.”
|
|
88
89
|
|
|
89
90
|
```ts
|
|
90
|
-
import { tabs } from 'asciify-engine/kit';
|
|
91
|
+
import { odometer, tabs } from 'asciify-engine/kit';
|
|
91
92
|
|
|
92
|
-
//
|
|
93
|
-
const
|
|
93
|
+
// <span class="thumb"> in the tablist, placed from --tabs-x / --tabs-y / --tabs-w / --tabs-h; role="tab" buttons
|
|
94
|
+
const figure = odometer(valueEl, { value: 1_280_000, format: compact });
|
|
95
|
+
const t = tabs(tablist, { panels: 'none', onChange: i => figure.update({ value: VALUES[i], format: FORMATS[i] }) });
|
|
94
96
|
t.select(2);
|
|
95
97
|
```
|
|
96
98
|
|
|
@@ -155,16 +157,19 @@ replayButton.onclick = () => d.replay();
|
|
|
155
157
|
Category: Components
|
|
156
158
|
|
|
157
159
|
Prompt:
|
|
158
|
-
“Build [our visitors analytics card] with bars drawn in Asciify characters:
|
|
160
|
+
“Build [our visitors analytics card] with bars drawn in Asciify characters: crisp glyph columns with a denser cap, today lit, growing in left to right. Hover or touch scrubs the bars and rolls the headline to that day; the 7d/30d toggle glides the shared days into place while the rest grow in.”
|
|
159
161
|
|
|
160
162
|
```ts
|
|
161
|
-
import { blockChart } from 'asciify-engine/kit';
|
|
163
|
+
import { blockChart, odometer } from 'asciify-engine/kit';
|
|
162
164
|
|
|
165
|
+
let range = '7d';
|
|
166
|
+
const headline = odometer(totalEl, { value: total[range] });
|
|
167
|
+
// plot: touch-action: pan-y; draw the axis labels in HTML below it.
|
|
163
168
|
const chart = blockChart(plot, {
|
|
164
|
-
values: visits['7d'], labels: days['7d'],
|
|
165
|
-
onHover: (i, v, day) => {
|
|
169
|
+
values: visits['7d'], labels: days['7d'], look: { cellSize: 4.5 }, // small cells keep a gap between 30 bars
|
|
170
|
+
onHover: (i, v, day) => { label.textContent = day ?? 'Visitors'; headline.set(i === null ? total[range] : v!); },
|
|
166
171
|
});
|
|
167
|
-
rangeToggle.onchange = () => chart.set(visits[
|
|
172
|
+
rangeToggle.onchange = () => { range = rangeToggle.value; chart.set(visits[range], days[range]); headline.set(total[range]); };
|
|
168
173
|
```
|
|
169
174
|
|
|
170
175
|
## route-transition: Page transition
|
|
@@ -176,8 +181,8 @@ Prompt:
|
|
|
176
181
|
```ts
|
|
177
182
|
import { pageDissolve, blockChart } from 'asciify-engine/kit';
|
|
178
183
|
|
|
179
|
-
const page = pageDissolve(view
|
|
180
|
-
const chart = blockChart(chartSlot, { values: series.overview }); // at rest the chart stays in characters
|
|
184
|
+
const page = pageDissolve(view); // one wave from the clicked tab, about 430ms
|
|
185
|
+
const chart = blockChart(chartSlot, { values: series.overview, lazy: false }); // at rest the chart stays in characters
|
|
181
186
|
for (const tab of navTabs) tab.onclick = () => page.swap(() => { renderView(tab.dataset.page!); chart.set(series[tab.dataset.page!]); }, tab);
|
|
182
187
|
```
|
|
183
188
|
|
|
@@ -213,7 +218,7 @@ const code = codeInput(codeRow, { length: 6, onComplete: async c => code.verify(
|
|
|
213
218
|
Category: Components
|
|
214
219
|
|
|
215
220
|
Prompt:
|
|
216
|
-
“Make [our toasts] with Asciify: each one gathers out of characters and
|
|
221
|
+
“Make [our toasts] with Asciify: each one rises in and gathers out of characters, the stack layers by tone and soft shadow with no outlines, hover fans it out, and dismissing or swiping a toast away breaks it into glyphs that drift the way it went. Include Undo.”
|
|
217
222
|
|
|
218
223
|
```ts
|
|
219
224
|
import { toastStack } from 'asciify-engine/kit';
|
|
@@ -308,15 +313,15 @@ resetButton.onclick = () => c.set(50, true);
|
|
|
308
313
|
Category: Media
|
|
309
314
|
|
|
310
315
|
Prompt:
|
|
311
|
-
“Build an image accordion for [our prints]: [five photos] as panels drawn in Asciify characters. The hovered or focused panel widens
|
|
316
|
+
“Build an image accordion for [our prints]: [five photos] as panels drawn in Asciify characters. The hovered, tapped or focused panel widens on one smooth spring while its characters cross over to the full photo, with a caption; a quick sweep across the strip doesn't open every panel on the way.”
|
|
312
317
|
|
|
313
318
|
```ts
|
|
314
319
|
import { accordion } from 'asciify-engine/kit';
|
|
315
320
|
|
|
316
|
-
// give the strip a height; panels open on hover, press or focus
|
|
321
|
+
// give the strip a height; panels open on hover (with intent), tap, press or focus
|
|
317
322
|
accordion(printStrip, {
|
|
318
323
|
images: [{ src: '/prints/stairwell.webp', title: 'Stairwell', meta: 'Silver print · $120' }, '/prints/shell.webp', '/prints/fern.webp', '/prints/dune.webp', '/prints/pier.webp'],
|
|
319
|
-
duration:
|
|
324
|
+
duration: 420,
|
|
320
325
|
});
|
|
321
326
|
```
|
|
322
327
|
|
|
@@ -324,7 +329,7 @@ accordion(printStrip, {
|
|
|
324
329
|
Category: Media
|
|
325
330
|
|
|
326
331
|
Prompt:
|
|
327
|
-
“Make an image dropzone with Asciify: a quiet ring of characters frames the drop area and
|
|
332
|
+
“Make an image dropzone with Asciify: a quiet ring of the lightest characters frames the drop area. On drag-over, packets of denser characters chase round it and a halo leans in toward the file. A dropped image opens out from the drop point in characters, with Replace and Download PNG.”
|
|
328
333
|
|
|
329
334
|
```ts
|
|
330
335
|
import { dropzone } from 'asciify-engine/kit';
|
|
@@ -355,14 +360,14 @@ async function removeRow(row: HTMLElement, id: string) {
|
|
|
355
360
|
Category: Components
|
|
356
361
|
|
|
357
362
|
Prompt:
|
|
358
|
-
“Add pull to refresh to [our feed]: pulling
|
|
363
|
+
“Add pull to refresh to [our feed]: pulling draws a small, iOS-sized ring of Asciify characters round in the gap, closing with a small pop at the threshold. Let go and it opens into a spinning arc while refreshing, draws a check, and new [posts] resolve in from characters. Include a Refresh button.”
|
|
359
364
|
|
|
360
365
|
```ts
|
|
361
366
|
import { pullRefresh } from 'asciify-engine/kit';
|
|
362
367
|
|
|
363
|
-
// feedScreen: overflow auto, content in its first child; the ring spins until onRefresh resolves, then draws a check
|
|
368
|
+
// feedScreen: overflow auto, content in its first child; the 26px ring spins until onRefresh resolves, then draws a check
|
|
364
369
|
// rows marked data-new resolve in from characters as the content springs back
|
|
365
|
-
const pull = pullRefresh(feedScreen, { threshold:
|
|
370
|
+
const pull = pullRefresh(feedScreen, { threshold: 64, reveal: '[data-new]', onRefresh: () => loadNewPosts() });
|
|
366
371
|
refreshButton.onclick = () => void pull.refresh();
|
|
367
372
|
```
|
|
368
373
|
|
|
@@ -399,7 +404,7 @@ refreshButton.onclick = async () => mrr.set(await fetchMrr());
|
|
|
399
404
|
Category: Pages
|
|
400
405
|
|
|
401
406
|
Prompt:
|
|
402
|
-
“Make a split sign-in page with Asciify: [image] in characters on the left that trail under the cursor, and
|
|
407
|
+
“Make a split sign-in page with Asciify: [image] in characters on the left that trail under the cursor, and on the right a labelled email field (a filled pill with a mail icon, a focus ring on :focus-visible, the error in the label row so nothing reflows), Continue and Continue with GitHub. Continue pulses the art and shows a loading glyph while the link sends.”
|
|
403
408
|
|
|
404
409
|
```ts
|
|
405
410
|
import { artPanel } from 'asciify-engine/kit';
|
|
@@ -473,29 +478,20 @@ const v = asciiVideo(player, { src: '/media/magnolia.mp4', poster: '/media/magno
|
|
|
473
478
|
playButton.onclick = () => playButton.setAttribute('aria-label', v.toggle() ? 'Pause' : 'Play');
|
|
474
479
|
```
|
|
475
480
|
|
|
476
|
-
## hero-background:
|
|
481
|
+
## hero-background: Background
|
|
477
482
|
Category: Backgrounds
|
|
478
483
|
|
|
479
484
|
Prompt:
|
|
480
|
-
“Put
|
|
485
|
+
“Put the Asciify Swell background behind our hero: a fine grid that swells in slow rolling waves, quiet in the middle. Dots by default, or characters. Keep it clear around the headline and let it answer the cursor.”
|
|
481
486
|
|
|
482
487
|
```ts
|
|
483
|
-
import {
|
|
488
|
+
import { background, swell } from 'asciify-engine/kit';
|
|
484
489
|
|
|
485
|
-
|
|
486
|
-
|
|
490
|
+
// One of 13 presets. Import only the one you use; bg.setPreset(other) cross-fades to another.
|
|
491
|
+
const bg = background(heroSection, { preset: swell, clear: heroText });
|
|
487
492
|
```
|
|
488
493
|
|
|
489
|
-
|
|
490
|
-
/* The veil: characters blur and fade toward the words instead of stopping at a box edge. */
|
|
491
|
-
.hero-text { position: relative; isolation: isolate; }
|
|
492
|
-
.hero-text::before {
|
|
493
|
-
content: ""; position: absolute; z-index: -1; inset: -24px -40px; pointer-events: none;
|
|
494
|
-
background: color-mix(in oklab, var(--bg) 58%, transparent);
|
|
495
|
-
backdrop-filter: blur(9px);
|
|
496
|
-
mask-image: radial-gradient(closest-side, #000 52%, rgb(0 0 0 / .6) 74%, transparent);
|
|
497
|
-
}
|
|
498
|
-
```
|
|
494
|
+
Any preset from [the kit reference](kit.md#backgrounds) fits the same call: `swell`, `drift`, `halo`, `caustics`, `contour`, `aurora`, `ripple`, `mesh`, `interference`, `constellation`, `cascade`, `wordField` and `fluid`, all on the GPU glyph field. `cursor: false` turns the pointer response off; `swell` takes `mark: 'glyph'` or a `charset` for characters instead of dots. For asciify.org's own hero ground, with the frosted veil and `pulse()`, use `fieldBackground(heroSection, { preset: 'hero', clear: heroText })`.
|
|
499
495
|
|
|
500
496
|
## Advanced: raw field
|
|
501
497
|
|
|
@@ -39,7 +39,7 @@ For an interface component or a background, use `asciify-engine/kit` and follow
|
|
|
39
39
|
| --- | --- | --- |
|
|
40
40
|
| A photo, video or GIF converted on their page, with optional hover | `asciify`, `asciifyVideo`, `asciifyGif` (+ `mountHover` from `/hover`) | Lightest path. Disable core hover and motion when `/hover` owns them. |
|
|
41
41
|
| A full-bleed hero or brand field that must feel smooth under the cursor, their name or word as the characters, an Unseen-style look | `mountGlyphField` from `/field` | WebGL2 on a GPU, 120 fps class. Glyph ramps only. Keep a poster and a fallback. See [glyph-field.md](glyph-field.md). |
|
|
42
|
-
| A calm background for a product page, docs, pricing or SaaS hero, in light or dark | Kit `background(el, { preset:
|
|
42
|
+
| A calm background for a product page, docs, pricing or SaaS hero, in light or dark | Kit `background(el, { preset: swell, clear })` or `fieldBackground(el, { preset: 'hero', clear })` | Graphite ink, clear zone plus veil. See [applying-asciify.md](applying-asciify.md#9-backgrounds). Raw `mountGlyphField` with `mark: 'dot'` only for a look the kit lacks ([glyph-field.md](glyph-field.md#halftone-for-interfaces-412)). |
|
|
43
43
|
| Art styles (halftone, dither, braille, print, mosaic, LED…), saved looks, backdrops, masks, effects, PNG/MP4/GIF export | `mountStudio` from `/studio` | Studio owns motion, hover and finish. Start from `studioLook(id)` when one of the 12 looks matches the mood. |
|
|
44
44
|
| Several media and text layers in one artwork | `mountStudioProject` from `/studio` | One loop and budget for up to eight layers. See [layered-projects.md](layered-projects.md). |
|
|
45
45
|
| An ambient animated background with no media (rain, stars, waves, aurora…) | Kit `background(el, { preset })` with one of the 26 presets | Import presets by name from `asciify-engine/kit`. See [applying-asciify.md](applying-asciify.md#9-backgrounds) for which suits which surface. |
|
|
@@ -34,8 +34,9 @@ Size the canvas with CSS (for example `position:absolute; inset:0; width:100%; h
|
|
|
34
34
|
| Option | Default | Notes |
|
|
35
35
|
| --- | --- | --- |
|
|
36
36
|
| `source` | none | URL (`.mp4`, `.webm`, `.mov` load as muted, looping, inline video), `HTMLImageElement`, `HTMLVideoElement`, `HTMLCanvasElement` or `ImageBitmap`. Cross-origin media needs CORS. |
|
|
37
|
-
| `scene` | `'flow'` | Generated motion when there is no source: `'flow'` (domain-warped noise), `'drift'` (a few broad lobes, made for halftone, 4.12), `'orb'` (lit sphere) or `'none'` (blank, wake only). |
|
|
37
|
+
| `scene` | `'flow'` | Generated motion when there is no source: `'flow'` (domain-warped noise), `'drift'` (a few broad lobes, made for halftone, 4.12), `'swell'` (three crossing sine swells rolling diagonally, made for a fine dot grid), `'orb'` (lit sphere), the kit's background scenes `'caustics'`, `'contour'`, `'aurora'`, `'ripple'`, `'halo'`, `'interference'`, `'mesh'`, `'cascade'` and `'constellation'` (`FIELD_SCENES` lists them all), or `'none'` (blank, wake only). |
|
|
38
38
|
| `mark`, `dotScale` | `'glyph'`, `0.9` | `'dot'` draws a halftone: one circle per cell whose area follows tone, antialiased at any pixel ratio. `dotScale` is the largest dot as a fraction of the cell; about 0.6 keeps a calm, open grid. (4.12) |
|
|
39
|
+
| `mark` (Studio styles) | | `FIELD_MARKS` also holds the Studio's tile and print styles, drawn per cell in the composite pass from the cell's tone and colour (one shader branch each, no extra pass or texture). Tiles, which fade with tone in `color: 'ink'` and stay solid in `'source'`: `'pixel'` (filled cell), `'mosaic'` (gapped tile), `'lego'` (gapped brick lit from above, with a ringed stud), `'voxel'` (isometric cube, faces at 1, 0.72 and 0.42), `'disco'` (gapped tile, lit upper facet, shaded lower), `'hex'` (flat-topped hexagon), `'led'` (round lamp, soft halo, glint). `'dither'` lights a 4x4 Bayer screen of about five dots a cell. `'cmyk'` separates the cell's hue into offset cyan, magenta and yellow dots, with the neutral share as a key dot in the ink's own lightness. Print marks, whose size carries the tone: `'stipple'` (four jittered dots a cell), `'engraving'` (parallel cuts at -35°, running on across cells), `'crosshatch'` (two more directions join in darker tones), `'woodblock'` (broad carved bands in five steps, edges wavering), `'risograph'` (main ink and a coral second ink, offset), `'pointillism'` (four small strokes, their shade varied). Every mark but `'dot'` leaves blank the cells the `charset` leaves blank (its first glyph), so keep a ramp that starts with a space. Cells near square suit them best. |
|
|
39
40
|
| `scale` | `1` | Feature size of generated scenes; higher is finer. Use about 1.8 on phones, where the field is tall. (4.12) |
|
|
40
41
|
| `clear` | `false` | Keeps the field quiet around content so text stays readable: an element, `{ element, padding, feather, shape }` (followed through layout changes), or a zone in field fractions. (4.12) |
|
|
41
42
|
| `charset` | `' .,:-=+*#%@'` | Ordered from empty to dense. Graphemes, so emoji, braille and block shading each take one cell. Up to 256. |
|