@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.
- package/LICENSE +21 -0
- package/README.md +53 -2
- package/dist/atlas.d.ts +55 -0
- package/dist/atlas.d.ts.map +1 -0
- package/dist/atlas.js +132 -0
- package/dist/atlas.js.map +1 -0
- package/dist/camera.d.ts +116 -0
- package/dist/camera.d.ts.map +1 -0
- package/dist/camera.js +368 -0
- package/dist/camera.js.map +1 -0
- package/dist/color.d.ts +12 -0
- package/dist/color.d.ts.map +1 -0
- package/dist/color.js +51 -0
- package/dist/color.js.map +1 -0
- package/dist/ctx.d.ts +57 -0
- package/dist/ctx.d.ts.map +1 -0
- package/dist/ctx.js +28 -0
- package/dist/ctx.js.map +1 -0
- package/dist/draw/background.d.ts +33 -0
- package/dist/draw/background.d.ts.map +1 -0
- package/dist/draw/background.js +105 -0
- package/dist/draw/background.js.map +1 -0
- package/dist/draw/badges.d.ts +26 -0
- package/dist/draw/badges.d.ts.map +1 -0
- package/dist/draw/badges.js +82 -0
- package/dist/draw/badges.js.map +1 -0
- package/dist/draw/collapsed.d.ts +15 -0
- package/dist/draw/collapsed.d.ts.map +1 -0
- package/dist/draw/collapsed.js +67 -0
- package/dist/draw/collapsed.js.map +1 -0
- package/dist/draw/edges.d.ts +14 -0
- package/dist/draw/edges.d.ts.map +1 -0
- package/dist/draw/edges.js +115 -0
- package/dist/draw/edges.js.map +1 -0
- package/dist/draw/glyphs.d.ts +31 -0
- package/dist/draw/glyphs.d.ts.map +1 -0
- package/dist/draw/glyphs.js +114 -0
- package/dist/draw/glyphs.js.map +1 -0
- package/dist/draw/halos.d.ts +19 -0
- package/dist/draw/halos.d.ts.map +1 -0
- package/dist/draw/halos.js +91 -0
- package/dist/draw/halos.js.map +1 -0
- package/dist/draw/labels.d.ts +55 -0
- package/dist/draw/labels.d.ts.map +1 -0
- package/dist/draw/labels.js +300 -0
- package/dist/draw/labels.js.map +1 -0
- package/dist/draw/link.d.ts +25 -0
- package/dist/draw/link.d.ts.map +1 -0
- package/dist/draw/link.js +122 -0
- package/dist/draw/link.js.map +1 -0
- package/dist/draw/nodes.d.ts +13 -0
- package/dist/draw/nodes.d.ts.map +1 -0
- package/dist/draw/nodes.js +165 -0
- package/dist/draw/nodes.js.map +1 -0
- package/dist/draw/shapes.d.ts +7 -0
- package/dist/draw/shapes.d.ts.map +1 -0
- package/dist/draw/shapes.js +26 -0
- package/dist/draw/shapes.js.map +1 -0
- package/dist/draw/view.d.ts +36 -0
- package/dist/draw/view.d.ts.map +1 -0
- package/dist/draw/view.js +16 -0
- package/dist/draw/view.js.map +1 -0
- package/dist/frame-cache.d.ts +103 -0
- package/dist/frame-cache.d.ts.map +1 -0
- package/dist/frame-cache.js +349 -0
- package/dist/frame-cache.js.map +1 -0
- package/dist/index.d.ts +162 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/input.d.ts +81 -0
- package/dist/input.d.ts.map +1 -0
- package/dist/input.js +329 -0
- package/dist/input.js.map +1 -0
- package/dist/labels.d.ts +103 -0
- package/dist/labels.d.ts.map +1 -0
- package/dist/labels.js +203 -0
- package/dist/labels.js.map +1 -0
- package/dist/math.d.ts +33 -0
- package/dist/math.d.ts.map +1 -0
- package/dist/math.js +138 -0
- package/dist/math.js.map +1 -0
- package/dist/minimap.d.ts +56 -0
- package/dist/minimap.d.ts.map +1 -0
- package/dist/minimap.js +501 -0
- package/dist/minimap.js.map +1 -0
- package/dist/paint-stats.d.ts +17 -0
- package/dist/paint-stats.d.ts.map +1 -0
- package/dist/paint-stats.js +23 -0
- package/dist/paint-stats.js.map +1 -0
- package/dist/paint.d.ts +64 -0
- package/dist/paint.d.ts.map +1 -0
- package/dist/paint.js +197 -0
- package/dist/paint.js.map +1 -0
- package/dist/pick.d.ts +26 -0
- package/dist/pick.d.ts.map +1 -0
- package/dist/pick.js +125 -0
- package/dist/pick.js.map +1 -0
- package/dist/renderer.d.ts +28 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/renderer.js +470 -0
- package/dist/renderer.js.map +1 -0
- package/dist/smooth-zoom.d.ts +21 -0
- package/dist/smooth-zoom.d.ts.map +1 -0
- package/dist/smooth-zoom.js +52 -0
- package/dist/smooth-zoom.js.map +1 -0
- package/dist/spatial.d.ts +26 -0
- package/dist/spatial.d.ts.map +1 -0
- package/dist/spatial.js +103 -0
- package/dist/spatial.js.map +1 -0
- package/dist/text.d.ts +36 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +123 -0
- package/dist/text.js.map +1 -0
- package/package.json +47 -3
- package/src/atlas.ts +171 -0
- package/src/camera.ts +482 -0
- package/src/color.ts +58 -0
- package/src/ctx.ts +102 -0
- package/src/draw/background.ts +139 -0
- package/src/draw/badges.ts +93 -0
- package/src/draw/collapsed.ts +86 -0
- package/src/draw/edges.ts +135 -0
- package/src/draw/glyphs.ts +168 -0
- package/src/draw/halos.ts +101 -0
- package/src/draw/labels.ts +399 -0
- package/src/draw/link.ts +157 -0
- package/src/draw/nodes.ts +184 -0
- package/src/draw/shapes.ts +36 -0
- package/src/draw/view.ts +37 -0
- package/src/frame-cache.ts +382 -0
- package/src/index.ts +161 -0
- package/src/input.ts +370 -0
- package/src/labels.ts +269 -0
- package/src/math.ts +185 -0
- package/src/minimap.ts +545 -0
- package/src/paint-stats.ts +38 -0
- package/src/paint.ts +235 -0
- package/src/pick.ts +173 -0
- package/src/renderer.ts +539 -0
- package/src/smooth-zoom.ts +65 -0
- package/src/spatial.ts +94 -0
- package/src/text.ts +130 -0
package/dist/paint.js
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
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 { LabelAtlas } from './atlas.js';
|
|
8
|
+
import { drawBackground, GridTiles } from './draw/background.js';
|
|
9
|
+
import { BadgePass } from './draw/badges.js';
|
|
10
|
+
import { drawCollapsed } from './draw/collapsed.js';
|
|
11
|
+
import { drawEdges } from './draw/edges.js';
|
|
12
|
+
import { drawGlyphArcs, drawPivots } from './draw/glyphs.js';
|
|
13
|
+
import { drawHalos, HaloSprites } from './draw/halos.js';
|
|
14
|
+
import { LabelPass } from './draw/labels.js';
|
|
15
|
+
import { drawNodes } from './draw/nodes.js';
|
|
16
|
+
import { Interner } from './frame-cache.js';
|
|
17
|
+
import { CollisionGrid } from './labels.js';
|
|
18
|
+
import { clamp, snap } from './math.js';
|
|
19
|
+
import { createStats, resetStats } from './paint-stats.js';
|
|
20
|
+
import { Fonts, TextMeasurer } from './text.js';
|
|
21
|
+
export function isSplit(frame) {
|
|
22
|
+
return 'before' in frame && 'after' in frame && 'split' in frame;
|
|
23
|
+
}
|
|
24
|
+
/** Divider position (css px, on the device-pixel grid) for a split fraction. */
|
|
25
|
+
export function splitX(split, width, dpr) {
|
|
26
|
+
return snap(clamp(Number.isFinite(split) ? split : 0.5, 0, 1) * width, dpr);
|
|
27
|
+
}
|
|
28
|
+
/** Caches that live as long as a renderer: fonts, text metrics, sprites, atlas, tiles. */
|
|
29
|
+
export class Resources {
|
|
30
|
+
factory;
|
|
31
|
+
fonts;
|
|
32
|
+
measurer;
|
|
33
|
+
atlas;
|
|
34
|
+
halos;
|
|
35
|
+
tiles;
|
|
36
|
+
interner = new Interner();
|
|
37
|
+
dpr = 0;
|
|
38
|
+
theme;
|
|
39
|
+
constructor(factory, theme, fallbackMeasureCtx) {
|
|
40
|
+
this.factory = factory;
|
|
41
|
+
this.theme = theme;
|
|
42
|
+
this.fonts = new Fonts(theme);
|
|
43
|
+
// A private context for measuring, so measuring never disturbs drawing state.
|
|
44
|
+
this.measurer = new TextMeasurer(factory(1, 1)?.ctx ?? fallbackMeasureCtx);
|
|
45
|
+
this.atlas = new LabelAtlas(factory);
|
|
46
|
+
this.halos = new HaloSprites(factory);
|
|
47
|
+
this.tiles = new GridTiles(factory);
|
|
48
|
+
}
|
|
49
|
+
setTheme(theme) {
|
|
50
|
+
if (theme === this.theme)
|
|
51
|
+
return;
|
|
52
|
+
this.theme = theme;
|
|
53
|
+
this.fonts.setTheme(theme);
|
|
54
|
+
this.measurer.clear();
|
|
55
|
+
this.halos.clear();
|
|
56
|
+
this.tiles.clear();
|
|
57
|
+
this.atlas?.configure(this.dpr || 1, theme.canvas.background);
|
|
58
|
+
}
|
|
59
|
+
/** Called before painting: re-keys pixel-ratio dependent caches. */
|
|
60
|
+
prepare(dpr) {
|
|
61
|
+
if (dpr === this.dpr)
|
|
62
|
+
return;
|
|
63
|
+
this.dpr = dpr;
|
|
64
|
+
this.tiles.clear();
|
|
65
|
+
this.atlas?.configure(dpr, this.theme.canvas.background);
|
|
66
|
+
}
|
|
67
|
+
/** Web fonts finished loading: metrics and rasterized labels are stale. */
|
|
68
|
+
fontsChanged() {
|
|
69
|
+
this.measurer.clear();
|
|
70
|
+
this.atlas?.wipe();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/** New label rasterizations per frame (≈ 3–5 ms of text rendering on mid-range hardware). */
|
|
74
|
+
export const LABEL_RASTER_BUDGET = 160;
|
|
75
|
+
export class Painter {
|
|
76
|
+
res;
|
|
77
|
+
stats = createStats();
|
|
78
|
+
/** Override for exports, which must contain every label in one paint. */
|
|
79
|
+
rasterBudget = LABEL_RASTER_BUDGET;
|
|
80
|
+
labels = new LabelPass();
|
|
81
|
+
badges = new BadgePass();
|
|
82
|
+
grid = new CollisionGrid();
|
|
83
|
+
view = {
|
|
84
|
+
k: 1,
|
|
85
|
+
ox: 0,
|
|
86
|
+
oy: 0,
|
|
87
|
+
width: 0,
|
|
88
|
+
height: 0,
|
|
89
|
+
dpr: 1,
|
|
90
|
+
x0: 0,
|
|
91
|
+
x1: 0,
|
|
92
|
+
y0: 0,
|
|
93
|
+
y1: 0,
|
|
94
|
+
strictX: false,
|
|
95
|
+
stats: this.stats,
|
|
96
|
+
};
|
|
97
|
+
constructor(res) {
|
|
98
|
+
this.res = res;
|
|
99
|
+
}
|
|
100
|
+
paint(target, cam, frame, caches, version, theme, grid) {
|
|
101
|
+
const { ctx, width, height, dpr } = target;
|
|
102
|
+
const v = this.view;
|
|
103
|
+
resetStats(this.stats);
|
|
104
|
+
this.res.prepare(dpr);
|
|
105
|
+
this.res.atlas?.beginFrame(this.rasterBudget);
|
|
106
|
+
v.k = cam.k;
|
|
107
|
+
v.ox = width / 2 - cam.x * cam.k;
|
|
108
|
+
v.oy = height / 2 - cam.y * cam.k;
|
|
109
|
+
v.width = width;
|
|
110
|
+
v.height = height;
|
|
111
|
+
v.dpr = dpr;
|
|
112
|
+
v.x0 = 0;
|
|
113
|
+
v.x1 = width;
|
|
114
|
+
v.y0 = 0;
|
|
115
|
+
v.y1 = height;
|
|
116
|
+
v.strictX = false;
|
|
117
|
+
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
118
|
+
ctx.imageSmoothingEnabled = true;
|
|
119
|
+
const split = frame !== null && isSplit(frame);
|
|
120
|
+
const spotlight = frame === null
|
|
121
|
+
? 0
|
|
122
|
+
: split
|
|
123
|
+
? Math.max(frame.before.spotlight, frame.after.spotlight)
|
|
124
|
+
: frame.spotlight;
|
|
125
|
+
drawBackground(ctx, v, theme, grid ? this.res.tiles : null, spotlight);
|
|
126
|
+
this.stats.phases.push('background');
|
|
127
|
+
if (frame === null)
|
|
128
|
+
return this.stats;
|
|
129
|
+
if (!split) {
|
|
130
|
+
caches.main.sync(frame, version, this.res.interner);
|
|
131
|
+
this.layers(ctx, frame, caches.main, theme);
|
|
132
|
+
return this.stats;
|
|
133
|
+
}
|
|
134
|
+
const sx = splitX(frame.split, width, dpr);
|
|
135
|
+
caches.before.sync(frame.before, version, this.res.interner);
|
|
136
|
+
caches.after.sync(frame.after, version, this.res.interner);
|
|
137
|
+
if (sx > 0) {
|
|
138
|
+
v.x0 = 0;
|
|
139
|
+
v.x1 = sx;
|
|
140
|
+
v.strictX = true;
|
|
141
|
+
ctx.save();
|
|
142
|
+
ctx.beginPath();
|
|
143
|
+
ctx.rect(0, 0, sx, height);
|
|
144
|
+
ctx.clip();
|
|
145
|
+
this.layers(ctx, frame.before, caches.before, theme);
|
|
146
|
+
ctx.restore();
|
|
147
|
+
}
|
|
148
|
+
if (sx < width) {
|
|
149
|
+
v.x0 = sx;
|
|
150
|
+
v.x1 = width;
|
|
151
|
+
v.strictX = true;
|
|
152
|
+
ctx.save();
|
|
153
|
+
ctx.beginPath();
|
|
154
|
+
ctx.rect(sx, 0, width - sx, height);
|
|
155
|
+
ctx.clip();
|
|
156
|
+
this.layers(ctx, frame.after, caches.after, theme);
|
|
157
|
+
ctx.restore();
|
|
158
|
+
}
|
|
159
|
+
if (sx > 0 && sx < width) {
|
|
160
|
+
// 1 css px divider on whole device pixels.
|
|
161
|
+
const w = Math.max(1, Math.round(dpr));
|
|
162
|
+
ctx.globalAlpha = 1;
|
|
163
|
+
ctx.fillStyle = theme.surface.borderStrong;
|
|
164
|
+
ctx.fillRect(Math.round(sx * dpr - w / 2) / dpr, 0, w / dpr, height);
|
|
165
|
+
}
|
|
166
|
+
this.stats.phases.push('divider');
|
|
167
|
+
return this.stats;
|
|
168
|
+
}
|
|
169
|
+
layers(ctx, frame, cache, theme) {
|
|
170
|
+
const v = this.view;
|
|
171
|
+
const res = this.res;
|
|
172
|
+
const phases = this.stats.phases;
|
|
173
|
+
// Screen-space layout first: node discs and badges are obstacles; labels and pills compete
|
|
174
|
+
// for the rest by priority. Drawing then follows the documented pass order.
|
|
175
|
+
this.labels.begin(frame, cache, v, this.grid);
|
|
176
|
+
this.badges.layout(frame, cache, v, res.fonts, res.measurer, this.grid);
|
|
177
|
+
this.labels.place(frame, cache, v, res, this.grid);
|
|
178
|
+
drawCollapsed(ctx, frame.collapsed, cache.pillShown, v, theme, res.fonts, res.measurer);
|
|
179
|
+
phases.push('collapsed');
|
|
180
|
+
drawEdges(ctx, frame, cache, v);
|
|
181
|
+
phases.push('edges');
|
|
182
|
+
drawGlyphArcs(ctx, frame, cache, v, theme, res.fonts);
|
|
183
|
+
phases.push('glyphs');
|
|
184
|
+
drawHalos(ctx, frame, cache, v, theme, res.halos);
|
|
185
|
+
phases.push('halos');
|
|
186
|
+
drawNodes(ctx, frame, cache, v, theme);
|
|
187
|
+
phases.push('nodes');
|
|
188
|
+
drawPivots(ctx, frame, cache, v, theme);
|
|
189
|
+
phases.push('pivots');
|
|
190
|
+
this.badges.draw(ctx, frame, theme);
|
|
191
|
+
phases.push('badges');
|
|
192
|
+
this.stats.labels += this.labels.draw(ctx, v, theme, res);
|
|
193
|
+
this.stats.deferredLabels = res.atlas?.deferred ?? 0;
|
|
194
|
+
phases.push('labels');
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=paint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paint.js","sourceRoot":"","sources":["../src/paint.ts"],"names":[],"mappings":"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"}
|
package/dist/pick.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hit testing at a screen point, topmost first: nodes (grid lookup; a point inside a disc beats
|
|
3
|
+
* the tolerance ring, then higher z), then edges (distance to the segment / curve / loop, higher
|
|
4
|
+
* z first), then collapsed pills. Invisible and fully transparent elements, and pills hidden by
|
|
5
|
+
* label collision, are never picked.
|
|
6
|
+
*/
|
|
7
|
+
import type { FrameVisuals } from '@kgdiff/scene';
|
|
8
|
+
import type { FrameCache } from './frame-cache.js';
|
|
9
|
+
import type { PickResult } from './index.js';
|
|
10
|
+
import type { Fonts, TextMeasurer } from './text.js';
|
|
11
|
+
/** Extra reach (px) around node discs. */
|
|
12
|
+
export declare const NODE_PICK_TOLERANCE = 3;
|
|
13
|
+
/** Extra reach (px) beyond half an edge's width. */
|
|
14
|
+
export declare const EDGE_PICK_TOLERANCE = 4;
|
|
15
|
+
export interface PickView {
|
|
16
|
+
readonly k: number;
|
|
17
|
+
readonly ox: number;
|
|
18
|
+
readonly oy: number;
|
|
19
|
+
readonly dpr: number;
|
|
20
|
+
}
|
|
21
|
+
export declare function pickNode(frame: FrameVisuals, cache: FrameCache, v: PickView, sx: number, sy: number): number;
|
|
22
|
+
export declare function pickEdge(frame: FrameVisuals, cache: FrameCache, v: PickView, sx: number, sy: number): number;
|
|
23
|
+
export declare function pickCollapsed(frame: FrameVisuals, cache: FrameCache, v: PickView, sx: number, sy: number, fonts: Fonts, measurer: TextMeasurer): number;
|
|
24
|
+
/** Topmost element at screen point (sx, sy), or null. */
|
|
25
|
+
export declare function pickAt(frame: FrameVisuals, cache: FrameCache, v: PickView, sx: number, sy: number, fonts: Fonts, measurer: TextMeasurer): PickResult | null;
|
|
26
|
+
//# sourceMappingURL=pick.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pick.d.ts","sourceRoot":"","sources":["../src/pick.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAKlD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAErD,0CAA0C;AAC1C,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,oDAAoD;AACpD,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAKD,wBAAgB,QAAQ,CACtB,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,UAAU,EACjB,CAAC,EAAE,QAAQ,EACX,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,GACT,MAAM,CA+BR;AAED,wBAAgB,QAAQ,CACtB,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,UAAU,EACjB,CAAC,EAAE,QAAQ,EACX,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,GACT,MAAM,CAmDR;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,UAAU,EACjB,CAAC,EAAE,QAAQ,EACX,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,YAAY,GACrB,MAAM,CAgBR;AAED,yDAAyD;AACzD,wBAAgB,MAAM,CACpB,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,UAAU,EACjB,CAAC,EAAE,QAAQ,EACX,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,YAAY,GACrB,UAAU,GAAG,IAAI,CAQnB"}
|
package/dist/pick.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { pillRect } from './draw/collapsed.js';
|
|
2
|
+
import { isLoop } from './draw/edges.js';
|
|
3
|
+
import { loopCenterY, loopRadius } from './draw/link.js';
|
|
4
|
+
import { NODE_MIN_R } from './draw/view.js';
|
|
5
|
+
import { distToQuadSq, distToSegmentSq } from './math.js';
|
|
6
|
+
/** Extra reach (px) around node discs. */
|
|
7
|
+
export const NODE_PICK_TOLERANCE = 3;
|
|
8
|
+
/** Extra reach (px) beyond half an edge's width. */
|
|
9
|
+
export const EDGE_PICK_TOLERANCE = 4;
|
|
10
|
+
const candidates = [];
|
|
11
|
+
const rect = new Float64Array(4);
|
|
12
|
+
export function pickNode(frame, cache, v, sx, sy) {
|
|
13
|
+
if (cache.nodeCount === 0)
|
|
14
|
+
return -1;
|
|
15
|
+
const { k } = v;
|
|
16
|
+
const wx = (sx - v.ox) / k;
|
|
17
|
+
const wy = (sy - v.oy) / k;
|
|
18
|
+
const grid = cache.nodeGrid();
|
|
19
|
+
const reach = Math.max(grid.maxR, NODE_MIN_R / k) + NODE_PICK_TOLERANCE / k;
|
|
20
|
+
grid.query(wx - reach, wy - reach, wx + reach, wy + reach, candidates);
|
|
21
|
+
let best = -1;
|
|
22
|
+
let bestInside = false;
|
|
23
|
+
let bestZ = Number.NEGATIVE_INFINITY;
|
|
24
|
+
let bestD = Number.POSITIVE_INFINITY;
|
|
25
|
+
for (const i of candidates) {
|
|
26
|
+
const n = frame.nodes[i];
|
|
27
|
+
const r = Math.max(n.r, NODE_MIN_R / k);
|
|
28
|
+
const d = Math.hypot(n.x - wx, n.y - wy);
|
|
29
|
+
if (d > r + NODE_PICK_TOLERANCE / k)
|
|
30
|
+
continue;
|
|
31
|
+
const inside = d <= r;
|
|
32
|
+
const better = best < 0 ||
|
|
33
|
+
(inside && !bestInside) ||
|
|
34
|
+
(inside === bestInside &&
|
|
35
|
+
(n.z > bestZ || (n.z === bestZ && (inside ? i > best : d < bestD))));
|
|
36
|
+
if (better) {
|
|
37
|
+
best = i;
|
|
38
|
+
bestInside = inside;
|
|
39
|
+
bestZ = n.z;
|
|
40
|
+
bestD = d;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return best;
|
|
44
|
+
}
|
|
45
|
+
export function pickEdge(frame, cache, v, sx, sy) {
|
|
46
|
+
const { k } = v;
|
|
47
|
+
const wx = (sx - v.ox) / k;
|
|
48
|
+
const wy = (sy - v.oy) / k;
|
|
49
|
+
let best = -1;
|
|
50
|
+
let bestZ = Number.NEGATIVE_INFINITY;
|
|
51
|
+
let bestD = Number.POSITIVE_INFINITY;
|
|
52
|
+
for (const b of cache.edgeBuckets) {
|
|
53
|
+
const tol = (b.width / 2 + EDGE_PICK_TOLERANCE) / k;
|
|
54
|
+
const tol2 = tol * tol;
|
|
55
|
+
for (const i of b.members) {
|
|
56
|
+
const e = frame.edges[i];
|
|
57
|
+
let d2;
|
|
58
|
+
if (isLoop(e.x1, e.y1, e.x2, e.y2)) {
|
|
59
|
+
const r = Math.max(e.r1 * k, NODE_MIN_R);
|
|
60
|
+
const rho = loopRadius(r, e.curvature) / k;
|
|
61
|
+
const cy = loopCenterY(e.y1 * k, r, rho * k) / k;
|
|
62
|
+
const d = Math.abs(Math.hypot(wx - e.x1, wy - cy) - rho);
|
|
63
|
+
d2 = d * d;
|
|
64
|
+
}
|
|
65
|
+
else if (e.curvature === 0) {
|
|
66
|
+
if (wx < Math.min(e.x1, e.x2) - tol ||
|
|
67
|
+
wx > Math.max(e.x1, e.x2) + tol ||
|
|
68
|
+
wy < Math.min(e.y1, e.y2) - tol ||
|
|
69
|
+
wy > Math.max(e.y1, e.y2) + tol) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
d2 = distToSegmentSq(wx, wy, e.x1, e.y1, e.x2, e.y2);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
const cx = (e.x1 + e.x2) / 2 - (e.y2 - e.y1) * e.curvature;
|
|
76
|
+
const cy = (e.y1 + e.y2) / 2 + (e.x2 - e.x1) * e.curvature;
|
|
77
|
+
if (wx < Math.min(e.x1, e.x2, cx) - tol ||
|
|
78
|
+
wx > Math.max(e.x1, e.x2, cx) + tol ||
|
|
79
|
+
wy < Math.min(e.y1, e.y2, cy) - tol ||
|
|
80
|
+
wy > Math.max(e.y1, e.y2, cy) + tol) {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
d2 = distToQuadSq(wx, wy, e.x1, e.y1, cx, cy, e.x2, e.y2);
|
|
84
|
+
}
|
|
85
|
+
if (d2 > tol2)
|
|
86
|
+
continue;
|
|
87
|
+
if (b.z > bestZ || (b.z === bestZ && d2 < bestD)) {
|
|
88
|
+
best = i;
|
|
89
|
+
bestZ = b.z;
|
|
90
|
+
bestD = d2;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return best;
|
|
95
|
+
}
|
|
96
|
+
export function pickCollapsed(frame, cache, v, sx, sy, fonts, measurer) {
|
|
97
|
+
const groups = frame.collapsed;
|
|
98
|
+
for (let i = groups.length - 1; i >= 0; i--) {
|
|
99
|
+
const g = groups[i];
|
|
100
|
+
if (!(g.count > 0) || !Number.isFinite(g.x + g.y) || !cache.pillPickable(i))
|
|
101
|
+
continue;
|
|
102
|
+
pillRect(g, v, fonts, measurer, rect);
|
|
103
|
+
if (sx >= rect[0] &&
|
|
104
|
+
sx <= rect[0] + rect[2] &&
|
|
105
|
+
sy >= rect[1] &&
|
|
106
|
+
sy <= rect[1] + rect[3]) {
|
|
107
|
+
return i;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return -1;
|
|
111
|
+
}
|
|
112
|
+
/** Topmost element at screen point (sx, sy), or null. */
|
|
113
|
+
export function pickAt(frame, cache, v, sx, sy, fonts, measurer) {
|
|
114
|
+
const node = pickNode(frame, cache, v, sx, sy);
|
|
115
|
+
if (node >= 0)
|
|
116
|
+
return { type: 'node', index: node };
|
|
117
|
+
const edge = pickEdge(frame, cache, v, sx, sy);
|
|
118
|
+
if (edge >= 0)
|
|
119
|
+
return { type: 'edge', index: edge };
|
|
120
|
+
const group = pickCollapsed(frame, cache, v, sx, sy, fonts, measurer);
|
|
121
|
+
if (group >= 0)
|
|
122
|
+
return { type: 'collapsed', index: group };
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=pick.js.map
|
package/dist/pick.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pick.js","sourceRoot":"","sources":["../src/pick.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Theme } from '@kgdiff/scene';
|
|
2
|
+
import { type Size } from './camera.js';
|
|
3
|
+
import { type Ctx2D, type SurfaceFactory } from './ctx.js';
|
|
4
|
+
import type { CameraState, Renderer, RendererOptions } from './index.js';
|
|
5
|
+
/** Test seams and platform overrides (not part of the public API). */
|
|
6
|
+
export interface RendererDeps {
|
|
7
|
+
/** Context to draw into instead of `canvas.getContext('2d')` (null = no drawing). */
|
|
8
|
+
readonly context?: Ctx2D | null;
|
|
9
|
+
readonly surfaceFactory?: SurfaceFactory;
|
|
10
|
+
readonly now?: () => number;
|
|
11
|
+
readonly requestFrame?: (cb: (time: number) => void) => number;
|
|
12
|
+
readonly cancelFrame?: (id: number) => void;
|
|
13
|
+
}
|
|
14
|
+
/** What the minimap needs from its renderer beyond the public API. */
|
|
15
|
+
export interface RendererInternals {
|
|
16
|
+
theme(): Theme;
|
|
17
|
+
pixelRatio(): number;
|
|
18
|
+
size(): Size;
|
|
19
|
+
onTheme(listener: (theme: Theme) => void): () => void;
|
|
20
|
+
/** Move the camera on behalf of the user (minimap drags): `camera` reports source 'user'. */
|
|
21
|
+
userSet(state: CameraState): void;
|
|
22
|
+
readonly requestFrame: (cb: (time: number) => void) => number;
|
|
23
|
+
readonly cancelFrame: (id: number) => void;
|
|
24
|
+
}
|
|
25
|
+
export declare const internals: WeakMap<Renderer, RendererInternals>;
|
|
26
|
+
/** Implementation of `createRenderer` with optional test seams. */
|
|
27
|
+
export declare function createRendererImpl(container: HTMLElement, options: RendererOptions, deps?: RendererDeps): Renderer;
|
|
28
|
+
//# sourceMappingURL=renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAgB,KAAK,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAA4C,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,EAAE,KAAK,KAAK,EAAqB,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AAE9E,OAAO,KAAK,EACV,WAAW,EAEX,QAAQ,EAER,eAAe,EAEhB,MAAM,YAAY,CAAC;AAMpB,sEAAsE;AACtE,MAAM,WAAW,YAAY;IAC3B,qFAAqF;IACrF,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IACzC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,KAAK,MAAM,CAAC;IAC/D,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AAED,sEAAsE;AACtE,MAAM,WAAW,iBAAiB;IAChC,KAAK,IAAI,KAAK,CAAC;IACf,UAAU,IAAI,MAAM,CAAC;IACrB,IAAI,IAAI,IAAI,CAAC;IACb,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACtD,6FAA6F;IAC7F,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,KAAK,MAAM,CAAC;IAC9D,QAAQ,CAAC,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5C;AAED,eAAO,MAAM,SAAS,sCAA6C,CAAC;AA8dpE,mEAAmE;AACnE,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,WAAW,EACtB,OAAO,EAAE,eAAe,EACxB,IAAI,GAAE,YAAiB,GACtB,QAAQ,CAKV"}
|