@prnt/dagr-explorer 0.1.3
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/CHANGELOG.md +93 -0
- package/LICENSE +21 -0
- package/README.md +441 -0
- package/dist/base.d.ts +63 -0
- package/dist/base.d.ts.map +1 -0
- package/dist/base.js +20 -0
- package/dist/base.js.map +1 -0
- package/dist/camera.d.ts +61 -0
- package/dist/camera.d.ts.map +1 -0
- package/dist/camera.js +142 -0
- package/dist/camera.js.map +1 -0
- package/dist/context.d.ts +110 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +71 -0
- package/dist/context.js.map +1 -0
- package/dist/dagr-explorer.d.ts +41 -0
- package/dist/dagr-explorer.d.ts.map +1 -0
- package/dist/dagr-explorer.js +13 -0
- package/dist/dagr-explorer.js.map +1 -0
- package/dist/errors.d.ts +55 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +57 -0
- package/dist/errors.js.map +1 -0
- package/dist/explorer-details.d.ts +44 -0
- package/dist/explorer-details.d.ts.map +1 -0
- package/dist/explorer-details.js +76 -0
- package/dist/explorer-details.js.map +1 -0
- package/dist/explorer-search.d.ts +31 -0
- package/dist/explorer-search.d.ts.map +1 -0
- package/dist/explorer-search.js +86 -0
- package/dist/explorer-search.js.map +1 -0
- package/dist/explorer-toolbar.d.ts +17 -0
- package/dist/explorer-toolbar.d.ts.map +1 -0
- package/dist/explorer-toolbar.js +44 -0
- package/dist/explorer-toolbar.js.map +1 -0
- package/dist/explorer-trace-toggle.d.ts +16 -0
- package/dist/explorer-trace-toggle.d.ts.map +1 -0
- package/dist/explorer-trace-toggle.js +8 -0
- package/dist/explorer-trace-toggle.js.map +1 -0
- package/dist/explorer-viewport.d.ts +69 -0
- package/dist/explorer-viewport.d.ts.map +1 -0
- package/dist/explorer-viewport.js +69 -0
- package/dist/explorer-viewport.js.map +1 -0
- package/dist/explorer-views.d.ts +24 -0
- package/dist/explorer-views.d.ts.map +1 -0
- package/dist/explorer-views.js +16 -0
- package/dist/explorer-views.js.map +1 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/isomorphic-layout-effect.d.ts +7 -0
- package/dist/isomorphic-layout-effect.d.ts.map +1 -0
- package/dist/isomorphic-layout-effect.js +7 -0
- package/dist/isomorphic-layout-effect.js.map +1 -0
- package/dist/labels.d.ts +67 -0
- package/dist/labels.d.ts.map +1 -0
- package/dist/labels.js +50 -0
- package/dist/labels.js.map +1 -0
- package/dist/layout.d.ts +82 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +244 -0
- package/dist/layout.js.map +1 -0
- package/dist/navigation.d.ts +20 -0
- package/dist/navigation.d.ts.map +1 -0
- package/dist/navigation.js +44 -0
- package/dist/navigation.js.map +1 -0
- package/dist/root.d.ts +89 -0
- package/dist/root.d.ts.map +1 -0
- package/dist/root.js +401 -0
- package/dist/root.js.map +1 -0
- package/dist/search.d.ts +19 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +31 -0
- package/dist/search.js.map +1 -0
- package/dist/size.d.ts +12 -0
- package/dist/size.d.ts.map +1 -0
- package/dist/size.js +20 -0
- package/dist/size.js.map +1 -0
- package/dist/svg-base.d.ts +33 -0
- package/dist/svg-base.d.ts.map +1 -0
- package/dist/svg-base.js +89 -0
- package/dist/svg-base.js.map +1 -0
- package/dist/types.d.ts +61 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/use-explorer-camera.d.ts +56 -0
- package/dist/use-explorer-camera.d.ts.map +1 -0
- package/dist/use-explorer-camera.js +641 -0
- package/dist/use-explorer-camera.js.map +1 -0
- package/dist/use-explorer.d.ts +23 -0
- package/dist/use-explorer.d.ts.map +1 -0
- package/dist/use-explorer.js +26 -0
- package/dist/use-explorer.js.map +1 -0
- package/dist/validate.d.ts +20 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +99 -0
- package/dist/validate.js.map +1 -0
- package/dist/viewport-surface.d.ts +90 -0
- package/dist/viewport-surface.d.ts.map +1 -0
- package/dist/viewport-surface.js +485 -0
- package/dist/viewport-surface.js.map +1 -0
- package/dist/visible-set.d.ts +65 -0
- package/dist/visible-set.d.ts.map +1 -0
- package/dist/visible-set.js +168 -0
- package/dist/visible-set.js.map +1 -0
- package/package.json +62 -0
- package/src/base.ts +67 -0
- package/src/camera.ts +206 -0
- package/src/context.ts +168 -0
- package/src/dagr-explorer.tsx +85 -0
- package/src/errors.ts +85 -0
- package/src/explorer-details.tsx +156 -0
- package/src/explorer-search.tsx +140 -0
- package/src/explorer-toolbar.tsx +77 -0
- package/src/explorer-trace-toggle.tsx +34 -0
- package/src/explorer-viewport.tsx +181 -0
- package/src/explorer-views.tsx +61 -0
- package/src/index.ts +76 -0
- package/src/isomorphic-layout-effect.ts +7 -0
- package/src/labels.ts +109 -0
- package/src/layout.ts +298 -0
- package/src/navigation.ts +51 -0
- package/src/root.tsx +544 -0
- package/src/search.ts +36 -0
- package/src/size.ts +23 -0
- package/src/svg-base.tsx +173 -0
- package/src/types.ts +69 -0
- package/src/use-explorer-camera.ts +675 -0
- package/src/use-explorer.ts +32 -0
- package/src/validate.ts +173 -0
- package/src/viewport-surface.tsx +650 -0
- package/src/visible-set.ts +225 -0
- package/styles.css +253 -0
|
@@ -0,0 +1,641 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The explorer's camera: one animation frame loop, a resize observer and the
|
|
3
|
+
* gestures, bound to a viewport element and the plane inside it.
|
|
4
|
+
*
|
|
5
|
+
* A port of the docs' `useGraphCamera` with its arithmetic taken out: every
|
|
6
|
+
* camera this file holds comes from `camera.ts`. What is left here is time
|
|
7
|
+
* (the frame loop), input (wheel, pointer, keys) and the DOM writes.
|
|
8
|
+
*
|
|
9
|
+
* **The camera never causes a React render.** A frame is one
|
|
10
|
+
* `style.transform` write on the plane, and `onFrame` is how the owner
|
|
11
|
+
* learns the camera moved. Whether that is worth a render (the visible set
|
|
12
|
+
* changed) is the owner's decision, not this hook's.
|
|
13
|
+
*
|
|
14
|
+
* **One engine per effect.** Everything mutable lives in a closure the
|
|
15
|
+
* effect creates and its cleanup disposes, so StrictMode's mount, cleanup,
|
|
16
|
+
* mount leaves exactly one loop and one set of listeners, and a frame that
|
|
17
|
+
* fires after cleanup finds the engine disposed and writes nothing. The
|
|
18
|
+
* controls the hook returns are stable for the component's lifetime and
|
|
19
|
+
* forward to whichever engine is live, or do nothing.
|
|
20
|
+
*
|
|
21
|
+
* **No size, no camera.** A viewport measured at zero (a hidden tab,
|
|
22
|
+
* `display: none`, the server) has no limits, so there is no camera to
|
|
23
|
+
* draw: the controls are no-ops and the plane stays hidden. The first real
|
|
24
|
+
* size places the fitted camera at once, without a flight.
|
|
25
|
+
*
|
|
26
|
+
* **A resize or a new layout keeps the user's place:** the world point at
|
|
27
|
+
* the center and the scale, under the new limits. Only a camera that was at
|
|
28
|
+
* fit is fitted again, so a user zoomed in on a node keeps it.
|
|
29
|
+
*
|
|
30
|
+
* Internal to the package. Nothing here is exported from the entry.
|
|
31
|
+
*/
|
|
32
|
+
import { useEffect, useRef, useState } from 'react';
|
|
33
|
+
import { cameraSettled, createCameraLimits, easeCamera, fitCamera, focusCamera, panCamera, revealCamera, screenToWorld, zoomCamera, } from './camera.js';
|
|
34
|
+
/** CSS pixels a press travels before it is a pan rather than a click. */
|
|
35
|
+
const DRAG_THRESHOLD = 5;
|
|
36
|
+
/** Zoom per unit of wheel delta, for a wheel and for a trackpad pinch. */
|
|
37
|
+
const WHEEL_GAIN = 0.002;
|
|
38
|
+
const PINCH_GAIN = 0.01;
|
|
39
|
+
/** The most wheel delta one event counts, in pixels. */
|
|
40
|
+
const WHEEL_CLAMP = 150;
|
|
41
|
+
/** What a flight's first frame counts as elapsed: one frame at 60 Hz. */
|
|
42
|
+
const FIRST_FRAME_MS = 16.7;
|
|
43
|
+
const KEY_ZOOM_IN = 1.25;
|
|
44
|
+
const KEY_ZOOM_OUT = 0.8;
|
|
45
|
+
const KEY_PAN = 60;
|
|
46
|
+
/** A press on one of these does not drag, unless it is a node. */
|
|
47
|
+
const CONTROL = 'a[href], button, input, select, textarea';
|
|
48
|
+
const NODE = '[data-dagr-explorer="node"]';
|
|
49
|
+
/** Keys typed in one of these belong to it. */
|
|
50
|
+
const TEXT_ENTRY = 'input, select, textarea, [contenteditable]';
|
|
51
|
+
const isFiniteBox = (box) => Number.isFinite(box.x) &&
|
|
52
|
+
Number.isFinite(box.y) &&
|
|
53
|
+
Number.isFinite(box.width) &&
|
|
54
|
+
Number.isFinite(box.height);
|
|
55
|
+
function createEngine(viewport, plane, initialLayout, onFrame) {
|
|
56
|
+
const reduced = typeof window.matchMedia === 'function'
|
|
57
|
+
? window.matchMedia('(prefers-reduced-motion: reduce)')
|
|
58
|
+
: null;
|
|
59
|
+
let layout = initialLayout;
|
|
60
|
+
let size = { width: 0, height: 0 };
|
|
61
|
+
let limits = null;
|
|
62
|
+
// `current` is what the ease has reached and `target` where it is going,
|
|
63
|
+
// both as asked for. `drawn` is `current` constrained, which is what the
|
|
64
|
+
// plane shows and what every reading of the camera answers with.
|
|
65
|
+
let current = null;
|
|
66
|
+
let target = null;
|
|
67
|
+
let drawn = null;
|
|
68
|
+
let frame = 0;
|
|
69
|
+
let lastTime = 0;
|
|
70
|
+
let disposed = false;
|
|
71
|
+
// Whether a drag or a pinch is moving the camera, which `composite` reads.
|
|
72
|
+
let dragging = false;
|
|
73
|
+
let composited = false;
|
|
74
|
+
/**
|
|
75
|
+
* A composited layer while the camera moves, and none at rest. Moving, it
|
|
76
|
+
* spares a repaint per frame. At rest, the content is rasterized again at
|
|
77
|
+
* the scale it is shown at: a layer cached at one scale and enlarged by the
|
|
78
|
+
* camera shows text blurred.
|
|
79
|
+
*/
|
|
80
|
+
const composite = () => {
|
|
81
|
+
const moving = !disposed && (frame !== 0 || dragging);
|
|
82
|
+
if (moving === composited)
|
|
83
|
+
return;
|
|
84
|
+
composited = moving;
|
|
85
|
+
if (moving)
|
|
86
|
+
plane.style.willChange = 'transform';
|
|
87
|
+
else
|
|
88
|
+
plane.style.removeProperty('will-change');
|
|
89
|
+
};
|
|
90
|
+
const stop = () => {
|
|
91
|
+
if (frame !== 0)
|
|
92
|
+
cancelAnimationFrame(frame);
|
|
93
|
+
frame = 0;
|
|
94
|
+
composite();
|
|
95
|
+
};
|
|
96
|
+
const draw = () => {
|
|
97
|
+
if (disposed || limits === null || current === null)
|
|
98
|
+
return;
|
|
99
|
+
const next = limits.constrain(current);
|
|
100
|
+
plane.style.transform = `translate(${String(next.x)}px, ${String(next.y)}px) scale(${String(next.scale)})`;
|
|
101
|
+
if (drawn === null || drawn.scale !== next.scale) {
|
|
102
|
+
plane.style.setProperty('--dagr-explorer-inv-zoom', String(1 / next.scale));
|
|
103
|
+
}
|
|
104
|
+
if (plane.style.visibility !== 'visible')
|
|
105
|
+
plane.style.visibility = 'visible';
|
|
106
|
+
drawn = next;
|
|
107
|
+
onFrame(next, size);
|
|
108
|
+
};
|
|
109
|
+
const tick = (time) => {
|
|
110
|
+
frame = 0;
|
|
111
|
+
if (disposed || current === null || target === null)
|
|
112
|
+
return;
|
|
113
|
+
// A frame's timestamp is when the frame began, which can be before the
|
|
114
|
+
// flight did. Counted as no time, the first frame would not move.
|
|
115
|
+
const elapsed = time > lastTime ? time - lastTime : FIRST_FRAME_MS;
|
|
116
|
+
lastTime = time;
|
|
117
|
+
const next = easeCamera(current, target, elapsed);
|
|
118
|
+
if (cameraSettled(next, target)) {
|
|
119
|
+
current = target;
|
|
120
|
+
draw();
|
|
121
|
+
composite();
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
current = next;
|
|
125
|
+
draw();
|
|
126
|
+
frame = requestAnimationFrame(tick);
|
|
127
|
+
};
|
|
128
|
+
/** Sets where the camera is going, constrained, and starts the flight. */
|
|
129
|
+
const aim = (next) => {
|
|
130
|
+
if (disposed || limits === null)
|
|
131
|
+
return;
|
|
132
|
+
target = limits.constrain(next);
|
|
133
|
+
if (reduced?.matches === true || current === null) {
|
|
134
|
+
stop();
|
|
135
|
+
current = target;
|
|
136
|
+
draw();
|
|
137
|
+
}
|
|
138
|
+
else if (frame === 0) {
|
|
139
|
+
lastTime = performance.now();
|
|
140
|
+
frame = requestAnimationFrame(tick);
|
|
141
|
+
composite();
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Whether the camera is at the fit for the current layout and `at`, the
|
|
146
|
+
* size `bounds` were built for. Read from the target, so a flight to the
|
|
147
|
+
* fit counts as at fit.
|
|
148
|
+
*/
|
|
149
|
+
const atFit = (bounds, at) => bounds !== null && target !== null && cameraSettled(target, bounds.constrain(fitCamera(layout, at, bounds)));
|
|
150
|
+
/** Rebuilds the limits for the layout and size. With none, there is no camera. */
|
|
151
|
+
const rebuild = () => {
|
|
152
|
+
limits = createCameraLimits(layout, size);
|
|
153
|
+
if (limits === null) {
|
|
154
|
+
stop();
|
|
155
|
+
current = target = drawn = null;
|
|
156
|
+
}
|
|
157
|
+
return limits;
|
|
158
|
+
};
|
|
159
|
+
/** Puts `camera` on screen at once, with no flight. */
|
|
160
|
+
const place = (camera) => {
|
|
161
|
+
stop();
|
|
162
|
+
current = null;
|
|
163
|
+
aim(camera);
|
|
164
|
+
};
|
|
165
|
+
const measure = () => {
|
|
166
|
+
if (disposed)
|
|
167
|
+
return;
|
|
168
|
+
const width = viewport.clientWidth;
|
|
169
|
+
const height = viewport.clientHeight;
|
|
170
|
+
// A zero dimension is a hidden viewport, not a tiny one. Keeping the last
|
|
171
|
+
// camera means showing it again needs no refit when the size comes back.
|
|
172
|
+
if (!(width > 0) || !(height > 0))
|
|
173
|
+
return;
|
|
174
|
+
if (width === size.width && height === size.height && limits !== null)
|
|
175
|
+
return;
|
|
176
|
+
const previous = size;
|
|
177
|
+
const wasAtFit = atFit(limits, previous);
|
|
178
|
+
size = { width, height };
|
|
179
|
+
const bounds = rebuild();
|
|
180
|
+
if (bounds === null)
|
|
181
|
+
return;
|
|
182
|
+
if (current === null || target === null) {
|
|
183
|
+
place(fitCamera(layout, size, bounds));
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
// The user's place is the world point at the center and the scale. The
|
|
187
|
+
// plane is anchored at its top left, so keeping the center is a pan by
|
|
188
|
+
// half the change in size, drawn now so the content does not jump.
|
|
189
|
+
const dx = (size.width - previous.width) / 2;
|
|
190
|
+
const dy = (size.height - previous.height) / 2;
|
|
191
|
+
current = panCamera(current, dx, dy);
|
|
192
|
+
target = panCamera(target, dx, dy);
|
|
193
|
+
draw();
|
|
194
|
+
aim(wasAtFit ? fitCamera(layout, size, bounds) : target);
|
|
195
|
+
};
|
|
196
|
+
// Gestures. A press records where it began, and becomes a pan only past
|
|
197
|
+
// the threshold, so a tap keeps its target and its click.
|
|
198
|
+
let press = null;
|
|
199
|
+
// Touch pointers down on the viewport, at their last point in viewport
|
|
200
|
+
// coordinates. Two of them are a pinch, which `pinch` holds the last
|
|
201
|
+
// reading of.
|
|
202
|
+
const touches = new Map();
|
|
203
|
+
let pinch = null;
|
|
204
|
+
// Set when a drag or a focusing tap ends: the click that follows is the
|
|
205
|
+
// gesture's own. Cleared once that click is swallowed, and by the next
|
|
206
|
+
// press or key, so a gesture that makes no click cannot eat a later one.
|
|
207
|
+
let suppress = false;
|
|
208
|
+
// Clicks let through since the last one suppressed. A dblclick follows
|
|
209
|
+
// two clicks, and is the drag's own if either of them was.
|
|
210
|
+
let clicksSinceSuppressed = Number.POSITIVE_INFINITY;
|
|
211
|
+
const containsFocus = () => viewport.contains(document.activeElement);
|
|
212
|
+
const focusViewport = () => {
|
|
213
|
+
if (!containsFocus())
|
|
214
|
+
viewport.focus({ preventScroll: true });
|
|
215
|
+
};
|
|
216
|
+
const local = (event) => {
|
|
217
|
+
const box = viewport.getBoundingClientRect();
|
|
218
|
+
return {
|
|
219
|
+
x: event.clientX - box.left - viewport.clientLeft,
|
|
220
|
+
y: event.clientY - box.top - viewport.clientTop,
|
|
221
|
+
};
|
|
222
|
+
};
|
|
223
|
+
const capture = (pointerId) => {
|
|
224
|
+
try {
|
|
225
|
+
viewport.setPointerCapture(pointerId);
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
// The pointer is already gone, which ends the gesture it began.
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
const release = (pointerId) => {
|
|
234
|
+
if (viewport.hasPointerCapture(pointerId))
|
|
235
|
+
viewport.releasePointerCapture(pointerId);
|
|
236
|
+
};
|
|
237
|
+
/** Takes a gesture's camera from where it is on screen, not from the end of a flight. */
|
|
238
|
+
const grab = () => {
|
|
239
|
+
if (limits === null || current === null)
|
|
240
|
+
return false;
|
|
241
|
+
stop();
|
|
242
|
+
current = target = drawn ?? limits.constrain(current);
|
|
243
|
+
return true;
|
|
244
|
+
};
|
|
245
|
+
const endPress = (pointerId) => {
|
|
246
|
+
if (press === null || press.id !== pointerId)
|
|
247
|
+
return;
|
|
248
|
+
const panned = press.panning;
|
|
249
|
+
press = null;
|
|
250
|
+
if (panned) {
|
|
251
|
+
suppress = true;
|
|
252
|
+
release(pointerId);
|
|
253
|
+
if (pinch === null) {
|
|
254
|
+
viewport.removeAttribute('data-dragging');
|
|
255
|
+
dragging = false;
|
|
256
|
+
composite();
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
const pinchReading = () => {
|
|
261
|
+
const [a, b] = [...touches.values()];
|
|
262
|
+
if (a === undefined || b === undefined)
|
|
263
|
+
return null;
|
|
264
|
+
return {
|
|
265
|
+
distance: Math.hypot(b.x - a.x, b.y - a.y),
|
|
266
|
+
mid: { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 },
|
|
267
|
+
};
|
|
268
|
+
};
|
|
269
|
+
const startPinch = () => {
|
|
270
|
+
const reading = pinchReading();
|
|
271
|
+
if (reading === null || !grab())
|
|
272
|
+
return;
|
|
273
|
+
// The pinch takes over the press its first finger began.
|
|
274
|
+
press = null;
|
|
275
|
+
pinch = reading;
|
|
276
|
+
for (const id of touches.keys())
|
|
277
|
+
capture(id);
|
|
278
|
+
viewport.setAttribute('data-dragging', 'true');
|
|
279
|
+
dragging = true;
|
|
280
|
+
composite();
|
|
281
|
+
};
|
|
282
|
+
const movePinch = () => {
|
|
283
|
+
const reading = pinchReading();
|
|
284
|
+
if (pinch === null || reading === null || limits === null || current === null)
|
|
285
|
+
return;
|
|
286
|
+
const factor = pinch.distance > 0 && reading.distance > 0 ? reading.distance / pinch.distance : 1;
|
|
287
|
+
const moved = panCamera(current, reading.mid.x - pinch.mid.x, reading.mid.y - pinch.mid.y);
|
|
288
|
+
current = target = limits.constrain(zoomCamera(moved, factor, reading.mid, limits));
|
|
289
|
+
pinch = reading;
|
|
290
|
+
draw();
|
|
291
|
+
};
|
|
292
|
+
const endPinch = () => {
|
|
293
|
+
pinch = null;
|
|
294
|
+
for (const id of touches.keys())
|
|
295
|
+
release(id);
|
|
296
|
+
viewport.removeAttribute('data-dragging');
|
|
297
|
+
suppress = true;
|
|
298
|
+
dragging = false;
|
|
299
|
+
composite();
|
|
300
|
+
};
|
|
301
|
+
const onPointerDown = (event) => {
|
|
302
|
+
if (event.pointerType === 'touch' && event.isPrimary) {
|
|
303
|
+
// The first finger of a new gesture: any finger still recorded lifted
|
|
304
|
+
// where this viewport did not hear it.
|
|
305
|
+
if (pinch !== null)
|
|
306
|
+
endPinch();
|
|
307
|
+
touches.clear();
|
|
308
|
+
}
|
|
309
|
+
suppress = false;
|
|
310
|
+
if (event.button !== 0)
|
|
311
|
+
return;
|
|
312
|
+
if (event.target instanceof Element) {
|
|
313
|
+
const control = event.target.closest(CONTROL);
|
|
314
|
+
if (control !== null && viewport.contains(control) && !control.matches(NODE))
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
if (event.pointerType === 'touch') {
|
|
318
|
+
if (!containsFocus()) {
|
|
319
|
+
// The first tap only focuses, so an unfocused graph never traps a
|
|
320
|
+
// swipe meant to scroll the page, and the click it makes activates
|
|
321
|
+
// nothing.
|
|
322
|
+
focusViewport();
|
|
323
|
+
suppress = true;
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
if (touches.size >= 2)
|
|
327
|
+
return;
|
|
328
|
+
touches.set(event.pointerId, local(event));
|
|
329
|
+
if (touches.size === 2) {
|
|
330
|
+
startPinch();
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
if (!event.isPrimary)
|
|
335
|
+
return;
|
|
336
|
+
press = {
|
|
337
|
+
id: event.pointerId,
|
|
338
|
+
startX: event.clientX,
|
|
339
|
+
startY: event.clientY,
|
|
340
|
+
lastX: event.clientX,
|
|
341
|
+
lastY: event.clientY,
|
|
342
|
+
panning: false,
|
|
343
|
+
};
|
|
344
|
+
};
|
|
345
|
+
const onPointerMove = (event) => {
|
|
346
|
+
if (touches.has(event.pointerId)) {
|
|
347
|
+
touches.set(event.pointerId, local(event));
|
|
348
|
+
if (pinch !== null) {
|
|
349
|
+
movePinch();
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
if (press === null || press.id !== event.pointerId)
|
|
354
|
+
return;
|
|
355
|
+
// No button down is a press released where this viewport did not hear it.
|
|
356
|
+
if (event.buttons === 0) {
|
|
357
|
+
endPress(event.pointerId);
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
if (!press.panning) {
|
|
361
|
+
const travelled = Math.hypot(event.clientX - press.startX, event.clientY - press.startY);
|
|
362
|
+
if (travelled <= DRAG_THRESHOLD)
|
|
363
|
+
return;
|
|
364
|
+
focusViewport();
|
|
365
|
+
if (!grab() || !capture(event.pointerId)) {
|
|
366
|
+
press = null;
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
press.panning = true;
|
|
370
|
+
viewport.setAttribute('data-dragging', 'true');
|
|
371
|
+
dragging = true;
|
|
372
|
+
composite();
|
|
373
|
+
}
|
|
374
|
+
const dx = event.clientX - press.lastX;
|
|
375
|
+
const dy = event.clientY - press.lastY;
|
|
376
|
+
press.lastX = event.clientX;
|
|
377
|
+
press.lastY = event.clientY;
|
|
378
|
+
// A drag is drawn in the event that moved it, with no ease: the content
|
|
379
|
+
// stays under the pointer.
|
|
380
|
+
if (limits === null || current === null)
|
|
381
|
+
return;
|
|
382
|
+
current = target = limits.constrain(panCamera(current, dx, dy));
|
|
383
|
+
draw();
|
|
384
|
+
};
|
|
385
|
+
/** `pointerup`, `pointercancel` and `lostpointercapture` all end what the pointer began. */
|
|
386
|
+
const onPointerEnd = (event) => {
|
|
387
|
+
endPress(event.pointerId);
|
|
388
|
+
if (touches.delete(event.pointerId) && pinch !== null)
|
|
389
|
+
endPinch();
|
|
390
|
+
};
|
|
391
|
+
const onClick = (event) => {
|
|
392
|
+
// A click with no count came from a key or a script, never from a drag.
|
|
393
|
+
if (!suppress || event.detail === 0) {
|
|
394
|
+
clicksSinceSuppressed += 1;
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
suppress = false;
|
|
398
|
+
clicksSinceSuppressed = 0;
|
|
399
|
+
event.preventDefault();
|
|
400
|
+
event.stopImmediatePropagation();
|
|
401
|
+
};
|
|
402
|
+
const onDoubleClick = (event) => {
|
|
403
|
+
if (!suppress && clicksSinceSuppressed >= 2)
|
|
404
|
+
return;
|
|
405
|
+
event.preventDefault();
|
|
406
|
+
event.stopImmediatePropagation();
|
|
407
|
+
};
|
|
408
|
+
const onWheel = (event) => {
|
|
409
|
+
// Command wheel is the browser's zoom, and an unfocused wheel, a pinch
|
|
410
|
+
// included, belongs to the page.
|
|
411
|
+
if (event.metaKey || !containsFocus())
|
|
412
|
+
return;
|
|
413
|
+
if (limits === null || target === null)
|
|
414
|
+
return;
|
|
415
|
+
// A trackpad pinch arrives as a Ctrl wheel.
|
|
416
|
+
const pinching = event.ctrlKey;
|
|
417
|
+
// A sideways swipe has nothing to do here, so the page or a scroller
|
|
418
|
+
// around the graph keeps it.
|
|
419
|
+
if (event.deltaY === 0 && (pinching || !event.shiftKey))
|
|
420
|
+
return;
|
|
421
|
+
event.preventDefault();
|
|
422
|
+
const unit = event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? size.height : 1;
|
|
423
|
+
if (event.shiftKey && !pinching) {
|
|
424
|
+
aim(panCamera(target, -(event.deltaX || event.deltaY) * unit, 0));
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
const delta = Math.max(-WHEEL_CLAMP, Math.min(WHEEL_CLAMP, event.deltaY * unit));
|
|
428
|
+
const factor = Math.exp(-delta * (pinching ? PINCH_GAIN : WHEEL_GAIN));
|
|
429
|
+
aim(zoomCamera(target, factor, local(event), limits));
|
|
430
|
+
};
|
|
431
|
+
const onKeyDown = (event) => {
|
|
432
|
+
suppress = false;
|
|
433
|
+
// Keys typed in a field are the field's, Escape included.
|
|
434
|
+
if (event.target instanceof Element && event.target.closest(TEXT_ENTRY) !== null)
|
|
435
|
+
return;
|
|
436
|
+
if (event.key === 'Escape') {
|
|
437
|
+
// Handled above, as the root does when the Escape closes the drawer:
|
|
438
|
+
// the graph keeps focus, and the next Escape leaves it.
|
|
439
|
+
if (event.defaultPrevented)
|
|
440
|
+
return;
|
|
441
|
+
const active = document.activeElement;
|
|
442
|
+
if (active instanceof HTMLElement && viewport.contains(active))
|
|
443
|
+
active.blur();
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
// Ctrl and Command with + - 0 are the browser's zoom.
|
|
447
|
+
if (event.ctrlKey || event.metaKey || event.altKey)
|
|
448
|
+
return;
|
|
449
|
+
// An arrow on a node moves focus, which the viewport surface does. With
|
|
450
|
+
// Shift it pans, as it does on the surface.
|
|
451
|
+
const onNode = event.target instanceof Element && event.target.closest(NODE) !== null;
|
|
452
|
+
if (onNode && !event.shiftKey && event.key.startsWith('Arrow'))
|
|
453
|
+
return;
|
|
454
|
+
if (limits === null || target === null)
|
|
455
|
+
return;
|
|
456
|
+
const center = { x: size.width / 2, y: size.height / 2 };
|
|
457
|
+
switch (event.key) {
|
|
458
|
+
case '+':
|
|
459
|
+
case '=':
|
|
460
|
+
aim(zoomCamera(target, KEY_ZOOM_IN, center, limits));
|
|
461
|
+
break;
|
|
462
|
+
case '-':
|
|
463
|
+
aim(zoomCamera(target, KEY_ZOOM_OUT, center, limits));
|
|
464
|
+
break;
|
|
465
|
+
case '0':
|
|
466
|
+
aim(fitCamera(layout, size, limits));
|
|
467
|
+
break;
|
|
468
|
+
case 'ArrowLeft':
|
|
469
|
+
aim(panCamera(target, KEY_PAN, 0));
|
|
470
|
+
break;
|
|
471
|
+
case 'ArrowRight':
|
|
472
|
+
aim(panCamera(target, -KEY_PAN, 0));
|
|
473
|
+
break;
|
|
474
|
+
case 'ArrowUp':
|
|
475
|
+
aim(panCamera(target, 0, KEY_PAN));
|
|
476
|
+
break;
|
|
477
|
+
case 'ArrowDown':
|
|
478
|
+
aim(panCamera(target, 0, -KEY_PAN));
|
|
479
|
+
break;
|
|
480
|
+
default:
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
event.preventDefault();
|
|
484
|
+
};
|
|
485
|
+
// A wheel listener only while the graph holds focus, when it can act.
|
|
486
|
+
// Unfocused it would do nothing, and its mere presence costs the page its
|
|
487
|
+
// scroll in WebKit under a root with `overscroll-behavior: none`: a
|
|
488
|
+
// non-passive wheel listener under the pointer, even one that returns at
|
|
489
|
+
// once, and the page does not move (found by the M5.6f-2 browser check).
|
|
490
|
+
let wheeling = false;
|
|
491
|
+
const listenForWheel = (on) => {
|
|
492
|
+
if (on === wheeling)
|
|
493
|
+
return;
|
|
494
|
+
wheeling = on;
|
|
495
|
+
if (on)
|
|
496
|
+
viewport.addEventListener('wheel', onWheel, { passive: false });
|
|
497
|
+
else
|
|
498
|
+
viewport.removeEventListener('wheel', onWheel);
|
|
499
|
+
};
|
|
500
|
+
// `touch-action: none` only while the graph holds focus, so an unfocused
|
|
501
|
+
// graph never traps a page scroll on touch.
|
|
502
|
+
const onFocusIn = () => {
|
|
503
|
+
viewport.style.touchAction = 'none';
|
|
504
|
+
listenForWheel(true);
|
|
505
|
+
};
|
|
506
|
+
const onFocusOut = (event) => {
|
|
507
|
+
const next = event.relatedTarget;
|
|
508
|
+
if (next instanceof Node && viewport.contains(next))
|
|
509
|
+
return;
|
|
510
|
+
viewport.style.touchAction = '';
|
|
511
|
+
listenForWheel(false);
|
|
512
|
+
};
|
|
513
|
+
const observer = new ResizeObserver(measure);
|
|
514
|
+
observer.observe(viewport);
|
|
515
|
+
viewport.addEventListener('keydown', onKeyDown);
|
|
516
|
+
viewport.addEventListener('pointerdown', onPointerDown);
|
|
517
|
+
viewport.addEventListener('pointermove', onPointerMove);
|
|
518
|
+
viewport.addEventListener('pointerup', onPointerEnd);
|
|
519
|
+
viewport.addEventListener('pointercancel', onPointerEnd);
|
|
520
|
+
viewport.addEventListener('lostpointercapture', onPointerEnd);
|
|
521
|
+
// Capture, so a suppressed click is gone before any listener on the
|
|
522
|
+
// viewport or below it sees it.
|
|
523
|
+
viewport.addEventListener('click', onClick, true);
|
|
524
|
+
viewport.addEventListener('dblclick', onDoubleClick, true);
|
|
525
|
+
viewport.addEventListener('focusin', onFocusIn);
|
|
526
|
+
viewport.addEventListener('focusout', onFocusOut);
|
|
527
|
+
if (containsFocus())
|
|
528
|
+
onFocusIn();
|
|
529
|
+
measure();
|
|
530
|
+
return {
|
|
531
|
+
fit() {
|
|
532
|
+
if (limits !== null)
|
|
533
|
+
aim(fitCamera(layout, size, limits));
|
|
534
|
+
},
|
|
535
|
+
zoomBy(factor) {
|
|
536
|
+
if (limits === null || target === null || !(factor > 0) || !Number.isFinite(factor))
|
|
537
|
+
return;
|
|
538
|
+
aim(zoomCamera(target, factor, { x: size.width / 2, y: size.height / 2 }, limits));
|
|
539
|
+
},
|
|
540
|
+
focusBox(box) {
|
|
541
|
+
if (limits === null || !isFiniteBox(box))
|
|
542
|
+
return;
|
|
543
|
+
aim(focusCamera(box, size, limits));
|
|
544
|
+
},
|
|
545
|
+
revealBox(box) {
|
|
546
|
+
if (target === null || !isFiniteBox(box))
|
|
547
|
+
return;
|
|
548
|
+
aim(revealCamera(target, box, size));
|
|
549
|
+
},
|
|
550
|
+
getCamera() {
|
|
551
|
+
return drawn;
|
|
552
|
+
},
|
|
553
|
+
screenToWorld(point) {
|
|
554
|
+
return drawn === null ? null : screenToWorld(drawn, point);
|
|
555
|
+
},
|
|
556
|
+
setLayout(next) {
|
|
557
|
+
if (disposed || next === layout)
|
|
558
|
+
return;
|
|
559
|
+
const wasAtFit = atFit(limits, size);
|
|
560
|
+
const kept = drawn;
|
|
561
|
+
layout = next;
|
|
562
|
+
if (!(size.width > 0 && size.height > 0))
|
|
563
|
+
return;
|
|
564
|
+
const bounds = rebuild();
|
|
565
|
+
if (bounds === null)
|
|
566
|
+
return;
|
|
567
|
+
// New content is placed, not flown to: easing from a camera framed on
|
|
568
|
+
// other content shows nothing meaningful on the way. At the same size,
|
|
569
|
+
// the same camera keeps the center's world point and the scale.
|
|
570
|
+
place(kept === null || wasAtFit ? fitCamera(layout, size, bounds) : kept);
|
|
571
|
+
},
|
|
572
|
+
dispose() {
|
|
573
|
+
disposed = true;
|
|
574
|
+
stop();
|
|
575
|
+
observer.disconnect();
|
|
576
|
+
listenForWheel(false);
|
|
577
|
+
viewport.removeEventListener('keydown', onKeyDown);
|
|
578
|
+
viewport.removeEventListener('pointerdown', onPointerDown);
|
|
579
|
+
viewport.removeEventListener('pointermove', onPointerMove);
|
|
580
|
+
viewport.removeEventListener('pointerup', onPointerEnd);
|
|
581
|
+
viewport.removeEventListener('pointercancel', onPointerEnd);
|
|
582
|
+
viewport.removeEventListener('lostpointercapture', onPointerEnd);
|
|
583
|
+
viewport.removeEventListener('click', onClick, true);
|
|
584
|
+
viewport.removeEventListener('dblclick', onDoubleClick, true);
|
|
585
|
+
viewport.removeEventListener('focusin', onFocusIn);
|
|
586
|
+
viewport.removeEventListener('focusout', onFocusOut);
|
|
587
|
+
if (press?.panning === true)
|
|
588
|
+
release(press.id);
|
|
589
|
+
for (const id of touches.keys())
|
|
590
|
+
release(id);
|
|
591
|
+
viewport.removeAttribute('data-dragging');
|
|
592
|
+
press = null;
|
|
593
|
+
pinch = null;
|
|
594
|
+
touches.clear();
|
|
595
|
+
dragging = false;
|
|
596
|
+
viewport.style.touchAction = '';
|
|
597
|
+
limits = null;
|
|
598
|
+
current = target = drawn = null;
|
|
599
|
+
},
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
export function useExplorerCamera(options) {
|
|
603
|
+
const { viewportRef, planeRef, layout, onFrame } = options;
|
|
604
|
+
const engineRef = useRef(null);
|
|
605
|
+
const layoutRef = useRef(layout);
|
|
606
|
+
const onFrameRef = useRef(onFrame);
|
|
607
|
+
// Declared first, so it has run by the time the effects below draw: a
|
|
608
|
+
// frame drawn for a new layout reaches the `onFrame` of the same render.
|
|
609
|
+
useEffect(() => {
|
|
610
|
+
onFrameRef.current = onFrame;
|
|
611
|
+
});
|
|
612
|
+
const [controls] = useState(() => ({
|
|
613
|
+
fit: () => engineRef.current?.fit(),
|
|
614
|
+
zoomBy: (factor) => engineRef.current?.zoomBy(factor),
|
|
615
|
+
focusBox: (box) => engineRef.current?.focusBox(box),
|
|
616
|
+
revealBox: (box) => engineRef.current?.revealBox(box),
|
|
617
|
+
getCamera: () => engineRef.current?.getCamera() ?? null,
|
|
618
|
+
screenToWorld: (point) => engineRef.current?.screenToWorld(point) ?? null,
|
|
619
|
+
}));
|
|
620
|
+
useEffect(() => {
|
|
621
|
+
const viewport = viewportRef.current;
|
|
622
|
+
const plane = planeRef.current;
|
|
623
|
+
if (viewport === null || plane === null)
|
|
624
|
+
return undefined;
|
|
625
|
+
const engine = createEngine(viewport, plane, layoutRef.current, (camera, size) => {
|
|
626
|
+
onFrameRef.current(camera, size);
|
|
627
|
+
});
|
|
628
|
+
engineRef.current = engine;
|
|
629
|
+
return () => {
|
|
630
|
+
engine.dispose();
|
|
631
|
+
if (engineRef.current === engine)
|
|
632
|
+
engineRef.current = null;
|
|
633
|
+
};
|
|
634
|
+
}, [viewportRef, planeRef]);
|
|
635
|
+
useEffect(() => {
|
|
636
|
+
layoutRef.current = layout;
|
|
637
|
+
engineRef.current?.setLayout(layout);
|
|
638
|
+
}, [layout]);
|
|
639
|
+
return controls;
|
|
640
|
+
}
|
|
641
|
+
//# sourceMappingURL=use-explorer-camera.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-explorer-camera.js","sourceRoot":"","sources":["../src/use-explorer-camera.ts"],"names":[],"mappings":"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"}
|