@idle-screens/schema 3.2.0 → 3.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.
- package/FORMAT.md +29 -3
- package/dist/index.d.ts +83 -3
- package/dist/index.js +464 -141
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/saver-spec.schema.json +20 -6
package/FORMAT.md
CHANGED
|
@@ -31,7 +31,8 @@ Additions to version 1 so far, all optional and backward compatible:
|
|
|
31
31
|
sprites, `colorWeights`, `pulse.wave`, `layout` (grid), `life`,
|
|
32
32
|
`links.mode/falloff/closed`, `blend: screen|multiply`, orbit layer-parents
|
|
33
33
|
(2026-07-21 — "the v1 ceiling");
|
|
34
|
-
`textBlock` sprite — deterministic multi-line text with viewport-unit sizing
|
|
34
|
+
`textBlock` sprite — deterministic multi-line text with viewport-unit sizing;
|
|
35
|
+
`textBlock.reveal` — animated typing/deleting via one steerable paint param.
|
|
35
36
|
|
|
36
37
|
## Safety invariants
|
|
37
38
|
|
|
@@ -169,6 +170,25 @@ with distance, removing pop-in at the cutoff.
|
|
|
169
170
|
layout target, not a hard clip.
|
|
170
171
|
Use with `count: 1`, `motion: { type: "static" }`, and `position`.
|
|
171
172
|
|
|
173
|
+
textBlock also accepts `reveal` — animated typing/deleting:
|
|
174
|
+
`{ "reveal": { "progress": 1, "mode": "typewriter", "speed": 0, "caret": true } }`.
|
|
175
|
+
Layout always runs on the **full** text; reveal only masks which glyphs are
|
|
176
|
+
painted, so lines never reflow and the block never resizes while typing.
|
|
177
|
+
`progress` (0–1, default 1) is the frontier — it is a numeric **paint**
|
|
178
|
+
param, so steering it with `dur`/`ease` animates typing in a single
|
|
179
|
+
`setParam` call, and gliding it back toward 0 deletes. `mode` quantizes the
|
|
180
|
+
frontier per grapheme (`typewriter`, default), per `word`, or per `line`.
|
|
181
|
+
`speed` (graphemes/sec, max 120) makes the block type itself from scene
|
|
182
|
+
start: effective progress is `min(progress, speed·t/total)`, so a steered
|
|
183
|
+
`progress` can still hold or delete a self-typing block. `caret` draws a
|
|
184
|
+
blinking caret at the frontier (`true`, or `{ "blink": 1.2, "color": "#fff" }`;
|
|
185
|
+
blink is in full cycles/sec, capped at 3 for flash safety, and is a square
|
|
186
|
+
wave of `t` like every other animation). With `align: "center"`/`"right"`
|
|
187
|
+
the revealing line stays anchored to its alignment as it types — only
|
|
188
|
+
left-aligned text reads as a classic typewriter. To "edit" text live:
|
|
189
|
+
glide `reveal.progress` to 0, swap `text` while nothing is visible, glide
|
|
190
|
+
back to 1.
|
|
191
|
+
|
|
172
192
|
`circle`, `ring`, `streak`, and `rect` all accept `colors: [...]` (seeded
|
|
173
193
|
per-entity palette pick) and `colorWeights: [...]` (relative weights, same
|
|
174
194
|
length — "mostly cool tones, occasional ember").
|
|
@@ -313,8 +333,14 @@ the final segment may omit duration (holds indefinitely).
|
|
|
313
333
|
**Advance mode:** `auto` (default), `input`, or `either`. Validated but not
|
|
314
334
|
wired to runtime behavior — timer/input drivers are planned for a follow-up.
|
|
315
335
|
|
|
316
|
-
**Transitions:** `{ type: 'cut' }`
|
|
317
|
-
|
|
336
|
+
**Transitions:** `{ type: 'cut' }` (default) performs a hard switch.
|
|
337
|
+
`{ type: 'morph', dur: number }` smoothly interpolates paint properties
|
|
338
|
+
(colors, opacity values) over `dur` ms when crossing into the next segment.
|
|
339
|
+
Morph requires structurally identical adjacent segments (same
|
|
340
|
+
`structuralSignature`); if they differ, the engine falls back to cut and the
|
|
341
|
+
validator emits a `morph-structural-mismatch` warning. During a morph, entity
|
|
342
|
+
placement inherits the outgoing segment's seed — the incoming segment's own
|
|
343
|
+
seed is unused. `dur` must be between 200 and 5000 ms.
|
|
318
344
|
|
|
319
345
|
**Time mapping:** global clock `T` maps to `(segmentIndex, localT)` via prefix
|
|
320
346
|
sums of durations. Half-open segments: `[start, start+duration)`. With
|
package/dist/index.d.ts
CHANGED
|
@@ -274,7 +274,42 @@ type SpriteSpec = {
|
|
|
274
274
|
lineHeight?: number;
|
|
275
275
|
align?: 'left' | 'center' | 'right';
|
|
276
276
|
color?: string;
|
|
277
|
+
reveal?: TextRevealSpec;
|
|
277
278
|
};
|
|
279
|
+
/**
|
|
280
|
+
* Animated typing/deleting for `textBlock`. Layout always runs on the FULL
|
|
281
|
+
* text — reveal only masks which glyphs are painted, so lines never reflow
|
|
282
|
+
* and the block's box never changes size. `progress` is a numeric paint
|
|
283
|
+
* param (excluded from the structural signature), so steering it with
|
|
284
|
+
* `dur`/`ease` animates typing client-side in one call; gliding it back to 0
|
|
285
|
+
* deletes. With center/right `align`, the revealing line stays anchored to
|
|
286
|
+
* its alignment as it types (only left-aligned text reads as a classic
|
|
287
|
+
* typewriter).
|
|
288
|
+
*/
|
|
289
|
+
interface TextRevealSpec {
|
|
290
|
+
/**
|
|
291
|
+
* 0..1 fraction of the text revealed (default 1 = fully shown). Quantized
|
|
292
|
+
* by `mode`. Steerable paint — glide it to animate typing or deleting.
|
|
293
|
+
*/
|
|
294
|
+
progress?: number;
|
|
295
|
+
/** Reveal granularity: per-grapheme (default), per-word, or per-line. */
|
|
296
|
+
mode?: 'typewriter' | 'word' | 'line';
|
|
297
|
+
/**
|
|
298
|
+
* Self-typing rate in graphemes/second from scene start (media time). The
|
|
299
|
+
* effective progress is `min(progress, speed·t/total)` — so a steered
|
|
300
|
+
* `progress` can hold or delete even while `speed` is set. 0 = off.
|
|
301
|
+
*/
|
|
302
|
+
speed?: number;
|
|
303
|
+
/**
|
|
304
|
+
* Caret at the reveal frontier. `true` for defaults, or configure blink
|
|
305
|
+
* rate (Hz, full cycles/sec, capped at 3 for flash safety) and color.
|
|
306
|
+
* Blink is a square wave of `t` — deterministic like everything else.
|
|
307
|
+
*/
|
|
308
|
+
caret?: boolean | {
|
|
309
|
+
blink?: number;
|
|
310
|
+
color?: string;
|
|
311
|
+
};
|
|
312
|
+
}
|
|
278
313
|
/** Rotate through sprite variants over time. Each entity offsets by its seeded phase. */
|
|
279
314
|
interface CycleSpec {
|
|
280
315
|
period: number;
|
|
@@ -426,14 +461,19 @@ declare const LIMITS: {
|
|
|
426
461
|
readonly minTextBlockFontSize: 0.01;
|
|
427
462
|
readonly maxTextBlockFontSize: 0.2;
|
|
428
463
|
readonly maxTextBlockMaxWidth: 1;
|
|
464
|
+
readonly maxRevealSpeed: 120;
|
|
465
|
+
readonly maxCaretBlinkHz: 3;
|
|
429
466
|
readonly maxSegments: 24;
|
|
430
467
|
readonly minSegmentDuration: 1000;
|
|
431
468
|
readonly maxTransitionDur: 5000;
|
|
432
469
|
readonly minTransitionDur: 200;
|
|
433
470
|
};
|
|
434
|
-
|
|
471
|
+
type SequenceTransition = {
|
|
435
472
|
type: 'cut';
|
|
436
|
-
}
|
|
473
|
+
} | {
|
|
474
|
+
type: 'morph';
|
|
475
|
+
dur: number;
|
|
476
|
+
};
|
|
437
477
|
interface SequenceSegment {
|
|
438
478
|
key: string;
|
|
439
479
|
scene: SaverSpec;
|
|
@@ -614,6 +654,36 @@ interface TextBlockLine {
|
|
|
614
654
|
* Explicit `\n` always forces a break. Pure, deterministic, no canvas needed.
|
|
615
655
|
*/
|
|
616
656
|
declare function breakTextBlock(text: string, maxWidthEm: number): TextBlockLine[];
|
|
657
|
+
/**
|
|
658
|
+
* Split a string into paint-safe grapheme clusters: surrogate pairs stay
|
|
659
|
+
* whole, combining marks / variation selectors / skin tones attach to their
|
|
660
|
+
* base, ZWJ joins sequences (emoji families), regional indicators pair up
|
|
661
|
+
* (flags). Deterministic across engines by construction.
|
|
662
|
+
*/
|
|
663
|
+
declare function graphemeClusters(text: string): string[];
|
|
664
|
+
interface TextRevealInput {
|
|
665
|
+
progress?: number;
|
|
666
|
+
mode?: 'typewriter' | 'word' | 'line';
|
|
667
|
+
speed?: number;
|
|
668
|
+
}
|
|
669
|
+
interface RevealState {
|
|
670
|
+
/** Effective 0..1 progress after combining authored progress and speed at t. */
|
|
671
|
+
progress: number;
|
|
672
|
+
/** Number of fully visible lines. */
|
|
673
|
+
fullLines: number;
|
|
674
|
+
/** Grapheme-safe visible prefix of the next line ('' when none). */
|
|
675
|
+
partialText: string;
|
|
676
|
+
/** Caret anchor: line index and the visible prefix on that line. */
|
|
677
|
+
caretLine: number;
|
|
678
|
+
caretPrefix: string;
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* Resolve which glyphs of a broken textBlock are visible at time `tMs`.
|
|
682
|
+
* Pure function of (lines, reveal, tMs) — the renderer paints exactly this,
|
|
683
|
+
* and perceive models exactly this, so agents and pixels agree. `speed` is
|
|
684
|
+
* graphemes/sec regardless of mode; mode only quantizes the frontier.
|
|
685
|
+
*/
|
|
686
|
+
declare function revealState(lines: TextBlockLine[], reveal: TextRevealInput, tMs: number): RevealState;
|
|
617
687
|
|
|
618
688
|
/** Derive a manifest so a compiled spec composes with @idle-screens/capabilities. */
|
|
619
689
|
declare function manifestFor(spec: SaverSpec): SaverManifest;
|
|
@@ -681,6 +751,14 @@ declare function adviseSpec(spec: SaverSpec, viewport?: {
|
|
|
681
751
|
width: number;
|
|
682
752
|
height: number;
|
|
683
753
|
}): SpecWarning[];
|
|
754
|
+
/**
|
|
755
|
+
* Non-blocking advisory warnings for a validated sequence envelope.
|
|
756
|
+
* Checks cross-segment luminance jumps at boundaries and per-segment advisories.
|
|
757
|
+
*/
|
|
758
|
+
declare function adviseSequence(seq: IdleSequence, viewport?: {
|
|
759
|
+
width: number;
|
|
760
|
+
height: number;
|
|
761
|
+
}): SpecWarning[];
|
|
684
762
|
|
|
685
763
|
interface LayerSnapshot {
|
|
686
764
|
key: string | undefined;
|
|
@@ -795,6 +873,8 @@ interface TextSpriteInfo {
|
|
|
795
873
|
count: number;
|
|
796
874
|
/** Representative rendered glyph height in px at the sample viewport. */
|
|
797
875
|
sizePx: number;
|
|
876
|
+
/** For a revealing textBlock: effective 0..1 fraction shown at sample t. */
|
|
877
|
+
revealed?: number;
|
|
798
878
|
}
|
|
799
879
|
/**
|
|
800
880
|
* List every text layer's actual strings and rendered size. No grid resolution
|
|
@@ -1075,4 +1155,4 @@ declare const EXAMPLE_SPECS: SaverSpec[];
|
|
|
1075
1155
|
/** Lookup by saver id. */
|
|
1076
1156
|
declare const EXAMPLE_BY_ID: Readonly<Record<string, SaverSpec>>;
|
|
1077
1157
|
|
|
1078
|
-
export { AQUARIUM_SPEC, AURORA_SPEC, type BackgroundDrift, type BackgroundSpec, type BandSpec, COMETS_SPEC, CONSTELLATION_SPEC, type CycleSpec, DASHBOARD_SPEC, type DominanceEntry, EXAMPLE_BY_ID, EXAMPLE_SPECS, type Entity, type GradientStop, HAIKU_SPEC, type IdleSequence, LANTERNS_SPEC, LIMITS, type LayerMotionStats, type LayerSnapshot, type LayerSpec, type LinkEdge, type LuminanceGrid, type LuminanceGridOptions, MATRIX_RAIN_SPEC, type MotionSpec, NOSTALGHIA_CANDLE_SPEC, ORRERY_SPEC, POLYGONS_SPEC, PROCESSION_SPEC, type PerceiveOptions, type Placed, RAIN_SPEC, type ResolvedSegment, SAKURA_SPEC, SCHEMA_EXAMPLES, SCHEMA_VERSION, SNOWFALL_SPEC, type SaverSpec, type SceneDescription, type SceneDiff, type ScenePerception, type SceneSnapshot, type SchemaExample, type SequenceSegment, type SequenceTransition, type SpecError, type SpecWarning, type SpriteSpec, type SteerDelta, type TextBlockLine, type TextSpriteInfo, type ValidationResult, WARP_NEAR, WARP_TUNNEL_SPEC, type WanderOsc, adviseSpec, alphaAt, applyDeltasToSpec, assertValidSequence, assertValidSpec, breakTextBlock, buildEntities, compileSaver, compileSequence, describeScene, diffScenes, dominanceRanking, easeSmooth, headingAt, lerpSpec, lifeAlphaAt, linkEdges, linkPairs, luminanceGrid, manifestFor, motionStats, perceiveScene, positionAt, renderBrailleMap, renderDensityMap, resolveSegment, resolveSpecPath, rotationAt, sizeAt, spriteIndexAt, spriteVariants, steerablePaths, structuralSignature, textSprites, validateSequence, validateSpec };
|
|
1158
|
+
export { AQUARIUM_SPEC, AURORA_SPEC, type BackgroundDrift, type BackgroundSpec, type BandSpec, COMETS_SPEC, CONSTELLATION_SPEC, type CycleSpec, DASHBOARD_SPEC, type DominanceEntry, EXAMPLE_BY_ID, EXAMPLE_SPECS, type Entity, type GradientStop, HAIKU_SPEC, type IdleSequence, LANTERNS_SPEC, LIMITS, type LayerMotionStats, type LayerSnapshot, type LayerSpec, type LinkEdge, type LuminanceGrid, type LuminanceGridOptions, MATRIX_RAIN_SPEC, type MotionSpec, NOSTALGHIA_CANDLE_SPEC, ORRERY_SPEC, POLYGONS_SPEC, PROCESSION_SPEC, type PerceiveOptions, type Placed, RAIN_SPEC, type ResolvedSegment, type RevealState, SAKURA_SPEC, SCHEMA_EXAMPLES, SCHEMA_VERSION, SNOWFALL_SPEC, type SaverSpec, type SceneDescription, type SceneDiff, type ScenePerception, type SceneSnapshot, type SchemaExample, type SequenceSegment, type SequenceTransition, type SpecError, type SpecWarning, type SpriteSpec, type SteerDelta, type TextBlockLine, type TextRevealInput, type TextRevealSpec, type TextSpriteInfo, type ValidationResult, WARP_NEAR, WARP_TUNNEL_SPEC, type WanderOsc, adviseSequence, adviseSpec, alphaAt, applyDeltasToSpec, assertValidSequence, assertValidSpec, breakTextBlock, buildEntities, compileSaver, compileSequence, describeScene, diffScenes, dominanceRanking, easeSmooth, graphemeClusters, headingAt, lerpSpec, lifeAlphaAt, linkEdges, linkPairs, luminanceGrid, manifestFor, motionStats, perceiveScene, positionAt, renderBrailleMap, renderDensityMap, resolveSegment, resolveSpecPath, revealState, rotationAt, sizeAt, spriteIndexAt, spriteVariants, steerablePaths, structuralSignature, textSprites, validateSequence, validateSpec };
|