@markdy/renderer-dom 0.7.29 → 0.8.1

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 CHANGED
@@ -5,12 +5,11 @@ Web Animations API renderer for [MarkdyScript](../../docs/SYNTAX.md) scenes. Tra
5
5
  ## Features
6
6
 
7
7
  - **Browser-native** — Web Animations API + CSS transforms, no Canvas or GSAP
8
- - **Emoji stick figures** — `figure` actor type with articulatable limbs, shoulder/hip joints, and body-part rig
9
- - **Expressive gestures** — built-in `wave`, `nod`, `jump`, `bounce`, and multi-part `pose` actions
8
+ - **Auto-layout diagrams** — renders positioned nodes and orthogonal, obstacle-aware edges from a compiled `RenderPlan`
9
+ - **Flow edges** — `->` request, `<-` response, `~>` event, `--` dependency, each with its own stroke, plus a pulse that travels the edge as it draws
10
+ - **Beat-driven cues** — `show`, `hide`, `glow`, and `focus`, sequenced by named beats
10
11
  - **Seek-safe** — manual `currentTime` control enables reliable `seek()` in any direction
11
- - **Face expressions** — instant emoji face swaps that work correctly on seek-back
12
- - **Speech bubbles** — auto-positioned bubbles with fade-in/fade-out
13
- - **Z-index layering** — `z` modifier for actor depth ordering
12
+ - **Semantic themes** — `midnight` and `paper`, with per-role node colors
14
13
  - **Single dependency** — only `@markdy/core`
15
14
 
16
15
  ## Installation
@@ -41,11 +40,12 @@ import { createPlayer } from "@markdy/renderer-dom";
41
40
  const player = createPlayer({
42
41
  container: document.getElementById("scene")!,
43
42
  code: `
44
- scene width=600 height=300 bg=white
45
- actor hero = figure(#c68642, m, 😎) at (200, 150)
46
- @0.0: hero.enter(from=left, dur=0.8)
47
- @1.5: hero.say("Hello!", dur=1.2)
48
- @1.5: hero.face("😄")
43
+ scene "Request" theme=midnight
44
+ browser Web
45
+ service API
46
+ beat main:
47
+ show $nodes
48
+ Web -> API "GET /users"
49
49
  `,
50
50
  autoplay: true,
51
51
  });
@@ -65,12 +65,11 @@ player.destroy(); // clean up DOM + cancel animations
65
65
  |---|---|---|---|
66
66
  | `container` | `HTMLElement` | *(required)* | DOM element to mount the scene into |
67
67
  | `code` | `string` | *(required)* | MarkdyScript source code |
68
- | `assets` | `Record<string, string>` | `{}` | Asset URL overrides (key = asset name) |
69
68
  | `autoplay` | `boolean` | `true` | Start playing immediately |
70
69
  | `loop` | `boolean` | `true` | Loop the animation when it reaches the end |
71
70
  | `copyright` | `boolean` | `true` | Show a small "Powered by Markdy" badge below the animation |
72
71
  | `progressBar` | `boolean` | `true` | Show a rainbow progress bar around the viewport border |
73
- | `onWarning` | `(warning: ParseWarning) => void` | `console.warn` | Called for each soft parse warning |
72
+ | `onWarning` | `(warning: Diagnostic) => void` | `console.warn` | Called for each soft parse warning |
74
73
  | `onTimeUpdate` | `(seconds: number, durationSeconds: number) => void` | — | Called whenever playback or seek changes the current time |
75
74
  | `onPlayStateChange` | `(playing: boolean) => void` | — | Called when playback starts or pauses |
76
75
 
@@ -84,46 +83,29 @@ player.destroy(); // clean up DOM + cancel animations
84
83
  | `currentTime()` | Current playback position in seconds |
85
84
  | `duration()` | Total scene duration in seconds |
86
85
  | `isPlaying()` | Whether the scene is currently playing |
87
- | `chapters()` | Named `scene "..." { ... }` chapter blocks, in author order (empty if none) |
88
- | `seekToChapter(name)` | Seek to the start of a named chapter; no-op if the name doesn't match |
86
+ | `beats()` | Named `beat` ranges, in author order (empty if none) |
87
+ | `seekToBeat(name)` | Seek to the start of a named beat; no-op if the name doesn't match |
89
88
  | `destroy()` | Remove DOM elements and cancel all animations |
90
89
 
91
90
  ## Module Structure
92
91
 
93
92
  ```
94
93
  src/
95
- index.ts — Barrel exports
96
- player.ts — Public API, rAF loop, face-swap engine
97
- animations.ts Timeline walker: dispatches each event to its handler
98
- actions/
99
- context.ts — ActionContext: the one argument every handler receives
100
- registry.ts — Action name → handler table
101
- transform.ts — move, enter, exit, fade, scale, rotate, shake, jump, bounce
102
- figure.ts — Figure-only gestures and limb articulation
103
- speech.ts — say (speech bubbles)
104
- projectile.ts — throw
105
- flow.ts — request / response / emit (system-diagram edges)
94
+ index.ts — Barrel exports (createPlayer)
95
+ player.ts — Public API, rAF loop, progress bar, responsive scaling
96
+ nodes.ts Node element factory + scene title
97
+ edges.ts — Flow-edge SVG runtime, routing, and cue animations
106
98
  geometry/
107
- rect.ts — Actor bounds and hit-testing (DOM-free, unit tested)
108
- path.ts — Polyline measurement and obstacle-aware edge routing
109
- camera.ts pan / zoom / shake on the scene-content layer
110
- stage.ts — t=0 staging and off-screen placement
111
- theme.ts — Scene-adaptive colors for renderer-drawn chrome
112
- actors.ts — Actor element factory (sprite, text, figure, box, caption)
113
- figure.ts — Stick-figure DOM factory (emoji body parts)
114
- types.ts — ActorState, FaceSwap, easing utilities
99
+ rect.ts — Rects, points, and hit-testing (DOM-free, unit tested)
100
+ path.ts — Polyline measurement + obstacle-aware orthogonal routing
101
+ theme.ts Scene ambience styles and theme-token application
115
102
  ```
116
103
 
117
- ### Adding an action
104
+ ### Adding a cue or edge kind
118
105
 
119
- 1. Write a handler a function taking `ActionContext` in the relevant
120
- `actions/` module (or a new one).
121
- 2. Register it by name in `actions/registry.ts`.
122
- 3. Add the name to the matching list in `@markdy/core`'s `registry.ts` so the
123
- parser accepts it.
124
-
125
- Step 3 is enforced: `tests/action-coverage.test.ts` fails the build if the
126
- parser accepts an action the renderer can't draw, or vice versa.
106
+ Cue and edge animations live in `edges.ts` (`buildCueAnimations`). Add the new
107
+ keyword or operator to `@markdy/core`'s `registry.ts` so the parser accepts it,
108
+ then handle it in the corresponding branch of `buildCueAnimations`.
127
109
 
128
110
  ## Documentation
129
111
 
package/dist/index.d.ts CHANGED
@@ -1,54 +1,18 @@
1
- import { Chapter, SceneAST, ParseWarning } from '@markdy/core';
1
+ import { BeatRange, Diagnostic } from '@markdy/core';
2
2
 
3
3
  /**
4
- * @markdy/renderer-domPlayer
5
- *
6
- * Translates a MarkdyScript program into DOM elements and drives the
7
- * timeline via the Web Animations API (WAAPI).
8
- *
9
- * Playback architecture: all WAAPI animations stay permanently paused.
10
- * A requestAnimationFrame loop advances `sceneMs` each frame and sets
11
- * `anim.currentTime = sceneMs` on every animation. This avoids two
12
- * known pitfalls with WAAPI's startTime-based resumption:
13
- *
14
- * 1. Setting `startTime` on a paused animation does not reliably change
15
- * the play state to "running" across all browsers.
16
- * 2. `fill:"both"` causes later-created animations to win the cascade
17
- * during their before-phase, overriding earlier animations' off-screen
18
- * backward fill.
19
- *
20
- * By using `fill:"forwards"` only and pre-initialising actor inline styles,
21
- * each actor's before-phase state falls through to the inline style we set,
22
- * which gives correct initial positions and opacity values.
4
+ * Diagram-native Markdy player renders RenderPlan via WAAPI.
23
5
  */
24
6
 
25
7
  interface PlayerOptions {
26
8
  container: HTMLElement;
27
9
  code: string;
28
- assets?: Record<string, string>;
29
- /**
30
- * Host-resolved ASTs for `import "<path>" as <ns>` statements. When
31
- * provided, the namespaces' `vars`, `defs`, and `seqs` merge into the
32
- * parsed scene under `ns.<name>`. Unresolved namespaces emit a soft
33
- * `import-unresolved` warning.
34
- */
35
- imports?: Record<string, SceneAST>;
36
10
  autoplay?: boolean;
37
- /** Loop the animation when it reaches the end. Defaults to true. */
38
11
  loop?: boolean;
39
- /** Show a small "Powered by Markdy" badge below the animation. Defaults to true. */
40
12
  copyright?: boolean;
41
- /** Show a rainbow progress bar around the viewport border. Defaults to true. */
42
13
  progressBar?: boolean;
43
- /**
44
- * Invoked once per soft `ParseWarning` emitted by the parser — e.g. unknown
45
- * actions, unknown modifier keys, unresolved imports. Defaults to `console.warn`.
46
- * Pass a no-op to silence; pass a custom collector to surface warnings in a UI.
47
- */
48
- onWarning?: (warning: ParseWarning) => void;
49
- /** Invoked whenever playback or seek changes the current timeline time. */
14
+ onWarning?: (warning: Diagnostic) => void;
50
15
  onTimeUpdate?: (seconds: number, durationSeconds: number) => void;
51
- /** Invoked when playback starts or pauses. */
52
16
  onPlayStateChange?: (playing: boolean) => void;
53
17
  }
54
18
  interface Player {
@@ -58,10 +22,8 @@ interface Player {
58
22
  currentTime(): number;
59
23
  duration(): number;
60
24
  isPlaying(): boolean;
61
- /** Named `scene "..." { ... }` chapter blocks, in author order. Empty when the scene has none. */
62
- chapters(): Chapter[];
63
- /** Seeks to the start of the named chapter. No-op if the name doesn't match a chapter. */
64
- seekToChapter(name: string): void;
25
+ beats(): BeatRange[];
26
+ seekToBeat(name: string): void;
65
27
  destroy(): void;
66
28
  }
67
29
  declare function createPlayer(opts: PlayerOptions): Player;