pele-animate 0.16.0 → 0.16.2
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/docs/contributing.md +1 -0
- package/docs/diagram-types.md +125 -66
- package/docs/getting-started.md +1 -1
- package/docs/icons.md +1 -1
- package/docs/step-order.md +3 -2
- package/package.json +1 -1
- package/pele-animate.js +12 -5
package/docs/contributing.md
CHANGED
|
@@ -18,6 +18,7 @@ pnpm build # builds the site (a placeholder until the site lands)
|
|
|
18
18
|
- The package is plain ESM at the repository root: no build step. The site lives in `site/`.
|
|
19
19
|
- Docs are the Markdown files in `docs/`. A fenced block marked `mermaid` must render, and every `@{ icon }` name in it must exist.
|
|
20
20
|
- Fence convention: ```` ```mermaid live ```` is a diagram GitHub can also draw; the site animates it. A diagram with `@{ icon }` nodes uses ```` ```mermaid-icons live ````, because GitHub's Mermaid cannot draw icons (it shows "?" boxes), so GitHub shows the source text and the site animates it.
|
|
21
|
+
- Every `live` fence carries a title after the word `live`: `title="Flowchart: cache hit or miss"`. The playground's examples menu shows it (grouped by page), so write "Type: what it shows".
|
|
21
22
|
- Tabler packs are generated: `node scripts/build-tabler.mjs <path to a tabler-icons checkout>` rewrites `tabler/*.js`. Do not edit those
|
|
22
23
|
files by hand. The Tabler version is recorded in each file header and in `THIRD-PARTY-NOTICES.md`.
|
|
23
24
|
- Add an entry to `CHANGELOG.md` for any user-visible change. Breaking changes also get a section in `docs/migrating.md`.
|
package/docs/diagram-types.md
CHANGED
|
@@ -7,16 +7,38 @@ section: Start
|
|
|
7
7
|
|
|
8
8
|
# Diagram types
|
|
9
9
|
|
|
10
|
-
pele-animate
|
|
11
|
-
|
|
10
|
+
pele-animate animates these Mermaid diagram types. Each one plays an intro when it scrolls into view and, on click, steps through its
|
|
11
|
+
items with previous / play / next controls.
|
|
12
|
+
|
|
13
|
+
| Type | Each step reveals | Pins, icons | Remarks |
|
|
14
|
+
|---|---|---|---|
|
|
15
|
+
| [Flowchart](#flowcharts)<br>`flowchart` | Nodes level by level, edges from their source | Pins and icons | The fullest support: groups, edge labels, large icon nodes. |
|
|
16
|
+
| [Sequence diagram](#sequence-diagrams)<br>`sequenceDiagram` | Actors, then one message at a time | Neither | The order is the source order; reordering messages changes what the diagram says. |
|
|
17
|
+
| [Architecture](#architecture-diagrams)<br>`architecture-beta` | Services level by level, edges from their source | Pins and icons | Icons are written `(name)` and are small and fixed in size. |
|
|
18
|
+
| [State diagram](#state-diagrams)<br>`stateDiagram-v2` | States and transitions from the start marker | Pins | Markers are `root_start` and `root_end`. Composite states are untested. |
|
|
19
|
+
| [C4 context](#c4-context-diagrams)<br>`C4Context` | People and systems, then relationships | Pins | Only `C4Context` is checked. Keep `Rel` labels short. |
|
|
20
|
+
| [Block diagram](#block-diagrams)<br>`block-beta` | Blocks and arrows from their source | Pins | Put linked blocks in the same row or column. |
|
|
21
|
+
| [Class diagram](#class-diagrams)<br>`classDiagram` | Classes and relationships, from the class written first | Pins | `A <\|-- B` reveals `A`, then `B`. |
|
|
22
|
+
| [ER diagram](#er-diagrams)<br>`erDiagram` | Entities and relationships, from the entity written first | Pins | Same written-order rule as class diagrams. |
|
|
23
|
+
| [Timeline](#timelines-journeys-git-graphs-and-gantt-charts)<br>`timeline` | One time period with its events | Neither | Section headers stay visible. |
|
|
24
|
+
| [User journey](#timelines-journeys-git-graphs-and-gantt-charts)<br>`journey` | One task, its face and the line joining it to the last | Neither | |
|
|
25
|
+
| [Git graph](#timelines-journeys-git-graphs-and-gantt-charts)<br>`gitGraph` | One commit with its edge; a branch with its first commit | Neither | Cherry-picks and tags are untested. |
|
|
26
|
+
| [Gantt chart](#timelines-journeys-git-graphs-and-gantt-charts)<br>`gantt` | One task, top to bottom | Neither | `todayMarker` and parallel tasks are untested. |
|
|
27
|
+
|
|
28
|
+
Pins are `%% pa:` comments; see [step order](./step-order.md). Types without pins use their source order. Icons are set up in
|
|
29
|
+
[icons](./icons.md). Pele renders the other Mermaid types too (pie, quadrant, radar and the rest), but pele-animate is not built
|
|
30
|
+
for them; see [Everything else](#everything-else).
|
|
12
31
|
|
|
13
32
|
## Flowcharts
|
|
14
33
|
|
|
15
34
|
Nodes appear in step order, edges draw from their source node, and edge labels fade in. Groups (`subgraph`) and their titles
|
|
16
35
|
are kept. Icon nodes (`@{ icon }`) work here; see [icons](./icons.md).
|
|
17
36
|
|
|
18
|
-
|
|
37
|
+
The pins below put "Serve" (the cache hit) before "Fetch", then draw the `Fetch` to `Serve` edge as its own last step. Without them, `Serve` and `Fetch` would appear together.
|
|
38
|
+
|
|
39
|
+
```mermaid live title="Flowchart: cache hit or miss, with pins and an edge pin"
|
|
19
40
|
flowchart LR
|
|
41
|
+
%% pa: 1=A 2=B 3=C 4=D 5=D>C
|
|
20
42
|
A[Client] --> B{Cached?}
|
|
21
43
|
B -->|yes| C[Serve]
|
|
22
44
|
B -->|no| D[Fetch] --> C
|
|
@@ -24,11 +46,13 @@ flowchart LR
|
|
|
24
46
|
|
|
25
47
|
## Sequence diagrams
|
|
26
48
|
|
|
27
|
-
Actors appear first, then
|
|
49
|
+
Actors appear first, then one step per message in source order, so a cache miss reads as five short steps. Participant boxes in a row get the same height, and group titles are bold.
|
|
28
50
|
|
|
29
|
-
```mermaid live
|
|
51
|
+
```mermaid live title="Sequence: API request with a cache miss"
|
|
30
52
|
sequenceDiagram
|
|
31
53
|
Client->>API: request
|
|
54
|
+
API->>Cache: lookup
|
|
55
|
+
Cache-->>API: miss
|
|
32
56
|
API->>Database: query
|
|
33
57
|
Database-->>API: rows
|
|
34
58
|
API-->>Client: response
|
|
@@ -40,19 +64,26 @@ sequenceDiagram
|
|
|
40
64
|
|
|
41
65
|
`architecture-beta`: services in groups, joined by edges. Services appear in step order like flowchart nodes, groups stay visible,
|
|
42
66
|
and `%% pa:` pins work the same way. The icon in parentheses is looked up in your icon packs, so Tabler names and `doverunner-*`
|
|
43
|
-
names work (import the packs as for [icons](./icons.md)).
|
|
67
|
+
names work (import the packs as for [icons](./icons.md)). The pins here follow a request: the user, the CDN, the API, the cache and database together, then the queue and worker.
|
|
44
68
|
|
|
45
|
-
```mermaid-icons live
|
|
69
|
+
```mermaid-icons live title="Architecture: request path through CDN, API, cache, database and worker"
|
|
46
70
|
architecture-beta
|
|
71
|
+
%% pa: 1=user 2=cdn 3=api 4=cache,db 5=queue 6=worker
|
|
47
72
|
group edge(cloud)[Edge]
|
|
48
73
|
group core(cloud)[Core]
|
|
49
74
|
service user(device-desktop)[User]
|
|
50
75
|
service cdn(cloud-computing)[CDN] in edge
|
|
51
76
|
service api(server)[API] in core
|
|
77
|
+
service cache(bolt)[Cache] in core
|
|
52
78
|
service db(database)[Database] in core
|
|
79
|
+
service queue(mail)[Queue] in core
|
|
80
|
+
service worker(settings)[Worker] in core
|
|
53
81
|
user:R --> L:cdn
|
|
54
82
|
cdn:R --> L:api
|
|
55
|
-
api:
|
|
83
|
+
api:T --> B:cache
|
|
84
|
+
api:B --> T:db
|
|
85
|
+
api:R --> L:queue
|
|
86
|
+
queue:R --> L:worker
|
|
56
87
|
```
|
|
57
88
|
|
|
58
89
|
Icons here are small and fixed in size; `form` and `h` apply to flowcharts only. Edges are read from their written direction
|
|
@@ -63,35 +94,43 @@ Icons here are small and fixed in size; `form` and `h` apply to flowcharts only.
|
|
|
63
94
|
`stateDiagram-v2`: states appear in step order, transitions draw from their source state, and transition labels fade in. The
|
|
64
95
|
start and end markers are nodes too, with the ids `root_start` and `root_end`, so pins can name them.
|
|
65
96
|
|
|
66
|
-
```mermaid live
|
|
97
|
+
```mermaid live title="State: media player with loading, error and retry"
|
|
67
98
|
stateDiagram-v2
|
|
68
|
-
%% pa: 1=root_start 2=Idle 3=
|
|
99
|
+
%% pa: 1=root_start 2=Idle 3=Loading 4=Playing 5=Paused 6=Error 7=root_end
|
|
69
100
|
[*] --> Idle
|
|
70
|
-
Idle -->
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
101
|
+
Idle --> Loading: play
|
|
102
|
+
Loading --> Playing: ready
|
|
103
|
+
Playing --> Paused: pause
|
|
104
|
+
Paused --> Playing: resume
|
|
105
|
+
Loading --> Error: fail
|
|
106
|
+
Error --> Idle: retry
|
|
107
|
+
Playing --> [*]: stop
|
|
74
108
|
```
|
|
75
109
|
|
|
76
|
-
Without pins the order is breadth-first from the start marker, which shows
|
|
110
|
+
The pins give each state its own step, in the order a viewer meets them. Without pins the order is breadth-first from the start marker, which shows states at the same distance together (here `Playing` and `Error`). Pele gives
|
|
77
111
|
state edges no readable ids, so pele-animate finds each transition's ends from where its path starts and stops. Composite
|
|
78
112
|
states and forks are untested. State diagrams take no icons.
|
|
79
113
|
|
|
80
114
|
## C4 context diagrams
|
|
81
115
|
|
|
82
116
|
`C4Context`: people and systems appear in step order and each `Rel` draws from its source, with its label. Pins use the ids you
|
|
83
|
-
give `Person(...)` and `System(...)`; an edge pin is `3=app>drm`.
|
|
117
|
+
give `Person(...)` and `System(...)`; an edge pin is `3=app>drm`. The example adds the DRM service, CDN and analytics one at a time, then the operator who reads the analytics.
|
|
84
118
|
|
|
85
|
-
```mermaid live
|
|
119
|
+
```mermaid live title="C4 context: player app and the systems around it"
|
|
86
120
|
C4Context
|
|
87
|
-
%% pa: 1=viewer 2=app 3=drm
|
|
121
|
+
%% pa: 1=viewer 2=app 3=drm 4=cdn 5=analytics 6=admin
|
|
88
122
|
Person(viewer, "Viewer", "Watches video")
|
|
89
123
|
System(app, "Player app", "Plays protected video")
|
|
90
124
|
System_Ext(drm, "DRM service", "Issues licenses")
|
|
91
|
-
|
|
92
|
-
|
|
125
|
+
System_Ext(cdn, "CDN", "Delivers segments")
|
|
126
|
+
System(analytics, "Analytics", "Tracks playback")
|
|
127
|
+
Person(admin, "Operator", "Reviews usage")
|
|
128
|
+
Rel(viewer, app, "watches")
|
|
93
129
|
Rel(app, drm, "license")
|
|
94
130
|
Rel(app, cdn, "segments")
|
|
131
|
+
Rel(app, analytics, "events")
|
|
132
|
+
Rel(admin, analytics, "reviews")
|
|
133
|
+
UpdateLayoutConfig($c4ShapeInRow="3", $c4BoundaryInRow="1")
|
|
95
134
|
```
|
|
96
135
|
|
|
97
136
|
Pele lays C4 diagrams out in rows, so a long label between two boxes in the same row can leave no room for the arrowhead:
|
|
@@ -101,14 +140,16 @@ keep `Rel` labels short. Only `C4Context` has been checked; the other C4 types a
|
|
|
101
140
|
|
|
102
141
|
`block-beta`: blocks appear in step order and each arrow draws from its source block. Pins use the block ids.
|
|
103
142
|
|
|
104
|
-
```mermaid live
|
|
143
|
+
```mermaid live title="Block: video pipeline with a storage branch"
|
|
105
144
|
block-beta
|
|
106
|
-
columns
|
|
107
|
-
%% pa: 1=
|
|
108
|
-
|
|
109
|
-
space space
|
|
110
|
-
|
|
111
|
-
|
|
145
|
+
columns 4
|
|
146
|
+
%% pa: 1=src 2=enc 3=pkg 4=cdn 5=store
|
|
147
|
+
src["Source"] enc["Encode"] pkg["Package"] cdn["CDN"]
|
|
148
|
+
space space store[("Storage")] space
|
|
149
|
+
src --> enc
|
|
150
|
+
enc --> pkg
|
|
151
|
+
pkg --> cdn
|
|
152
|
+
pkg --> store
|
|
112
153
|
```
|
|
113
154
|
|
|
114
155
|
Pele routes arrows between blocks in straight lines or short bends, so place linked blocks in the same row or column; a diagonal
|
|
@@ -116,30 +157,35 @@ neighbour can give a bent arrow that runs along another one. Block diagrams take
|
|
|
116
157
|
|
|
117
158
|
## Class diagrams
|
|
118
159
|
|
|
119
|
-
`classDiagram`: classes appear in step order, relationships draw from the class written first. `
|
|
120
|
-
and then `
|
|
160
|
+
`classDiagram`: classes appear in step order, relationships draw from the class written first. `Media <|-- Video` reveals `Media`
|
|
161
|
+
and then `Video`, whichever way the arrowhead points. Pins use the class names; the example shows the base class, its subtypes, then the classes that use them.
|
|
121
162
|
|
|
122
|
-
```mermaid live
|
|
163
|
+
```mermaid live title="Class: media types, player and license"
|
|
123
164
|
classDiagram
|
|
124
|
-
%% pa: 1=
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
165
|
+
%% pa: 1=Media 2=Video,Audio 3=Player 4=License 5=Session
|
|
166
|
+
Media <|-- Video
|
|
167
|
+
Media <|-- Audio
|
|
168
|
+
Player --> Media : plays
|
|
169
|
+
Player --> License : needs
|
|
170
|
+
License --> Session : opens
|
|
171
|
+
Media : +id
|
|
172
|
+
Media : +title
|
|
173
|
+
Player : +play()
|
|
174
|
+
License : +expiry
|
|
130
175
|
```
|
|
131
176
|
|
|
132
177
|
## ER diagrams
|
|
133
178
|
|
|
134
179
|
`erDiagram`: entities appear in step order, relationships draw from the entity written first (`CUSTOMER ||--o{ ORDER` reveals
|
|
135
|
-
`CUSTOMER`, then `ORDER`).
|
|
180
|
+
`CUSTOMER`, then `ORDER`). The example reads from the customer down to the supplier.
|
|
136
181
|
|
|
137
|
-
```mermaid live
|
|
182
|
+
```mermaid live title="ER: customer orders and product suppliers"
|
|
138
183
|
erDiagram
|
|
139
|
-
%% pa: 1=CUSTOMER 2=ORDER 3=LINE
|
|
184
|
+
%% pa: 1=CUSTOMER 2=ORDER 3=LINE 4=PRODUCT 5=SUPPLIER
|
|
140
185
|
CUSTOMER ||--o{ ORDER : places
|
|
141
186
|
ORDER ||--|{ LINE : contains
|
|
142
|
-
|
|
187
|
+
LINE }o--|| PRODUCT : lists
|
|
188
|
+
PRODUCT }o--|| SUPPLIER : "supplied by"
|
|
143
189
|
```
|
|
144
190
|
|
|
145
191
|
Neither takes icons.
|
|
@@ -149,53 +195,66 @@ Neither takes icons.
|
|
|
149
195
|
These have no edges to follow, so each steps through its items in reading order and `%% pa:` pins do nothing (as for sequence
|
|
150
196
|
diagrams). Section headers, axes, grids and legends stay visible.
|
|
151
197
|
|
|
152
|
-
- **`timeline`:** one step per time period, with its events.
|
|
198
|
+
- **`timeline`:** one step per time period, with its events. List periods in time order.
|
|
153
199
|
|
|
154
|
-
```mermaid live
|
|
200
|
+
```mermaid live title="Timeline: product history in two phases"
|
|
155
201
|
timeline
|
|
156
|
-
title
|
|
157
|
-
section
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
section
|
|
161
|
-
|
|
202
|
+
title Product history
|
|
203
|
+
section Build
|
|
204
|
+
2019 : Prototype
|
|
205
|
+
2020 : Private beta : First customers
|
|
206
|
+
section Grow
|
|
207
|
+
2021 : Public launch
|
|
208
|
+
2023 : Mobile apps : Offline mode
|
|
209
|
+
2025 : Global rollout
|
|
162
210
|
```
|
|
163
211
|
|
|
164
212
|
- **`journey`:** one step per task: the task, its face, and the line segment that joins it to the task before.
|
|
165
213
|
|
|
166
|
-
```mermaid live
|
|
214
|
+
```mermaid live title="User journey: watching a protected video"
|
|
167
215
|
journey
|
|
168
|
-
title
|
|
169
|
-
section
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
section
|
|
173
|
-
|
|
216
|
+
title Watching a protected video
|
|
217
|
+
section Find
|
|
218
|
+
Open the app: 5: Viewer
|
|
219
|
+
Pick a title: 4: Viewer
|
|
220
|
+
section Play
|
|
221
|
+
Wait for the license: 2: Viewer, App
|
|
222
|
+
Playback starts: 5: Viewer
|
|
223
|
+
section Finish
|
|
224
|
+
Resume later: 4: Viewer
|
|
225
|
+
Rate the title: 3: Viewer
|
|
174
226
|
```
|
|
175
227
|
|
|
176
228
|
- **`gitGraph`:** one step per commit in the order written, with the edge that ends on it. A branch's label and lane appear with
|
|
177
229
|
its first commit.
|
|
178
230
|
|
|
179
|
-
```mermaid live
|
|
231
|
+
```mermaid live title="Git graph: feature branch, merge and release"
|
|
180
232
|
gitGraph
|
|
181
|
-
commit id: "
|
|
182
|
-
branch
|
|
183
|
-
commit id: "
|
|
233
|
+
commit id: "init"
|
|
234
|
+
branch feature
|
|
235
|
+
commit id: "api"
|
|
236
|
+
commit id: "ui"
|
|
184
237
|
checkout main
|
|
185
|
-
commit id: "
|
|
186
|
-
merge
|
|
238
|
+
commit id: "fix"
|
|
239
|
+
merge feature id: "m"
|
|
240
|
+
branch release
|
|
241
|
+
commit id: "v1"
|
|
187
242
|
```
|
|
188
243
|
|
|
189
|
-
- **`gantt`:** one step per task, top to bottom.
|
|
244
|
+
- **`gantt`:** one step per task, top to bottom: write tasks in the order you want them to appear.
|
|
190
245
|
|
|
191
|
-
```mermaid live
|
|
246
|
+
```mermaid live title="Gantt: plan, build and ship"
|
|
192
247
|
gantt
|
|
193
248
|
dateFormat YYYY-MM-DD
|
|
249
|
+
section Plan
|
|
250
|
+
Scope :a1, 2024-01-01, 3d
|
|
251
|
+
Design :after a1, 4d
|
|
194
252
|
section Build
|
|
195
|
-
|
|
196
|
-
|
|
253
|
+
Code :b1, 2024-01-08, 8d
|
|
254
|
+
Review :after b1, 2d
|
|
197
255
|
section Ship
|
|
198
|
-
Test :2024-01-
|
|
256
|
+
Test :2024-01-18, 4d
|
|
257
|
+
Release :2024-01-22, 1d
|
|
199
258
|
```
|
|
200
259
|
|
|
201
260
|
None of these take icons. Only these small examples have been checked in a browser; long diagrams, `todayMarker`, tags, cherry-picks and
|
package/docs/getting-started.md
CHANGED
|
@@ -43,7 +43,7 @@ watch(el, src); // pele-animate animates it, and re-applies when Pele
|
|
|
43
43
|
|
|
44
44
|
The Mermaid source:
|
|
45
45
|
|
|
46
|
-
```mermaid-icons live
|
|
46
|
+
```mermaid-icons live title="Icons: request, load balancer and cloud service"
|
|
47
47
|
flowchart LR
|
|
48
48
|
%% pa: 1=C 2=L 3=S
|
|
49
49
|
C@{ icon: "http-get", form: "square", h: 88, label: "Request" }
|
package/docs/icons.md
CHANGED
|
@@ -9,7 +9,7 @@ section: Guides
|
|
|
9
9
|
|
|
10
10
|
A flowchart node becomes an illustrated node with Mermaid's own `@{ }` syntax:
|
|
11
11
|
|
|
12
|
-
```mermaid-icons live
|
|
12
|
+
```mermaid-icons live title="Icons: laptop sending a request to a server"
|
|
13
13
|
flowchart LR
|
|
14
14
|
A@{ icon: "device-desktop", form: "square", h: 88, label: "Laptop" }
|
|
15
15
|
B@{ icon: "server", form: "square", h: 88, label: "Server" }
|
package/docs/step-order.md
CHANGED
|
@@ -26,7 +26,7 @@ them. By default, the order follows the edges. A `%% pa:` comment lets you set i
|
|
|
26
26
|
|
|
27
27
|
Add one comment line anywhere in the source:
|
|
28
28
|
|
|
29
|
-
```mermaid live
|
|
29
|
+
```mermaid live title="Pins: request, validate, respond with a shortcut"
|
|
30
30
|
flowchart LR
|
|
31
31
|
%% pa: 1=A 2=B 3=C
|
|
32
32
|
A[Request] --> B[Validate] --> C[Respond]
|
|
@@ -40,7 +40,7 @@ level.
|
|
|
40
40
|
|
|
41
41
|
`X>Y` pins the edge from X to Y to its own step, so an edge between two nodes that are already visible can be a step:
|
|
42
42
|
|
|
43
|
-
```mermaid live
|
|
43
|
+
```mermaid live title="Edge pins: a reply as its own step"
|
|
44
44
|
flowchart LR
|
|
45
45
|
%% pa: 1=A,B 2=C 3=A>B
|
|
46
46
|
A[Client] --> B[Server]
|
|
@@ -52,6 +52,7 @@ Rules that avoid surprises:
|
|
|
52
52
|
|
|
53
53
|
- **Pin the nodes first.** An edge pinned before its target appears lands early.
|
|
54
54
|
- A two-way edge (`A <--> B`) is pinned in the direction you wrote it first (`A>B`).
|
|
55
|
+
- The ends may be named in either order (`Video>Media` or `Media>Video`), unless the diagram also has the opposite edge: then the order picks which of the two is meant.
|
|
55
56
|
- Do not rename node ids after pinning: pins match ids.
|
|
56
57
|
- Translated pages keep the same ids, so copy the `%% pa:` line across languages after checking the ids match.
|
|
57
58
|
|
package/package.json
CHANGED
package/pele-animate.js
CHANGED
|
@@ -127,12 +127,15 @@ function sequentialSteps(svg) {
|
|
|
127
127
|
if (svg.classList.contains('pele-timeline')) return all('.pele-period').map((p) => [p]);
|
|
128
128
|
if (svg.classList.contains('pele-gantt')) return all('.pele-task').map((t) => [t]);
|
|
129
129
|
if (svg.classList.contains('pele-journey')) {
|
|
130
|
-
|
|
131
|
-
const
|
|
130
|
+
// Wide: tasks, faces and one polyline are separate. Narrow (vertical list): each step holds its face, edges join the steps.
|
|
131
|
+
const tasks = all('.pele-task, .pele-journey-step');
|
|
132
|
+
const faces = all('.pele-face').filter((f) => !f.closest('.pele-node'));
|
|
132
133
|
// The satisfaction line is one polyline `M x,yL x,y...`: split it so each segment arrives with its task.
|
|
133
134
|
const segs = [];
|
|
134
|
-
|
|
135
|
-
const
|
|
135
|
+
for (const line of all('path.pele-edge')) {
|
|
136
|
+
const d = line.getAttribute('d');
|
|
137
|
+
if (!/^M[-\d.,]+(L[-\d.,]+)+$/.test(d)) { segs.push(line); continue; }
|
|
138
|
+
const p = d.slice(1).split('L');
|
|
136
139
|
for (let i = 1; i < p.length; i++) {
|
|
137
140
|
const seg = line.cloneNode();
|
|
138
141
|
seg.setAttribute('d', `M${p[i - 1]}L${p[i]}`);
|
|
@@ -216,13 +219,17 @@ export function animate(svg, { hover = svg, source = '' } = {}) {
|
|
|
216
219
|
return geoEndpoints(e, boxes);
|
|
217
220
|
});
|
|
218
221
|
const level = bfs(ids, pairs.filter(Boolean), parseOrder(source));
|
|
222
|
+
// An edge pin may name the ends in either order (`Video>Media` for `Media <|-- Video`, or either end of an undirected edge),
|
|
223
|
+
// unless the diagram also has the opposite edge, where the order picks which of the two is meant.
|
|
224
|
+
const real = new Set(pairs.filter(Boolean).map(([a, b]) => `${a}>${b}`));
|
|
225
|
+
const pinOf = (s, d) => level.get(`${s}>${d}`) ?? (real.has(`${d}>${s}`) ? undefined : level.get(`${d}>${s}`));
|
|
219
226
|
const u = Math.min(UNIT, MAX_INTRO / (Math.max(0, ...level.values()) + 1));
|
|
220
227
|
const k = u / UNIT;
|
|
221
228
|
nodes.forEach((n) => { set(n, level.get(n.dataset.id) * u); step.set(n, level.get(n.dataset.id)); });
|
|
222
229
|
// Start after the source is up, but never so early that the arrow lands before its target appears (pinned steps).
|
|
223
230
|
edges.forEach((e, i) => {
|
|
224
231
|
const [s, d] = pairs[i] ?? [];
|
|
225
|
-
const pin =
|
|
232
|
+
const pin = pinOf(s, d); // edge pinned to a step: starts with that step, once its source is up
|
|
226
233
|
step.set(e, pin ?? Math.max(level.get(s) ?? 0, level.get(d) ?? 0));
|
|
227
234
|
times.set(e, pin !== undefined
|
|
228
235
|
? Math.max(pin * u, (level.get(s) ?? 0) * u + 0.3 * k)
|