@kgdiff/renderer 0.0.0-stage → 0.1.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,470 @@
1
+ import { KgdiffError } from '@kgdiff/core';
2
+ import { CameraController, NO_INSETS } from './camera.js';
3
+ import { domSurfaceFactory } from './ctx.js';
4
+ import { FrameCache, unionBounds } from './frame-cache.js';
5
+ import { attachInput } from './input.js';
6
+ import { clamp } from './math.js';
7
+ import { isSplit, LABEL_RASTER_BUDGET, Painter, Resources, splitX } from './paint.js';
8
+ import { pickAt } from './pick.js';
9
+ export const internals = new WeakMap();
10
+ const MAX_PIXEL_RATIO = 3;
11
+ function samePick(a, b) {
12
+ return a === b || (a !== null && b !== null && a.type === b.type && a.index === b.index);
13
+ }
14
+ function windowRatio() {
15
+ return typeof window !== 'undefined' && window.devicePixelRatio > 0 ? window.devicePixelRatio : 1;
16
+ }
17
+ class CanvasRenderer {
18
+ canvas;
19
+ camera;
20
+ ctx;
21
+ theme;
22
+ safe;
23
+ grid;
24
+ fixedRatio;
25
+ dpr = 1;
26
+ width = 0;
27
+ height = 0;
28
+ frame = null;
29
+ version = 0;
30
+ caches = {
31
+ main: new FrameCache(),
32
+ before: new FrameCache(),
33
+ after: new FrameCache(),
34
+ };
35
+ res;
36
+ painter;
37
+ listeners = {
38
+ hover: new Set(),
39
+ click: new Set(),
40
+ dblclick: new Set(),
41
+ camera: new Set(),
42
+ frame: new Set(),
43
+ };
44
+ themeListeners = new Set();
45
+ cleanup = [];
46
+ now;
47
+ requestFrame;
48
+ cancelFrame;
49
+ motionQuery;
50
+ rafId = 0;
51
+ dirty = true;
52
+ busy = false;
53
+ destroyed = false;
54
+ cameraChanged = true;
55
+ /** The viewport changed size: `camera` fires even if the state did not change. */
56
+ viewportChanged = true;
57
+ emitted = null;
58
+ autoFitted = false;
59
+ pointer = null;
60
+ hoverPending = false;
61
+ hovered = null;
62
+ dragging = false;
63
+ constructor(container, options, deps) {
64
+ const minZoom = options.minZoom ?? 0.05;
65
+ const maxZoom = options.maxZoom ?? 6;
66
+ if (!(minZoom > 0) || !(maxZoom >= minZoom) || !Number.isFinite(maxZoom)) {
67
+ throw new KgdiffError('invalid-input', `createRenderer: expected 0 < minZoom ≤ maxZoom, got minZoom ${minZoom}, maxZoom ${maxZoom}`);
68
+ }
69
+ if (options.pixelRatio !== undefined && !(options.pixelRatio > 0)) {
70
+ throw new KgdiffError('invalid-input', `createRenderer: pixelRatio must be > 0, got ${options.pixelRatio}`);
71
+ }
72
+ this.theme = options.theme;
73
+ this.safe = options.safeArea ?? NO_INSETS;
74
+ this.grid = options.grid ?? true;
75
+ this.fixedRatio = options.pixelRatio;
76
+ this.now = deps.now ?? (() => performance.now());
77
+ this.requestFrame =
78
+ deps.requestFrame ??
79
+ ((cb) => (typeof requestAnimationFrame === 'function' ? requestAnimationFrame(cb) : 0));
80
+ this.cancelFrame =
81
+ deps.cancelFrame ??
82
+ ((id) => (typeof cancelAnimationFrame === 'function' ? cancelAnimationFrame(id) : undefined));
83
+ this.motionQuery =
84
+ typeof window !== 'undefined' && typeof window.matchMedia === 'function'
85
+ ? window.matchMedia('(prefers-reduced-motion: reduce)')
86
+ : null;
87
+ const canvas = document.createElement('canvas');
88
+ canvas.setAttribute('role', 'img');
89
+ const st = canvas.style;
90
+ st.position = 'absolute';
91
+ st.left = '0';
92
+ st.top = '0';
93
+ st.width = '100%';
94
+ st.height = '100%';
95
+ st.display = 'block';
96
+ st.touchAction = 'none';
97
+ st.userSelect = 'none';
98
+ st.setProperty('-webkit-user-select', 'none');
99
+ st.setProperty('-webkit-tap-highlight-color', 'transparent');
100
+ st.outline = 'none';
101
+ container.appendChild(canvas);
102
+ this.canvas = canvas;
103
+ this.ctx =
104
+ deps.context !== undefined ? deps.context : canvas.getContext('2d', { alpha: false });
105
+ this.camera = new CameraController({
106
+ size: () => ({ width: this.width, height: this.height }),
107
+ safeArea: () => this.safe,
108
+ contentBounds: () => this.contentBounds(),
109
+ reducedMotion: () => this.motionQuery?.matches ?? false,
110
+ invalidate: () => {
111
+ this.cameraChanged = true;
112
+ if (this.pointer)
113
+ this.hoverPending = true;
114
+ this.requestRender();
115
+ },
116
+ }, minZoom, maxZoom);
117
+ this.res = new Resources(deps.surfaceFactory ?? domSurfaceFactory, this.theme, this.ctx);
118
+ this.painter = new Painter(this.res);
119
+ this.observeSize();
120
+ this.watchPixelRatio();
121
+ this.watchFonts();
122
+ if (options.interactive ?? true) {
123
+ this.cleanup.push(attachInput(canvas, {
124
+ camera: this.camera,
125
+ hover: (x, y) => {
126
+ this.pointer = { x, y };
127
+ this.hoverPending = true;
128
+ this.schedule();
129
+ },
130
+ leave: () => {
131
+ this.pointer = null;
132
+ this.setHover(null);
133
+ },
134
+ click: (x, y, event) => {
135
+ this.emit('click', {
136
+ pick: this.pick(x, y),
137
+ world: this.camera.screenToWorld({ x, y }),
138
+ event,
139
+ });
140
+ },
141
+ dblclick: (x, y, event) => {
142
+ this.emit('dblclick', {
143
+ pick: this.pick(x, y),
144
+ world: this.camera.screenToWorld({ x, y }),
145
+ event,
146
+ });
147
+ },
148
+ dragging: (active) => {
149
+ this.dragging = active;
150
+ this.canvas.style.cursor = active ? 'grabbing' : '';
151
+ if (active)
152
+ this.setHover(null);
153
+ else if (this.pointer) {
154
+ this.hoverPending = true;
155
+ this.schedule();
156
+ }
157
+ },
158
+ now: this.now,
159
+ }));
160
+ }
161
+ internals.set(this, {
162
+ theme: () => this.theme,
163
+ pixelRatio: () => this.dpr,
164
+ size: () => ({ width: this.width, height: this.height }),
165
+ userSet: (state) => this.camera.set(state, 'user'),
166
+ onTheme: (listener) => {
167
+ this.themeListeners.add(listener);
168
+ return () => this.themeListeners.delete(listener);
169
+ },
170
+ requestFrame: this.requestFrame,
171
+ cancelFrame: this.cancelFrame,
172
+ });
173
+ this.resize();
174
+ }
175
+ // ─── Public API ────────────────────────────────────────────────────────────
176
+ setFrame(frame) {
177
+ if (this.destroyed)
178
+ return;
179
+ this.frame = frame;
180
+ this.version++;
181
+ if (this.pointer)
182
+ this.hoverPending = true;
183
+ this.requestRender();
184
+ }
185
+ setTheme(theme) {
186
+ if (this.destroyed || theme === this.theme)
187
+ return;
188
+ this.theme = theme;
189
+ this.res.setTheme(theme);
190
+ for (const fn of this.themeListeners)
191
+ fn(theme);
192
+ this.requestRender();
193
+ }
194
+ setSafeArea(area) {
195
+ this.safe = { top: area.top, right: area.right, bottom: area.bottom, left: area.left };
196
+ }
197
+ pick(x, y) {
198
+ const f = this.frame;
199
+ if (!f || !Number.isFinite(x) || !Number.isFinite(y))
200
+ return null;
201
+ const k = this.camera.k;
202
+ const view = {
203
+ k,
204
+ ox: this.width / 2 - this.camera.x * k,
205
+ oy: this.height / 2 - this.camera.y * k,
206
+ dpr: this.dpr,
207
+ };
208
+ let frame;
209
+ let cache;
210
+ if (isSplit(f)) {
211
+ const left = x < splitX(f.split, this.width, this.dpr);
212
+ frame = left ? f.before : f.after;
213
+ cache = left ? this.caches.before : this.caches.after;
214
+ }
215
+ else {
216
+ frame = f;
217
+ cache = this.caches.main;
218
+ }
219
+ cache.sync(frame, this.version, this.res.interner);
220
+ return pickAt(frame, cache, view, x, y, this.res.fonts, this.res.measurer);
221
+ }
222
+ on(type, listener) {
223
+ const set = this.listeners[type];
224
+ set.add(listener);
225
+ return () => {
226
+ set.delete(listener);
227
+ };
228
+ }
229
+ resize() {
230
+ if (this.destroyed)
231
+ return;
232
+ this.applySize(this.canvas.clientWidth, this.canvas.clientHeight, null);
233
+ this.draw();
234
+ }
235
+ requestRender() {
236
+ if (this.destroyed)
237
+ return;
238
+ this.dirty = true;
239
+ if (!this.busy)
240
+ this.schedule();
241
+ }
242
+ toDataURL(scale) {
243
+ const s = scale !== undefined && scale > 0 ? Math.min(scale, 8) : this.dpr;
244
+ if (!this.ctx)
245
+ return this.canvas.toDataURL('image/png');
246
+ if (s === this.dpr) {
247
+ // Exports contain every label: no per-frame raster budget.
248
+ this.painter.rasterBudget = Number.POSITIVE_INFINITY;
249
+ this.draw();
250
+ this.painter.rasterBudget = LABEL_RASTER_BUDGET;
251
+ return this.canvas.toDataURL('image/png');
252
+ }
253
+ const out = document.createElement('canvas');
254
+ out.width = Math.max(1, Math.round(this.width * s));
255
+ out.height = Math.max(1, Math.round(this.height * s));
256
+ const ctx = out.getContext('2d', { alpha: false });
257
+ if (!ctx)
258
+ return this.canvas.toDataURL('image/png');
259
+ this.painter.rasterBudget = Number.POSITIVE_INFINITY;
260
+ this.painter.paint({ ctx, width: this.width, height: this.height, dpr: s }, this.camera, this.frame, this.caches, this.version, this.theme, this.grid);
261
+ this.painter.rasterBudget = LABEL_RASTER_BUDGET;
262
+ this.dirty = true; // pixel-ratio caches were re-keyed for the export
263
+ this.schedule();
264
+ return out.toDataURL('image/png');
265
+ }
266
+ destroy() {
267
+ if (this.destroyed)
268
+ return;
269
+ this.destroyed = true;
270
+ if (this.rafId)
271
+ this.cancelFrame(this.rafId);
272
+ this.rafId = 0;
273
+ this.camera.stop();
274
+ for (const fn of this.cleanup.splice(0))
275
+ fn();
276
+ for (const set of Object.values(this.listeners))
277
+ set.clear();
278
+ this.themeListeners.clear();
279
+ this.canvas.remove();
280
+ internals.delete(this);
281
+ }
282
+ // ─── Loop ─────────────────────────────────────────────────────────────────
283
+ schedule() {
284
+ if (this.rafId === 0 && !this.destroyed)
285
+ this.rafId = this.requestFrame(this.tick) || 0;
286
+ }
287
+ tick = (time) => {
288
+ this.rafId = 0;
289
+ if (this.destroyed)
290
+ return;
291
+ this.busy = true;
292
+ try {
293
+ this.camera.tick(time);
294
+ this.emitCamera();
295
+ if (this.hoverPending)
296
+ this.updateHover();
297
+ }
298
+ finally {
299
+ this.busy = false;
300
+ }
301
+ if (this.dirty)
302
+ this.draw();
303
+ if (this.camera.animating)
304
+ this.schedule();
305
+ };
306
+ draw() {
307
+ if (this.destroyed)
308
+ return;
309
+ const ctx = this.ctx;
310
+ if (!ctx || this.width <= 0 || this.height <= 0) {
311
+ this.dirty = false;
312
+ return;
313
+ }
314
+ this.busy = true;
315
+ try {
316
+ this.autoFit();
317
+ this.dirty = false;
318
+ const t0 = this.now();
319
+ this.painter.paint({ ctx, width: this.width, height: this.height, dpr: this.dpr }, this.camera, this.frame, this.caches, this.version, this.theme, this.grid);
320
+ const ms = this.now() - t0;
321
+ // Labels the raster budget left for the next frame.
322
+ if (this.painter.stats.deferredLabels > 0)
323
+ this.dirty = true;
324
+ this.emitCamera();
325
+ this.emit('frame', { ms });
326
+ }
327
+ finally {
328
+ this.busy = false;
329
+ }
330
+ if (this.dirty)
331
+ this.schedule();
332
+ }
333
+ /** The first frame with content is fitted (as a jump) unless the camera was used already. */
334
+ autoFit() {
335
+ if (this.autoFitted || this.camera.touched || !this.frame)
336
+ return;
337
+ const bounds = this.contentBounds();
338
+ if (!bounds)
339
+ return;
340
+ this.autoFitted = true;
341
+ this.camera.jump(this.camera.targetFor(bounds, {}, { width: this.width, height: this.height }));
342
+ }
343
+ emitCamera() {
344
+ if (!this.cameraChanged)
345
+ return;
346
+ this.cameraChanged = false;
347
+ const s = this.camera.get();
348
+ const e = this.emitted;
349
+ const resized = this.viewportChanged;
350
+ this.viewportChanged = false;
351
+ const source = this.camera.takeSource();
352
+ if (!resized && e && e.x === s.x && e.y === s.y && e.k === s.k)
353
+ return;
354
+ this.emitted = s;
355
+ this.emit('camera', { x: s.x, y: s.y, k: s.k, source });
356
+ }
357
+ updateHover() {
358
+ this.hoverPending = false;
359
+ if (!this.pointer || this.dragging)
360
+ return;
361
+ this.setHover(this.pick(this.pointer.x, this.pointer.y));
362
+ }
363
+ setHover(pick) {
364
+ if (samePick(pick, this.hovered))
365
+ return;
366
+ this.hovered = pick;
367
+ if (!this.dragging)
368
+ this.canvas.style.cursor = pick ? 'pointer' : '';
369
+ this.emit('hover', pick);
370
+ }
371
+ emit(type, event) {
372
+ for (const fn of this.listeners[type])
373
+ fn(event);
374
+ }
375
+ contentBounds() {
376
+ const f = this.frame;
377
+ if (!f)
378
+ return null;
379
+ const { interner } = this.res;
380
+ if (isSplit(f)) {
381
+ this.caches.before.sync(f.before, this.version, interner);
382
+ this.caches.after.sync(f.after, this.version, interner);
383
+ return unionBounds(this.caches.before.contentBounds(), this.caches.after.contentBounds());
384
+ }
385
+ this.caches.main.sync(f, this.version, interner);
386
+ return this.caches.main.contentBounds();
387
+ }
388
+ // ─── Size, pixel ratio, fonts ─────────────────────────────────────────────
389
+ pixelRatio() {
390
+ return clamp(this.fixedRatio ?? windowRatio(), 0.25, MAX_PIXEL_RATIO);
391
+ }
392
+ applySize(width, height, device) {
393
+ const dpr = this.pixelRatio();
394
+ const exact = device !== null && this.fixedRatio === undefined && windowRatio() <= MAX_PIXEL_RATIO;
395
+ const bw = Math.max(1, exact ? device[0] : Math.round(width * dpr));
396
+ const bh = Math.max(1, exact ? device[1] : Math.round(height * dpr));
397
+ if (this.canvas.width !== bw)
398
+ this.canvas.width = bw;
399
+ if (this.canvas.height !== bh)
400
+ this.canvas.height = bh;
401
+ const changed = width !== this.width || height !== this.height || dpr !== this.dpr;
402
+ this.width = Math.max(0, width);
403
+ this.height = Math.max(0, height);
404
+ this.dpr = dpr;
405
+ if (changed) {
406
+ this.cameraChanged = true;
407
+ this.viewportChanged = true;
408
+ this.camera.resized();
409
+ }
410
+ this.dirty = true;
411
+ }
412
+ observeSize() {
413
+ if (typeof ResizeObserver !== 'function')
414
+ return;
415
+ const ro = new ResizeObserver((entries) => {
416
+ if (this.destroyed)
417
+ return;
418
+ const entry = entries[entries.length - 1];
419
+ if (!entry)
420
+ return;
421
+ const box = entry.contentBoxSize?.[0];
422
+ const width = box ? box.inlineSize : entry.contentRect.width;
423
+ const height = box ? box.blockSize : entry.contentRect.height;
424
+ const dev = entry.devicePixelContentBoxSize?.[0];
425
+ this.applySize(width, height, dev ? [dev.inlineSize, dev.blockSize] : null);
426
+ this.draw(); // synchronously, before the browser paints the cleared canvas
427
+ });
428
+ try {
429
+ ro.observe(this.canvas, { box: 'device-pixel-content-box' });
430
+ }
431
+ catch {
432
+ ro.observe(this.canvas);
433
+ }
434
+ this.cleanup.push(() => ro.disconnect());
435
+ }
436
+ watchPixelRatio() {
437
+ if (typeof window === 'undefined' || typeof window.matchMedia !== 'function')
438
+ return;
439
+ let query = null;
440
+ const onChange = () => {
441
+ query?.removeEventListener('change', onChange);
442
+ query = window.matchMedia(`(resolution: ${windowRatio()}dppx)`);
443
+ query.addEventListener('change', onChange);
444
+ if (!this.destroyed && this.pixelRatio() !== this.dpr)
445
+ this.resize();
446
+ };
447
+ query = window.matchMedia(`(resolution: ${windowRatio()}dppx)`);
448
+ query.addEventListener('change', onChange);
449
+ this.cleanup.push(() => query?.removeEventListener('change', onChange));
450
+ }
451
+ watchFonts() {
452
+ const fonts = typeof document !== 'undefined' ? document.fonts : undefined;
453
+ if (!fonts || typeof fonts.addEventListener !== 'function')
454
+ return;
455
+ const onLoaded = () => {
456
+ this.res.fontsChanged();
457
+ this.requestRender();
458
+ };
459
+ fonts.addEventListener('loadingdone', onLoaded);
460
+ this.cleanup.push(() => fonts.removeEventListener('loadingdone', onLoaded));
461
+ }
462
+ }
463
+ /** Implementation of `createRenderer` with optional test seams. */
464
+ export function createRendererImpl(container, options, deps = {}) {
465
+ if (!container || typeof container.appendChild !== 'function') {
466
+ throw new KgdiffError('invalid-input', 'createRenderer: container must be an HTMLElement');
467
+ }
468
+ return new CanvasRenderer(container, options, deps);
469
+ }
470
+ //# sourceMappingURL=renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Van Wijk & Nuij, "Smooth and efficient zooming and panning" (InfoVis 2003).
3
+ *
4
+ * Interpolates between two views (centre + visible width) along the path that is optimal
5
+ * for perceived motion: zoom out while travelling, zoom back in on arrival.
6
+ */
7
+ export interface ZoomView {
8
+ readonly x: number;
9
+ readonly y: number;
10
+ /** Visible extent in world units (inverse of zoom). */
11
+ readonly w: number;
12
+ }
13
+ export interface ZoomPath {
14
+ /** Path length `S` in the paper's units (≥ 0). Duration is derived from it. */
15
+ readonly S: number;
16
+ /** View at `t ∈ [0, 1]`; exact endpoints at 0 and 1. */
17
+ at(t: number): ZoomView;
18
+ }
19
+ /** Optimal zoom-and-pan path from `a` to `b`. `rho` trades zooming for panning (√2 by default). */
20
+ export declare function smoothZoom(a: ZoomView, b: ZoomView, rho?: number): ZoomPath;
21
+ //# sourceMappingURL=smooth-zoom.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smooth-zoom.d.ts","sourceRoot":"","sources":["../src/smooth-zoom.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,+EAA+E;IAC/E,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,EAAE,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;CACzB;AAID,mGAAmG;AACnG,wBAAgB,UAAU,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,GAAG,GAAE,MAAmB,GAAG,QAAQ,CAwCvF"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Van Wijk & Nuij, "Smooth and efficient zooming and panning" (InfoVis 2003).
3
+ *
4
+ * Interpolates between two views (centre + visible width) along the path that is optimal
5
+ * for perceived motion: zoom out while travelling, zoom back in on arrival.
6
+ */
7
+ const TINY = 1e-12;
8
+ /** Optimal zoom-and-pan path from `a` to `b`. `rho` trades zooming for panning (√2 by default). */
9
+ export function smoothZoom(a, b, rho = Math.SQRT2) {
10
+ const rho2 = rho * rho;
11
+ const rho4 = rho2 * rho2;
12
+ const w0 = Math.max(a.w, TINY);
13
+ const w1 = Math.max(b.w, TINY);
14
+ const dx = b.x - a.x;
15
+ const dy = b.y - a.y;
16
+ const d1 = Math.hypot(dx, dy);
17
+ if (d1 < 1e-9 * Math.max(w0, w1)) {
18
+ // Pure zoom (or no motion): exponential in the width keeps perceived speed constant.
19
+ const ratio = Math.log(w1 / w0);
20
+ return {
21
+ S: Math.abs(ratio) / rho,
22
+ at(t) {
23
+ if (t <= 0)
24
+ return a;
25
+ if (t >= 1)
26
+ return b;
27
+ return { x: a.x + t * dx, y: a.y + t * dy, w: w0 * Math.exp(ratio * t) };
28
+ },
29
+ };
30
+ }
31
+ const b0 = (w1 * w1 - w0 * w0 + rho4 * d1 * d1) / (2 * w0 * rho2 * d1);
32
+ const b1 = (w1 * w1 - w0 * w0 - rho4 * d1 * d1) / (2 * w1 * rho2 * d1);
33
+ // ln(√(b²+1) − b) = −asinh(b), numerically stable for large |b|.
34
+ const r0 = -Math.asinh(b0);
35
+ const r1 = -Math.asinh(b1);
36
+ const S = (r1 - r0) / rho;
37
+ const coshR0 = Math.cosh(r0);
38
+ const sinhR0 = Math.sinh(r0);
39
+ return {
40
+ S,
41
+ at(t) {
42
+ if (t <= 0)
43
+ return a;
44
+ if (t >= 1)
45
+ return b;
46
+ const s = t * S;
47
+ const u = (w0 / (rho2 * d1)) * (coshR0 * Math.tanh(rho * s + r0) - sinhR0);
48
+ return { x: a.x + u * dx, y: a.y + u * dy, w: (w0 * coshR0) / Math.cosh(rho * s + r0) };
49
+ },
50
+ };
51
+ }
52
+ //# sourceMappingURL=smooth-zoom.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smooth-zoom.js","sourceRoot":"","sources":["../src/smooth-zoom.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Uniform grid over points (node centres) in compressed-row form: O(n) build with two passes
3
+ * and no per-cell arrays, O(k) rectangle queries. Used for picking and glyph endpoint lookup.
4
+ */
5
+ export declare class PointGrid {
6
+ private x0;
7
+ private y0;
8
+ private cell;
9
+ private cols;
10
+ private rows;
11
+ private start;
12
+ private items;
13
+ /** Largest radius among the indexed points (query rectangles grow by it). */
14
+ maxR: number;
15
+ /** Number of indexed points. */
16
+ size: number;
17
+ /**
18
+ * Index `n` points. `ids[i]` is reported by queries for the point at (xs[i], ys[i]).
19
+ * The cell size targets about one point per cell, bounded by the largest radius.
20
+ */
21
+ build(xs: Float64Array, ys: Float64Array, rs: Float64Array, ids: Int32Array, n: number): void;
22
+ /** Ids of points whose centre may lie in [x0, x1] × [y0, y1]; returns how many were written. */
23
+ query(x0: number, y0: number, x1: number, y1: number, out: number[]): number;
24
+ private cellOf;
25
+ }
26
+ //# sourceMappingURL=spatial.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spatial.d.ts","sourceRoot":"","sources":["../src/spatial.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,qBAAa,SAAS;IACpB,OAAO,CAAC,EAAE,CAAK;IACf,OAAO,CAAC,EAAE,CAAK;IACf,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,KAAK,CAAqB;IAClC,6EAA6E;IAC7E,IAAI,SAAK;IACT,gCAAgC;IAChC,IAAI,SAAK;IAET;;;OAGG;IACH,KAAK,CAAC,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CA4C5F;IAED,gGAAgG;IAChG,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,CAe3E;IAED,OAAO,CAAC,MAAM;CAKf"}