@weasel-js/labkit 1.3.0 → 1.4.0-pre.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/dist/_dts/CanvasStackContext-DtAn_3O-.d.ts +42 -0
- package/dist/_dts/DrawCommand-B3bskUsC.d.ts +564 -0
- package/dist/_dts/{PrefsForm-BYa6cWnO.d.ts → PrefsForm-BkUJZx0A.d.ts} +4 -1
- package/dist/_dts/fitViewToBounds-dZ2UDB6e.d.ts +21 -0
- package/dist/_dts/frac-Cp3NivlC.d.ts +728 -0
- package/dist/_dts/index-BDVzvRzQ.d.ts +236 -0
- package/dist/_dts/shapeKinds-Cx_rxwsa.d.ts +87 -0
- package/dist/_dts/{DrawCommand-DBB45NfN.d.ts → types-C-gh9Ap-.d.ts} +1 -582
- package/dist/_dts/{types-DCGEcMO_.d.ts → types-D6s4b7if.d.ts} +1 -1
- package/dist/_dts/{types-1Sdxy_Pv.d.ts → types-DYMaEvM5.d.ts} +26 -1
- package/dist/_dts/{useTrialState-CsGMjhu9.d.ts → useTrialState-gmMvZqPc.d.ts} +7 -2
- package/dist/canvas/index.d.ts +43 -25
- package/dist/canvas/index.js +5 -4
- package/dist/chrome/index.d.ts +9 -6
- package/dist/chrome/index.js +6 -6
- package/dist/chunk-2AYGEN57.js +32 -0
- package/dist/chunk-2AYGEN57.js.map +1 -0
- package/dist/{chunk-QRYPXSGP.js → chunk-3P5TTTA7.js} +16 -8
- package/dist/chunk-3P5TTTA7.js.map +1 -0
- package/dist/{chunk-BDJXIBRZ.js → chunk-3ZELRRBV.js} +44 -27
- package/dist/chunk-3ZELRRBV.js.map +1 -0
- package/dist/{chunk-LGKRIUSW.js → chunk-4EY67BKJ.js} +32 -7
- package/dist/chunk-4EY67BKJ.js.map +1 -0
- package/dist/{chunk-3XXPU73K.js → chunk-5TCEVMPI.js} +9 -7
- package/dist/chunk-5TCEVMPI.js.map +1 -0
- package/dist/{chunk-JDROYQM3.js → chunk-6JMU56CU.js} +130 -131
- package/dist/chunk-6JMU56CU.js.map +1 -0
- package/dist/{chunk-CPUJ3QXL.js → chunk-CQLQPQ4P.js} +2 -2
- package/dist/chunk-CQLQPQ4P.js.map +1 -0
- package/dist/chunk-CTRKTLYZ.js +33 -0
- package/dist/chunk-CTRKTLYZ.js.map +1 -0
- package/dist/chunk-EQIB2PGC.js +458 -0
- package/dist/chunk-EQIB2PGC.js.map +1 -0
- package/dist/chunk-HEORBLVT.js +7128 -0
- package/dist/chunk-HEORBLVT.js.map +1 -0
- package/dist/{chunk-BMW4TDP5.js → chunk-JDDIZSLL.js} +3 -3
- package/dist/{chunk-BMW4TDP5.js.map → chunk-JDDIZSLL.js.map} +1 -1
- package/dist/chunk-LITE5YFB.js +669 -0
- package/dist/chunk-LITE5YFB.js.map +1 -0
- package/dist/{chunk-QCICIHEO.js → chunk-ROQDRXKW.js} +716 -311
- package/dist/chunk-ROQDRXKW.js.map +1 -0
- package/dist/{chunk-4TMMVIDM.js → chunk-XJ6N32QP.js} +50 -6
- package/dist/chunk-XJ6N32QP.js.map +1 -0
- package/dist/{chunk-WTI26YTM.js → chunk-YQJNT4XQ.js} +40 -13
- package/dist/chunk-YQJNT4XQ.js.map +1 -0
- package/dist/controls/index.d.ts +4 -28
- package/dist/controls/index.js +3 -3
- package/dist/dragdrop/index.d.ts +9 -5
- package/dist/dragdrop/index.js +3 -3
- package/dist/index.d.ts +518 -190
- package/dist/index.js +1753 -75
- package/dist/index.js.map +1 -1
- package/dist/layers/index.d.ts +6 -5
- package/dist/layers/index.js +3 -3
- package/dist/loupe/index.d.ts +187 -0
- package/dist/loupe/index.js +7 -0
- package/dist/loupe/index.js.map +1 -0
- package/dist/passthrough/weasel-canvas.d.ts +3 -1
- package/dist/passthrough/weasel-canvas.js +1 -1
- package/dist/passthrough/weasel-ui.d.ts +138 -91
- package/dist/passthrough/weasel-ui.js +2 -2
- package/dist/primitives/index.d.ts +3 -1
- package/dist/primitives/index.js +5 -5
- package/dist/state/index.d.ts +3 -3
- package/dist/state/index.js +2 -2
- package/dist/styles.css +229 -1
- package/dist/surface/index.d.ts +18 -2
- package/dist/surface/index.js +2 -2
- package/dist/ui/layers/index.js +2 -2
- package/dist/undo/index.d.ts +5 -4
- package/package.json +14 -7
- package/src/annotations/AnnotationOverlay.tsx +205 -0
- package/src/annotations/AnnotationTargets.tsx +37 -0
- package/src/annotations/Annotations.less +129 -0
- package/src/annotations/Annotations.meaning.test.tsx +111 -0
- package/src/annotations/Annotations.overlay.test.tsx +142 -0
- package/src/annotations/AnnotationsContext.ts +49 -0
- package/src/annotations/ExportMenu.test.tsx +86 -0
- package/src/annotations/ExportMenu.tsx +182 -0
- package/src/annotations/MarkList.tsx +75 -0
- package/src/annotations/capture.test.ts +140 -0
- package/src/annotations/capture.ts +237 -0
- package/src/annotations/drawOne.test.ts +56 -0
- package/src/annotations/drawOne.ts +47 -0
- package/src/annotations/frac.test.ts +59 -0
- package/src/annotations/frac.ts +66 -0
- package/src/annotations/history.test.ts +82 -0
- package/src/annotations/history.ts +118 -0
- package/src/annotations/index.ts +37 -0
- package/src/annotations/paint.test.ts +125 -0
- package/src/annotations/paint.ts +130 -0
- package/src/annotations/staleness.test.ts +56 -0
- package/src/annotations/staleness.ts +41 -0
- package/src/annotations/store.test.ts +175 -0
- package/src/annotations/store.ts +317 -0
- package/src/annotations/svgNodes.test.ts +77 -0
- package/src/annotations/svgNodes.ts +74 -0
- package/src/annotations/toolMap.test.ts +36 -0
- package/src/annotations/toolMap.ts +54 -0
- package/src/annotations/types.ts +222 -0
- package/src/annotations/view.test.ts +37 -0
- package/src/annotations/view.ts +40 -0
- package/src/canvas/AGENTS.md +55 -5
- package/src/canvas/CanvasStack.test.tsx +27 -1
- package/src/canvas/CanvasStack.tsx +29 -4
- package/src/canvas/CanvasStackContext.ts +23 -4
- package/src/canvas/camera.test.ts +78 -0
- package/src/canvas/camera.ts +62 -0
- package/src/canvas/canvasCoords.test.ts +26 -0
- package/src/canvas/canvasCoords.ts +20 -7
- package/src/canvas/index.ts +5 -1
- package/src/canvas/useLayerScheduler.ts +7 -3
- package/src/canvas/usePanZoom.test.ts +36 -5
- package/src/canvas/usePanZoom.ts +20 -15
- package/src/canvas/worldSpec.test.ts +63 -0
- package/src/canvas/worldSpec.ts +48 -0
- package/src/chrome/builtins.test.ts +31 -1
- package/src/chrome/builtins.tsx +63 -19
- package/src/chrome/regions/PaletteRegion.test.tsx +22 -1
- package/src/chrome/regions/PaletteRegion.tsx +4 -0
- package/src/chrome/regions/SidebarRegion.tsx +37 -13
- package/src/chrome/regions/ToolbarRegion.tsx +2 -1
- package/src/chrome/regions/ViewportRegion.tsx +9 -1
- package/src/chrome/regions/regions.test.tsx +6 -1
- package/src/chrome/types.ts +20 -0
- package/src/controls/ControlPanel.test.tsx +38 -0
- package/src/controls/ControlPanel.tsx +50 -3
- package/src/dragdrop/DragDropRuntime.tsx +8 -2
- package/src/dragdrop/dragDrop.test.tsx +29 -2
- package/src/index.test.ts +22 -0
- package/src/index.ts +87 -2
- package/src/instrument/SineWave.smoke.test.tsx +1 -0
- package/src/instrument/types.ts +24 -1
- package/src/lab/Lab.surface.test.tsx +162 -0
- package/src/lab/Lab.tsx +102 -17
- package/src/lab/Lab.undock.test.tsx +85 -0
- package/src/lab/LabFullChrome.stories.tsx +20 -0
- package/src/lab/LabShell.less +11 -0
- package/src/lab/Workspace.less +73 -0
- package/src/lab/Workspace.surface.test.tsx +2 -0
- package/src/lab/Workspace.tsx +97 -8
- package/src/lab/index.ts +1 -1
- package/src/lab/panelHost.ts +37 -0
- package/src/loupe/AGENTS.md +49 -0
- package/src/loupe/CanvasLoupe.tsx +83 -0
- package/src/loupe/DomLoupe.tsx +62 -0
- package/src/loupe/Loupe.less +38 -0
- package/src/loupe/LoupeBubble.tsx +32 -0
- package/src/loupe/TrialLoupe.tsx +93 -0
- package/src/loupe/canvasLens.test.ts +205 -0
- package/src/loupe/canvasLens.ts +141 -0
- package/src/loupe/index.ts +19 -0
- package/src/loupe/types.test.ts +29 -0
- package/src/loupe/types.ts +90 -0
- package/src/loupe/useHostSize.ts +30 -0
- package/src/loupe/useLoupe.test.tsx +197 -0
- package/src/loupe/useLoupe.ts +189 -0
- package/src/passthrough/weasel-ui.ts +3 -0
- package/src/primitives/FloatingPanel.test.tsx +76 -1
- package/src/primitives/FloatingPanel.tsx +19 -3
- package/src/primitives/ScaleIndicator.test.tsx +7 -2
- package/src/primitives/Sidebar.less +18 -0
- package/src/primitives/Toolbar.less +8 -0
- package/src/primitives/Toolbar.tsx +5 -0
- package/src/primitives/useRovingTabIndex.test.ts +21 -0
- package/src/primitives/useRovingTabIndex.ts +26 -17
- package/src/state/document.test.ts +23 -0
- package/src/state/document.ts +14 -2
- package/src/state/index.ts +2 -0
- package/src/state/store.test.ts +24 -0
- package/src/state/store.ts +35 -1
- package/src/state/types.ts +11 -0
- package/src/state/undock.test.ts +40 -0
- package/src/state/undock.ts +39 -0
- package/src/styles.less +2 -0
- package/src/surface/SurfaceContext.ts +4 -0
- package/src/surface/index.ts +8 -3
- package/src/surface/useSurfaceTile.test.tsx +2 -0
- package/src/surface/useSurfaceTile.ts +7 -1
- package/src/surface/useTiledSurface.test.tsx +58 -0
- package/src/surface/useTiledSurface.ts +38 -3
- package/src/trial/Trial.annotations.persist.test.tsx +166 -0
- package/src/trial/Trial.annotations.test.tsx +121 -0
- package/src/trial/Trial.canvas.test.tsx +76 -1
- package/src/trial/Trial.less +19 -0
- package/src/trial/Trial.loupe.test.tsx +128 -0
- package/src/trial/Trial.stories.tsx +1 -0
- package/src/trial/Trial.test.tsx +12 -0
- package/src/trial/Trial.trialId.test.tsx +36 -0
- package/src/trial/Trial.tsx +215 -40
- package/src/trial/TrialChrome.tsx +35 -0
- package/src/trial/UndockedSections.tsx +65 -0
- package/src/trial/trialOps.test.ts +21 -0
- package/src/trial/trialOps.ts +5 -3
- package/dist/_dts/types-BttTIent.d.ts +0 -314
- package/dist/chunk-3XXPU73K.js.map +0 -1
- package/dist/chunk-4TMMVIDM.js.map +0 -1
- package/dist/chunk-6X5RBC6G.js +0 -366
- package/dist/chunk-6X5RBC6G.js.map +0 -1
- package/dist/chunk-BDJXIBRZ.js.map +0 -1
- package/dist/chunk-CPUJ3QXL.js.map +0 -1
- package/dist/chunk-JDROYQM3.js.map +0 -1
- package/dist/chunk-LGKRIUSW.js.map +0 -1
- package/dist/chunk-QCICIHEO.js.map +0 -1
- package/dist/chunk-QRYPXSGP.js.map +0 -1
- package/dist/chunk-RGT4EJIB.js +0 -6961
- package/dist/chunk-RGT4EJIB.js.map +0 -1
- package/dist/chunk-T66HU3HX.js +0 -17
- package/dist/chunk-T66HU3HX.js.map +0 -1
- package/dist/chunk-WTI26YTM.js.map +0 -1
|
@@ -3,7 +3,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
3
3
|
import earcut from 'earcut';
|
|
4
4
|
import polygonClipping from 'polygon-clipping';
|
|
5
5
|
|
|
6
|
-
// ../core/dist/chunk-
|
|
6
|
+
// ../core/dist/chunk-H6E6KPTU.js
|
|
7
7
|
|
|
8
8
|
// ../gestures/dist/index.js
|
|
9
9
|
var GESTURE_DESCRIPTORS = [
|
|
@@ -287,7 +287,7 @@ function matchSpec(e, spec, isMac, phaseCtx) {
|
|
|
287
287
|
}
|
|
288
288
|
var EMPTY_ENGAGED = /* @__PURE__ */ new Set();
|
|
289
289
|
|
|
290
|
-
// ../core/dist/chunk-
|
|
290
|
+
// ../core/dist/chunk-H6E6KPTU.js
|
|
291
291
|
var DepRegistryContext = createContext(null);
|
|
292
292
|
function DepRegistryProvider({ children }) {
|
|
293
293
|
const sourcesRef = useRef(/* @__PURE__ */ new Map());
|
|
@@ -428,6 +428,12 @@ function validateActionDefaultBinding(action) {
|
|
|
428
428
|
}
|
|
429
429
|
}
|
|
430
430
|
}
|
|
431
|
+
function warnSharedScope() {
|
|
432
|
+
if (!IS_DEV) return;
|
|
433
|
+
console.warn(
|
|
434
|
+
"weasel: a second dispatcher claimed this <ActionsProvider>, so only the newest <SceneCanvas> under it will respond to input. Give each canvas its own scope with <WeaselProvider isolate>."
|
|
435
|
+
);
|
|
436
|
+
}
|
|
431
437
|
var ActionsContext = createContext(null);
|
|
432
438
|
function ActionsProvider({ children }) {
|
|
433
439
|
const actionsRef = useRef(/* @__PURE__ */ new Map());
|
|
@@ -438,6 +444,7 @@ function ActionsProvider({ children }) {
|
|
|
438
444
|
const depReg = useOptionalDepRegistry();
|
|
439
445
|
const depRegRef = useRef(depReg);
|
|
440
446
|
depRegRef.current = depReg;
|
|
447
|
+
const warnedRef = useRef(false);
|
|
441
448
|
const wiredDepRegRef = useRef(null);
|
|
442
449
|
const dispatcherRef = useRef(null);
|
|
443
450
|
const registry4 = useMemo(() => {
|
|
@@ -510,10 +517,20 @@ function ActionsProvider({ children }) {
|
|
|
510
517
|
};
|
|
511
518
|
},
|
|
512
519
|
setDispatcher: (d) => {
|
|
520
|
+
if (d && dispatcherRef.current && dispatcherRef.current !== d && !warnedRef.current) {
|
|
521
|
+
warnedRef.current = true;
|
|
522
|
+
warnSharedScope();
|
|
523
|
+
}
|
|
513
524
|
dispatcherRef.current = d;
|
|
525
|
+
return () => {
|
|
526
|
+
if (dispatcherRef.current === d) dispatcherRef.current = null;
|
|
527
|
+
};
|
|
514
528
|
},
|
|
515
529
|
setDepRegistry: (r) => {
|
|
516
530
|
wiredDepRegRef.current = r;
|
|
531
|
+
return () => {
|
|
532
|
+
if (wiredDepRegRef.current === r) wiredDepRegRef.current = null;
|
|
533
|
+
};
|
|
517
534
|
},
|
|
518
535
|
begin: (id, params) => {
|
|
519
536
|
const disp = dispatcherRef.current;
|
|
@@ -535,7 +552,7 @@ function ActionsProvider({ children }) {
|
|
|
535
552
|
}, []);
|
|
536
553
|
return /* @__PURE__ */ jsx(ActionsContext.Provider, { value: registry4, children });
|
|
537
554
|
}
|
|
538
|
-
(() => {
|
|
555
|
+
var IS_DEV = (() => {
|
|
539
556
|
try {
|
|
540
557
|
return Boolean(import.meta.env?.DEV);
|
|
541
558
|
} catch {
|
|
@@ -879,8 +896,19 @@ function transformCoords(coords, m) {
|
|
|
879
896
|
}
|
|
880
897
|
return out;
|
|
881
898
|
}
|
|
899
|
+
function clampAxis(start, size, low, extent, padding) {
|
|
900
|
+
const min = low + padding;
|
|
901
|
+
return Math.max(min, Math.min(start, min + extent - padding * 2 - size));
|
|
902
|
+
}
|
|
903
|
+
function clampRectWithin(rect, boundary, padding = 0) {
|
|
904
|
+
return {
|
|
905
|
+
...rect,
|
|
906
|
+
x: clampAxis(rect.x, rect.width, boundary.x, boundary.width, padding),
|
|
907
|
+
y: clampAxis(rect.y, rect.height, boundary.y, boundary.height, padding)
|
|
908
|
+
};
|
|
909
|
+
}
|
|
882
910
|
|
|
883
|
-
// ../core/dist/chunk-
|
|
911
|
+
// ../core/dist/chunk-SBFC6J3C.js
|
|
884
912
|
function resolveUnit(v, unitSystem) {
|
|
885
913
|
if (typeof v === "number") return v;
|
|
886
914
|
if (!unitSystem) {
|
|
@@ -1315,6 +1343,17 @@ var PathBuilder = class _PathBuilder {
|
|
|
1315
1343
|
function rectPath(x, y, width, height) {
|
|
1316
1344
|
return { kind: "rect", x, y, width, height };
|
|
1317
1345
|
}
|
|
1346
|
+
function polylineFromPoints(points) {
|
|
1347
|
+
const b = new PathBuilder();
|
|
1348
|
+
const first = points[0];
|
|
1349
|
+
if (!first) return rectPath(0, 0, 0, 0);
|
|
1350
|
+
b.moveTo(first.x, first.y);
|
|
1351
|
+
for (let i = 1; i < points.length; i++) {
|
|
1352
|
+
const p = points[i];
|
|
1353
|
+
if (p) b.lineTo(p.x, p.y);
|
|
1354
|
+
}
|
|
1355
|
+
return b.build();
|
|
1356
|
+
}
|
|
1318
1357
|
function polygonFromPoints(points, opts = {}) {
|
|
1319
1358
|
if (points.length === 0) {
|
|
1320
1359
|
return {
|
|
@@ -1690,7 +1729,7 @@ function createDeleteOp(args) {
|
|
|
1690
1729
|
}
|
|
1691
1730
|
registerOpFactory("delete", (args) => createDeleteOp(args));
|
|
1692
1731
|
|
|
1693
|
-
// ../core/dist/chunk-
|
|
1732
|
+
// ../core/dist/chunk-Y5KS66G7.js
|
|
1694
1733
|
function createTransformOp(args) {
|
|
1695
1734
|
const { id, from, to, label, coalesceKey = `transform:${id}` } = args;
|
|
1696
1735
|
return {
|
|
@@ -1814,7 +1853,7 @@ function snap(strategy, opts = {}) {
|
|
|
1814
1853
|
};
|
|
1815
1854
|
}
|
|
1816
1855
|
|
|
1817
|
-
// ../core/dist/chunk-
|
|
1856
|
+
// ../core/dist/chunk-BLJNRMKB.js
|
|
1818
1857
|
function lockAspectWithModifier(opts = {}) {
|
|
1819
1858
|
const { key = "shift" } = opts;
|
|
1820
1859
|
return {
|
|
@@ -4224,7 +4263,7 @@ function serialToEntry(se, custom, logger) {
|
|
|
4224
4263
|
};
|
|
4225
4264
|
}
|
|
4226
4265
|
|
|
4227
|
-
// ../core/dist/chunk-
|
|
4266
|
+
// ../core/dist/chunk-IMFXEINV.js
|
|
4228
4267
|
function worldToScreen(worldX, worldY, view) {
|
|
4229
4268
|
return [view.panX + worldX * view.zoom.x, view.panY + worldY * view.zoom.y];
|
|
4230
4269
|
}
|
|
@@ -5551,6 +5590,9 @@ function flattenPolygon(p, tolerance) {
|
|
|
5551
5590
|
let coordIdx = 0;
|
|
5552
5591
|
let prevX = 0;
|
|
5553
5592
|
let prevY = 0;
|
|
5593
|
+
let startX = 0;
|
|
5594
|
+
let startY = 0;
|
|
5595
|
+
let startAnchor = -1;
|
|
5554
5596
|
let prevAnchor = -1;
|
|
5555
5597
|
let anchorCounter = 0;
|
|
5556
5598
|
for (let cmdIdx = 0; cmdIdx < commands.length; cmdIdx++) {
|
|
@@ -5560,6 +5602,9 @@ function flattenPolygon(p, tolerance) {
|
|
|
5560
5602
|
contourStarts.push(out.length / 2);
|
|
5561
5603
|
prevX = coords[coordIdx];
|
|
5562
5604
|
prevY = coords[coordIdx + 1];
|
|
5605
|
+
startX = prevX;
|
|
5606
|
+
startY = prevY;
|
|
5607
|
+
startAnchor = anchorCounter;
|
|
5563
5608
|
out.push(prevX, prevY);
|
|
5564
5609
|
anchorA.push(anchorCounter);
|
|
5565
5610
|
anchorB.push(anchorCounter);
|
|
@@ -5629,6 +5674,9 @@ function flattenPolygon(p, tolerance) {
|
|
|
5629
5674
|
break;
|
|
5630
5675
|
}
|
|
5631
5676
|
case PATH_Z: {
|
|
5677
|
+
prevX = startX;
|
|
5678
|
+
prevY = startY;
|
|
5679
|
+
prevAnchor = startAnchor;
|
|
5632
5680
|
break;
|
|
5633
5681
|
}
|
|
5634
5682
|
default:
|
|
@@ -8444,6 +8492,7 @@ var WeaselRenderer = class {
|
|
|
8444
8492
|
heightCss;
|
|
8445
8493
|
dpr;
|
|
8446
8494
|
canvas = null;
|
|
8495
|
+
target = null;
|
|
8447
8496
|
imageMinification;
|
|
8448
8497
|
flattenTolerance;
|
|
8449
8498
|
bakeBudget;
|
|
@@ -8461,6 +8510,12 @@ var WeaselRenderer = class {
|
|
|
8461
8510
|
const gl = opts.gl ?? opts.canvas.getContext("webgl2", { stencil: true });
|
|
8462
8511
|
if (!gl) throw new Error("WeaselRenderer: WebGL2 not available");
|
|
8463
8512
|
this.gl = gl;
|
|
8513
|
+
const attrs = typeof this.gl.getContextAttributes === "function" ? this.gl.getContextAttributes() : null;
|
|
8514
|
+
if (attrs && attrs.stencil === false) {
|
|
8515
|
+
throw new Error(
|
|
8516
|
+
"WeaselRenderer: the supplied WebGL2 context has no stencil buffer. Create it with { stencil: true } \u2014 clips and even-odd fills need one."
|
|
8517
|
+
);
|
|
8518
|
+
}
|
|
8464
8519
|
this.widthCss = opts.width;
|
|
8465
8520
|
this.heightCss = opts.height;
|
|
8466
8521
|
this.dpr = opts.dpr;
|
|
@@ -8479,12 +8534,8 @@ var WeaselRenderer = class {
|
|
|
8479
8534
|
this.canvas.addEventListener("webglcontextlost", this.boundOnLost);
|
|
8480
8535
|
this.canvas.addEventListener("webglcontextrestored", this.boundOnRestored);
|
|
8481
8536
|
}
|
|
8482
|
-
this.
|
|
8483
|
-
this.
|
|
8484
|
-
this.gl.disable(this.gl.DEPTH_TEST);
|
|
8485
|
-
this.gl.disable(this.gl.CULL_FACE);
|
|
8486
|
-
this.gl.clearColor(0, 0, 0, 0);
|
|
8487
|
-
this.applyViewport();
|
|
8537
|
+
this.applyGlState();
|
|
8538
|
+
this.applyTarget();
|
|
8488
8539
|
this.pathFill = new ShaderProgram(this.gl, VERT_SRC, FRAG_SRC);
|
|
8489
8540
|
this.pathFill.lookupUniforms(PATH_FILL_UNIFORMS);
|
|
8490
8541
|
this.pathFill.lookupAttributes(PATH_FILL_ATTRIBUTES);
|
|
@@ -8574,8 +8625,42 @@ var WeaselRenderer = class {
|
|
|
8574
8625
|
}
|
|
8575
8626
|
return this.programRegistry.get(id) ?? null;
|
|
8576
8627
|
}
|
|
8577
|
-
|
|
8578
|
-
|
|
8628
|
+
/** The GL state every frame assumes. Applied per `render()` rather than once
|
|
8629
|
+
* at construction because a co-tenant sharing this context moves all of it
|
|
8630
|
+
* between our frames. */
|
|
8631
|
+
applyGlState() {
|
|
8632
|
+
const gl = this.gl;
|
|
8633
|
+
gl.enable(gl.BLEND);
|
|
8634
|
+
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
|
8635
|
+
gl.disable(gl.DEPTH_TEST);
|
|
8636
|
+
gl.disable(gl.CULL_FACE);
|
|
8637
|
+
gl.clearColor(0, 0, 0, 0);
|
|
8638
|
+
}
|
|
8639
|
+
/** Viewport and scissor for this frame. Re-applied inside `render()` because
|
|
8640
|
+
* a co-tenant on the same context moves both between our frames. */
|
|
8641
|
+
applyTarget() {
|
|
8642
|
+
const gl = this.gl;
|
|
8643
|
+
const w = Math.round(this.widthCss * this.dpr);
|
|
8644
|
+
const h = Math.round(this.heightCss * this.dpr);
|
|
8645
|
+
if (!this.target) {
|
|
8646
|
+
gl.disable(gl.SCISSOR_TEST);
|
|
8647
|
+
gl.viewport(0, 0, w, h);
|
|
8648
|
+
return;
|
|
8649
|
+
}
|
|
8650
|
+
const x = Math.round(this.target.origin.x * this.dpr);
|
|
8651
|
+
const y = gl.drawingBufferHeight - Math.round(this.target.origin.y * this.dpr) - h;
|
|
8652
|
+
gl.viewport(x, y, w, h);
|
|
8653
|
+
gl.scissor(x, y, w, h);
|
|
8654
|
+
gl.enable(gl.SCISSOR_TEST);
|
|
8655
|
+
}
|
|
8656
|
+
/** Confine this renderer to a rect of its drawing buffer, or pass null to
|
|
8657
|
+
* give it the whole buffer back. Takes effect from the next `render()`. */
|
|
8658
|
+
setTarget(target) {
|
|
8659
|
+
this.target = target;
|
|
8660
|
+
this.applyTarget();
|
|
8661
|
+
}
|
|
8662
|
+
getTarget() {
|
|
8663
|
+
return this.target;
|
|
8579
8664
|
}
|
|
8580
8665
|
isContextLost() {
|
|
8581
8666
|
return this.contextLost;
|
|
@@ -8586,12 +8671,8 @@ var WeaselRenderer = class {
|
|
|
8586
8671
|
}
|
|
8587
8672
|
onContextRestored() {
|
|
8588
8673
|
this.contextLost = false;
|
|
8589
|
-
this.
|
|
8590
|
-
this.
|
|
8591
|
-
this.gl.disable(this.gl.DEPTH_TEST);
|
|
8592
|
-
this.gl.disable(this.gl.CULL_FACE);
|
|
8593
|
-
this.gl.clearColor(0, 0, 0, 0);
|
|
8594
|
-
this.applyViewport();
|
|
8674
|
+
this.applyGlState();
|
|
8675
|
+
this.applyTarget();
|
|
8595
8676
|
this.pathFill = new ShaderProgram(this.gl, VERT_SRC, FRAG_SRC);
|
|
8596
8677
|
this.pathFill.lookupUniforms(PATH_FILL_UNIFORMS);
|
|
8597
8678
|
this.pathFill.lookupAttributes(PATH_FILL_ATTRIBUTES);
|
|
@@ -8698,8 +8779,12 @@ var WeaselRenderer = class {
|
|
|
8698
8779
|
this.meshCache.drainPendingDeletes();
|
|
8699
8780
|
resetBakeBudget(this.bakeBudget);
|
|
8700
8781
|
this.groupState.reset();
|
|
8701
|
-
|
|
8702
|
-
|
|
8782
|
+
this.applyGlState();
|
|
8783
|
+
this.applyTarget();
|
|
8784
|
+
if (this.target?.clear !== false) {
|
|
8785
|
+
gl.stencilMask(255);
|
|
8786
|
+
gl.clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
|
8787
|
+
}
|
|
8703
8788
|
const ctx = {
|
|
8704
8789
|
gl,
|
|
8705
8790
|
pathFill: this.pathFill,
|
|
@@ -8742,7 +8827,7 @@ var WeaselRenderer = class {
|
|
|
8742
8827
|
this.canvas.style.height = `${dims.height}px`;
|
|
8743
8828
|
}
|
|
8744
8829
|
}
|
|
8745
|
-
this.
|
|
8830
|
+
this.applyTarget();
|
|
8746
8831
|
}
|
|
8747
8832
|
/** @internal */
|
|
8748
8833
|
_gl() {
|
|
@@ -9382,10 +9467,10 @@ function targetSizesPx(targetScale = 1) {
|
|
|
9382
9467
|
rotationDistance: BASE_PX.rotationDistance * targetScale
|
|
9383
9468
|
};
|
|
9384
9469
|
}
|
|
9385
|
-
var
|
|
9386
|
-
var
|
|
9470
|
+
var DEFAULT_MIN_ZOOM = 0.1;
|
|
9471
|
+
var DEFAULT_MAX_ZOOM = 8;
|
|
9387
9472
|
function fitViewToBounds(bounds, viewportDims, currentView, opts = {}) {
|
|
9388
|
-
const { padding = 16, maxScale =
|
|
9473
|
+
const { padding = 16, maxScale = DEFAULT_MAX_ZOOM, minScale = DEFAULT_MIN_ZOOM } = opts;
|
|
9389
9474
|
if (bounds.width <= 0 || bounds.height <= 0) {
|
|
9390
9475
|
console.warn("[weasel] fitViewToBounds: bounds has zero or negative area; returning currentView unchanged.", bounds);
|
|
9391
9476
|
return currentView;
|
|
@@ -9429,15 +9514,19 @@ function fitViewToBounds(bounds, viewportDims, currentView, opts = {}) {
|
|
|
9429
9514
|
scale: { x: scaleX, y: scaleY }
|
|
9430
9515
|
};
|
|
9431
9516
|
}
|
|
9517
|
+
function clampScale(scale2, min, max) {
|
|
9518
|
+
const magnitude = Math.min(max, Math.max(min, Math.abs(scale2)));
|
|
9519
|
+
return scale2 < 0 ? -magnitude : magnitude;
|
|
9520
|
+
}
|
|
9432
9521
|
function zoomAt(view, anchor, factor, opts) {
|
|
9433
9522
|
const fx = typeof factor === "number" ? factor : factor.x;
|
|
9434
9523
|
const fy = typeof factor === "number" ? factor : factor.y;
|
|
9435
|
-
const minX = typeof opts?.min === "number" ? opts.min : opts?.min?.x ??
|
|
9436
|
-
const minY = typeof opts?.min === "number" ? opts.min : opts?.min?.y ??
|
|
9437
|
-
const maxX = typeof opts?.max === "number" ? opts.max : opts?.max?.x ??
|
|
9438
|
-
const maxY = typeof opts?.max === "number" ? opts.max : opts?.max?.y ??
|
|
9439
|
-
const nextX =
|
|
9440
|
-
const nextY =
|
|
9524
|
+
const minX = typeof opts?.min === "number" ? opts.min : opts?.min?.x ?? DEFAULT_MIN_ZOOM;
|
|
9525
|
+
const minY = typeof opts?.min === "number" ? opts.min : opts?.min?.y ?? DEFAULT_MIN_ZOOM;
|
|
9526
|
+
const maxX = typeof opts?.max === "number" ? opts.max : opts?.max?.x ?? DEFAULT_MAX_ZOOM;
|
|
9527
|
+
const maxY = typeof opts?.max === "number" ? opts.max : opts?.max?.y ?? DEFAULT_MAX_ZOOM;
|
|
9528
|
+
const nextX = clampScale(view.scale.x * fx, minX, maxX);
|
|
9529
|
+
const nextY = clampScale(view.scale.y * fy, minY, maxY);
|
|
9441
9530
|
const worldX = anchor.x / view.scale.x + view.x;
|
|
9442
9531
|
const worldY = anchor.y / view.scale.y + view.y;
|
|
9443
9532
|
return {
|
|
@@ -9447,22 +9536,24 @@ function zoomAt(view, anchor, factor, opts) {
|
|
|
9447
9536
|
};
|
|
9448
9537
|
}
|
|
9449
9538
|
function clampView(view, bounds, canvas) {
|
|
9450
|
-
const visW = canvas.width / view.scale.x;
|
|
9451
|
-
const visH = canvas.height / view.scale.y;
|
|
9539
|
+
const visW = Math.abs(canvas.width / view.scale.x);
|
|
9540
|
+
const visH = Math.abs(canvas.height / view.scale.y);
|
|
9541
|
+
const flipX = view.scale.x < 0;
|
|
9542
|
+
const flipY = view.scale.y < 0;
|
|
9452
9543
|
let x;
|
|
9453
9544
|
if (visW >= bounds.width) {
|
|
9454
|
-
x = bounds.x + (bounds.width - visW) / 2;
|
|
9545
|
+
x = bounds.x + (bounds.width - visW) / 2 + (flipX ? visW : 0);
|
|
9455
9546
|
} else {
|
|
9456
|
-
const minX = bounds.x;
|
|
9457
|
-
const maxX = bounds.x + bounds.width - visW;
|
|
9547
|
+
const minX = flipX ? bounds.x + visW : bounds.x;
|
|
9548
|
+
const maxX = flipX ? bounds.x + bounds.width : bounds.x + bounds.width - visW;
|
|
9458
9549
|
x = view.x < minX ? minX : view.x > maxX ? maxX : view.x;
|
|
9459
9550
|
}
|
|
9460
9551
|
let y;
|
|
9461
9552
|
if (visH >= bounds.height) {
|
|
9462
|
-
y = bounds.y + (bounds.height - visH) / 2;
|
|
9553
|
+
y = bounds.y + (bounds.height - visH) / 2 + (flipY ? visH : 0);
|
|
9463
9554
|
} else {
|
|
9464
|
-
const minY = bounds.y;
|
|
9465
|
-
const maxY = bounds.y + bounds.height - visH;
|
|
9555
|
+
const minY = flipY ? bounds.y + visH : bounds.y;
|
|
9556
|
+
const maxY = flipY ? bounds.y + bounds.height : bounds.y + bounds.height - visH;
|
|
9466
9557
|
y = view.y < minY ? minY : view.y > maxY ? maxY : view.y;
|
|
9467
9558
|
}
|
|
9468
9559
|
return x === view.x && y === view.y ? view : { x, y, scale: view.scale };
|
|
@@ -11165,7 +11256,7 @@ function keyAnchor(view) {
|
|
|
11165
11256
|
}
|
|
11166
11257
|
var WHEEL_STEP = 1.1;
|
|
11167
11258
|
function makeViewportZoomAction(opts = {}) {
|
|
11168
|
-
const clamp2 = { min: opts.min ??
|
|
11259
|
+
const clamp2 = { min: opts.min ?? DEFAULT_MIN_ZOOM, max: opts.max ?? DEFAULT_MAX_ZOOM };
|
|
11169
11260
|
const wheelSpec = opts.wheel === "plain" ? { kind: "wheel" } : { kind: "wheel", mods: { mod: true } };
|
|
11170
11261
|
const rawAnimate = opts.animate === true ? {} : opts.animate || null;
|
|
11171
11262
|
const { resetMs, ...animateRest } = rawAnimate ?? {};
|
|
@@ -11814,7 +11905,7 @@ var lassoSelectAction = {
|
|
|
11814
11905
|
enabled: () => true
|
|
11815
11906
|
};
|
|
11816
11907
|
function makePinchZoomAction(opts = {}) {
|
|
11817
|
-
const clamp2 = { min: opts.min ??
|
|
11908
|
+
const clamp2 = { min: opts.min ?? DEFAULT_MIN_ZOOM, max: opts.max ?? DEFAULT_MAX_ZOOM };
|
|
11818
11909
|
return {
|
|
11819
11910
|
id: "viewport.pinchZoom",
|
|
11820
11911
|
label: "Pinch Zoom",
|
|
@@ -16349,154 +16440,6 @@ function useGestureDispatcher(opts) {
|
|
|
16349
16440
|
};
|
|
16350
16441
|
}, [enabled, keyboard, canvasRef]);
|
|
16351
16442
|
}
|
|
16352
|
-
function useVelocityTracker() {
|
|
16353
|
-
const samplesRef = useRef([]);
|
|
16354
|
-
return useMemo(() => ({
|
|
16355
|
-
record(dx, dy, t) {
|
|
16356
|
-
samplesRef.current.push({ dx, dy, t });
|
|
16357
|
-
const cutoff = t - 100;
|
|
16358
|
-
samplesRef.current = samplesRef.current.filter((s) => s.t >= cutoff);
|
|
16359
|
-
},
|
|
16360
|
-
getVelocity() {
|
|
16361
|
-
const s = samplesRef.current;
|
|
16362
|
-
if (s.length < 2) return { vx: 0, vy: 0 };
|
|
16363
|
-
const dt = s[s.length - 1].t - s[0].t;
|
|
16364
|
-
if (dt === 0) return { vx: 0, vy: 0 };
|
|
16365
|
-
const totalDx = s.slice(1).reduce((acc, p) => acc + p.dx, 0);
|
|
16366
|
-
const totalDy = s.slice(1).reduce((acc, p) => acc + p.dy, 0);
|
|
16367
|
-
return { vx: totalDx / dt, vy: totalDy / dt };
|
|
16368
|
-
},
|
|
16369
|
-
reset() {
|
|
16370
|
-
samplesRef.current = [];
|
|
16371
|
-
}
|
|
16372
|
-
}), []);
|
|
16373
|
-
}
|
|
16374
|
-
var SPRING_DAMPING = 0.5;
|
|
16375
|
-
function useDecayLoop() {
|
|
16376
|
-
const stateRef = useRef(null);
|
|
16377
|
-
const frameLoop = useVisibleRaf(
|
|
16378
|
-
(now) => {
|
|
16379
|
-
tick(now);
|
|
16380
|
-
},
|
|
16381
|
-
{
|
|
16382
|
-
// Coasting does not continue while suspended: dropping `lastTime` makes
|
|
16383
|
-
// the resuming frame seed a fresh interval instead of applying an hour of
|
|
16384
|
-
// friction at once, which would end the decay before it was seen.
|
|
16385
|
-
onResume: useCallback(() => {
|
|
16386
|
-
if (stateRef.current) stateRef.current.lastTime = null;
|
|
16387
|
-
}, [])
|
|
16388
|
-
}
|
|
16389
|
-
);
|
|
16390
|
-
const cancel = useCallback(() => {
|
|
16391
|
-
frameLoop.cancel();
|
|
16392
|
-
stateRef.current = null;
|
|
16393
|
-
}, [frameLoop]);
|
|
16394
|
-
const tick = useCallback((now) => {
|
|
16395
|
-
const s = stateRef.current;
|
|
16396
|
-
if (!s) return;
|
|
16397
|
-
if (s.lastTime === null) {
|
|
16398
|
-
s.lastTime = now;
|
|
16399
|
-
frameLoop.request();
|
|
16400
|
-
return;
|
|
16401
|
-
}
|
|
16402
|
-
const dt = Math.min(now - s.lastTime, 64);
|
|
16403
|
-
s.lastTime = now;
|
|
16404
|
-
const f = Math.pow(s.friction, dt / 16.67);
|
|
16405
|
-
s.vx *= f;
|
|
16406
|
-
s.vy *= f;
|
|
16407
|
-
const speed = Math.sqrt(s.vx * s.vx + s.vy * s.vy);
|
|
16408
|
-
if (speed < s.minSpeed) {
|
|
16409
|
-
stateRef.current = null;
|
|
16410
|
-
frameLoop.cancel();
|
|
16411
|
-
s.onEnd?.();
|
|
16412
|
-
return;
|
|
16413
|
-
}
|
|
16414
|
-
let dx = s.vx * dt;
|
|
16415
|
-
let dy = s.vy * dt;
|
|
16416
|
-
if (s.viewBounds && s.boundary) {
|
|
16417
|
-
const { minX, maxX, minY, maxY } = s.viewBounds;
|
|
16418
|
-
const newX = s.posX + dx;
|
|
16419
|
-
const newY = s.posY + dy;
|
|
16420
|
-
if (s.boundary === "stop") {
|
|
16421
|
-
if (minX !== void 0 && newX < minX) {
|
|
16422
|
-
dx = minX - s.posX;
|
|
16423
|
-
s.vx = 0;
|
|
16424
|
-
} else if (maxX !== void 0 && newX > maxX) {
|
|
16425
|
-
dx = maxX - s.posX;
|
|
16426
|
-
s.vx = 0;
|
|
16427
|
-
}
|
|
16428
|
-
if (minY !== void 0 && newY < minY) {
|
|
16429
|
-
dy = minY - s.posY;
|
|
16430
|
-
s.vy = 0;
|
|
16431
|
-
} else if (maxY !== void 0 && newY > maxY) {
|
|
16432
|
-
dy = maxY - s.posY;
|
|
16433
|
-
s.vy = 0;
|
|
16434
|
-
}
|
|
16435
|
-
} else if (s.boundary === "spring") {
|
|
16436
|
-
if (minX !== void 0 && newX < minX) {
|
|
16437
|
-
dx = minX - s.posX;
|
|
16438
|
-
s.vx = Math.abs(s.vx) * SPRING_DAMPING;
|
|
16439
|
-
} else if (maxX !== void 0 && newX > maxX) {
|
|
16440
|
-
dx = maxX - s.posX;
|
|
16441
|
-
s.vx = -Math.abs(s.vx) * SPRING_DAMPING;
|
|
16442
|
-
}
|
|
16443
|
-
if (minY !== void 0 && newY < minY) {
|
|
16444
|
-
dy = minY - s.posY;
|
|
16445
|
-
s.vy = Math.abs(s.vy) * SPRING_DAMPING;
|
|
16446
|
-
} else if (maxY !== void 0 && newY > maxY) {
|
|
16447
|
-
dy = maxY - s.posY;
|
|
16448
|
-
s.vy = -Math.abs(s.vy) * SPRING_DAMPING;
|
|
16449
|
-
}
|
|
16450
|
-
} else {
|
|
16451
|
-
if (minX !== void 0 && newX < minX) {
|
|
16452
|
-
dx = minX - s.posX;
|
|
16453
|
-
s.vx = Math.abs(s.vx);
|
|
16454
|
-
} else if (maxX !== void 0 && newX > maxX) {
|
|
16455
|
-
dx = maxX - s.posX;
|
|
16456
|
-
s.vx = -Math.abs(s.vx);
|
|
16457
|
-
}
|
|
16458
|
-
if (minY !== void 0 && newY < minY) {
|
|
16459
|
-
dy = minY - s.posY;
|
|
16460
|
-
s.vy = Math.abs(s.vy);
|
|
16461
|
-
} else if (maxY !== void 0 && newY > maxY) {
|
|
16462
|
-
dy = maxY - s.posY;
|
|
16463
|
-
s.vy = -Math.abs(s.vy);
|
|
16464
|
-
}
|
|
16465
|
-
}
|
|
16466
|
-
s.posX += dx;
|
|
16467
|
-
s.posY += dy;
|
|
16468
|
-
}
|
|
16469
|
-
s.onTick(dx, dy);
|
|
16470
|
-
frameLoop.request();
|
|
16471
|
-
}, [frameLoop]);
|
|
16472
|
-
const start = useCallback((config) => {
|
|
16473
|
-
cancel();
|
|
16474
|
-
const { velocity, friction = 0.92, minSpeed = 0.01, viewBounds, boundary, initialPosition, onTick, onEnd } = config;
|
|
16475
|
-
const speed = Math.sqrt(velocity.vx ** 2 + velocity.vy ** 2);
|
|
16476
|
-
if (speed < minSpeed) {
|
|
16477
|
-
onEnd?.();
|
|
16478
|
-
return;
|
|
16479
|
-
}
|
|
16480
|
-
stateRef.current = {
|
|
16481
|
-
vx: velocity.vx,
|
|
16482
|
-
vy: velocity.vy,
|
|
16483
|
-
friction,
|
|
16484
|
-
minSpeed,
|
|
16485
|
-
lastTime: null,
|
|
16486
|
-
posX: initialPosition?.x ?? 0,
|
|
16487
|
-
posY: initialPosition?.y ?? 0,
|
|
16488
|
-
viewBounds,
|
|
16489
|
-
boundary,
|
|
16490
|
-
onTick,
|
|
16491
|
-
onEnd
|
|
16492
|
-
};
|
|
16493
|
-
frameLoop.request();
|
|
16494
|
-
}, [cancel, frameLoop]);
|
|
16495
|
-
useEffect(() => () => {
|
|
16496
|
-
cancel();
|
|
16497
|
-
}, [cancel]);
|
|
16498
|
-
return { start, cancel };
|
|
16499
|
-
}
|
|
16500
16443
|
function dist(a, b) {
|
|
16501
16444
|
return Math.hypot(b.x - a.x, b.y - a.y);
|
|
16502
16445
|
}
|
|
@@ -16575,15 +16518,180 @@ function interpolateView(from, to) {
|
|
|
16575
16518
|
return { x: a.x, y: b.x, scale: { x: a.s, y: b.s } };
|
|
16576
16519
|
};
|
|
16577
16520
|
}
|
|
16521
|
+
var linear = (t) => t;
|
|
16522
|
+
var easeInQuad = (t) => t * t;
|
|
16578
16523
|
var easeOutQuad = (t) => 1 - (1 - t) * (1 - t);
|
|
16524
|
+
var easeInOutQuad = (t) => t < 0.5 ? 2 * t * t : 1 - 2 * (1 - t) * (1 - t);
|
|
16525
|
+
var easeInCubic = (t) => t * t * t;
|
|
16579
16526
|
var easeOutCubic = (t) => 1 - Math.pow(1 - t, 3);
|
|
16527
|
+
var easeInOutCubic = (t) => t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
|
|
16528
|
+
var easeInQuart = (t) => t * t * t * t;
|
|
16529
|
+
var easeOutQuart = (t) => 1 - Math.pow(1 - t, 4);
|
|
16530
|
+
var easeInOutQuart = (t) => t < 0.5 ? 8 * t * t * t * t : 1 - Math.pow(-2 * t + 2, 4) / 2;
|
|
16531
|
+
var easeInQuint = (t) => t * t * t * t * t;
|
|
16532
|
+
var easeOutQuint = (t) => 1 - Math.pow(1 - t, 5);
|
|
16533
|
+
var easeInOutQuint = (t) => t < 0.5 ? 16 * t * t * t * t * t : 1 - Math.pow(-2 * t + 2, 5) / 2;
|
|
16534
|
+
var easeInSine = (t) => 1 - Math.cos(t * Math.PI / 2);
|
|
16535
|
+
var easeOutSine = (t) => Math.sin(t * Math.PI / 2);
|
|
16536
|
+
var easeInOutSine = (t) => -(Math.cos(Math.PI * t) - 1) / 2;
|
|
16537
|
+
var easeInExpo = (t) => t === 0 ? 0 : Math.pow(2, 10 * t - 10);
|
|
16538
|
+
var easeOutExpo = (t) => t === 1 ? 1 : 1 - Math.pow(2, -10 * t);
|
|
16539
|
+
var easeInOutExpo = (t) => {
|
|
16540
|
+
if (t === 0) return 0;
|
|
16541
|
+
if (t === 1) return 1;
|
|
16542
|
+
return t < 0.5 ? Math.pow(2, 20 * t - 10) / 2 : (2 - Math.pow(2, -20 * t + 10)) / 2;
|
|
16543
|
+
};
|
|
16544
|
+
var easeInCirc = (t) => 1 - Math.sqrt(1 - t * t);
|
|
16545
|
+
var easeOutCirc = (t) => Math.sqrt(1 - Math.pow(t - 1, 2));
|
|
16546
|
+
var easeInOutCirc = (t) => t < 0.5 ? (1 - Math.sqrt(1 - Math.pow(2 * t, 2))) / 2 : (Math.sqrt(1 - Math.pow(-2 * t + 2, 2)) + 1) / 2;
|
|
16547
|
+
var C1 = 1.70158;
|
|
16548
|
+
var C2 = C1 * 1.525;
|
|
16549
|
+
var C3 = C1 + 1;
|
|
16550
|
+
var C4 = 2 * Math.PI / 3;
|
|
16551
|
+
var C5 = 2 * Math.PI / 4.5;
|
|
16552
|
+
var easeInBack = (t) => C3 * t * t * t - C1 * t * t;
|
|
16553
|
+
var easeOutBack = (t) => 1 + C3 * Math.pow(t - 1, 3) + C1 * Math.pow(t - 1, 2);
|
|
16554
|
+
var easeInOutBack = (t) => t < 0.5 ? Math.pow(2 * t, 2) * ((C2 + 1) * 2 * t - C2) / 2 : (Math.pow(2 * t - 2, 2) * ((C2 + 1) * (2 * t - 2) + C2) + 2) / 2;
|
|
16555
|
+
var easeInElastic = (t) => {
|
|
16556
|
+
if (t === 0) return 0;
|
|
16557
|
+
if (t === 1) return 1;
|
|
16558
|
+
return -Math.pow(2, 10 * t - 10) * Math.sin((t * 10 - 10.75) * C4);
|
|
16559
|
+
};
|
|
16560
|
+
var easeOutElastic = (t) => {
|
|
16561
|
+
if (t === 0) return 0;
|
|
16562
|
+
if (t === 1) return 1;
|
|
16563
|
+
return Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * C4) + 1;
|
|
16564
|
+
};
|
|
16565
|
+
var easeInOutElastic = (t) => {
|
|
16566
|
+
if (t === 0) return 0;
|
|
16567
|
+
if (t === 1) return 1;
|
|
16568
|
+
return t < 0.5 ? -(Math.pow(2, 20 * t - 10) * Math.sin((20 * t - 11.125) * C5)) / 2 : Math.pow(2, -20 * t + 10) * Math.sin((20 * t - 11.125) * C5) / 2 + 1;
|
|
16569
|
+
};
|
|
16570
|
+
var easeOutBounce = (t) => {
|
|
16571
|
+
const n1 = 7.5625;
|
|
16572
|
+
const d1 = 2.75;
|
|
16573
|
+
if (t < 1 / d1) return n1 * t * t;
|
|
16574
|
+
if (t < 2 / d1) {
|
|
16575
|
+
t -= 1.5 / d1;
|
|
16576
|
+
return n1 * t * t + 0.75;
|
|
16577
|
+
}
|
|
16578
|
+
if (t < 2.5 / d1) {
|
|
16579
|
+
t -= 2.25 / d1;
|
|
16580
|
+
return n1 * t * t + 0.9375;
|
|
16581
|
+
}
|
|
16582
|
+
t -= 2.625 / d1;
|
|
16583
|
+
return n1 * t * t + 0.984375;
|
|
16584
|
+
};
|
|
16585
|
+
var easeInBounce = (t) => 1 - easeOutBounce(1 - t);
|
|
16586
|
+
var easeInOutBounce = (t) => t < 0.5 ? (1 - easeOutBounce(1 - 2 * t)) / 2 : (1 + easeOutBounce(2 * t - 1)) / 2;
|
|
16580
16587
|
var easeOut = easeOutQuad;
|
|
16588
|
+
var EASINGS = {
|
|
16589
|
+
linear,
|
|
16590
|
+
easeInQuad,
|
|
16591
|
+
easeOutQuad,
|
|
16592
|
+
easeInOutQuad,
|
|
16593
|
+
easeInCubic,
|
|
16594
|
+
easeOutCubic,
|
|
16595
|
+
easeInOutCubic,
|
|
16596
|
+
easeInQuart,
|
|
16597
|
+
easeOutQuart,
|
|
16598
|
+
easeInOutQuart,
|
|
16599
|
+
easeInQuint,
|
|
16600
|
+
easeOutQuint,
|
|
16601
|
+
easeInOutQuint,
|
|
16602
|
+
easeInSine,
|
|
16603
|
+
easeOutSine,
|
|
16604
|
+
easeInOutSine,
|
|
16605
|
+
easeInExpo,
|
|
16606
|
+
easeOutExpo,
|
|
16607
|
+
easeInOutExpo,
|
|
16608
|
+
easeInCirc,
|
|
16609
|
+
easeOutCirc,
|
|
16610
|
+
easeInOutCirc,
|
|
16611
|
+
easeInBack,
|
|
16612
|
+
easeOutBack,
|
|
16613
|
+
easeInOutBack,
|
|
16614
|
+
easeInElastic,
|
|
16615
|
+
easeOutElastic,
|
|
16616
|
+
easeInOutElastic,
|
|
16617
|
+
easeInBounce,
|
|
16618
|
+
easeOutBounce,
|
|
16619
|
+
easeInOutBounce
|
|
16620
|
+
};
|
|
16581
16621
|
var SPRING_PRESETS = {
|
|
16582
16622
|
gentle: { stiffness: 120, damping: 14, mass: 1 },
|
|
16583
16623
|
wobbly: { stiffness: 180, damping: 12, mass: 1 },
|
|
16584
16624
|
stiff: { stiffness: 210, damping: 20, mass: 1 },
|
|
16585
16625
|
slow: { stiffness: 80, damping: 20, mass: 1 }
|
|
16586
16626
|
};
|
|
16627
|
+
var NEWTON_ITERATIONS = 8;
|
|
16628
|
+
var NEWTON_MIN_SLOPE = 1e-3;
|
|
16629
|
+
var SUBDIVISION_EPSILON = 1e-7;
|
|
16630
|
+
var SUBDIVISION_MAX = 12;
|
|
16631
|
+
function bezierAt(t, a1, a2) {
|
|
16632
|
+
const c = 3 * a1;
|
|
16633
|
+
const b = 3 * (a2 - a1) - c;
|
|
16634
|
+
const a = 1 - c - b;
|
|
16635
|
+
return ((a * t + b) * t + c) * t;
|
|
16636
|
+
}
|
|
16637
|
+
function bezierSlope(t, a1, a2) {
|
|
16638
|
+
const c = 3 * a1;
|
|
16639
|
+
const b = 3 * (a2 - a1) - c;
|
|
16640
|
+
const a = 1 - c - b;
|
|
16641
|
+
return (3 * a * t + 2 * b) * t + c;
|
|
16642
|
+
}
|
|
16643
|
+
function solveForX(x, x1, x2) {
|
|
16644
|
+
let t = x;
|
|
16645
|
+
for (let i = 0; i < NEWTON_ITERATIONS; i++) {
|
|
16646
|
+
const slope = bezierSlope(t, x1, x2);
|
|
16647
|
+
if (slope < NEWTON_MIN_SLOPE) break;
|
|
16648
|
+
t -= (bezierAt(t, x1, x2) - x) / slope;
|
|
16649
|
+
}
|
|
16650
|
+
let lo = 0;
|
|
16651
|
+
let hi = 1;
|
|
16652
|
+
t = Math.min(1, Math.max(0, t));
|
|
16653
|
+
for (let i = 0; i < SUBDIVISION_MAX; i++) {
|
|
16654
|
+
const err = bezierAt(t, x1, x2) - x;
|
|
16655
|
+
if (Math.abs(err) < SUBDIVISION_EPSILON) return t;
|
|
16656
|
+
if (err > 0) hi = t;
|
|
16657
|
+
else lo = t;
|
|
16658
|
+
t = (lo + hi) / 2;
|
|
16659
|
+
}
|
|
16660
|
+
return t;
|
|
16661
|
+
}
|
|
16662
|
+
function cubicBezierEasing(x1, y1, x2, y2) {
|
|
16663
|
+
const cx1 = Math.min(1, Math.max(0, x1));
|
|
16664
|
+
const cx2 = Math.min(1, Math.max(0, x2));
|
|
16665
|
+
return (t) => {
|
|
16666
|
+
if (t <= 0) return 0;
|
|
16667
|
+
if (t >= 1) return 1;
|
|
16668
|
+
return bezierAt(solveForX(t, cx1, cx2), y1, y2);
|
|
16669
|
+
};
|
|
16670
|
+
}
|
|
16671
|
+
var bezierCache = /* @__PURE__ */ new Map();
|
|
16672
|
+
function isBezier(spec) {
|
|
16673
|
+
return typeof spec === "object" && spec !== null && "bezier" in spec;
|
|
16674
|
+
}
|
|
16675
|
+
function resolveEasing(spec) {
|
|
16676
|
+
if (spec === void 0) return EASINGS.linear;
|
|
16677
|
+
if (typeof spec === "function") return spec;
|
|
16678
|
+
if (typeof spec === "string") {
|
|
16679
|
+
const fn = EASINGS[spec];
|
|
16680
|
+
if (!fn) throw new Error(`resolveEasing: unknown easing name "${spec}"`);
|
|
16681
|
+
return fn;
|
|
16682
|
+
}
|
|
16683
|
+
if (isBezier(spec)) {
|
|
16684
|
+
const [x1, y1, x2, y2] = spec.bezier;
|
|
16685
|
+
const key = `${x1},${y1},${x2},${y2}`;
|
|
16686
|
+
let fn = bezierCache.get(key);
|
|
16687
|
+
if (!fn) {
|
|
16688
|
+
fn = cubicBezierEasing(x1, y1, x2, y2);
|
|
16689
|
+
bezierCache.set(key, fn);
|
|
16690
|
+
}
|
|
16691
|
+
return fn;
|
|
16692
|
+
}
|
|
16693
|
+
throw new Error("resolveEasing: unrecognized easing spec");
|
|
16694
|
+
}
|
|
16587
16695
|
function createLoop(createSupervisor, factory, opts = {}) {
|
|
16588
16696
|
const max = opts.count ?? Infinity;
|
|
16589
16697
|
let iteration = 0;
|
|
@@ -16623,6 +16731,7 @@ function createLoop(createSupervisor, factory, opts = {}) {
|
|
|
16623
16731
|
supervisor.setTimeScale(s);
|
|
16624
16732
|
current?.setTimeScale(s);
|
|
16625
16733
|
},
|
|
16734
|
+
timeScale: () => supervisor.timeScale(),
|
|
16626
16735
|
isPaused: () => supervisor.isPaused()
|
|
16627
16736
|
};
|
|
16628
16737
|
}
|
|
@@ -16782,6 +16891,9 @@ var CompositeHandle = class {
|
|
|
16782
16891
|
this.timeScale_ = s;
|
|
16783
16892
|
for (const c of this.children) c.setTimeScale(s);
|
|
16784
16893
|
}
|
|
16894
|
+
timeScale() {
|
|
16895
|
+
return this.timeScale_;
|
|
16896
|
+
}
|
|
16785
16897
|
isPaused() {
|
|
16786
16898
|
return this.paused_;
|
|
16787
16899
|
}
|
|
@@ -16889,7 +17001,7 @@ function sampleTrack(track, t, segmentCache) {
|
|
|
16889
17001
|
const b = keys[i + 1];
|
|
16890
17002
|
const span = b.t - a.t;
|
|
16891
17003
|
const raw = span <= 0 ? 1 : (t - a.t) / span;
|
|
16892
|
-
const u = b.easing ? b.easing(raw) : raw;
|
|
17004
|
+
const u = b.easing ? resolveEasing(b.easing)(raw) : raw;
|
|
16893
17005
|
if (track.interpolator) {
|
|
16894
17006
|
let fn = segmentCache?.get(i + 1);
|
|
16895
17007
|
if (!fn) {
|
|
@@ -16968,7 +17080,10 @@ function createTimeline(register, id, opts) {
|
|
|
16968
17080
|
for (const track of tracks) {
|
|
16969
17081
|
if (track.kind === "event") {
|
|
16970
17082
|
const end = firstAfter(track.events, to);
|
|
16971
|
-
for (let i = firstAfter(track.events, from); i < end; i += 1)
|
|
17083
|
+
for (let i = firstAfter(track.events, from); i < end; i += 1) {
|
|
17084
|
+
const ev = track.events[i];
|
|
17085
|
+
ev.fire(to - ev.t);
|
|
17086
|
+
}
|
|
16972
17087
|
} else if (track.kind === "timeline") {
|
|
16973
17088
|
fireEvents(track.timeline.tracks, from - track.at, to - track.at);
|
|
16974
17089
|
}
|
|
@@ -17048,6 +17163,7 @@ function createTimeline(register, id, opts) {
|
|
|
17048
17163
|
wantScale = s;
|
|
17049
17164
|
base.setTimeScale(s);
|
|
17050
17165
|
},
|
|
17166
|
+
timeScale: () => live ? base.timeScale() : wantScale,
|
|
17051
17167
|
isPaused: () => live ? base.isPaused() : wantPaused,
|
|
17052
17168
|
seek(t) {
|
|
17053
17169
|
offset = t - lastVirtual;
|
|
@@ -17058,6 +17174,10 @@ function createTimeline(register, id, opts) {
|
|
|
17058
17174
|
time: () => playhead,
|
|
17059
17175
|
duration: () => duration,
|
|
17060
17176
|
tracks: () => opts.tracks,
|
|
17177
|
+
setLoop(loop) {
|
|
17178
|
+
loopsLeft = loop === true ? Infinity : loop === false ? 0 : loop;
|
|
17179
|
+
},
|
|
17180
|
+
loop: () => loopsLeft === Infinity ? true : loopsLeft === 0 ? false : loopsLeft,
|
|
17061
17181
|
edit(fn) {
|
|
17062
17182
|
fn();
|
|
17063
17183
|
caches = /* @__PURE__ */ new WeakMap();
|
|
@@ -17272,6 +17392,7 @@ function useAnimator(opts = {}) {
|
|
|
17272
17392
|
const a = animations.current.get(anim.id);
|
|
17273
17393
|
if (a) a.timeScale = s;
|
|
17274
17394
|
},
|
|
17395
|
+
timeScale: () => animations.current.get(anim.id)?.timeScale ?? 1,
|
|
17275
17396
|
isPaused: () => animations.current.get(anim.id)?.paused ?? false
|
|
17276
17397
|
};
|
|
17277
17398
|
};
|
|
@@ -17293,6 +17414,7 @@ function useAnimator(opts = {}) {
|
|
|
17293
17414
|
pause: base.pause,
|
|
17294
17415
|
resume: base.resume,
|
|
17295
17416
|
setTimeScale: base.setTimeScale,
|
|
17417
|
+
timeScale: base.timeScale,
|
|
17296
17418
|
isPaused: base.isPaused,
|
|
17297
17419
|
setOnCancel: (cb) => {
|
|
17298
17420
|
onCancelCb = cb;
|
|
@@ -17303,7 +17425,7 @@ function useAnimator(opts = {}) {
|
|
|
17303
17425
|
const tween = (o) => {
|
|
17304
17426
|
const id = nextId.current++;
|
|
17305
17427
|
const start = 0;
|
|
17306
|
-
const easing = o.easing ?? easeOut;
|
|
17428
|
+
const easing = resolveEasing(o.easing ?? easeOut);
|
|
17307
17429
|
const factoryFn = o.interpolator ? o.interpolator(o.from, o.to) : null;
|
|
17308
17430
|
const perTickInterp = factoryFn ? null : o.interpolate ?? ((a, b, t) => {
|
|
17309
17431
|
if (typeof a === "number" && typeof b === "number") {
|
|
@@ -17458,6 +17580,7 @@ function useAnimator(opts = {}) {
|
|
|
17458
17580
|
setTimeScale: (s) => {
|
|
17459
17581
|
globalTimeScale.current = s;
|
|
17460
17582
|
},
|
|
17583
|
+
timeScale: () => globalTimeScale.current,
|
|
17461
17584
|
pauseKey: (key) => {
|
|
17462
17585
|
for (const a of animations.current.values()) if (a.cancelKey === key) a.paused = true;
|
|
17463
17586
|
},
|
|
@@ -18055,6 +18178,21 @@ function LineIcon({ className, size = 20 }) {
|
|
|
18055
18178
|
}
|
|
18056
18179
|
);
|
|
18057
18180
|
}
|
|
18181
|
+
function ArrowIcon({ className, size = 20 }) {
|
|
18182
|
+
return /* @__PURE__ */ jsxs(
|
|
18183
|
+
"svg",
|
|
18184
|
+
{
|
|
18185
|
+
...ICON_SVG_BASE,
|
|
18186
|
+
className,
|
|
18187
|
+
width: size,
|
|
18188
|
+
height: size,
|
|
18189
|
+
children: [
|
|
18190
|
+
/* @__PURE__ */ jsx("path", { d: "M3.5 16.5 12.9 7.1", strokeLinecap: "round" }),
|
|
18191
|
+
/* @__PURE__ */ jsx("path", { d: "M16.5 3.5 11.06 5.98 14.03 8.95Z", fill: "currentColor", strokeLinejoin: "round" })
|
|
18192
|
+
]
|
|
18193
|
+
}
|
|
18194
|
+
);
|
|
18195
|
+
}
|
|
18058
18196
|
function PolygonIcon({ className, size = 20 }) {
|
|
18059
18197
|
return /* @__PURE__ */ jsx(
|
|
18060
18198
|
"svg",
|
|
@@ -18632,6 +18770,14 @@ var TEXT_PAINTER = {
|
|
|
18632
18770
|
);
|
|
18633
18771
|
if (boxes.length === 0) return null;
|
|
18634
18772
|
return rectsToPath(boxes);
|
|
18773
|
+
},
|
|
18774
|
+
// `filled` is unconditional: a text node's `data.fill: null` still resolves
|
|
18775
|
+
// to the default in `ResolvedRun`, so there is no outline-only text to
|
|
18776
|
+
// report. The reach is the point — a heavily outlined glyph was unpickable
|
|
18777
|
+
// across the width of its own outline.
|
|
18778
|
+
ink: (node, _pose, ctx) => {
|
|
18779
|
+
const d = node.data;
|
|
18780
|
+
return { filled: true, ...inkReach(resolveNodeStroke(d.stroke), ctx?.scale) };
|
|
18635
18781
|
}
|
|
18636
18782
|
};
|
|
18637
18783
|
function rectsToPath(rects) {
|
|
@@ -18897,10 +19043,10 @@ var RECT_FALLBACK_PAINTER = {
|
|
|
18897
19043
|
};
|
|
18898
19044
|
function registerBuiltInShapePainters() {
|
|
18899
19045
|
registerNodeShape(TEXT_PAINTER);
|
|
19046
|
+
registerNodeShape(DERIVED_PAINTER);
|
|
18900
19047
|
registerNodeShape(PATH_PAINTER);
|
|
18901
19048
|
registerNodeShape(SHAPE_PAINTER);
|
|
18902
19049
|
registerNodeShape(IMAGE_PAINTER);
|
|
18903
|
-
registerNodeShape(DERIVED_PAINTER);
|
|
18904
19050
|
registerNodeShape(RECT_FALLBACK_PAINTER);
|
|
18905
19051
|
}
|
|
18906
19052
|
registerBuiltInShapePainters();
|
|
@@ -19909,11 +20055,7 @@ function useRotateTool(adapter, options) {
|
|
|
19909
20055
|
[overlay]
|
|
19910
20056
|
);
|
|
19911
20057
|
}
|
|
19912
|
-
function useHandTool(
|
|
19913
|
-
const inertia = opts.inertia === false ? false : opts.inertia;
|
|
19914
|
-
const axis = opts.axis ?? "both";
|
|
19915
|
-
const tracker = useVelocityTracker();
|
|
19916
|
-
const decay = useDecayLoop();
|
|
20058
|
+
function useHandTool(_opts = {}) {
|
|
19917
20059
|
return useMemo(
|
|
19918
20060
|
() => Object.assign(defineViewportTool({
|
|
19919
20061
|
id: "hand",
|
|
@@ -19933,8 +20075,7 @@ function useHandTool(opts = {}) {
|
|
|
19933
20075
|
// phase entry.
|
|
19934
20076
|
bindings: [{ spec: { kind: "drag" }, actionId: "viewport.dragPan" }]
|
|
19935
20077
|
}),
|
|
19936
|
-
|
|
19937
|
-
[inertia, axis, tracker, decay]
|
|
20078
|
+
[]
|
|
19938
20079
|
);
|
|
19939
20080
|
}
|
|
19940
20081
|
var PRESENTATION = {
|
|
@@ -19963,7 +20104,7 @@ function usePinchZoomTool(canvasRef, getView, setView, opts = {}) {
|
|
|
19963
20104
|
getViewRef.current = getView;
|
|
19964
20105
|
const setViewRef = useRef(setView);
|
|
19965
20106
|
setViewRef.current = setView;
|
|
19966
|
-
const { min =
|
|
20107
|
+
const { min = DEFAULT_MIN_ZOOM, max = DEFAULT_MAX_ZOOM, enabled = true } = opts;
|
|
19967
20108
|
const resolveTargetRef = useRef(opts.resolveTarget);
|
|
19968
20109
|
resolveTargetRef.current = opts.resolveTarget;
|
|
19969
20110
|
usePinchGesture(canvasRef, (clientAnchor, scaleFactor) => {
|
|
@@ -21616,14 +21757,89 @@ function wrapNodeOutput(cmds, pose, alpha) {
|
|
|
21616
21757
|
}
|
|
21617
21758
|
return rotated;
|
|
21618
21759
|
}
|
|
21619
|
-
function
|
|
21760
|
+
function insetAlong(start, extent, size, align, by) {
|
|
21761
|
+
if (align === "start") return start + by;
|
|
21762
|
+
if (align === "end") return start + extent - size - by;
|
|
21763
|
+
return start + (extent - size) / 2 + by;
|
|
21764
|
+
}
|
|
21765
|
+
function hostAnchorRect(input) {
|
|
21766
|
+
const { host, panel, viewport, align, offset, padding = 0 } = input;
|
|
21767
|
+
const desired = {
|
|
21768
|
+
x: insetAlong(host.x, host.width, panel.width, align.x, offset.x),
|
|
21769
|
+
y: insetAlong(host.y, host.height, panel.height, align.y, offset.y),
|
|
21770
|
+
width: panel.width,
|
|
21771
|
+
height: panel.height
|
|
21772
|
+
};
|
|
21773
|
+
return clampRectWithin(desired, { x: 0, y: 0, width: viewport.width, height: viewport.height }, padding);
|
|
21774
|
+
}
|
|
21775
|
+
function hostAnchorCss(rect, align, viewport) {
|
|
21776
|
+
return {
|
|
21777
|
+
...align.y === "end" ? { bottom: viewport.height - rect.y - rect.height } : { top: rect.y },
|
|
21778
|
+
...align.x === "end" ? { right: viewport.width - rect.x - rect.width } : { left: rect.x }
|
|
21779
|
+
};
|
|
21780
|
+
}
|
|
21781
|
+
function useHostAnchor(resolveHost, options) {
|
|
21782
|
+
const [panel, setPanel] = useState(null);
|
|
21783
|
+
const [style, setStyle] = useState(null);
|
|
21784
|
+
const ref = useCallback((el) => setPanel(el), []);
|
|
21785
|
+
const resolve = useRef(resolveHost);
|
|
21786
|
+
resolve.current = resolveHost;
|
|
21787
|
+
const { align, offset, padding = 0 } = options;
|
|
21788
|
+
const { x: alignX, y: alignY } = align;
|
|
21789
|
+
const { x: offsetX, y: offsetY } = offset;
|
|
21790
|
+
const recompute = useCallback(() => {
|
|
21791
|
+
const hostEl = resolve.current();
|
|
21792
|
+
if (!hostEl) {
|
|
21793
|
+
setStyle(null);
|
|
21794
|
+
return;
|
|
21795
|
+
}
|
|
21796
|
+
const h = hostEl.getBoundingClientRect();
|
|
21797
|
+
const p = panel?.getBoundingClientRect();
|
|
21798
|
+
const viewport = { width: window.innerWidth, height: window.innerHeight };
|
|
21799
|
+
const align2 = { x: alignX, y: alignY };
|
|
21800
|
+
const rect = hostAnchorRect({
|
|
21801
|
+
host: { x: h.left, y: h.top, width: h.width, height: h.height },
|
|
21802
|
+
panel: { width: p?.width ?? 0, height: p?.height ?? 0 },
|
|
21803
|
+
viewport,
|
|
21804
|
+
align: align2,
|
|
21805
|
+
offset: { x: offsetX, y: offsetY },
|
|
21806
|
+
padding
|
|
21807
|
+
});
|
|
21808
|
+
setStyle(hostAnchorCss(rect, align2, viewport));
|
|
21809
|
+
}, [panel, alignX, alignY, offsetX, offsetY, padding]);
|
|
21810
|
+
const raf = useVisibleRaf(recompute);
|
|
21811
|
+
useEffect(() => {
|
|
21812
|
+
recompute();
|
|
21813
|
+
const schedule = () => raf.request();
|
|
21814
|
+
window.addEventListener("scroll", schedule, true);
|
|
21815
|
+
window.addEventListener("resize", schedule);
|
|
21816
|
+
const observer = typeof ResizeObserver !== "undefined" ? new ResizeObserver(schedule) : null;
|
|
21817
|
+
if (panel) observer?.observe(panel);
|
|
21818
|
+
const hostEl = resolve.current();
|
|
21819
|
+
if (hostEl) observer?.observe(hostEl);
|
|
21820
|
+
return () => {
|
|
21821
|
+
window.removeEventListener("scroll", schedule, true);
|
|
21822
|
+
window.removeEventListener("resize", schedule);
|
|
21823
|
+
raf.cancel();
|
|
21824
|
+
observer?.disconnect();
|
|
21825
|
+
};
|
|
21826
|
+
}, [recompute, raf, panel]);
|
|
21827
|
+
return { ref, style };
|
|
21828
|
+
}
|
|
21829
|
+
function CursorCoordsHud({ canvasRef, anchorRef, viewRef, offset }) {
|
|
21620
21830
|
const [state, setState] = useState({
|
|
21621
21831
|
client: { x: 0, y: 0 },
|
|
21622
21832
|
world: null,
|
|
21623
|
-
inCanvas: false
|
|
21624
|
-
anchor: null
|
|
21833
|
+
inCanvas: false
|
|
21625
21834
|
});
|
|
21626
21835
|
const [fps, setFps] = useState(0);
|
|
21836
|
+
const { ref, style: anchorStyle } = useHostAnchor(
|
|
21837
|
+
() => anchorRef?.current ?? canvasRef.current?.parentElement ?? canvasRef.current,
|
|
21838
|
+
{
|
|
21839
|
+
align: { x: "end", y: "start" },
|
|
21840
|
+
offset: { x: offset?.right ?? 8, y: offset?.top ?? 8 }
|
|
21841
|
+
}
|
|
21842
|
+
);
|
|
21627
21843
|
const framesRef = useRef(0);
|
|
21628
21844
|
const lastFlushRef = useRef(0);
|
|
21629
21845
|
const fpsLoop = useVisibleRaf(
|
|
@@ -21653,49 +21869,33 @@ function CursorCoordsHud({ canvasRef, viewRef, offset }) {
|
|
|
21653
21869
|
return () => fpsLoop.cancel();
|
|
21654
21870
|
}, [fpsLoop]);
|
|
21655
21871
|
useEffect(() => {
|
|
21656
|
-
const readAnchor = () => {
|
|
21657
|
-
const canvas = canvasRef.current;
|
|
21658
|
-
if (!canvas) return null;
|
|
21659
|
-
const host = canvas.parentElement ?? canvas;
|
|
21660
|
-
const rect = host.getBoundingClientRect();
|
|
21661
|
-
return { top: rect.top, right: window.innerWidth - rect.right };
|
|
21662
|
-
};
|
|
21663
21872
|
const onMove = (e) => {
|
|
21664
21873
|
const canvas = canvasRef.current;
|
|
21665
21874
|
const view = viewRef.current;
|
|
21666
21875
|
const client = { x: e.clientX, y: e.clientY };
|
|
21667
|
-
const anchor = readAnchor();
|
|
21668
21876
|
if (!canvas || !view) {
|
|
21669
|
-
setState({ client, world: null, inCanvas: false
|
|
21877
|
+
setState({ client, world: null, inCanvas: false });
|
|
21670
21878
|
return;
|
|
21671
21879
|
}
|
|
21672
21880
|
const rect = canvas.getBoundingClientRect();
|
|
21673
21881
|
const inCanvas = e.clientX >= rect.left && e.clientX <= rect.right && e.clientY >= rect.top && e.clientY <= rect.bottom;
|
|
21674
21882
|
const [wx, wy] = clientToWorld(e.clientX, e.clientY, rect, view);
|
|
21675
21883
|
const world = { x: wx, y: wy };
|
|
21676
|
-
setState({ client, world, inCanvas
|
|
21884
|
+
setState({ client, world, inCanvas });
|
|
21677
21885
|
};
|
|
21678
|
-
const onLayout = () => setState((s) => ({ ...s, anchor: readAnchor() }));
|
|
21679
21886
|
document.addEventListener("pointermove", onMove);
|
|
21680
|
-
window.addEventListener("scroll", onLayout, true);
|
|
21681
|
-
window.addEventListener("resize", onLayout);
|
|
21682
|
-
setState((s) => ({ ...s, anchor: readAnchor() }));
|
|
21683
21887
|
return () => {
|
|
21684
21888
|
document.removeEventListener("pointermove", onMove);
|
|
21685
|
-
window.removeEventListener("scroll", onLayout, true);
|
|
21686
|
-
window.removeEventListener("resize", onLayout);
|
|
21687
21889
|
};
|
|
21688
21890
|
}, [canvasRef, viewRef]);
|
|
21689
|
-
if (!
|
|
21690
|
-
const top = state.anchor.top + (offset?.top ?? 8);
|
|
21691
|
-
const right = state.anchor.right + (offset?.right ?? 8);
|
|
21891
|
+
if (!anchorStyle) return null;
|
|
21692
21892
|
return /* @__PURE__ */ jsxs(
|
|
21693
21893
|
"div",
|
|
21694
21894
|
{
|
|
21895
|
+
ref,
|
|
21695
21896
|
style: {
|
|
21696
21897
|
position: "fixed",
|
|
21697
|
-
|
|
21698
|
-
right,
|
|
21898
|
+
...anchorStyle,
|
|
21699
21899
|
zIndex: 1e4,
|
|
21700
21900
|
background: "rgba(0,0,0,0.7)",
|
|
21701
21901
|
color: "#e8e8e8",
|
|
@@ -21718,33 +21918,31 @@ function CursorCoordsHud({ canvasRef, viewRef, offset }) {
|
|
|
21718
21918
|
);
|
|
21719
21919
|
}
|
|
21720
21920
|
var PickHud_default = {};
|
|
21721
|
-
function PickHud({ canvasRef, viewRef, pickEvery, pickBest, offset }) {
|
|
21921
|
+
function PickHud({ canvasRef, anchorRef, viewRef, pickEvery, pickBest, offset }) {
|
|
21722
21922
|
const [state, setState] = useState({
|
|
21723
21923
|
ids: [],
|
|
21724
21924
|
best: null,
|
|
21725
|
-
inCanvas: false
|
|
21726
|
-
anchor: null
|
|
21925
|
+
inCanvas: false
|
|
21727
21926
|
});
|
|
21927
|
+
const { ref, style } = useHostAnchor(
|
|
21928
|
+
() => anchorRef?.current ?? canvasRef.current?.parentElement ?? canvasRef.current,
|
|
21929
|
+
{
|
|
21930
|
+
align: { x: "end", y: "start" },
|
|
21931
|
+
offset: { x: offset?.right ?? 8, y: offset?.top ?? 76 }
|
|
21932
|
+
}
|
|
21933
|
+
);
|
|
21728
21934
|
useEffect(() => {
|
|
21729
|
-
const readAnchor = () => {
|
|
21730
|
-
const canvas = canvasRef.current;
|
|
21731
|
-
if (!canvas) return null;
|
|
21732
|
-
const host = canvas.parentElement ?? canvas;
|
|
21733
|
-
const rect = host.getBoundingClientRect();
|
|
21734
|
-
return { top: rect.top, right: window.innerWidth - rect.right };
|
|
21735
|
-
};
|
|
21736
21935
|
const onMove = (e) => {
|
|
21737
21936
|
const canvas = canvasRef.current;
|
|
21738
21937
|
const view = viewRef.current;
|
|
21739
|
-
const anchor = readAnchor();
|
|
21740
21938
|
if (!canvas || !view) {
|
|
21741
|
-
setState({ ids: [], best: null, inCanvas: false
|
|
21939
|
+
setState({ ids: [], best: null, inCanvas: false });
|
|
21742
21940
|
return;
|
|
21743
21941
|
}
|
|
21744
21942
|
const rect = canvas.getBoundingClientRect();
|
|
21745
21943
|
const inCanvas = e.clientX >= rect.left && e.clientX <= rect.right && e.clientY >= rect.top && e.clientY <= rect.bottom;
|
|
21746
21944
|
if (!inCanvas) {
|
|
21747
|
-
setState({ ids: [], best: null, inCanvas: false
|
|
21945
|
+
setState({ ids: [], best: null, inCanvas: false });
|
|
21748
21946
|
return;
|
|
21749
21947
|
}
|
|
21750
21948
|
const worldX = (e.clientX - rect.left) / view.scale.x + view.x;
|
|
@@ -21763,24 +21961,15 @@ function PickHud({ canvasRef, viewRef, pickEvery, pickBest, offset }) {
|
|
|
21763
21961
|
best = null;
|
|
21764
21962
|
}
|
|
21765
21963
|
}
|
|
21766
|
-
setState({ ids, best, inCanvas: true
|
|
21964
|
+
setState({ ids, best, inCanvas: true });
|
|
21767
21965
|
};
|
|
21768
|
-
const onLayout = () => setState((s) => ({ ...s, anchor: readAnchor() }));
|
|
21769
21966
|
document.addEventListener("pointermove", onMove);
|
|
21770
|
-
window.addEventListener("scroll", onLayout, true);
|
|
21771
|
-
window.addEventListener("resize", onLayout);
|
|
21772
|
-
setState((s) => ({ ...s, anchor: readAnchor() }));
|
|
21773
21967
|
return () => {
|
|
21774
21968
|
document.removeEventListener("pointermove", onMove);
|
|
21775
|
-
window.removeEventListener("scroll", onLayout, true);
|
|
21776
|
-
window.removeEventListener("resize", onLayout);
|
|
21777
21969
|
};
|
|
21778
21970
|
}, [canvasRef, viewRef, pickEvery, pickBest]);
|
|
21779
|
-
if (!
|
|
21780
|
-
|
|
21781
|
-
const right = state.anchor.right + (offset?.right ?? 8);
|
|
21782
|
-
const style = { top, right };
|
|
21783
|
-
return /* @__PURE__ */ jsxs("div", { className: PickHud_default.hud, style, children: [
|
|
21971
|
+
if (!style) return null;
|
|
21972
|
+
return /* @__PURE__ */ jsxs("div", { ref, className: PickHud_default.hud, style, children: [
|
|
21784
21973
|
/* @__PURE__ */ jsxs("div", { className: PickHud_default.header, children: [
|
|
21785
21974
|
"pickEvery (",
|
|
21786
21975
|
state.ids.length,
|
|
@@ -21797,34 +21986,20 @@ function PickHud({ canvasRef, viewRef, pickEvery, pickBest, offset }) {
|
|
|
21797
21986
|
] });
|
|
21798
21987
|
}
|
|
21799
21988
|
var ModalityHud_default = {};
|
|
21800
|
-
function ModalityHud({ canvasRef, modeId, offset }) {
|
|
21989
|
+
function ModalityHud({ canvasRef, anchorRef, modeId, offset }) {
|
|
21801
21990
|
const toolCtx = useOptionalActiveToolContext();
|
|
21802
|
-
const
|
|
21803
|
-
|
|
21804
|
-
|
|
21805
|
-
|
|
21806
|
-
|
|
21807
|
-
|
|
21808
|
-
|
|
21809
|
-
|
|
21810
|
-
};
|
|
21811
|
-
const onLayout = () => setState({ anchor: readAnchor() });
|
|
21812
|
-
onLayout();
|
|
21813
|
-
window.addEventListener("scroll", onLayout, true);
|
|
21814
|
-
window.addEventListener("resize", onLayout);
|
|
21815
|
-
return () => {
|
|
21816
|
-
window.removeEventListener("scroll", onLayout, true);
|
|
21817
|
-
window.removeEventListener("resize", onLayout);
|
|
21818
|
-
};
|
|
21819
|
-
}, [canvasRef]);
|
|
21820
|
-
if (!state.anchor) return null;
|
|
21821
|
-
const top = state.anchor.top + (offset?.top ?? 220);
|
|
21822
|
-
const right = state.anchor.right + (offset?.right ?? 8);
|
|
21823
|
-
const style = { top, right };
|
|
21991
|
+
const { ref, style } = useHostAnchor(
|
|
21992
|
+
() => anchorRef?.current ?? canvasRef.current?.parentElement ?? canvasRef.current,
|
|
21993
|
+
{
|
|
21994
|
+
align: { x: "end", y: "start" },
|
|
21995
|
+
offset: { x: offset?.right ?? 8, y: offset?.top ?? 220 }
|
|
21996
|
+
}
|
|
21997
|
+
);
|
|
21998
|
+
if (!style) return null;
|
|
21824
21999
|
const active = toolCtx?.active ?? null;
|
|
21825
22000
|
const hotkeys = toolCtx?.hotkeyStack ?? [];
|
|
21826
22001
|
const hotkeyTop = hotkeys.length > 0 ? hotkeys[hotkeys.length - 1] : null;
|
|
21827
|
-
return /* @__PURE__ */ jsxs("div", { className: ModalityHud_default.hud, style, children: [
|
|
22002
|
+
return /* @__PURE__ */ jsxs("div", { ref, className: ModalityHud_default.hud, style, children: [
|
|
21828
22003
|
/* @__PURE__ */ jsxs("div", { className: ModalityHud_default.row, children: [
|
|
21829
22004
|
/* @__PURE__ */ jsx("span", { className: ModalityHud_default.label, children: "mode" }),
|
|
21830
22005
|
/* @__PURE__ */ jsx("span", { className: modeId ? ModalityHud_default.value : ModalityHud_default.valueMuted, children: modeId ?? "\u2014" })
|
|
@@ -21955,6 +22130,8 @@ function CanvasInner(props, ref) {
|
|
|
21955
22130
|
boundsOf: boundsOf2,
|
|
21956
22131
|
pickEvery,
|
|
21957
22132
|
clientToWorld: clientToWorld2,
|
|
22133
|
+
paintInto,
|
|
22134
|
+
inputElement,
|
|
21958
22135
|
geometry = AUTO_POSE_DESCRIPTOR,
|
|
21959
22136
|
className,
|
|
21960
22137
|
style,
|
|
@@ -22000,6 +22177,15 @@ function CanvasInner(props, ref) {
|
|
|
22000
22177
|
debugSinkRefForCtx.current = debugSink;
|
|
22001
22178
|
const adapter = adapterProp;
|
|
22002
22179
|
const canvasRef = useRef(null);
|
|
22180
|
+
const ownCanvasRef = useRef(null);
|
|
22181
|
+
const detached = !!paintInto;
|
|
22182
|
+
if (detached) {
|
|
22183
|
+
canvasRef.current = inputElement ?? null;
|
|
22184
|
+
}
|
|
22185
|
+
const paintTargetRef = useRef(null);
|
|
22186
|
+
paintTargetRef.current = detached ? paintInto.canvas ?? null : null;
|
|
22187
|
+
const paintRectRef = useRef(null);
|
|
22188
|
+
paintRectRef.current = detached ? { x: paintInto.x, y: paintInto.y } : null;
|
|
22003
22189
|
const helpersForLayersRef = useRef(null);
|
|
22004
22190
|
const dimsRef = useRef({ width, height });
|
|
22005
22191
|
dimsRef.current = { width, height };
|
|
@@ -22087,7 +22273,10 @@ function CanvasInner(props, ref) {
|
|
|
22087
22273
|
};
|
|
22088
22274
|
}, []);
|
|
22089
22275
|
useImperativeHandle(ref, () => ({
|
|
22090
|
-
|
|
22276
|
+
// Named rather than read off `canvasRef` so the handle rebuilds when a
|
|
22277
|
+
// detached surface's input element arrives, which is a render later.
|
|
22278
|
+
element: detached ? inputElement ?? null : canvasRef.current,
|
|
22279
|
+
surface: detached ? paintInto?.canvas ?? null : ownCanvasRef.current,
|
|
22091
22280
|
requestRedraw,
|
|
22092
22281
|
subscribeFrame,
|
|
22093
22282
|
registerLayer,
|
|
@@ -22098,6 +22287,10 @@ function CanvasInner(props, ref) {
|
|
|
22098
22287
|
getPaintedVersion
|
|
22099
22288
|
}), [
|
|
22100
22289
|
canvasRef,
|
|
22290
|
+
ownCanvasRef,
|
|
22291
|
+
detached,
|
|
22292
|
+
inputElement,
|
|
22293
|
+
paintInto?.canvas,
|
|
22101
22294
|
requestRedraw,
|
|
22102
22295
|
subscribeFrame,
|
|
22103
22296
|
registerLayer,
|
|
@@ -22393,8 +22586,9 @@ function CanvasInner(props, ref) {
|
|
|
22393
22586
|
shaders
|
|
22394
22587
|
};
|
|
22395
22588
|
const paint = useCallback(() => {
|
|
22396
|
-
const c =
|
|
22589
|
+
const c = paintTargetRef.current ?? ownCanvasRef.current;
|
|
22397
22590
|
if (!c) return false;
|
|
22591
|
+
const rect = paintRectRef.current;
|
|
22398
22592
|
const {
|
|
22399
22593
|
layers: paintLayers,
|
|
22400
22594
|
width: w,
|
|
@@ -22423,7 +22617,9 @@ function CanvasInner(props, ref) {
|
|
|
22423
22617
|
try {
|
|
22424
22618
|
renderer = new WeaselRenderer({
|
|
22425
22619
|
gl,
|
|
22426
|
-
|
|
22620
|
+
// A shared buffer is the caller's to size. Handing the renderer the
|
|
22621
|
+
// element would have every co-tenant resize it to its own pane.
|
|
22622
|
+
...rect ? {} : { canvas: c },
|
|
22427
22623
|
width: w,
|
|
22428
22624
|
height: h,
|
|
22429
22625
|
dpr
|
|
@@ -22442,6 +22638,7 @@ function CanvasInner(props, ref) {
|
|
|
22442
22638
|
lastResizeRef.current = { w, h, dpr };
|
|
22443
22639
|
}
|
|
22444
22640
|
}
|
|
22641
|
+
renderer.setTarget(rect ? { origin: { x: rect.x, y: rect.y } } : null);
|
|
22445
22642
|
const view = viewRef.current;
|
|
22446
22643
|
const commands = drawLayers(
|
|
22447
22644
|
paintLayers,
|
|
@@ -22490,31 +22687,69 @@ function CanvasInner(props, ref) {
|
|
|
22490
22687
|
}, [shaderIdKey]);
|
|
22491
22688
|
const toolsCursor = tools ? resolveToolsCursor(tools, toolsCtxBase) : void 0;
|
|
22492
22689
|
const effectiveStyle = toolsCursor ? { ...style, cursor: toolsCursor } : style;
|
|
22493
|
-
|
|
22494
|
-
|
|
22495
|
-
|
|
22690
|
+
const layersForMoveRef = useRef(layersWithDebug);
|
|
22691
|
+
layersForMoveRef.current = layersWithDebug;
|
|
22692
|
+
useEffect(() => {
|
|
22693
|
+
if (!detached || !inputElement) return;
|
|
22694
|
+
const el = inputElement;
|
|
22695
|
+
const onDown = () => {
|
|
22696
|
+
if (autoFocusOnPointerDown) el.focus();
|
|
22697
|
+
pointerDownRef.current = true;
|
|
22698
|
+
};
|
|
22699
|
+
const onMove = (e) => {
|
|
22700
|
+
if (pointerDownRef.current) return;
|
|
22701
|
+
const view = viewRef.current;
|
|
22702
|
+
const [worldX, worldY] = toWorld(
|
|
22703
|
+
el,
|
|
22704
|
+
e.clientX,
|
|
22705
|
+
e.clientY,
|
|
22706
|
+
view,
|
|
22707
|
+
clientToWorldRef.current
|
|
22708
|
+
);
|
|
22709
|
+
const dims = dimsRef.current;
|
|
22710
|
+
for (const layer of layersForMoveRef.current) {
|
|
22711
|
+
layer.onUncapturedMove?.(worldX, worldY, e, view, dims);
|
|
22712
|
+
}
|
|
22713
|
+
};
|
|
22714
|
+
const onUp = () => {
|
|
22715
|
+
pointerDownRef.current = false;
|
|
22716
|
+
};
|
|
22717
|
+
const onLeave = () => {
|
|
22718
|
+
pointerDownRef.current = false;
|
|
22719
|
+
for (const layer of layersForMoveRef.current) layer.onUncapturedLeave?.();
|
|
22720
|
+
};
|
|
22721
|
+
const onMenu = (e) => e.preventDefault();
|
|
22722
|
+
el.addEventListener("pointerdown", onDown);
|
|
22723
|
+
el.addEventListener("pointermove", onMove);
|
|
22724
|
+
el.addEventListener("pointerup", onUp);
|
|
22725
|
+
el.addEventListener("pointerleave", onLeave);
|
|
22726
|
+
el.addEventListener("contextmenu", onMenu);
|
|
22727
|
+
return () => {
|
|
22728
|
+
el.removeEventListener("pointerdown", onDown);
|
|
22729
|
+
el.removeEventListener("pointermove", onMove);
|
|
22730
|
+
el.removeEventListener("pointerup", onUp);
|
|
22731
|
+
el.removeEventListener("pointerleave", onLeave);
|
|
22732
|
+
el.removeEventListener("contextmenu", onMenu);
|
|
22733
|
+
};
|
|
22734
|
+
}, [detached, inputElement, autoFocusOnPointerDown]);
|
|
22735
|
+
useEffect(() => {
|
|
22736
|
+
if (!detached || !inputElement) return;
|
|
22737
|
+
inputElement.style.cursor = toolsCursor ?? "";
|
|
22738
|
+
}, [detached, inputElement, toolsCursor]);
|
|
22739
|
+
const huds = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
22740
|
+
cursorCoordsHud && /* @__PURE__ */ jsx(
|
|
22741
|
+
CursorCoordsHud,
|
|
22496
22742
|
{
|
|
22497
|
-
|
|
22498
|
-
|
|
22499
|
-
|
|
22500
|
-
tabIndex,
|
|
22501
|
-
className,
|
|
22502
|
-
style: effectiveStyle,
|
|
22503
|
-
onFocus,
|
|
22504
|
-
onBlur,
|
|
22505
|
-
onPointerDown: handlePointerDown,
|
|
22506
|
-
onPointerMove: handlePointerMove,
|
|
22507
|
-
onPointerUp: handlePointerUp,
|
|
22508
|
-
onPointerCancel: handlePointerCancel,
|
|
22509
|
-
onPointerLeave: handlePointerLeave,
|
|
22510
|
-
onContextMenu: (e) => e.preventDefault()
|
|
22743
|
+
canvasRef,
|
|
22744
|
+
...detached ? { anchorRef: canvasRef } : {},
|
|
22745
|
+
viewRef
|
|
22511
22746
|
}
|
|
22512
22747
|
),
|
|
22513
|
-
cursorCoordsHud && /* @__PURE__ */ jsx(CursorCoordsHud, { canvasRef, viewRef }),
|
|
22514
22748
|
pickHud && /* @__PURE__ */ jsx(
|
|
22515
22749
|
PickHud,
|
|
22516
22750
|
{
|
|
22517
22751
|
canvasRef,
|
|
22752
|
+
...detached ? { anchorRef: canvasRef } : {},
|
|
22518
22753
|
viewRef,
|
|
22519
22754
|
pickEvery: stablePickEveryForHud,
|
|
22520
22755
|
pickBest: stablePickBestForHud
|
|
@@ -22524,10 +22759,37 @@ function CanvasInner(props, ref) {
|
|
|
22524
22759
|
ModalityHud,
|
|
22525
22760
|
{
|
|
22526
22761
|
canvasRef,
|
|
22762
|
+
...detached ? { anchorRef: canvasRef } : {},
|
|
22527
22763
|
modeId: typeof modalityHud === "object" ? modalityHud.modeId : void 0
|
|
22528
22764
|
}
|
|
22529
22765
|
)
|
|
22530
22766
|
] });
|
|
22767
|
+
if (detached) return inputElement ? huds : null;
|
|
22768
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
22769
|
+
/* @__PURE__ */ jsx(
|
|
22770
|
+
"canvas",
|
|
22771
|
+
{
|
|
22772
|
+
ref: (el) => {
|
|
22773
|
+
ownCanvasRef.current = el;
|
|
22774
|
+
canvasRef.current = el;
|
|
22775
|
+
},
|
|
22776
|
+
width,
|
|
22777
|
+
height,
|
|
22778
|
+
tabIndex,
|
|
22779
|
+
className,
|
|
22780
|
+
style: effectiveStyle,
|
|
22781
|
+
onFocus,
|
|
22782
|
+
onBlur,
|
|
22783
|
+
onPointerDown: handlePointerDown,
|
|
22784
|
+
onPointerMove: handlePointerMove,
|
|
22785
|
+
onPointerUp: handlePointerUp,
|
|
22786
|
+
onPointerCancel: handlePointerCancel,
|
|
22787
|
+
onPointerLeave: handlePointerLeave,
|
|
22788
|
+
onContextMenu: (e) => e.preventDefault()
|
|
22789
|
+
}
|
|
22790
|
+
),
|
|
22791
|
+
huds
|
|
22792
|
+
] });
|
|
22531
22793
|
}
|
|
22532
22794
|
var Canvas = forwardRef(CanvasInner);
|
|
22533
22795
|
function composeAlphaFor(scene, alphaFor) {
|
|
@@ -23656,6 +23918,32 @@ function sceneFromJSON(json, options) {
|
|
|
23656
23918
|
});
|
|
23657
23919
|
}
|
|
23658
23920
|
var SelectionContext = createContext(null);
|
|
23921
|
+
function SelectionContextProvider({ children }) {
|
|
23922
|
+
const [state, setState] = useState({ selection: [], kinds: void 0 });
|
|
23923
|
+
const lastSerializedRef = useRef("");
|
|
23924
|
+
const publishSelection = useCallback((ids, kinds) => {
|
|
23925
|
+
const next = JSON.stringify([ids, kinds]);
|
|
23926
|
+
if (next === lastSerializedRef.current) return;
|
|
23927
|
+
lastSerializedRef.current = next;
|
|
23928
|
+
setState({ selection: ids, kinds });
|
|
23929
|
+
}, []);
|
|
23930
|
+
const value = useMemo(
|
|
23931
|
+
() => ({
|
|
23932
|
+
selection: state.selection,
|
|
23933
|
+
...state.kinds !== void 0 ? { kinds: state.kinds } : {},
|
|
23934
|
+
publishSelection
|
|
23935
|
+
}),
|
|
23936
|
+
[state, publishSelection]
|
|
23937
|
+
);
|
|
23938
|
+
return /* @__PURE__ */ jsx(SelectionContext.Provider, { value, children });
|
|
23939
|
+
}
|
|
23940
|
+
function SelectionContextProviderIfRoot({
|
|
23941
|
+
children
|
|
23942
|
+
}) {
|
|
23943
|
+
const parent = useContext(SelectionContext);
|
|
23944
|
+
if (parent !== null) return /* @__PURE__ */ jsx(Fragment, { children });
|
|
23945
|
+
return /* @__PURE__ */ jsx(SelectionContextProvider, { children });
|
|
23946
|
+
}
|
|
23659
23947
|
function usePublishSelection(ids, kinds) {
|
|
23660
23948
|
const ctx = useContext(SelectionContext);
|
|
23661
23949
|
const idsRef = useRef(ids);
|
|
@@ -25113,7 +25401,7 @@ function useDispatcherOverlayLayer(args) {
|
|
|
25113
25401
|
break;
|
|
25114
25402
|
case "pencil": {
|
|
25115
25403
|
if (geom.samples.length < 2) break;
|
|
25116
|
-
pathCmd =
|
|
25404
|
+
pathCmd = polylineFromPoints(projectPoints(geom.samples));
|
|
25117
25405
|
break;
|
|
25118
25406
|
}
|
|
25119
25407
|
}
|
|
@@ -25125,7 +25413,7 @@ function useDispatcherOverlayLayer(args) {
|
|
|
25125
25413
|
stroke: { paint: { color: cfg.stroke }, width: cfg.lineWidth, dash: cfg.dash }
|
|
25126
25414
|
};
|
|
25127
25415
|
out.push(cmd);
|
|
25128
|
-
if (ov.anchorPoint) {
|
|
25416
|
+
if (ov.anchorPoint && ov.shape !== "pencil") {
|
|
25129
25417
|
const anchorScreen = projectPoint(ov.anchorPoint.x, ov.anchorPoint.y);
|
|
25130
25418
|
out.push({
|
|
25131
25419
|
kind: "path",
|
|
@@ -26994,7 +27282,7 @@ function SceneCanvasInner(props, ref) {
|
|
|
26994
27282
|
boundary: inertiaObj.boundary,
|
|
26995
27283
|
bounds: inertiaObj.bounds
|
|
26996
27284
|
} : void 0;
|
|
26997
|
-
const handTool = useHandTool(handToolInertia ? {
|
|
27285
|
+
const handTool = useHandTool(handToolInertia ? {} : {});
|
|
26998
27286
|
const viewportAmbient = [];
|
|
26999
27287
|
const baseRequestedTools = defaultTools ?? (toolBundle ? BUNDLE_TOOLS[toolBundle] : null) ?? (viewportRegistered ? ["select", "rotate", "hand"] : ["select", "rotate"]);
|
|
27000
27288
|
const KNOWN_BUILTIN_IDS = /* @__PURE__ */ new Set([
|
|
@@ -27719,14 +28007,12 @@ function StandardActionsRegistrar({
|
|
|
27719
28007
|
}, [registry22, actionsRegistryRef]);
|
|
27720
28008
|
useEffect(() => {
|
|
27721
28009
|
if (!registry22) return;
|
|
27722
|
-
registry22.setDispatcher(dispatcher);
|
|
27723
|
-
return () => registry22.setDispatcher(null);
|
|
28010
|
+
return registry22.setDispatcher(dispatcher);
|
|
27724
28011
|
}, [registry22, dispatcher]);
|
|
27725
28012
|
const wiredDepRegistry = useDepRegistry();
|
|
27726
28013
|
useEffect(() => {
|
|
27727
28014
|
if (!registry22) return;
|
|
27728
|
-
registry22.setDepRegistry(wiredDepRegistry);
|
|
27729
|
-
return () => registry22.setDepRegistry(null);
|
|
28015
|
+
return registry22.setDepRegistry(wiredDepRegistry);
|
|
27730
28016
|
}, [registry22, wiredDepRegistry]);
|
|
27731
28017
|
useEffect(() => {
|
|
27732
28018
|
if (!registry22) return;
|
|
@@ -27787,7 +28073,7 @@ var SceneCanvasInnerForwardRef = forwardRef(SceneCanvasInner);
|
|
|
27787
28073
|
function SceneCanvasWrapper(props, ref) {
|
|
27788
28074
|
return /* @__PURE__ */ jsx(ActiveToolContextProviderIfRoot, { children: /* @__PURE__ */ jsx(ViewRegistryProvider, { children: /* @__PURE__ */ jsx(SceneCanvasInnerForwardRef, { ...props, ref }) }) });
|
|
27789
28075
|
}
|
|
27790
|
-
forwardRef(SceneCanvasWrapper);
|
|
28076
|
+
var SceneCanvas = forwardRef(SceneCanvasWrapper);
|
|
27791
28077
|
var RAD_TO_DEG = 180 / Math.PI;
|
|
27792
28078
|
var rotationDegreesUnit = {
|
|
27793
28079
|
toDisplay: (rad) => Math.round(rad * RAD_TO_DEG * 10) / 10,
|
|
@@ -27919,9 +28205,9 @@ function shapeSchema(opts = {}) {
|
|
|
27919
28205
|
fontWeight: { kind: "number", name: "Weight", description: "Font weight, 100\u2013900.", default: 400, min: 100, max: 900, step: 100, pair: "Size / weight" },
|
|
27920
28206
|
fontStyle: { kind: "enum", name: "Style", description: "Upright or italic.", default: "normal", options: [{ value: "normal", label: "Normal" }, { value: "italic", label: "Italic" }] },
|
|
27921
28207
|
letterSpacing: { kind: "number", name: "Tracking", description: "Extra advance per glyph, world units.", default: 0, step: 0.1 },
|
|
27922
|
-
underline: { kind: "boolean", name: "Underline", description: "Underline the text.", default: false },
|
|
27923
|
-
strikethrough: { kind: "boolean", name: "Strikethrough", description: "Strike through the text.", default: false },
|
|
27924
|
-
overline: { kind: "boolean", name: "Overline", description: "Rule the text above its ascent.", default: false }
|
|
28208
|
+
underline: { kind: "boolean", name: "Underline", description: "Underline the text.", default: false, control: "toggle", short: "U", pair: "Decoration" },
|
|
28209
|
+
strikethrough: { kind: "boolean", name: "Strikethrough", description: "Strike through the text.", default: false, control: "toggle", short: "S", pair: "Decoration" },
|
|
28210
|
+
overline: { kind: "boolean", name: "Overline", description: "Rule the text above its ascent.", default: false, control: "toggle", short: "O", pair: "Decoration" }
|
|
27925
28211
|
}
|
|
27926
28212
|
},
|
|
27927
28213
|
paragraph: {
|
|
@@ -28274,6 +28560,125 @@ function MinimapCanvasInner(props) {
|
|
|
28274
28560
|
);
|
|
28275
28561
|
}
|
|
28276
28562
|
var MinimapCanvas = MinimapCanvasInner;
|
|
28563
|
+
function planPixelRender(args) {
|
|
28564
|
+
const { sourceRect, scale: scale2 } = args;
|
|
28565
|
+
for (const [label, v] of [
|
|
28566
|
+
["sourceRect.width", sourceRect.width],
|
|
28567
|
+
["sourceRect.height", sourceRect.height],
|
|
28568
|
+
["scale.x", scale2.x],
|
|
28569
|
+
["scale.y", scale2.y]
|
|
28570
|
+
]) {
|
|
28571
|
+
if (!Number.isFinite(v) || v <= 0) {
|
|
28572
|
+
throw new Error(`renderSceneToPixels: ${label} must be a positive finite number, got ${v}`);
|
|
28573
|
+
}
|
|
28574
|
+
}
|
|
28575
|
+
for (const [label, v] of [
|
|
28576
|
+
["sourceRect.x", sourceRect.x],
|
|
28577
|
+
["sourceRect.y", sourceRect.y]
|
|
28578
|
+
]) {
|
|
28579
|
+
if (!Number.isFinite(v)) {
|
|
28580
|
+
throw new Error(`renderSceneToPixels: ${label} must be a finite number, got ${v}`);
|
|
28581
|
+
}
|
|
28582
|
+
}
|
|
28583
|
+
const width = Math.max(1, Math.round(sourceRect.width * scale2.x));
|
|
28584
|
+
const height = Math.max(1, Math.round(sourceRect.height * scale2.y));
|
|
28585
|
+
const view = { x: sourceRect.x, y: sourceRect.y, scale: { x: scale2.x, y: scale2.y } };
|
|
28586
|
+
const resolveImage = args.resolveImage;
|
|
28587
|
+
const drawOne = args.drawOne ?? ((node, pose, view2, ctx) => defaultDrawOne(node, pose, view2, { ...ctx, resolveImage }));
|
|
28588
|
+
const commands = [];
|
|
28589
|
+
if (args.background !== void 0) {
|
|
28590
|
+
commands.push({
|
|
28591
|
+
kind: "path",
|
|
28592
|
+
path: { kind: "rect", x: 0, y: 0, width, height },
|
|
28593
|
+
fill: { fill: "solid", color: args.background }
|
|
28594
|
+
});
|
|
28595
|
+
}
|
|
28596
|
+
commands.push(...buildSceneViewCommands(args.scene, view, drawOne, void 0, args.alphaFor));
|
|
28597
|
+
return { width, height, view, commands };
|
|
28598
|
+
}
|
|
28599
|
+
function defaultCreateCanvas(width, height) {
|
|
28600
|
+
if (typeof OffscreenCanvas !== "undefined") {
|
|
28601
|
+
return new OffscreenCanvas(width, height);
|
|
28602
|
+
}
|
|
28603
|
+
if (typeof document !== "undefined") {
|
|
28604
|
+
const c = document.createElement("canvas");
|
|
28605
|
+
c.width = width;
|
|
28606
|
+
c.height = height;
|
|
28607
|
+
return c;
|
|
28608
|
+
}
|
|
28609
|
+
throw new Error("renderSceneToPixels: no canvas source in this environment \u2014 supply `gl` or `createCanvas`");
|
|
28610
|
+
}
|
|
28611
|
+
function flipRows(raw, width, height) {
|
|
28612
|
+
const rowBytes = width * 4;
|
|
28613
|
+
const out = new Uint8ClampedArray(raw.length);
|
|
28614
|
+
for (let y = 0; y < height; y++) {
|
|
28615
|
+
out.set(raw.subarray((height - 1 - y) * rowBytes, (height - y) * rowBytes), y * rowBytes);
|
|
28616
|
+
}
|
|
28617
|
+
return out;
|
|
28618
|
+
}
|
|
28619
|
+
function unpremultiply(data) {
|
|
28620
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
28621
|
+
const a = data[i + 3];
|
|
28622
|
+
if (a === 0 || a === 255) continue;
|
|
28623
|
+
const inv = 255 / a;
|
|
28624
|
+
data[i] = data[i] * inv;
|
|
28625
|
+
data[i + 1] = data[i + 1] * inv;
|
|
28626
|
+
data[i + 2] = data[i + 2] * inv;
|
|
28627
|
+
}
|
|
28628
|
+
}
|
|
28629
|
+
function renderSceneToPixels(args) {
|
|
28630
|
+
if (args.gl && args.createCanvas) {
|
|
28631
|
+
throw new Error("renderSceneToPixels: `gl` and `createCanvas` are mutually exclusive");
|
|
28632
|
+
}
|
|
28633
|
+
const plan = planPixelRender(args);
|
|
28634
|
+
const { width, height } = plan;
|
|
28635
|
+
let gl = args.gl;
|
|
28636
|
+
if (!gl) {
|
|
28637
|
+
const canvas = (args.createCanvas ?? defaultCreateCanvas)(width, height);
|
|
28638
|
+
canvas.width = width;
|
|
28639
|
+
canvas.height = height;
|
|
28640
|
+
gl = canvas.getContext("webgl2", { preserveDrawingBuffer: true, stencil: true }) ?? void 0;
|
|
28641
|
+
}
|
|
28642
|
+
if (!gl || typeof gl.enable !== "function") {
|
|
28643
|
+
throw new Error("renderSceneToPixels: WebGL2 is unavailable \u2014 supply `gl` or a WebGL2-capable `createCanvas`");
|
|
28644
|
+
}
|
|
28645
|
+
if (typeof gl.isContextLost === "function" && gl.isContextLost()) {
|
|
28646
|
+
throw new Error("renderSceneToPixels: the supplied WebGL2 context is lost");
|
|
28647
|
+
}
|
|
28648
|
+
const flattenTolerancePx = args.flattenTolerancePx ?? 0.25;
|
|
28649
|
+
const renderer = new WeaselRenderer({
|
|
28650
|
+
gl,
|
|
28651
|
+
width,
|
|
28652
|
+
height,
|
|
28653
|
+
dpr: 1,
|
|
28654
|
+
imageMinification: "mipmap",
|
|
28655
|
+
flattenTolerance: flattenTolerancePx / Math.max(args.scale.x, args.scale.y),
|
|
28656
|
+
// Dynamic canvas-SDF glyphs must all bake inline — this path is
|
|
28657
|
+
// synchronous with no notify-and-redraw, and print must be complete.
|
|
28658
|
+
bakeBudget: Infinity
|
|
28659
|
+
});
|
|
28660
|
+
try {
|
|
28661
|
+
renderer.render(plan.commands, viewToMat3(plan.view));
|
|
28662
|
+
if (typeof gl.isContextLost === "function" && gl.isContextLost()) {
|
|
28663
|
+
throw new Error("renderSceneToPixels: WebGL2 context was lost during render");
|
|
28664
|
+
}
|
|
28665
|
+
const raw = new Uint8Array(width * height * 4);
|
|
28666
|
+
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, raw);
|
|
28667
|
+
const data = flipRows(raw, width, height);
|
|
28668
|
+
unpremultiply(data);
|
|
28669
|
+
return { width, height, data };
|
|
28670
|
+
} finally {
|
|
28671
|
+
renderer.dispose();
|
|
28672
|
+
}
|
|
28673
|
+
}
|
|
28674
|
+
function WeaselProvider({ children, isolate = false }) {
|
|
28675
|
+
const Deps = isolate ? DepRegistryProvider : DepRegistryProviderIfRoot;
|
|
28676
|
+
const Actions = isolate ? ActionsProvider : ActionsProviderIfRoot;
|
|
28677
|
+
const ActiveTool = isolate ? ActiveToolContextProvider : ActiveToolContextProviderIfRoot;
|
|
28678
|
+
const Selection = isolate ? SelectionContextProvider : SelectionContextProviderIfRoot;
|
|
28679
|
+
const Pointer = isolate ? PointerContextProvider : PointerProviderIfRoot;
|
|
28680
|
+
return /* @__PURE__ */ jsx(Deps, { children: /* @__PURE__ */ jsx(Actions, { children: /* @__PURE__ */ jsx(ActiveTool, { children: /* @__PURE__ */ jsx(Selection, { children: /* @__PURE__ */ jsx(Pointer, { children }) }) }) }) });
|
|
28681
|
+
}
|
|
28277
28682
|
function createSetTextOp(args) {
|
|
28278
28683
|
const { id, from, to, label, coalesceKey = `setText:${id}` } = args;
|
|
28279
28684
|
return {
|
|
@@ -28410,6 +28815,6 @@ function oklchToOklab(L, C, h) {
|
|
|
28410
28815
|
return [L, C * Math.cos(h), C * Math.sin(h)];
|
|
28411
28816
|
}
|
|
28412
28817
|
|
|
28413
|
-
export { FALLBACK_FIT_VIEW, MinimapCanvas, SceneViewCanvas, UnknownIcon, buildSceneViewCommands, computeFitView, computeIndicatorCommand, eligibleContribution, evaluateEnabled, isBuiltinToolPref, oklabToSrgbU8, oklchToOklab, renderSceneToCanvas, rgbaToHex, useActionsRegistry, useOptionalDepRegistry, useVisibleRaf };
|
|
28414
|
-
//# sourceMappingURL=chunk-
|
|
28415
|
-
//# sourceMappingURL=chunk-
|
|
28818
|
+
export { ArrowIcon, EllipseIcon, FALLBACK_FIT_VIEW, LineIcon, MinimapCanvas, PATH_C, PATH_L, PATH_M, PATH_Q, PATH_Z, PathBuilder, PencilIcon, RectIcon, SCRIPT_METRICS, SceneCanvas, SceneViewCanvas, SelectIcon, TextIcon, UnknownIcon, WeaselProvider, asNodeId, boundsOfPath, buildSceneViewCommands, computeFitView, computeIndicatorCommand, createScene, eligibleContribution, ellipsePath, evaluateEnabled, getMarker, getPaintKind, isBuiltinToolPref, linePath, markerDrawCommands, oklabToSrgbU8, oklchToOklab, rectPath, renderSceneToCanvas, renderSceneToPixels, resolveStrokeWidth, rgbaToHex, sceneFromJSON, textCommand, tileGeometry, useActionsRegistry, useActiveToolContext, useOptionalDepRegistry, useVisibleRaf };
|
|
28819
|
+
//# sourceMappingURL=chunk-ROQDRXKW.js.map
|
|
28820
|
+
//# sourceMappingURL=chunk-ROQDRXKW.js.map
|