@kgdiff/renderer 0.0.0-stage → 0.2.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.
Files changed (143) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +53 -2
  3. package/dist/atlas.d.ts +55 -0
  4. package/dist/atlas.d.ts.map +1 -0
  5. package/dist/atlas.js +132 -0
  6. package/dist/atlas.js.map +1 -0
  7. package/dist/camera.d.ts +116 -0
  8. package/dist/camera.d.ts.map +1 -0
  9. package/dist/camera.js +368 -0
  10. package/dist/camera.js.map +1 -0
  11. package/dist/color.d.ts +12 -0
  12. package/dist/color.d.ts.map +1 -0
  13. package/dist/color.js +51 -0
  14. package/dist/color.js.map +1 -0
  15. package/dist/ctx.d.ts +57 -0
  16. package/dist/ctx.d.ts.map +1 -0
  17. package/dist/ctx.js +28 -0
  18. package/dist/ctx.js.map +1 -0
  19. package/dist/draw/background.d.ts +33 -0
  20. package/dist/draw/background.d.ts.map +1 -0
  21. package/dist/draw/background.js +105 -0
  22. package/dist/draw/background.js.map +1 -0
  23. package/dist/draw/badges.d.ts +26 -0
  24. package/dist/draw/badges.d.ts.map +1 -0
  25. package/dist/draw/badges.js +82 -0
  26. package/dist/draw/badges.js.map +1 -0
  27. package/dist/draw/collapsed.d.ts +15 -0
  28. package/dist/draw/collapsed.d.ts.map +1 -0
  29. package/dist/draw/collapsed.js +67 -0
  30. package/dist/draw/collapsed.js.map +1 -0
  31. package/dist/draw/edges.d.ts +14 -0
  32. package/dist/draw/edges.d.ts.map +1 -0
  33. package/dist/draw/edges.js +115 -0
  34. package/dist/draw/edges.js.map +1 -0
  35. package/dist/draw/glyphs.d.ts +31 -0
  36. package/dist/draw/glyphs.d.ts.map +1 -0
  37. package/dist/draw/glyphs.js +114 -0
  38. package/dist/draw/glyphs.js.map +1 -0
  39. package/dist/draw/halos.d.ts +19 -0
  40. package/dist/draw/halos.d.ts.map +1 -0
  41. package/dist/draw/halos.js +91 -0
  42. package/dist/draw/halos.js.map +1 -0
  43. package/dist/draw/labels.d.ts +55 -0
  44. package/dist/draw/labels.d.ts.map +1 -0
  45. package/dist/draw/labels.js +300 -0
  46. package/dist/draw/labels.js.map +1 -0
  47. package/dist/draw/link.d.ts +25 -0
  48. package/dist/draw/link.d.ts.map +1 -0
  49. package/dist/draw/link.js +122 -0
  50. package/dist/draw/link.js.map +1 -0
  51. package/dist/draw/nodes.d.ts +13 -0
  52. package/dist/draw/nodes.d.ts.map +1 -0
  53. package/dist/draw/nodes.js +165 -0
  54. package/dist/draw/nodes.js.map +1 -0
  55. package/dist/draw/shapes.d.ts +7 -0
  56. package/dist/draw/shapes.d.ts.map +1 -0
  57. package/dist/draw/shapes.js +26 -0
  58. package/dist/draw/shapes.js.map +1 -0
  59. package/dist/draw/view.d.ts +36 -0
  60. package/dist/draw/view.d.ts.map +1 -0
  61. package/dist/draw/view.js +16 -0
  62. package/dist/draw/view.js.map +1 -0
  63. package/dist/frame-cache.d.ts +103 -0
  64. package/dist/frame-cache.d.ts.map +1 -0
  65. package/dist/frame-cache.js +349 -0
  66. package/dist/frame-cache.js.map +1 -0
  67. package/dist/index.d.ts +162 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +19 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/input.d.ts +81 -0
  72. package/dist/input.d.ts.map +1 -0
  73. package/dist/input.js +329 -0
  74. package/dist/input.js.map +1 -0
  75. package/dist/labels.d.ts +103 -0
  76. package/dist/labels.d.ts.map +1 -0
  77. package/dist/labels.js +203 -0
  78. package/dist/labels.js.map +1 -0
  79. package/dist/math.d.ts +33 -0
  80. package/dist/math.d.ts.map +1 -0
  81. package/dist/math.js +138 -0
  82. package/dist/math.js.map +1 -0
  83. package/dist/minimap.d.ts +56 -0
  84. package/dist/minimap.d.ts.map +1 -0
  85. package/dist/minimap.js +501 -0
  86. package/dist/minimap.js.map +1 -0
  87. package/dist/paint-stats.d.ts +17 -0
  88. package/dist/paint-stats.d.ts.map +1 -0
  89. package/dist/paint-stats.js +23 -0
  90. package/dist/paint-stats.js.map +1 -0
  91. package/dist/paint.d.ts +64 -0
  92. package/dist/paint.d.ts.map +1 -0
  93. package/dist/paint.js +197 -0
  94. package/dist/paint.js.map +1 -0
  95. package/dist/pick.d.ts +26 -0
  96. package/dist/pick.d.ts.map +1 -0
  97. package/dist/pick.js +125 -0
  98. package/dist/pick.js.map +1 -0
  99. package/dist/renderer.d.ts +28 -0
  100. package/dist/renderer.d.ts.map +1 -0
  101. package/dist/renderer.js +470 -0
  102. package/dist/renderer.js.map +1 -0
  103. package/dist/smooth-zoom.d.ts +21 -0
  104. package/dist/smooth-zoom.d.ts.map +1 -0
  105. package/dist/smooth-zoom.js +52 -0
  106. package/dist/smooth-zoom.js.map +1 -0
  107. package/dist/spatial.d.ts +26 -0
  108. package/dist/spatial.d.ts.map +1 -0
  109. package/dist/spatial.js +103 -0
  110. package/dist/spatial.js.map +1 -0
  111. package/dist/text.d.ts +36 -0
  112. package/dist/text.d.ts.map +1 -0
  113. package/dist/text.js +123 -0
  114. package/dist/text.js.map +1 -0
  115. package/package.json +47 -3
  116. package/src/atlas.ts +171 -0
  117. package/src/camera.ts +482 -0
  118. package/src/color.ts +58 -0
  119. package/src/ctx.ts +102 -0
  120. package/src/draw/background.ts +139 -0
  121. package/src/draw/badges.ts +93 -0
  122. package/src/draw/collapsed.ts +86 -0
  123. package/src/draw/edges.ts +135 -0
  124. package/src/draw/glyphs.ts +168 -0
  125. package/src/draw/halos.ts +101 -0
  126. package/src/draw/labels.ts +399 -0
  127. package/src/draw/link.ts +157 -0
  128. package/src/draw/nodes.ts +184 -0
  129. package/src/draw/shapes.ts +36 -0
  130. package/src/draw/view.ts +37 -0
  131. package/src/frame-cache.ts +382 -0
  132. package/src/index.ts +161 -0
  133. package/src/input.ts +370 -0
  134. package/src/labels.ts +269 -0
  135. package/src/math.ts +185 -0
  136. package/src/minimap.ts +545 -0
  137. package/src/paint-stats.ts +38 -0
  138. package/src/paint.ts +235 -0
  139. package/src/pick.ts +173 -0
  140. package/src/renderer.ts +539 -0
  141. package/src/smooth-zoom.ts +65 -0
  142. package/src/spatial.ts +94 -0
  143. package/src/text.ts +130 -0
@@ -0,0 +1,501 @@
1
+ import { KgdiffError } from '@kgdiff/core';
2
+ import { domSurfaceFactory } from './ctx.js';
3
+ import { roundRectPath } from './draw/shapes.js';
4
+ import { clamp, TAU } from './math.js';
5
+ import { internals } from './renderer.js';
6
+ const PAD = 8;
7
+ const RADIUS = 12;
8
+ /** Neutral dot size (css px) and alpha. */
9
+ const NEUTRAL_DOT = 1.5;
10
+ const NEUTRAL_ALPHA = 0.45;
11
+ /** Changed dot diameter and background outline (css px). */
12
+ const CHANGE_DOT = 2.5;
13
+ const CHANGE_OUTLINE = 1;
14
+ /** Edges are drawn below this count, as hairlines. */
15
+ const EDGE_LIMIT = 3000;
16
+ const EDGE_WIDTH = 0.5;
17
+ const EDGE_ALPHA = 0.12;
18
+ /** Window growth time constant (ms): settles in ~150 ms. */
19
+ const GROW_TAU = 50;
20
+ /** The window grows back only once it is this much smaller than needed (hysteresis). */
21
+ const GROW_SLACK = 0.8;
22
+ /** The family color of a change mark, or null for neutral context (by `NodeVisual.family`). */
23
+ export function markColor(n, theme) {
24
+ const f = n.family;
25
+ if (f === 'neutral')
26
+ return null;
27
+ return theme.family[f]?.base ?? null;
28
+ }
29
+ /**
30
+ * The minimap's world window: centred on the content, covering the content and the viewport.
31
+ * Extending symmetrically keeps the content centred; the viewport always fits inside.
32
+ */
33
+ export function minimapWindow(content, viewport) {
34
+ const cx = content.x + content.width / 2;
35
+ const cy = content.y + content.height / 2;
36
+ let hw = Math.max(content.width / 2, 1);
37
+ let hh = Math.max(content.height / 2, 1);
38
+ if (viewport &&
39
+ Number.isFinite(viewport.x + viewport.y + viewport.width + viewport.height) &&
40
+ viewport.width > 0 &&
41
+ viewport.height > 0) {
42
+ hw = Math.max(hw, cx - viewport.x, viewport.x + viewport.width - cx);
43
+ hh = Math.max(hh, cy - viewport.y, viewport.y + viewport.height - cy);
44
+ }
45
+ return { x: cx - hw, y: cy - hh, width: 2 * hw, height: 2 * hh };
46
+ }
47
+ /**
48
+ * Minimap zoom (px per world unit) with asymmetric smoothing: shrinks at once (the viewport
49
+ * must stay visible), grows back eased and only once it has `GROW_SLACK` room (no jitter).
50
+ */
51
+ export class WindowScale {
52
+ value = 0;
53
+ target = 0;
54
+ growing = false;
55
+ /** Set the scale the window needs now; returns whether `value` changed. */
56
+ retarget(target) {
57
+ if (!(target > 0) || !Number.isFinite(target))
58
+ return false;
59
+ this.target = target;
60
+ if (!(this.value > 0) || target <= this.value) {
61
+ const changed = target !== this.value;
62
+ this.value = target;
63
+ this.growing = false;
64
+ return changed;
65
+ }
66
+ if (!this.growing && this.value < target * GROW_SLACK)
67
+ this.growing = true;
68
+ return false;
69
+ }
70
+ /** Advance the eased growth by `dt` ms; returns whether it is still growing. */
71
+ step(dt) {
72
+ if (!this.growing)
73
+ return false;
74
+ this.value += (this.target - this.value) * (1 - Math.exp(-Math.max(0, dt) / GROW_TAU));
75
+ if (Math.abs(this.target - this.value) <= this.target * 0.002) {
76
+ this.value = this.target;
77
+ this.growing = false;
78
+ }
79
+ return this.growing;
80
+ }
81
+ }
82
+ /** Uniform scale + offset that fits `bounds` into a w × h box with padding, centred. */
83
+ export function fitTransform(bounds, w, h, pad) {
84
+ const aw = Math.max(1, w - 2 * pad);
85
+ const ah = Math.max(1, h - 2 * pad);
86
+ const bw = Math.max(bounds.width, 1e-9);
87
+ const bh = Math.max(bounds.height, 1e-9);
88
+ const s = Math.min(aw / bw, ah / bh);
89
+ return { s, ox: (w - bw * s) / 2 - bounds.x * s, oy: (h - bh * s) / 2 - bounds.y * s };
90
+ }
91
+ class CanvasMinimap {
92
+ renderer;
93
+ canvas;
94
+ ctx;
95
+ factory;
96
+ width;
97
+ height;
98
+ theme;
99
+ dpr = 1;
100
+ layer = null;
101
+ frame = null;
102
+ collapsed = [];
103
+ fit = null;
104
+ content = null;
105
+ scale = new WindowScale();
106
+ rafId = 0;
107
+ lastTick = -1;
108
+ cleanup = [];
109
+ drag = null;
110
+ destroyed = false;
111
+ constructor(container, renderer, options, deps) {
112
+ this.renderer = renderer;
113
+ const host = internals.get(renderer);
114
+ if (!host) {
115
+ throw new KgdiffError('invalid-input', 'createMinimap: renderer is destroyed or was not created by createRenderer');
116
+ }
117
+ this.width = Math.max(16, Math.round(options.width ?? 184));
118
+ this.height = Math.max(16, Math.round(options.height ?? 128));
119
+ this.theme = host.theme();
120
+ this.factory = deps.surfaceFactory ?? domSurfaceFactory;
121
+ const canvas = document.createElement('canvas');
122
+ canvas.setAttribute('aria-hidden', 'true');
123
+ const st = canvas.style;
124
+ st.display = 'block';
125
+ st.width = `${this.width}px`;
126
+ st.height = `${this.height}px`;
127
+ st.borderRadius = `${RADIUS}px`;
128
+ st.touchAction = 'none';
129
+ st.cursor = 'pointer';
130
+ st.setProperty('-webkit-tap-highlight-color', 'transparent');
131
+ container.appendChild(canvas);
132
+ this.canvas = canvas;
133
+ this.ctx = deps.context !== undefined ? deps.context : canvas.getContext('2d');
134
+ this.style();
135
+ this.resizeBuffer(host.pixelRatio());
136
+ this.cleanup.push(renderer.on('camera', () => {
137
+ this.refit(false);
138
+ this.redraw();
139
+ }));
140
+ this.cleanup.push(host.onTheme((theme) => {
141
+ this.theme = theme;
142
+ this.style();
143
+ this.rasterize();
144
+ this.redraw();
145
+ }));
146
+ const listen = (type, fn) => {
147
+ canvas.addEventListener(type, fn);
148
+ this.cleanup.push(() => canvas.removeEventListener(type, fn));
149
+ };
150
+ listen('pointerdown', (e) => this.onDown(e));
151
+ listen('pointermove', (e) => this.onMove(e));
152
+ listen('pointerup', (e) => this.onUp(e));
153
+ listen('pointercancel', (e) => this.onUp(e));
154
+ this.redraw();
155
+ }
156
+ update(frame, collapsed) {
157
+ if (this.destroyed)
158
+ return;
159
+ this.frame = frame;
160
+ this.collapsed = collapsed ?? frame.collapsed;
161
+ const host = internals.get(this.renderer);
162
+ if (host && host.pixelRatio() !== this.dpr)
163
+ this.resizeBuffer(host.pixelRatio());
164
+ const first = this.content === null;
165
+ this.content = this.bounds();
166
+ this.refit(first);
167
+ this.rasterize();
168
+ this.redraw();
169
+ }
170
+ transform() {
171
+ return this.fit;
172
+ }
173
+ destroy() {
174
+ if (this.destroyed)
175
+ return;
176
+ this.destroyed = true;
177
+ if (this.rafId)
178
+ internals.get(this.renderer)?.cancelFrame(this.rafId);
179
+ this.rafId = 0;
180
+ for (const fn of this.cleanup.splice(0))
181
+ fn();
182
+ this.canvas.remove();
183
+ this.layer = null;
184
+ this.frame = null;
185
+ }
186
+ style() {
187
+ const st = this.canvas.style;
188
+ st.background = this.theme.surface.overlay;
189
+ st.boxShadow = this.theme.surface.shadow;
190
+ st.setProperty('backdrop-filter', 'blur(16px)');
191
+ st.setProperty('-webkit-backdrop-filter', 'blur(16px)');
192
+ }
193
+ /**
194
+ * Recompute the window for the current content and viewport. Frozen while dragging on the
195
+ * minimap, so the world point under the pointer does not move. `reset` jumps to the target.
196
+ */
197
+ refit(reset) {
198
+ const content = this.content;
199
+ if (!content) {
200
+ this.fit = null;
201
+ return;
202
+ }
203
+ if (this.drag && !reset)
204
+ return;
205
+ const viewport = this.renderer.camera.viewport();
206
+ const target = fitTransform(minimapWindow(content, viewport), this.width, this.height, PAD).s;
207
+ if (reset)
208
+ this.scale.value = 0;
209
+ const jumped = this.scale.retarget(target);
210
+ this.applyScale();
211
+ if (jumped && !reset)
212
+ this.rasterize();
213
+ if (this.scale.growing)
214
+ this.schedule();
215
+ }
216
+ applyScale() {
217
+ const content = this.content;
218
+ const s = this.scale.value;
219
+ if (!content || !(s > 0)) {
220
+ this.fit = null;
221
+ return;
222
+ }
223
+ const cx = content.x + content.width / 2;
224
+ const cy = content.y + content.height / 2;
225
+ this.fit = { s, ox: this.width / 2 - cx * s, oy: this.height / 2 - cy * s };
226
+ }
227
+ schedule() {
228
+ if (this.rafId || this.destroyed)
229
+ return;
230
+ const host = internals.get(this.renderer);
231
+ if (!host)
232
+ return;
233
+ this.rafId = host.requestFrame(this.tick) || 0;
234
+ }
235
+ tick = (time) => {
236
+ this.rafId = 0;
237
+ if (this.destroyed)
238
+ return;
239
+ const dt = this.lastTick < 0 ? 16 : Math.min(64, time - this.lastTick);
240
+ const growing = this.scale.step(dt);
241
+ this.lastTick = growing ? time : -1;
242
+ this.applyScale();
243
+ this.rasterize();
244
+ this.redraw();
245
+ if (growing)
246
+ this.schedule();
247
+ };
248
+ resizeBuffer(dpr) {
249
+ this.dpr = dpr;
250
+ this.canvas.width = Math.round(this.width * dpr);
251
+ this.canvas.height = Math.round(this.height * dpr);
252
+ this.layer = this.factory(this.canvas.width, this.canvas.height);
253
+ this.rasterize();
254
+ }
255
+ bounds() {
256
+ const frame = this.frame;
257
+ if (!frame)
258
+ return null;
259
+ let x0 = Number.POSITIVE_INFINITY;
260
+ let y0 = Number.POSITIVE_INFINITY;
261
+ let x1 = Number.NEGATIVE_INFINITY;
262
+ let y1 = Number.NEGATIVE_INFINITY;
263
+ for (const n of frame.nodes) {
264
+ if (!n.visible || !Number.isFinite(n.x + n.y))
265
+ continue;
266
+ if (n.x < x0)
267
+ x0 = n.x;
268
+ if (n.y < y0)
269
+ y0 = n.y;
270
+ if (n.x > x1)
271
+ x1 = n.x;
272
+ if (n.y > y1)
273
+ y1 = n.y;
274
+ }
275
+ for (const g of this.collapsed) {
276
+ if (!Number.isFinite(g.x + g.y))
277
+ continue;
278
+ x0 = Math.min(x0, g.x);
279
+ y0 = Math.min(y0, g.y);
280
+ x1 = Math.max(x1, g.x);
281
+ y1 = Math.max(y1, g.y);
282
+ }
283
+ return x0 <= x1 ? { x: x0, y: y0, width: x1 - x0, height: y1 - y0 } : null;
284
+ }
285
+ /** Rasterize the marks into the offscreen layer (device px, snapped squares). */
286
+ rasterize() {
287
+ const target = this.layer?.ctx ?? null;
288
+ if (!target)
289
+ return;
290
+ target.setTransform(1, 0, 0, 1, 0, 0);
291
+ target.clearRect(0, 0, this.canvas.width, this.canvas.height);
292
+ this.drawMarks(target);
293
+ }
294
+ drawMarks(ctx) {
295
+ const frame = this.frame;
296
+ const fit = this.fit;
297
+ if (!frame || !fit)
298
+ return;
299
+ const theme = this.theme;
300
+ const dpr = this.dpr;
301
+ const sx = (wx) => (wx * fit.s + fit.ox) * dpr;
302
+ const sy = (wy) => (wy * fit.s + fit.oy) * dpr;
303
+ const neutral = theme.name === 'light' ? theme.neutral.nodeStroke : theme.neutral.node;
304
+ // Structure: edges as device-pixel hairlines (cheap below a few thousand).
305
+ if (frame.edges.length > 0 && frame.edges.length < EDGE_LIMIT) {
306
+ ctx.globalAlpha = EDGE_ALPHA;
307
+ ctx.strokeStyle = neutral;
308
+ ctx.lineWidth = Math.max(1, EDGE_WIDTH * dpr);
309
+ ctx.setLineDash([]);
310
+ ctx.beginPath();
311
+ for (const e of frame.edges) {
312
+ if (!e.visible || !Number.isFinite(e.x1 + e.y1 + e.x2 + e.y2))
313
+ continue;
314
+ ctx.moveTo(sx(e.x1), sy(e.y1));
315
+ ctx.lineTo(sx(e.x2), sy(e.y2));
316
+ }
317
+ ctx.stroke();
318
+ }
319
+ // Neutral context: small squares on the device-pixel grid.
320
+ const small = Math.max(1, Math.round(NEUTRAL_DOT * dpr));
321
+ const changed = new Map();
322
+ ctx.globalAlpha = NEUTRAL_ALPHA;
323
+ ctx.fillStyle = neutral;
324
+ ctx.beginPath();
325
+ for (let i = 0; i < frame.nodes.length; i++) {
326
+ const n = frame.nodes[i];
327
+ if (!n.visible || !Number.isFinite(n.x + n.y))
328
+ continue;
329
+ const color = markColor(n, theme);
330
+ if (color !== null) {
331
+ let list = changed.get(color);
332
+ if (!list) {
333
+ list = [];
334
+ changed.set(color, list);
335
+ }
336
+ list.push(i);
337
+ continue;
338
+ }
339
+ ctx.rect(Math.round(sx(n.x) - small / 2), Math.round(sy(n.y) - small / 2), small, small);
340
+ }
341
+ ctx.fill();
342
+ const r = (CHANGE_DOT / 2) * dpr;
343
+ const outline = r + CHANGE_OUTLINE * dpr;
344
+ ctx.globalAlpha = 0.6;
345
+ ctx.fillStyle = theme.text.muted;
346
+ ctx.beginPath();
347
+ for (const g of this.collapsed) {
348
+ if (!Number.isFinite(g.x + g.y))
349
+ continue;
350
+ ctx.rect(Math.round(sx(g.x) - r), Math.round(sy(g.y) - r), Math.round(2 * r), Math.round(2 * r));
351
+ }
352
+ ctx.fill();
353
+ // Changes: dots in family color over a background-colored outline, so they pop.
354
+ if (changed.size === 0)
355
+ return;
356
+ ctx.globalAlpha = 1;
357
+ ctx.fillStyle = theme.canvas.background;
358
+ ctx.beginPath();
359
+ for (const list of changed.values()) {
360
+ for (const i of list) {
361
+ const n = frame.nodes[i];
362
+ ctx.moveTo(sx(n.x) + outline, sy(n.y));
363
+ ctx.arc(sx(n.x), sy(n.y), outline, 0, TAU);
364
+ }
365
+ }
366
+ ctx.fill();
367
+ for (const [color, list] of changed) {
368
+ ctx.fillStyle = color;
369
+ ctx.beginPath();
370
+ for (const i of list) {
371
+ const n = frame.nodes[i];
372
+ ctx.moveTo(sx(n.x) + r, sy(n.y));
373
+ ctx.arc(sx(n.x), sy(n.y), r, 0, TAU);
374
+ }
375
+ ctx.fill();
376
+ }
377
+ }
378
+ /** Blit the marks, then draw the viewport rectangle and the card border. */
379
+ redraw() {
380
+ const ctx = this.ctx;
381
+ if (!ctx || this.destroyed)
382
+ return;
383
+ const ratio = internals.get(this.renderer)?.pixelRatio();
384
+ if (ratio !== undefined && ratio !== this.dpr)
385
+ this.resizeBuffer(ratio);
386
+ const dpr = this.dpr;
387
+ const w = this.width;
388
+ const h = this.height;
389
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
390
+ ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
391
+ ctx.save();
392
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
393
+ ctx.beginPath();
394
+ roundRectPath(ctx, 0, 0, w, h, RADIUS);
395
+ ctx.clip();
396
+ if (this.layer) {
397
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
398
+ ctx.drawImage(this.layer.canvas, 0, 0, this.canvas.width, this.canvas.height);
399
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
400
+ }
401
+ else {
402
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
403
+ this.drawMarks(ctx);
404
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
405
+ }
406
+ const fit = this.fit;
407
+ if (fit) {
408
+ const vp = this.renderer.camera.viewport();
409
+ const x0 = clamp(vp.x * fit.s + fit.ox, -2, w + 2);
410
+ const y0 = clamp(vp.y * fit.s + fit.oy, -2, h + 2);
411
+ const x1 = clamp((vp.x + vp.width) * fit.s + fit.ox, -2, w + 2);
412
+ const y1 = clamp((vp.y + vp.height) * fit.s + fit.oy, -2, h + 2);
413
+ if (x1 - x0 > 0.5 && y1 - y0 > 0.5) {
414
+ const snapPx = (v) => Math.round(v * dpr) / dpr;
415
+ const rx = snapPx(x0);
416
+ const ry = snapPx(y0);
417
+ const rw = Math.max(2, snapPx(x1) - rx);
418
+ const rh = Math.max(2, snapPx(y1) - ry);
419
+ ctx.globalAlpha = 1;
420
+ ctx.fillStyle = this.theme.accent.soft;
421
+ ctx.fillRect(rx, ry, rw, rh);
422
+ ctx.strokeStyle = this.theme.accent.base;
423
+ ctx.lineWidth = 1.25;
424
+ ctx.setLineDash([]);
425
+ ctx.beginPath();
426
+ ctx.rect(rx + 0.625, ry + 0.625, rw - 1.25, rh - 1.25);
427
+ ctx.stroke();
428
+ }
429
+ }
430
+ ctx.restore();
431
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
432
+ ctx.globalAlpha = 1;
433
+ ctx.strokeStyle = this.theme.surface.border;
434
+ ctx.lineWidth = 1;
435
+ ctx.beginPath();
436
+ roundRectPath(ctx, 0.5, 0.5, w - 1, h - 1, RADIUS - 0.5);
437
+ ctx.stroke();
438
+ }
439
+ toWorld(e) {
440
+ const fit = this.fit;
441
+ if (!fit)
442
+ return null;
443
+ const r = this.canvas.getBoundingClientRect();
444
+ const mx = e.clientX - r.left;
445
+ const my = e.clientY - r.top;
446
+ return { x: (mx - fit.ox) / fit.s, y: (my - fit.oy) / fit.s };
447
+ }
448
+ onDown(e) {
449
+ if (e.pointerType === 'mouse' && e.button !== 0)
450
+ return;
451
+ const p = this.toWorld(e);
452
+ if (!p)
453
+ return;
454
+ e.preventDefault();
455
+ try {
456
+ this.canvas.setPointerCapture(e.pointerId);
457
+ }
458
+ catch {
459
+ // Best effort.
460
+ }
461
+ const cam = this.renderer.camera;
462
+ const s = cam.get();
463
+ const vp = cam.viewport();
464
+ const inside = p.x >= vp.x && p.x <= vp.x + vp.width && p.y >= vp.y && p.y <= vp.y + vp.height;
465
+ // Grabbing the rectangle keeps the grab offset; clicking elsewhere centres the view there.
466
+ this.drag = inside
467
+ ? { id: e.pointerId, dx: s.x - p.x, dy: s.y - p.y }
468
+ : { id: e.pointerId, dx: 0, dy: 0 };
469
+ if (!inside)
470
+ this.move({ x: p.x, y: p.y, k: s.k });
471
+ }
472
+ /** Navigate on the user's behalf (the `camera` event reports source 'user'). */
473
+ move(state) {
474
+ const host = internals.get(this.renderer);
475
+ if (host)
476
+ host.userSet(state);
477
+ else
478
+ this.renderer.camera.set(state);
479
+ }
480
+ onMove(e) {
481
+ const drag = this.drag;
482
+ if (!drag || drag.id !== e.pointerId)
483
+ return;
484
+ const p = this.toWorld(e);
485
+ if (!p)
486
+ return;
487
+ this.move({ x: p.x + drag.dx, y: p.y + drag.dy, k: this.renderer.camera.get().k });
488
+ }
489
+ onUp(e) {
490
+ if (this.drag?.id !== e.pointerId)
491
+ return;
492
+ this.drag = null;
493
+ // The window was frozen during the drag: catch up with the viewport now.
494
+ this.refit(false);
495
+ this.redraw();
496
+ }
497
+ }
498
+ export function createMinimapImpl(container, renderer, options = {}, deps = {}) {
499
+ return new CanvasMinimap(container, renderer, options, deps);
500
+ }
501
+ //# sourceMappingURL=minimap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"minimap.js","sourceRoot":"","sources":["../src/minimap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /** Counters filled by each paint (tests, the dev harness readout). */
2
+ export interface PaintStats {
3
+ nodes: number;
4
+ edges: number;
5
+ culledNodes: number;
6
+ culledEdges: number;
7
+ labels: number;
8
+ /** `stroke()` calls issued for edges (one per non-empty style bucket). */
9
+ edgeStrokes: number;
10
+ /** Labels placed but not yet rasterized (budget); the renderer schedules another frame. */
11
+ deferredLabels: number;
12
+ /** Passes in draw order, per layer. */
13
+ readonly phases: string[];
14
+ }
15
+ export declare function createStats(): PaintStats;
16
+ export declare function resetStats(s: PaintStats): void;
17
+ //# sourceMappingURL=paint-stats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paint-stats.d.ts","sourceRoot":"","sources":["../src/paint-stats.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB,2FAA2F;IAC3F,cAAc,EAAE,MAAM,CAAC;IACvB,uCAAuC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,wBAAgB,WAAW,IAAI,UAAU,CAWxC;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,UAAU,GAAG,IAAI,CAS9C"}
@@ -0,0 +1,23 @@
1
+ export function createStats() {
2
+ return {
3
+ nodes: 0,
4
+ edges: 0,
5
+ culledNodes: 0,
6
+ culledEdges: 0,
7
+ labels: 0,
8
+ edgeStrokes: 0,
9
+ deferredLabels: 0,
10
+ phases: [],
11
+ };
12
+ }
13
+ export function resetStats(s) {
14
+ s.nodes = 0;
15
+ s.edges = 0;
16
+ s.culledNodes = 0;
17
+ s.culledEdges = 0;
18
+ s.labels = 0;
19
+ s.edgeStrokes = 0;
20
+ s.deferredLabels = 0;
21
+ s.phases.length = 0;
22
+ }
23
+ //# sourceMappingURL=paint-stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paint-stats.js","sourceRoot":"","sources":["../src/paint-stats.ts"],"names":[],"mappings":"AAeA,MAAM,UAAU,WAAW;IACzB,OAAO;QACL,KAAK,EAAE,CAAC;QACR,KAAK,EAAE,CAAC;QACR,WAAW,EAAE,CAAC;QACd,WAAW,EAAE,CAAC;QACd,MAAM,EAAE,CAAC;QACT,WAAW,EAAE,CAAC;QACd,cAAc,EAAE,CAAC;QACjB,MAAM,EAAE,EAAE;KACX,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,CAAa;IACtC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;IACZ,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;IACZ,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC;IAClB,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC;IAClB,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IACb,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC;IAClB,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC;IACrB,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;AACtB,CAAC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Paints one frame (or a swipe pair) into a `Ctx2D`. Pass order (docs/visual-language.md):
3
+ * background + grid → collapsed pills → edges → glyph arcs → halos → nodes (+ rings, pulses)
4
+ * → pivots → badges → labels. Swipe draws the background once, then each side clipped to its
5
+ * half with its own label placement.
6
+ */
7
+ import type { FrameVisuals, Theme } from '@kgdiff/scene';
8
+ import { LabelAtlas } from './atlas.js';
9
+ import type { Ctx2D, SurfaceFactory } from './ctx.js';
10
+ import { GridTiles } from './draw/background.js';
11
+ import { HaloSprites } from './draw/halos.js';
12
+ import { type FrameCache, Interner } from './frame-cache.js';
13
+ import type { CameraState, SplitFrame } from './index.js';
14
+ import { type PaintStats } from './paint-stats.js';
15
+ import { Fonts, TextMeasurer } from './text.js';
16
+ export declare function isSplit(frame: FrameVisuals | SplitFrame): frame is SplitFrame;
17
+ /** Divider position (css px, on the device-pixel grid) for a split fraction. */
18
+ export declare function splitX(split: number, width: number, dpr: number): number;
19
+ /** Caches that live as long as a renderer: fonts, text metrics, sprites, atlas, tiles. */
20
+ export declare class Resources {
21
+ readonly factory: SurfaceFactory;
22
+ readonly fonts: Fonts;
23
+ readonly measurer: TextMeasurer;
24
+ readonly atlas: LabelAtlas | null;
25
+ readonly halos: HaloSprites;
26
+ readonly tiles: GridTiles;
27
+ readonly interner: Interner;
28
+ private dpr;
29
+ private theme;
30
+ constructor(factory: SurfaceFactory, theme: Theme, fallbackMeasureCtx: Ctx2D | null);
31
+ setTheme(theme: Theme): void;
32
+ /** Called before painting: re-keys pixel-ratio dependent caches. */
33
+ prepare(dpr: number): void;
34
+ /** Web fonts finished loading: metrics and rasterized labels are stale. */
35
+ fontsChanged(): void;
36
+ }
37
+ export interface PaintTarget {
38
+ readonly ctx: Ctx2D;
39
+ /** css px */
40
+ readonly width: number;
41
+ readonly height: number;
42
+ readonly dpr: number;
43
+ }
44
+ export interface PaintCaches {
45
+ readonly main: FrameCache;
46
+ readonly before: FrameCache;
47
+ readonly after: FrameCache;
48
+ }
49
+ /** New label rasterizations per frame (≈ 3–5 ms of text rendering on mid-range hardware). */
50
+ export declare const LABEL_RASTER_BUDGET = 160;
51
+ export declare class Painter {
52
+ private readonly res;
53
+ readonly stats: PaintStats;
54
+ /** Override for exports, which must contain every label in one paint. */
55
+ rasterBudget: number;
56
+ private readonly labels;
57
+ private readonly badges;
58
+ private readonly grid;
59
+ private readonly view;
60
+ constructor(res: Resources);
61
+ paint(target: PaintTarget, cam: CameraState, frame: FrameVisuals | SplitFrame | null, caches: PaintCaches, version: number, theme: Theme, grid: boolean): PaintStats;
62
+ private layers;
63
+ }
64
+ //# sourceMappingURL=paint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paint.d.ts","sourceRoot":"","sources":["../src/paint.ts"],"names":[],"mappings":"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"}