@weasel-js/labkit 1.3.0 → 1.4.0-pre.1
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/README.md +226 -55
- package/dist/_dts/CanvasStackContext-LnCfqNBA.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-C-2c72Ij.d.ts +735 -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 +110 -26
- 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-6OEYTYML.js +669 -0
- package/dist/chunk-6OEYTYML.js.map +1 -0
- package/dist/{chunk-BMW4TDP5.js → chunk-AE5CNVRU.js} +3 -3
- package/dist/{chunk-BMW4TDP5.js.map → chunk-AE5CNVRU.js.map} +1 -1
- 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-E2UQVZ44.js +458 -0
- package/dist/chunk-E2UQVZ44.js.map +1 -0
- package/dist/{chunk-LGKRIUSW.js → chunk-ESIQNQ6K.js} +32 -7
- package/dist/chunk-ESIQNQ6K.js.map +1 -0
- package/dist/{chunk-JDROYQM3.js → chunk-HHGVISVZ.js} +130 -131
- package/dist/chunk-HHGVISVZ.js.map +1 -0
- package/dist/{chunk-BDJXIBRZ.js → chunk-HMFODCOX.js} +126 -29
- package/dist/chunk-HMFODCOX.js.map +1 -0
- package/dist/{chunk-QCICIHEO.js → chunk-L5QJOOLV.js} +839 -320
- package/dist/chunk-L5QJOOLV.js.map +1 -0
- package/dist/{chunk-3XXPU73K.js → chunk-M75ZU6ZZ.js} +9 -7
- package/dist/chunk-M75ZU6ZZ.js.map +1 -0
- package/dist/{chunk-QRYPXSGP.js → chunk-QB5SM4BM.js} +16 -8
- package/dist/chunk-QB5SM4BM.js.map +1 -0
- package/dist/chunk-RBGKL7NF.js +7128 -0
- package/dist/chunk-RBGKL7NF.js.map +1 -0
- package/dist/{chunk-WTI26YTM.js → chunk-TO2FUOKF.js} +40 -13
- package/dist/chunk-TO2FUOKF.js.map +1 -0
- package/dist/{chunk-4TMMVIDM.js → chunk-XJ6N32QP.js} +50 -6
- package/dist/chunk-XJ6N32QP.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 +517 -234
- package/dist/index.js +1769 -143
- 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 +247 -0
- package/src/annotations/store.ts +347 -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 +229 -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 +16 -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 +23 -0
- package/src/index.ts +93 -4
- 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 {
|
|
@@ -3802,6 +3841,120 @@ function eligibleContribution(reg, entry) {
|
|
|
3802
3841
|
return eligibleForMode(reg.current(), entry.eligibility?.capabilities ?? []);
|
|
3803
3842
|
}
|
|
3804
3843
|
|
|
3844
|
+
// ../cursor/dist/index.js
|
|
3845
|
+
var CURSOR_INK = "#141418";
|
|
3846
|
+
var CURSOR_HALO = "#ffffff";
|
|
3847
|
+
var CURSOR_HALO_WIDTH = 2.6;
|
|
3848
|
+
var CURSOR_MAX_CSS_PX = 128;
|
|
3849
|
+
function renderHalo(p) {
|
|
3850
|
+
switch (p.role) {
|
|
3851
|
+
case "ink":
|
|
3852
|
+
case "accent":
|
|
3853
|
+
return `<path d="${p.d}" fill="${CURSOR_HALO}" stroke="${CURSOR_HALO}" stroke-width="${CURSOR_HALO_WIDTH}" stroke-linejoin="round"/>`;
|
|
3854
|
+
case "stroke":
|
|
3855
|
+
return `<path d="${p.d}" fill="none" stroke="${CURSOR_HALO}" stroke-width="${p.width + CURSOR_HALO_WIDTH}" stroke-linecap="round" stroke-linejoin="round"/>`;
|
|
3856
|
+
// A detail IS halo-coloured and sits on top of the ink; it has no halo.
|
|
3857
|
+
case "detail":
|
|
3858
|
+
return "";
|
|
3859
|
+
}
|
|
3860
|
+
}
|
|
3861
|
+
function renderInk(p) {
|
|
3862
|
+
switch (p.role) {
|
|
3863
|
+
case "ink":
|
|
3864
|
+
return `<path d="${p.d}" fill="${CURSOR_INK}"/>`;
|
|
3865
|
+
case "stroke":
|
|
3866
|
+
return `<path d="${p.d}" fill="none" stroke="${CURSOR_INK}" stroke-width="${p.width}" stroke-linecap="round" stroke-linejoin="round"/>`;
|
|
3867
|
+
case "detail":
|
|
3868
|
+
return `<path d="${p.d}" fill="none" stroke="${CURSOR_HALO}" stroke-width="${p.width}" stroke-linecap="round"/>`;
|
|
3869
|
+
case "accent":
|
|
3870
|
+
return `<path d="${p.d}" fill="${p.fill}"/>`;
|
|
3871
|
+
}
|
|
3872
|
+
}
|
|
3873
|
+
function bakeCursor(glyph, opts = {}) {
|
|
3874
|
+
const size = opts.size ?? 24;
|
|
3875
|
+
if (size > CURSOR_MAX_CSS_PX) {
|
|
3876
|
+
throw new RangeError(
|
|
3877
|
+
`cursor size ${size} exceeds the ${CURSOR_MAX_CSS_PX}px cap: the browser would drop the image and silently fall back. Use the painted tier.`
|
|
3878
|
+
);
|
|
3879
|
+
}
|
|
3880
|
+
const body = glyph.paths.map(renderHalo).join("") + glyph.paths.map(renderInk).join("");
|
|
3881
|
+
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${glyph.box} ${glyph.box}">${body}</svg>`;
|
|
3882
|
+
const hx = Math.round(glyph.hotspot[0] / glyph.box * size);
|
|
3883
|
+
const hy = Math.round(glyph.hotspot[1] / glyph.box * size);
|
|
3884
|
+
const uri = `data:image/svg+xml,${encodeURIComponent(svg)}`;
|
|
3885
|
+
return `url("${uri}") ${hx} ${hy}, ${opts.fallback ?? "default"}`;
|
|
3886
|
+
}
|
|
3887
|
+
var GLYPHS = {
|
|
3888
|
+
"pencil": {
|
|
3889
|
+
"box": 24,
|
|
3890
|
+
"hotspot": [
|
|
3891
|
+
5,
|
|
3892
|
+
19
|
|
3893
|
+
],
|
|
3894
|
+
"paths": [
|
|
3895
|
+
{
|
|
3896
|
+
"role": "ink",
|
|
3897
|
+
"d": "M 5 19 L 7.5 16.5 L 16 8 L 19 11 L 10.5 19.5 L 8 19 Z"
|
|
3898
|
+
},
|
|
3899
|
+
{
|
|
3900
|
+
"role": "detail",
|
|
3901
|
+
"d": "M 14 6 L 19 11",
|
|
3902
|
+
"width": 1.2
|
|
3903
|
+
}
|
|
3904
|
+
]
|
|
3905
|
+
},
|
|
3906
|
+
"pen": {
|
|
3907
|
+
"box": 24,
|
|
3908
|
+
"hotspot": [
|
|
3909
|
+
5,
|
|
3910
|
+
19
|
|
3911
|
+
],
|
|
3912
|
+
"paths": [
|
|
3913
|
+
{
|
|
3914
|
+
"role": "ink",
|
|
3915
|
+
"d": "M 5 19 L 8.5 9.5 L 13 5 L 18 10 L 13.5 14.5 Z"
|
|
3916
|
+
},
|
|
3917
|
+
{
|
|
3918
|
+
"role": "detail",
|
|
3919
|
+
"d": "M 8.4 13.9 L 12.2 10.1",
|
|
3920
|
+
"width": 0.9
|
|
3921
|
+
}
|
|
3922
|
+
]
|
|
3923
|
+
},
|
|
3924
|
+
"eyedropper": {
|
|
3925
|
+
"box": 24,
|
|
3926
|
+
"hotspot": [
|
|
3927
|
+
5,
|
|
3928
|
+
19
|
|
3929
|
+
],
|
|
3930
|
+
"paths": [
|
|
3931
|
+
{
|
|
3932
|
+
"role": "ink",
|
|
3933
|
+
"d": "M 5 19 L 6.8 14.8 L 14.4 7.2 L 16.8 9.6 L 9.2 17.2 Z"
|
|
3934
|
+
},
|
|
3935
|
+
{
|
|
3936
|
+
"role": "ink",
|
|
3937
|
+
"d": "M 18.2 2.6 A 3.2 3.2 0 1 0 18.2 9 A 3.2 3.2 0 1 0 18.2 2.6 Z"
|
|
3938
|
+
}
|
|
3939
|
+
]
|
|
3940
|
+
}
|
|
3941
|
+
};
|
|
3942
|
+
var cache2 = /* @__PURE__ */ new Map();
|
|
3943
|
+
function cursorFor(name, opts = {}) {
|
|
3944
|
+
const size = opts.size ?? 24;
|
|
3945
|
+
const fallback = opts.fallback ?? "default";
|
|
3946
|
+
const key = `${name}|${size}|${fallback}`;
|
|
3947
|
+
const hit = cache2.get(key);
|
|
3948
|
+
if (hit !== void 0) return hit;
|
|
3949
|
+
const glyph = GLYPHS[name];
|
|
3950
|
+
if (glyph === void 0) {
|
|
3951
|
+
throw new Error(`unknown cursor glyph: ${String(name)}`);
|
|
3952
|
+
}
|
|
3953
|
+
const css = bakeCursor(glyph, { size, fallback });
|
|
3954
|
+
cache2.set(key, css);
|
|
3955
|
+
return css;
|
|
3956
|
+
}
|
|
3957
|
+
|
|
3805
3958
|
// ../history/dist/index.js
|
|
3806
3959
|
var RESUMERS = /* @__PURE__ */ new WeakMap();
|
|
3807
3960
|
function _resumeJournalInternal(j) {
|
|
@@ -4224,7 +4377,7 @@ function serialToEntry(se, custom, logger) {
|
|
|
4224
4377
|
};
|
|
4225
4378
|
}
|
|
4226
4379
|
|
|
4227
|
-
// ../core/dist/chunk-
|
|
4380
|
+
// ../core/dist/chunk-FUQWXDG3.js
|
|
4228
4381
|
function worldToScreen(worldX, worldY, view) {
|
|
4229
4382
|
return [view.panX + worldX * view.zoom.x, view.panY + worldY * view.zoom.y];
|
|
4230
4383
|
}
|
|
@@ -5551,6 +5704,9 @@ function flattenPolygon(p, tolerance) {
|
|
|
5551
5704
|
let coordIdx = 0;
|
|
5552
5705
|
let prevX = 0;
|
|
5553
5706
|
let prevY = 0;
|
|
5707
|
+
let startX = 0;
|
|
5708
|
+
let startY = 0;
|
|
5709
|
+
let startAnchor = -1;
|
|
5554
5710
|
let prevAnchor = -1;
|
|
5555
5711
|
let anchorCounter = 0;
|
|
5556
5712
|
for (let cmdIdx = 0; cmdIdx < commands.length; cmdIdx++) {
|
|
@@ -5560,6 +5716,9 @@ function flattenPolygon(p, tolerance) {
|
|
|
5560
5716
|
contourStarts.push(out.length / 2);
|
|
5561
5717
|
prevX = coords[coordIdx];
|
|
5562
5718
|
prevY = coords[coordIdx + 1];
|
|
5719
|
+
startX = prevX;
|
|
5720
|
+
startY = prevY;
|
|
5721
|
+
startAnchor = anchorCounter;
|
|
5563
5722
|
out.push(prevX, prevY);
|
|
5564
5723
|
anchorA.push(anchorCounter);
|
|
5565
5724
|
anchorB.push(anchorCounter);
|
|
@@ -5629,6 +5788,9 @@ function flattenPolygon(p, tolerance) {
|
|
|
5629
5788
|
break;
|
|
5630
5789
|
}
|
|
5631
5790
|
case PATH_Z: {
|
|
5791
|
+
prevX = startX;
|
|
5792
|
+
prevY = startY;
|
|
5793
|
+
prevAnchor = startAnchor;
|
|
5632
5794
|
break;
|
|
5633
5795
|
}
|
|
5634
5796
|
default:
|
|
@@ -5773,12 +5935,12 @@ function pointInContour(coords, start, end, x, y) {
|
|
|
5773
5935
|
}
|
|
5774
5936
|
return inside;
|
|
5775
5937
|
}
|
|
5776
|
-
var
|
|
5938
|
+
var cache3 = /* @__PURE__ */ new WeakMap();
|
|
5777
5939
|
function getMesh(path) {
|
|
5778
|
-
const cached2 =
|
|
5940
|
+
const cached2 = cache3.get(path);
|
|
5779
5941
|
if (cached2 !== void 0) return cached2;
|
|
5780
5942
|
const mesh = tessellate(path);
|
|
5781
|
-
|
|
5943
|
+
cache3.set(path, mesh);
|
|
5782
5944
|
return mesh;
|
|
5783
5945
|
}
|
|
5784
5946
|
function extractPolylines(path, opts = {}) {
|
|
@@ -6798,7 +6960,7 @@ function outlineMesh(key, d) {
|
|
|
6798
6960
|
}
|
|
6799
6961
|
var OUTLINE_STROKE_MESH_CACHE_LIMIT = 2048;
|
|
6800
6962
|
var WIDTH_QUANTUM = 1 / 1024;
|
|
6801
|
-
var
|
|
6963
|
+
var cache32 = /* @__PURE__ */ new Map();
|
|
6802
6964
|
function quantizeEmWidth(emWidth) {
|
|
6803
6965
|
return Math.round(emWidth / WIDTH_QUANTUM) * WIDTH_QUANTUM;
|
|
6804
6966
|
}
|
|
@@ -6813,15 +6975,15 @@ function outlineStrokeMesh(glyphKey, d, emWidth, stroke) {
|
|
|
6813
6975
|
stroke.align ?? "center",
|
|
6814
6976
|
(stroke.dash ?? []).join(",")
|
|
6815
6977
|
].join("|");
|
|
6816
|
-
const cached2 =
|
|
6978
|
+
const cached2 = cache32.get(key);
|
|
6817
6979
|
if (cached2 !== void 0) return cached2.indices.length === 0 ? null : cached2;
|
|
6818
|
-
if (
|
|
6980
|
+
if (cache32.size >= OUTLINE_STROKE_MESH_CACHE_LIMIT) cache32 = /* @__PURE__ */ new Map();
|
|
6819
6981
|
const mesh = tessellateStroke(
|
|
6820
6982
|
pathFromD(d),
|
|
6821
6983
|
{ ...stroke, width: emWidth },
|
|
6822
6984
|
{ flattenTolerance: OUTLINE_FLATTEN_TOLERANCE }
|
|
6823
6985
|
);
|
|
6824
|
-
|
|
6986
|
+
cache32.set(key, mesh);
|
|
6825
6987
|
return mesh.indices.length === 0 ? null : mesh;
|
|
6826
6988
|
}
|
|
6827
6989
|
function poly(pts, size, close = true) {
|
|
@@ -8444,6 +8606,7 @@ var WeaselRenderer = class {
|
|
|
8444
8606
|
heightCss;
|
|
8445
8607
|
dpr;
|
|
8446
8608
|
canvas = null;
|
|
8609
|
+
target = null;
|
|
8447
8610
|
imageMinification;
|
|
8448
8611
|
flattenTolerance;
|
|
8449
8612
|
bakeBudget;
|
|
@@ -8461,6 +8624,12 @@ var WeaselRenderer = class {
|
|
|
8461
8624
|
const gl = opts.gl ?? opts.canvas.getContext("webgl2", { stencil: true });
|
|
8462
8625
|
if (!gl) throw new Error("WeaselRenderer: WebGL2 not available");
|
|
8463
8626
|
this.gl = gl;
|
|
8627
|
+
const attrs = typeof this.gl.getContextAttributes === "function" ? this.gl.getContextAttributes() : null;
|
|
8628
|
+
if (attrs && attrs.stencil === false) {
|
|
8629
|
+
throw new Error(
|
|
8630
|
+
"WeaselRenderer: the supplied WebGL2 context has no stencil buffer. Create it with { stencil: true } \u2014 clips and even-odd fills need one."
|
|
8631
|
+
);
|
|
8632
|
+
}
|
|
8464
8633
|
this.widthCss = opts.width;
|
|
8465
8634
|
this.heightCss = opts.height;
|
|
8466
8635
|
this.dpr = opts.dpr;
|
|
@@ -8479,12 +8648,8 @@ var WeaselRenderer = class {
|
|
|
8479
8648
|
this.canvas.addEventListener("webglcontextlost", this.boundOnLost);
|
|
8480
8649
|
this.canvas.addEventListener("webglcontextrestored", this.boundOnRestored);
|
|
8481
8650
|
}
|
|
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();
|
|
8651
|
+
this.applyGlState();
|
|
8652
|
+
this.applyTarget();
|
|
8488
8653
|
this.pathFill = new ShaderProgram(this.gl, VERT_SRC, FRAG_SRC);
|
|
8489
8654
|
this.pathFill.lookupUniforms(PATH_FILL_UNIFORMS);
|
|
8490
8655
|
this.pathFill.lookupAttributes(PATH_FILL_ATTRIBUTES);
|
|
@@ -8574,8 +8739,42 @@ var WeaselRenderer = class {
|
|
|
8574
8739
|
}
|
|
8575
8740
|
return this.programRegistry.get(id) ?? null;
|
|
8576
8741
|
}
|
|
8577
|
-
|
|
8578
|
-
|
|
8742
|
+
/** The GL state every frame assumes. Applied per `render()` rather than once
|
|
8743
|
+
* at construction because a co-tenant sharing this context moves all of it
|
|
8744
|
+
* between our frames. */
|
|
8745
|
+
applyGlState() {
|
|
8746
|
+
const gl = this.gl;
|
|
8747
|
+
gl.enable(gl.BLEND);
|
|
8748
|
+
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
|
8749
|
+
gl.disable(gl.DEPTH_TEST);
|
|
8750
|
+
gl.disable(gl.CULL_FACE);
|
|
8751
|
+
gl.clearColor(0, 0, 0, 0);
|
|
8752
|
+
}
|
|
8753
|
+
/** Viewport and scissor for this frame. Re-applied inside `render()` because
|
|
8754
|
+
* a co-tenant on the same context moves both between our frames. */
|
|
8755
|
+
applyTarget() {
|
|
8756
|
+
const gl = this.gl;
|
|
8757
|
+
const w = Math.round(this.widthCss * this.dpr);
|
|
8758
|
+
const h = Math.round(this.heightCss * this.dpr);
|
|
8759
|
+
if (!this.target) {
|
|
8760
|
+
gl.disable(gl.SCISSOR_TEST);
|
|
8761
|
+
gl.viewport(0, 0, w, h);
|
|
8762
|
+
return;
|
|
8763
|
+
}
|
|
8764
|
+
const x = Math.round(this.target.origin.x * this.dpr);
|
|
8765
|
+
const y = gl.drawingBufferHeight - Math.round(this.target.origin.y * this.dpr) - h;
|
|
8766
|
+
gl.viewport(x, y, w, h);
|
|
8767
|
+
gl.scissor(x, y, w, h);
|
|
8768
|
+
gl.enable(gl.SCISSOR_TEST);
|
|
8769
|
+
}
|
|
8770
|
+
/** Confine this renderer to a rect of its drawing buffer, or pass null to
|
|
8771
|
+
* give it the whole buffer back. Takes effect from the next `render()`. */
|
|
8772
|
+
setTarget(target) {
|
|
8773
|
+
this.target = target;
|
|
8774
|
+
this.applyTarget();
|
|
8775
|
+
}
|
|
8776
|
+
getTarget() {
|
|
8777
|
+
return this.target;
|
|
8579
8778
|
}
|
|
8580
8779
|
isContextLost() {
|
|
8581
8780
|
return this.contextLost;
|
|
@@ -8586,12 +8785,8 @@ var WeaselRenderer = class {
|
|
|
8586
8785
|
}
|
|
8587
8786
|
onContextRestored() {
|
|
8588
8787
|
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();
|
|
8788
|
+
this.applyGlState();
|
|
8789
|
+
this.applyTarget();
|
|
8595
8790
|
this.pathFill = new ShaderProgram(this.gl, VERT_SRC, FRAG_SRC);
|
|
8596
8791
|
this.pathFill.lookupUniforms(PATH_FILL_UNIFORMS);
|
|
8597
8792
|
this.pathFill.lookupAttributes(PATH_FILL_ATTRIBUTES);
|
|
@@ -8698,8 +8893,12 @@ var WeaselRenderer = class {
|
|
|
8698
8893
|
this.meshCache.drainPendingDeletes();
|
|
8699
8894
|
resetBakeBudget(this.bakeBudget);
|
|
8700
8895
|
this.groupState.reset();
|
|
8701
|
-
|
|
8702
|
-
|
|
8896
|
+
this.applyGlState();
|
|
8897
|
+
this.applyTarget();
|
|
8898
|
+
if (this.target?.clear !== false) {
|
|
8899
|
+
gl.stencilMask(255);
|
|
8900
|
+
gl.clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
|
8901
|
+
}
|
|
8703
8902
|
const ctx = {
|
|
8704
8903
|
gl,
|
|
8705
8904
|
pathFill: this.pathFill,
|
|
@@ -8742,7 +8941,7 @@ var WeaselRenderer = class {
|
|
|
8742
8941
|
this.canvas.style.height = `${dims.height}px`;
|
|
8743
8942
|
}
|
|
8744
8943
|
}
|
|
8745
|
-
this.
|
|
8944
|
+
this.applyTarget();
|
|
8746
8945
|
}
|
|
8747
8946
|
/** @internal */
|
|
8748
8947
|
_gl() {
|
|
@@ -9382,10 +9581,10 @@ function targetSizesPx(targetScale = 1) {
|
|
|
9382
9581
|
rotationDistance: BASE_PX.rotationDistance * targetScale
|
|
9383
9582
|
};
|
|
9384
9583
|
}
|
|
9385
|
-
var
|
|
9386
|
-
var
|
|
9584
|
+
var DEFAULT_MIN_ZOOM = 0.1;
|
|
9585
|
+
var DEFAULT_MAX_ZOOM = 8;
|
|
9387
9586
|
function fitViewToBounds(bounds, viewportDims, currentView, opts = {}) {
|
|
9388
|
-
const { padding = 16, maxScale =
|
|
9587
|
+
const { padding = 16, maxScale = DEFAULT_MAX_ZOOM, minScale = DEFAULT_MIN_ZOOM } = opts;
|
|
9389
9588
|
if (bounds.width <= 0 || bounds.height <= 0) {
|
|
9390
9589
|
console.warn("[weasel] fitViewToBounds: bounds has zero or negative area; returning currentView unchanged.", bounds);
|
|
9391
9590
|
return currentView;
|
|
@@ -9429,15 +9628,19 @@ function fitViewToBounds(bounds, viewportDims, currentView, opts = {}) {
|
|
|
9429
9628
|
scale: { x: scaleX, y: scaleY }
|
|
9430
9629
|
};
|
|
9431
9630
|
}
|
|
9631
|
+
function clampScale(scale2, min, max) {
|
|
9632
|
+
const magnitude = Math.min(max, Math.max(min, Math.abs(scale2)));
|
|
9633
|
+
return scale2 < 0 ? -magnitude : magnitude;
|
|
9634
|
+
}
|
|
9432
9635
|
function zoomAt(view, anchor, factor, opts) {
|
|
9433
9636
|
const fx = typeof factor === "number" ? factor : factor.x;
|
|
9434
9637
|
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 =
|
|
9638
|
+
const minX = typeof opts?.min === "number" ? opts.min : opts?.min?.x ?? DEFAULT_MIN_ZOOM;
|
|
9639
|
+
const minY = typeof opts?.min === "number" ? opts.min : opts?.min?.y ?? DEFAULT_MIN_ZOOM;
|
|
9640
|
+
const maxX = typeof opts?.max === "number" ? opts.max : opts?.max?.x ?? DEFAULT_MAX_ZOOM;
|
|
9641
|
+
const maxY = typeof opts?.max === "number" ? opts.max : opts?.max?.y ?? DEFAULT_MAX_ZOOM;
|
|
9642
|
+
const nextX = clampScale(view.scale.x * fx, minX, maxX);
|
|
9643
|
+
const nextY = clampScale(view.scale.y * fy, minY, maxY);
|
|
9441
9644
|
const worldX = anchor.x / view.scale.x + view.x;
|
|
9442
9645
|
const worldY = anchor.y / view.scale.y + view.y;
|
|
9443
9646
|
return {
|
|
@@ -9447,22 +9650,24 @@ function zoomAt(view, anchor, factor, opts) {
|
|
|
9447
9650
|
};
|
|
9448
9651
|
}
|
|
9449
9652
|
function clampView(view, bounds, canvas) {
|
|
9450
|
-
const visW = canvas.width / view.scale.x;
|
|
9451
|
-
const visH = canvas.height / view.scale.y;
|
|
9653
|
+
const visW = Math.abs(canvas.width / view.scale.x);
|
|
9654
|
+
const visH = Math.abs(canvas.height / view.scale.y);
|
|
9655
|
+
const flipX = view.scale.x < 0;
|
|
9656
|
+
const flipY = view.scale.y < 0;
|
|
9452
9657
|
let x;
|
|
9453
9658
|
if (visW >= bounds.width) {
|
|
9454
|
-
x = bounds.x + (bounds.width - visW) / 2;
|
|
9659
|
+
x = bounds.x + (bounds.width - visW) / 2 + (flipX ? visW : 0);
|
|
9455
9660
|
} else {
|
|
9456
|
-
const minX = bounds.x;
|
|
9457
|
-
const maxX = bounds.x + bounds.width - visW;
|
|
9661
|
+
const minX = flipX ? bounds.x + visW : bounds.x;
|
|
9662
|
+
const maxX = flipX ? bounds.x + bounds.width : bounds.x + bounds.width - visW;
|
|
9458
9663
|
x = view.x < minX ? minX : view.x > maxX ? maxX : view.x;
|
|
9459
9664
|
}
|
|
9460
9665
|
let y;
|
|
9461
9666
|
if (visH >= bounds.height) {
|
|
9462
|
-
y = bounds.y + (bounds.height - visH) / 2;
|
|
9667
|
+
y = bounds.y + (bounds.height - visH) / 2 + (flipY ? visH : 0);
|
|
9463
9668
|
} else {
|
|
9464
|
-
const minY = bounds.y;
|
|
9465
|
-
const maxY = bounds.y + bounds.height - visH;
|
|
9669
|
+
const minY = flipY ? bounds.y + visH : bounds.y;
|
|
9670
|
+
const maxY = flipY ? bounds.y + bounds.height : bounds.y + bounds.height - visH;
|
|
9466
9671
|
y = view.y < minY ? minY : view.y > maxY ? maxY : view.y;
|
|
9467
9672
|
}
|
|
9468
9673
|
return x === view.x && y === view.y ? view : { x, y, scale: view.scale };
|
|
@@ -11165,7 +11370,7 @@ function keyAnchor(view) {
|
|
|
11165
11370
|
}
|
|
11166
11371
|
var WHEEL_STEP = 1.1;
|
|
11167
11372
|
function makeViewportZoomAction(opts = {}) {
|
|
11168
|
-
const clamp2 = { min: opts.min ??
|
|
11373
|
+
const clamp2 = { min: opts.min ?? DEFAULT_MIN_ZOOM, max: opts.max ?? DEFAULT_MAX_ZOOM };
|
|
11169
11374
|
const wheelSpec = opts.wheel === "plain" ? { kind: "wheel" } : { kind: "wheel", mods: { mod: true } };
|
|
11170
11375
|
const rawAnimate = opts.animate === true ? {} : opts.animate || null;
|
|
11171
11376
|
const { resetMs, ...animateRest } = rawAnimate ?? {};
|
|
@@ -11814,7 +12019,7 @@ var lassoSelectAction = {
|
|
|
11814
12019
|
enabled: () => true
|
|
11815
12020
|
};
|
|
11816
12021
|
function makePinchZoomAction(opts = {}) {
|
|
11817
|
-
const clamp2 = { min: opts.min ??
|
|
12022
|
+
const clamp2 = { min: opts.min ?? DEFAULT_MIN_ZOOM, max: opts.max ?? DEFAULT_MAX_ZOOM };
|
|
11818
12023
|
return {
|
|
11819
12024
|
id: "viewport.pinchZoom",
|
|
11820
12025
|
label: "Pinch Zoom",
|
|
@@ -16349,154 +16554,6 @@ function useGestureDispatcher(opts) {
|
|
|
16349
16554
|
};
|
|
16350
16555
|
}, [enabled, keyboard, canvasRef]);
|
|
16351
16556
|
}
|
|
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
16557
|
function dist(a, b) {
|
|
16501
16558
|
return Math.hypot(b.x - a.x, b.y - a.y);
|
|
16502
16559
|
}
|
|
@@ -16575,15 +16632,180 @@ function interpolateView(from, to) {
|
|
|
16575
16632
|
return { x: a.x, y: b.x, scale: { x: a.s, y: b.s } };
|
|
16576
16633
|
};
|
|
16577
16634
|
}
|
|
16635
|
+
var linear = (t) => t;
|
|
16636
|
+
var easeInQuad = (t) => t * t;
|
|
16578
16637
|
var easeOutQuad = (t) => 1 - (1 - t) * (1 - t);
|
|
16638
|
+
var easeInOutQuad = (t) => t < 0.5 ? 2 * t * t : 1 - 2 * (1 - t) * (1 - t);
|
|
16639
|
+
var easeInCubic = (t) => t * t * t;
|
|
16579
16640
|
var easeOutCubic = (t) => 1 - Math.pow(1 - t, 3);
|
|
16641
|
+
var easeInOutCubic = (t) => t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
|
|
16642
|
+
var easeInQuart = (t) => t * t * t * t;
|
|
16643
|
+
var easeOutQuart = (t) => 1 - Math.pow(1 - t, 4);
|
|
16644
|
+
var easeInOutQuart = (t) => t < 0.5 ? 8 * t * t * t * t : 1 - Math.pow(-2 * t + 2, 4) / 2;
|
|
16645
|
+
var easeInQuint = (t) => t * t * t * t * t;
|
|
16646
|
+
var easeOutQuint = (t) => 1 - Math.pow(1 - t, 5);
|
|
16647
|
+
var easeInOutQuint = (t) => t < 0.5 ? 16 * t * t * t * t * t : 1 - Math.pow(-2 * t + 2, 5) / 2;
|
|
16648
|
+
var easeInSine = (t) => 1 - Math.cos(t * Math.PI / 2);
|
|
16649
|
+
var easeOutSine = (t) => Math.sin(t * Math.PI / 2);
|
|
16650
|
+
var easeInOutSine = (t) => -(Math.cos(Math.PI * t) - 1) / 2;
|
|
16651
|
+
var easeInExpo = (t) => t === 0 ? 0 : Math.pow(2, 10 * t - 10);
|
|
16652
|
+
var easeOutExpo = (t) => t === 1 ? 1 : 1 - Math.pow(2, -10 * t);
|
|
16653
|
+
var easeInOutExpo = (t) => {
|
|
16654
|
+
if (t === 0) return 0;
|
|
16655
|
+
if (t === 1) return 1;
|
|
16656
|
+
return t < 0.5 ? Math.pow(2, 20 * t - 10) / 2 : (2 - Math.pow(2, -20 * t + 10)) / 2;
|
|
16657
|
+
};
|
|
16658
|
+
var easeInCirc = (t) => 1 - Math.sqrt(1 - t * t);
|
|
16659
|
+
var easeOutCirc = (t) => Math.sqrt(1 - Math.pow(t - 1, 2));
|
|
16660
|
+
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;
|
|
16661
|
+
var C1 = 1.70158;
|
|
16662
|
+
var C2 = C1 * 1.525;
|
|
16663
|
+
var C3 = C1 + 1;
|
|
16664
|
+
var C4 = 2 * Math.PI / 3;
|
|
16665
|
+
var C5 = 2 * Math.PI / 4.5;
|
|
16666
|
+
var easeInBack = (t) => C3 * t * t * t - C1 * t * t;
|
|
16667
|
+
var easeOutBack = (t) => 1 + C3 * Math.pow(t - 1, 3) + C1 * Math.pow(t - 1, 2);
|
|
16668
|
+
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;
|
|
16669
|
+
var easeInElastic = (t) => {
|
|
16670
|
+
if (t === 0) return 0;
|
|
16671
|
+
if (t === 1) return 1;
|
|
16672
|
+
return -Math.pow(2, 10 * t - 10) * Math.sin((t * 10 - 10.75) * C4);
|
|
16673
|
+
};
|
|
16674
|
+
var easeOutElastic = (t) => {
|
|
16675
|
+
if (t === 0) return 0;
|
|
16676
|
+
if (t === 1) return 1;
|
|
16677
|
+
return Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * C4) + 1;
|
|
16678
|
+
};
|
|
16679
|
+
var easeInOutElastic = (t) => {
|
|
16680
|
+
if (t === 0) return 0;
|
|
16681
|
+
if (t === 1) return 1;
|
|
16682
|
+
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;
|
|
16683
|
+
};
|
|
16684
|
+
var easeOutBounce = (t) => {
|
|
16685
|
+
const n1 = 7.5625;
|
|
16686
|
+
const d1 = 2.75;
|
|
16687
|
+
if (t < 1 / d1) return n1 * t * t;
|
|
16688
|
+
if (t < 2 / d1) {
|
|
16689
|
+
t -= 1.5 / d1;
|
|
16690
|
+
return n1 * t * t + 0.75;
|
|
16691
|
+
}
|
|
16692
|
+
if (t < 2.5 / d1) {
|
|
16693
|
+
t -= 2.25 / d1;
|
|
16694
|
+
return n1 * t * t + 0.9375;
|
|
16695
|
+
}
|
|
16696
|
+
t -= 2.625 / d1;
|
|
16697
|
+
return n1 * t * t + 0.984375;
|
|
16698
|
+
};
|
|
16699
|
+
var easeInBounce = (t) => 1 - easeOutBounce(1 - t);
|
|
16700
|
+
var easeInOutBounce = (t) => t < 0.5 ? (1 - easeOutBounce(1 - 2 * t)) / 2 : (1 + easeOutBounce(2 * t - 1)) / 2;
|
|
16580
16701
|
var easeOut = easeOutQuad;
|
|
16702
|
+
var EASINGS = {
|
|
16703
|
+
linear,
|
|
16704
|
+
easeInQuad,
|
|
16705
|
+
easeOutQuad,
|
|
16706
|
+
easeInOutQuad,
|
|
16707
|
+
easeInCubic,
|
|
16708
|
+
easeOutCubic,
|
|
16709
|
+
easeInOutCubic,
|
|
16710
|
+
easeInQuart,
|
|
16711
|
+
easeOutQuart,
|
|
16712
|
+
easeInOutQuart,
|
|
16713
|
+
easeInQuint,
|
|
16714
|
+
easeOutQuint,
|
|
16715
|
+
easeInOutQuint,
|
|
16716
|
+
easeInSine,
|
|
16717
|
+
easeOutSine,
|
|
16718
|
+
easeInOutSine,
|
|
16719
|
+
easeInExpo,
|
|
16720
|
+
easeOutExpo,
|
|
16721
|
+
easeInOutExpo,
|
|
16722
|
+
easeInCirc,
|
|
16723
|
+
easeOutCirc,
|
|
16724
|
+
easeInOutCirc,
|
|
16725
|
+
easeInBack,
|
|
16726
|
+
easeOutBack,
|
|
16727
|
+
easeInOutBack,
|
|
16728
|
+
easeInElastic,
|
|
16729
|
+
easeOutElastic,
|
|
16730
|
+
easeInOutElastic,
|
|
16731
|
+
easeInBounce,
|
|
16732
|
+
easeOutBounce,
|
|
16733
|
+
easeInOutBounce
|
|
16734
|
+
};
|
|
16581
16735
|
var SPRING_PRESETS = {
|
|
16582
16736
|
gentle: { stiffness: 120, damping: 14, mass: 1 },
|
|
16583
16737
|
wobbly: { stiffness: 180, damping: 12, mass: 1 },
|
|
16584
16738
|
stiff: { stiffness: 210, damping: 20, mass: 1 },
|
|
16585
16739
|
slow: { stiffness: 80, damping: 20, mass: 1 }
|
|
16586
16740
|
};
|
|
16741
|
+
var NEWTON_ITERATIONS = 8;
|
|
16742
|
+
var NEWTON_MIN_SLOPE = 1e-3;
|
|
16743
|
+
var SUBDIVISION_EPSILON = 1e-7;
|
|
16744
|
+
var SUBDIVISION_MAX = 12;
|
|
16745
|
+
function bezierAt(t, a1, a2) {
|
|
16746
|
+
const c = 3 * a1;
|
|
16747
|
+
const b = 3 * (a2 - a1) - c;
|
|
16748
|
+
const a = 1 - c - b;
|
|
16749
|
+
return ((a * t + b) * t + c) * t;
|
|
16750
|
+
}
|
|
16751
|
+
function bezierSlope(t, a1, a2) {
|
|
16752
|
+
const c = 3 * a1;
|
|
16753
|
+
const b = 3 * (a2 - a1) - c;
|
|
16754
|
+
const a = 1 - c - b;
|
|
16755
|
+
return (3 * a * t + 2 * b) * t + c;
|
|
16756
|
+
}
|
|
16757
|
+
function solveForX(x, x1, x2) {
|
|
16758
|
+
let t = x;
|
|
16759
|
+
for (let i = 0; i < NEWTON_ITERATIONS; i++) {
|
|
16760
|
+
const slope = bezierSlope(t, x1, x2);
|
|
16761
|
+
if (slope < NEWTON_MIN_SLOPE) break;
|
|
16762
|
+
t -= (bezierAt(t, x1, x2) - x) / slope;
|
|
16763
|
+
}
|
|
16764
|
+
let lo = 0;
|
|
16765
|
+
let hi = 1;
|
|
16766
|
+
t = Math.min(1, Math.max(0, t));
|
|
16767
|
+
for (let i = 0; i < SUBDIVISION_MAX; i++) {
|
|
16768
|
+
const err = bezierAt(t, x1, x2) - x;
|
|
16769
|
+
if (Math.abs(err) < SUBDIVISION_EPSILON) return t;
|
|
16770
|
+
if (err > 0) hi = t;
|
|
16771
|
+
else lo = t;
|
|
16772
|
+
t = (lo + hi) / 2;
|
|
16773
|
+
}
|
|
16774
|
+
return t;
|
|
16775
|
+
}
|
|
16776
|
+
function cubicBezierEasing(x1, y1, x2, y2) {
|
|
16777
|
+
const cx1 = Math.min(1, Math.max(0, x1));
|
|
16778
|
+
const cx2 = Math.min(1, Math.max(0, x2));
|
|
16779
|
+
return (t) => {
|
|
16780
|
+
if (t <= 0) return 0;
|
|
16781
|
+
if (t >= 1) return 1;
|
|
16782
|
+
return bezierAt(solveForX(t, cx1, cx2), y1, y2);
|
|
16783
|
+
};
|
|
16784
|
+
}
|
|
16785
|
+
var bezierCache = /* @__PURE__ */ new Map();
|
|
16786
|
+
function isBezier(spec) {
|
|
16787
|
+
return typeof spec === "object" && spec !== null && "bezier" in spec;
|
|
16788
|
+
}
|
|
16789
|
+
function resolveEasing(spec) {
|
|
16790
|
+
if (spec === void 0) return EASINGS.linear;
|
|
16791
|
+
if (typeof spec === "function") return spec;
|
|
16792
|
+
if (typeof spec === "string") {
|
|
16793
|
+
const fn = EASINGS[spec];
|
|
16794
|
+
if (!fn) throw new Error(`resolveEasing: unknown easing name "${spec}"`);
|
|
16795
|
+
return fn;
|
|
16796
|
+
}
|
|
16797
|
+
if (isBezier(spec)) {
|
|
16798
|
+
const [x1, y1, x2, y2] = spec.bezier;
|
|
16799
|
+
const key = `${x1},${y1},${x2},${y2}`;
|
|
16800
|
+
let fn = bezierCache.get(key);
|
|
16801
|
+
if (!fn) {
|
|
16802
|
+
fn = cubicBezierEasing(x1, y1, x2, y2);
|
|
16803
|
+
bezierCache.set(key, fn);
|
|
16804
|
+
}
|
|
16805
|
+
return fn;
|
|
16806
|
+
}
|
|
16807
|
+
throw new Error("resolveEasing: unrecognized easing spec");
|
|
16808
|
+
}
|
|
16587
16809
|
function createLoop(createSupervisor, factory, opts = {}) {
|
|
16588
16810
|
const max = opts.count ?? Infinity;
|
|
16589
16811
|
let iteration = 0;
|
|
@@ -16623,6 +16845,7 @@ function createLoop(createSupervisor, factory, opts = {}) {
|
|
|
16623
16845
|
supervisor.setTimeScale(s);
|
|
16624
16846
|
current?.setTimeScale(s);
|
|
16625
16847
|
},
|
|
16848
|
+
timeScale: () => supervisor.timeScale(),
|
|
16626
16849
|
isPaused: () => supervisor.isPaused()
|
|
16627
16850
|
};
|
|
16628
16851
|
}
|
|
@@ -16782,6 +17005,9 @@ var CompositeHandle = class {
|
|
|
16782
17005
|
this.timeScale_ = s;
|
|
16783
17006
|
for (const c of this.children) c.setTimeScale(s);
|
|
16784
17007
|
}
|
|
17008
|
+
timeScale() {
|
|
17009
|
+
return this.timeScale_;
|
|
17010
|
+
}
|
|
16785
17011
|
isPaused() {
|
|
16786
17012
|
return this.paused_;
|
|
16787
17013
|
}
|
|
@@ -16889,7 +17115,7 @@ function sampleTrack(track, t, segmentCache) {
|
|
|
16889
17115
|
const b = keys[i + 1];
|
|
16890
17116
|
const span = b.t - a.t;
|
|
16891
17117
|
const raw = span <= 0 ? 1 : (t - a.t) / span;
|
|
16892
|
-
const u = b.easing ? b.easing(raw) : raw;
|
|
17118
|
+
const u = b.easing ? resolveEasing(b.easing)(raw) : raw;
|
|
16893
17119
|
if (track.interpolator) {
|
|
16894
17120
|
let fn = segmentCache?.get(i + 1);
|
|
16895
17121
|
if (!fn) {
|
|
@@ -16968,7 +17194,10 @@ function createTimeline(register, id, opts) {
|
|
|
16968
17194
|
for (const track of tracks) {
|
|
16969
17195
|
if (track.kind === "event") {
|
|
16970
17196
|
const end = firstAfter(track.events, to);
|
|
16971
|
-
for (let i = firstAfter(track.events, from); i < end; i += 1)
|
|
17197
|
+
for (let i = firstAfter(track.events, from); i < end; i += 1) {
|
|
17198
|
+
const ev = track.events[i];
|
|
17199
|
+
ev.fire(to - ev.t);
|
|
17200
|
+
}
|
|
16972
17201
|
} else if (track.kind === "timeline") {
|
|
16973
17202
|
fireEvents(track.timeline.tracks, from - track.at, to - track.at);
|
|
16974
17203
|
}
|
|
@@ -17048,6 +17277,7 @@ function createTimeline(register, id, opts) {
|
|
|
17048
17277
|
wantScale = s;
|
|
17049
17278
|
base.setTimeScale(s);
|
|
17050
17279
|
},
|
|
17280
|
+
timeScale: () => live ? base.timeScale() : wantScale,
|
|
17051
17281
|
isPaused: () => live ? base.isPaused() : wantPaused,
|
|
17052
17282
|
seek(t) {
|
|
17053
17283
|
offset = t - lastVirtual;
|
|
@@ -17058,6 +17288,10 @@ function createTimeline(register, id, opts) {
|
|
|
17058
17288
|
time: () => playhead,
|
|
17059
17289
|
duration: () => duration,
|
|
17060
17290
|
tracks: () => opts.tracks,
|
|
17291
|
+
setLoop(loop) {
|
|
17292
|
+
loopsLeft = loop === true ? Infinity : loop === false ? 0 : loop;
|
|
17293
|
+
},
|
|
17294
|
+
loop: () => loopsLeft === Infinity ? true : loopsLeft === 0 ? false : loopsLeft,
|
|
17061
17295
|
edit(fn) {
|
|
17062
17296
|
fn();
|
|
17063
17297
|
caches = /* @__PURE__ */ new WeakMap();
|
|
@@ -17272,6 +17506,7 @@ function useAnimator(opts = {}) {
|
|
|
17272
17506
|
const a = animations.current.get(anim.id);
|
|
17273
17507
|
if (a) a.timeScale = s;
|
|
17274
17508
|
},
|
|
17509
|
+
timeScale: () => animations.current.get(anim.id)?.timeScale ?? 1,
|
|
17275
17510
|
isPaused: () => animations.current.get(anim.id)?.paused ?? false
|
|
17276
17511
|
};
|
|
17277
17512
|
};
|
|
@@ -17293,6 +17528,7 @@ function useAnimator(opts = {}) {
|
|
|
17293
17528
|
pause: base.pause,
|
|
17294
17529
|
resume: base.resume,
|
|
17295
17530
|
setTimeScale: base.setTimeScale,
|
|
17531
|
+
timeScale: base.timeScale,
|
|
17296
17532
|
isPaused: base.isPaused,
|
|
17297
17533
|
setOnCancel: (cb) => {
|
|
17298
17534
|
onCancelCb = cb;
|
|
@@ -17303,7 +17539,7 @@ function useAnimator(opts = {}) {
|
|
|
17303
17539
|
const tween = (o) => {
|
|
17304
17540
|
const id = nextId.current++;
|
|
17305
17541
|
const start = 0;
|
|
17306
|
-
const easing = o.easing ?? easeOut;
|
|
17542
|
+
const easing = resolveEasing(o.easing ?? easeOut);
|
|
17307
17543
|
const factoryFn = o.interpolator ? o.interpolator(o.from, o.to) : null;
|
|
17308
17544
|
const perTickInterp = factoryFn ? null : o.interpolate ?? ((a, b, t) => {
|
|
17309
17545
|
if (typeof a === "number" && typeof b === "number") {
|
|
@@ -17458,6 +17694,7 @@ function useAnimator(opts = {}) {
|
|
|
17458
17694
|
setTimeScale: (s) => {
|
|
17459
17695
|
globalTimeScale.current = s;
|
|
17460
17696
|
},
|
|
17697
|
+
timeScale: () => globalTimeScale.current,
|
|
17461
17698
|
pauseKey: (key) => {
|
|
17462
17699
|
for (const a of animations.current.values()) if (a.cancelKey === key) a.paused = true;
|
|
17463
17700
|
},
|
|
@@ -18055,6 +18292,21 @@ function LineIcon({ className, size = 20 }) {
|
|
|
18055
18292
|
}
|
|
18056
18293
|
);
|
|
18057
18294
|
}
|
|
18295
|
+
function ArrowIcon({ className, size = 20 }) {
|
|
18296
|
+
return /* @__PURE__ */ jsxs(
|
|
18297
|
+
"svg",
|
|
18298
|
+
{
|
|
18299
|
+
...ICON_SVG_BASE,
|
|
18300
|
+
className,
|
|
18301
|
+
width: size,
|
|
18302
|
+
height: size,
|
|
18303
|
+
children: [
|
|
18304
|
+
/* @__PURE__ */ jsx("path", { d: "M3.5 16.5 12.9 7.1", strokeLinecap: "round" }),
|
|
18305
|
+
/* @__PURE__ */ jsx("path", { d: "M16.5 3.5 11.06 5.98 14.03 8.95Z", fill: "currentColor", strokeLinejoin: "round" })
|
|
18306
|
+
]
|
|
18307
|
+
}
|
|
18308
|
+
);
|
|
18309
|
+
}
|
|
18058
18310
|
function PolygonIcon({ className, size = 20 }) {
|
|
18059
18311
|
return /* @__PURE__ */ jsx(
|
|
18060
18312
|
"svg",
|
|
@@ -18632,6 +18884,14 @@ var TEXT_PAINTER = {
|
|
|
18632
18884
|
);
|
|
18633
18885
|
if (boxes.length === 0) return null;
|
|
18634
18886
|
return rectsToPath(boxes);
|
|
18887
|
+
},
|
|
18888
|
+
// `filled` is unconditional: a text node's `data.fill: null` still resolves
|
|
18889
|
+
// to the default in `ResolvedRun`, so there is no outline-only text to
|
|
18890
|
+
// report. The reach is the point — a heavily outlined glyph was unpickable
|
|
18891
|
+
// across the width of its own outline.
|
|
18892
|
+
ink: (node, _pose, ctx) => {
|
|
18893
|
+
const d = node.data;
|
|
18894
|
+
return { filled: true, ...inkReach(resolveNodeStroke(d.stroke), ctx?.scale) };
|
|
18635
18895
|
}
|
|
18636
18896
|
};
|
|
18637
18897
|
function rectsToPath(rects) {
|
|
@@ -18897,10 +19157,10 @@ var RECT_FALLBACK_PAINTER = {
|
|
|
18897
19157
|
};
|
|
18898
19158
|
function registerBuiltInShapePainters() {
|
|
18899
19159
|
registerNodeShape(TEXT_PAINTER);
|
|
19160
|
+
registerNodeShape(DERIVED_PAINTER);
|
|
18900
19161
|
registerNodeShape(PATH_PAINTER);
|
|
18901
19162
|
registerNodeShape(SHAPE_PAINTER);
|
|
18902
19163
|
registerNodeShape(IMAGE_PAINTER);
|
|
18903
|
-
registerNodeShape(DERIVED_PAINTER);
|
|
18904
19164
|
registerNodeShape(RECT_FALLBACK_PAINTER);
|
|
18905
19165
|
}
|
|
18906
19166
|
registerBuiltInShapePainters();
|
|
@@ -19909,11 +20169,7 @@ function useRotateTool(adapter, options) {
|
|
|
19909
20169
|
[overlay]
|
|
19910
20170
|
);
|
|
19911
20171
|
}
|
|
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();
|
|
20172
|
+
function useHandTool(_opts = {}) {
|
|
19917
20173
|
return useMemo(
|
|
19918
20174
|
() => Object.assign(defineViewportTool({
|
|
19919
20175
|
id: "hand",
|
|
@@ -19933,8 +20189,7 @@ function useHandTool(opts = {}) {
|
|
|
19933
20189
|
// phase entry.
|
|
19934
20190
|
bindings: [{ spec: { kind: "drag" }, actionId: "viewport.dragPan" }]
|
|
19935
20191
|
}),
|
|
19936
|
-
|
|
19937
|
-
[inertia, axis, tracker, decay]
|
|
20192
|
+
[]
|
|
19938
20193
|
);
|
|
19939
20194
|
}
|
|
19940
20195
|
var PRESENTATION = {
|
|
@@ -19963,7 +20218,7 @@ function usePinchZoomTool(canvasRef, getView, setView, opts = {}) {
|
|
|
19963
20218
|
getViewRef.current = getView;
|
|
19964
20219
|
const setViewRef = useRef(setView);
|
|
19965
20220
|
setViewRef.current = setView;
|
|
19966
|
-
const { min =
|
|
20221
|
+
const { min = DEFAULT_MIN_ZOOM, max = DEFAULT_MAX_ZOOM, enabled = true } = opts;
|
|
19967
20222
|
const resolveTargetRef = useRef(opts.resolveTarget);
|
|
19968
20223
|
resolveTargetRef.current = opts.resolveTarget;
|
|
19969
20224
|
usePinchGesture(canvasRef, (clientAnchor, scaleFactor) => {
|
|
@@ -20227,7 +20482,7 @@ function usePenTool(options) {
|
|
|
20227
20482
|
hookName: "usePenTool",
|
|
20228
20483
|
// Reads the tool's own ref rather than a scratch handed in by a
|
|
20229
20484
|
// dispatcher — the pen owns this state and nothing else needs it.
|
|
20230
|
-
cursor: () => scratchRef.current?.closeHintActive ? "pointer" : "crosshair",
|
|
20485
|
+
cursor: () => scratchRef.current?.closeHintActive ? "pointer" : cursorFor("pen", { fallback: "crosshair" }),
|
|
20231
20486
|
presentation: {
|
|
20232
20487
|
label: "Pen",
|
|
20233
20488
|
icon: createElement(PenIcon),
|
|
@@ -20612,7 +20867,7 @@ function usePencilTool() {
|
|
|
20612
20867
|
id: "pencil",
|
|
20613
20868
|
capabilities: ["creates-paths"],
|
|
20614
20869
|
hookName: "usePencilTool",
|
|
20615
|
-
cursor: "crosshair",
|
|
20870
|
+
cursor: cursorFor("pencil", { fallback: "crosshair" }),
|
|
20616
20871
|
presentation: {
|
|
20617
20872
|
label: "Pencil",
|
|
20618
20873
|
group: "draw",
|
|
@@ -21616,14 +21871,89 @@ function wrapNodeOutput(cmds, pose, alpha) {
|
|
|
21616
21871
|
}
|
|
21617
21872
|
return rotated;
|
|
21618
21873
|
}
|
|
21619
|
-
function
|
|
21874
|
+
function insetAlong(start, extent, size, align, by) {
|
|
21875
|
+
if (align === "start") return start + by;
|
|
21876
|
+
if (align === "end") return start + extent - size - by;
|
|
21877
|
+
return start + (extent - size) / 2 + by;
|
|
21878
|
+
}
|
|
21879
|
+
function hostAnchorRect(input) {
|
|
21880
|
+
const { host, panel, viewport, align, offset, padding = 0 } = input;
|
|
21881
|
+
const desired = {
|
|
21882
|
+
x: insetAlong(host.x, host.width, panel.width, align.x, offset.x),
|
|
21883
|
+
y: insetAlong(host.y, host.height, panel.height, align.y, offset.y),
|
|
21884
|
+
width: panel.width,
|
|
21885
|
+
height: panel.height
|
|
21886
|
+
};
|
|
21887
|
+
return clampRectWithin(desired, { x: 0, y: 0, width: viewport.width, height: viewport.height }, padding);
|
|
21888
|
+
}
|
|
21889
|
+
function hostAnchorCss(rect, align, viewport) {
|
|
21890
|
+
return {
|
|
21891
|
+
...align.y === "end" ? { bottom: viewport.height - rect.y - rect.height } : { top: rect.y },
|
|
21892
|
+
...align.x === "end" ? { right: viewport.width - rect.x - rect.width } : { left: rect.x }
|
|
21893
|
+
};
|
|
21894
|
+
}
|
|
21895
|
+
function useHostAnchor(resolveHost, options) {
|
|
21896
|
+
const [panel, setPanel] = useState(null);
|
|
21897
|
+
const [style, setStyle] = useState(null);
|
|
21898
|
+
const ref = useCallback((el) => setPanel(el), []);
|
|
21899
|
+
const resolve = useRef(resolveHost);
|
|
21900
|
+
resolve.current = resolveHost;
|
|
21901
|
+
const { align, offset, padding = 0 } = options;
|
|
21902
|
+
const { x: alignX, y: alignY } = align;
|
|
21903
|
+
const { x: offsetX, y: offsetY } = offset;
|
|
21904
|
+
const recompute = useCallback(() => {
|
|
21905
|
+
const hostEl = resolve.current();
|
|
21906
|
+
if (!hostEl) {
|
|
21907
|
+
setStyle(null);
|
|
21908
|
+
return;
|
|
21909
|
+
}
|
|
21910
|
+
const h = hostEl.getBoundingClientRect();
|
|
21911
|
+
const p = panel?.getBoundingClientRect();
|
|
21912
|
+
const viewport = { width: window.innerWidth, height: window.innerHeight };
|
|
21913
|
+
const align2 = { x: alignX, y: alignY };
|
|
21914
|
+
const rect = hostAnchorRect({
|
|
21915
|
+
host: { x: h.left, y: h.top, width: h.width, height: h.height },
|
|
21916
|
+
panel: { width: p?.width ?? 0, height: p?.height ?? 0 },
|
|
21917
|
+
viewport,
|
|
21918
|
+
align: align2,
|
|
21919
|
+
offset: { x: offsetX, y: offsetY },
|
|
21920
|
+
padding
|
|
21921
|
+
});
|
|
21922
|
+
setStyle(hostAnchorCss(rect, align2, viewport));
|
|
21923
|
+
}, [panel, alignX, alignY, offsetX, offsetY, padding]);
|
|
21924
|
+
const raf = useVisibleRaf(recompute);
|
|
21925
|
+
useEffect(() => {
|
|
21926
|
+
recompute();
|
|
21927
|
+
const schedule = () => raf.request();
|
|
21928
|
+
window.addEventListener("scroll", schedule, true);
|
|
21929
|
+
window.addEventListener("resize", schedule);
|
|
21930
|
+
const observer = typeof ResizeObserver !== "undefined" ? new ResizeObserver(schedule) : null;
|
|
21931
|
+
if (panel) observer?.observe(panel);
|
|
21932
|
+
const hostEl = resolve.current();
|
|
21933
|
+
if (hostEl) observer?.observe(hostEl);
|
|
21934
|
+
return () => {
|
|
21935
|
+
window.removeEventListener("scroll", schedule, true);
|
|
21936
|
+
window.removeEventListener("resize", schedule);
|
|
21937
|
+
raf.cancel();
|
|
21938
|
+
observer?.disconnect();
|
|
21939
|
+
};
|
|
21940
|
+
}, [recompute, raf, panel]);
|
|
21941
|
+
return { ref, style };
|
|
21942
|
+
}
|
|
21943
|
+
function CursorCoordsHud({ canvasRef, anchorRef, viewRef, offset }) {
|
|
21620
21944
|
const [state, setState] = useState({
|
|
21621
21945
|
client: { x: 0, y: 0 },
|
|
21622
21946
|
world: null,
|
|
21623
|
-
inCanvas: false
|
|
21624
|
-
anchor: null
|
|
21947
|
+
inCanvas: false
|
|
21625
21948
|
});
|
|
21626
21949
|
const [fps, setFps] = useState(0);
|
|
21950
|
+
const { ref, style: anchorStyle } = useHostAnchor(
|
|
21951
|
+
() => anchorRef?.current ?? canvasRef.current?.parentElement ?? canvasRef.current,
|
|
21952
|
+
{
|
|
21953
|
+
align: { x: "end", y: "start" },
|
|
21954
|
+
offset: { x: offset?.right ?? 8, y: offset?.top ?? 8 }
|
|
21955
|
+
}
|
|
21956
|
+
);
|
|
21627
21957
|
const framesRef = useRef(0);
|
|
21628
21958
|
const lastFlushRef = useRef(0);
|
|
21629
21959
|
const fpsLoop = useVisibleRaf(
|
|
@@ -21653,49 +21983,33 @@ function CursorCoordsHud({ canvasRef, viewRef, offset }) {
|
|
|
21653
21983
|
return () => fpsLoop.cancel();
|
|
21654
21984
|
}, [fpsLoop]);
|
|
21655
21985
|
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
21986
|
const onMove = (e) => {
|
|
21664
21987
|
const canvas = canvasRef.current;
|
|
21665
21988
|
const view = viewRef.current;
|
|
21666
21989
|
const client = { x: e.clientX, y: e.clientY };
|
|
21667
|
-
const anchor = readAnchor();
|
|
21668
21990
|
if (!canvas || !view) {
|
|
21669
|
-
setState({ client, world: null, inCanvas: false
|
|
21991
|
+
setState({ client, world: null, inCanvas: false });
|
|
21670
21992
|
return;
|
|
21671
21993
|
}
|
|
21672
21994
|
const rect = canvas.getBoundingClientRect();
|
|
21673
21995
|
const inCanvas = e.clientX >= rect.left && e.clientX <= rect.right && e.clientY >= rect.top && e.clientY <= rect.bottom;
|
|
21674
21996
|
const [wx, wy] = clientToWorld(e.clientX, e.clientY, rect, view);
|
|
21675
21997
|
const world = { x: wx, y: wy };
|
|
21676
|
-
setState({ client, world, inCanvas
|
|
21998
|
+
setState({ client, world, inCanvas });
|
|
21677
21999
|
};
|
|
21678
|
-
const onLayout = () => setState((s) => ({ ...s, anchor: readAnchor() }));
|
|
21679
22000
|
document.addEventListener("pointermove", onMove);
|
|
21680
|
-
window.addEventListener("scroll", onLayout, true);
|
|
21681
|
-
window.addEventListener("resize", onLayout);
|
|
21682
|
-
setState((s) => ({ ...s, anchor: readAnchor() }));
|
|
21683
22001
|
return () => {
|
|
21684
22002
|
document.removeEventListener("pointermove", onMove);
|
|
21685
|
-
window.removeEventListener("scroll", onLayout, true);
|
|
21686
|
-
window.removeEventListener("resize", onLayout);
|
|
21687
22003
|
};
|
|
21688
22004
|
}, [canvasRef, viewRef]);
|
|
21689
|
-
if (!
|
|
21690
|
-
const top = state.anchor.top + (offset?.top ?? 8);
|
|
21691
|
-
const right = state.anchor.right + (offset?.right ?? 8);
|
|
22005
|
+
if (!anchorStyle) return null;
|
|
21692
22006
|
return /* @__PURE__ */ jsxs(
|
|
21693
22007
|
"div",
|
|
21694
22008
|
{
|
|
22009
|
+
ref,
|
|
21695
22010
|
style: {
|
|
21696
22011
|
position: "fixed",
|
|
21697
|
-
|
|
21698
|
-
right,
|
|
22012
|
+
...anchorStyle,
|
|
21699
22013
|
zIndex: 1e4,
|
|
21700
22014
|
background: "rgba(0,0,0,0.7)",
|
|
21701
22015
|
color: "#e8e8e8",
|
|
@@ -21718,33 +22032,31 @@ function CursorCoordsHud({ canvasRef, viewRef, offset }) {
|
|
|
21718
22032
|
);
|
|
21719
22033
|
}
|
|
21720
22034
|
var PickHud_default = {};
|
|
21721
|
-
function PickHud({ canvasRef, viewRef, pickEvery, pickBest, offset }) {
|
|
22035
|
+
function PickHud({ canvasRef, anchorRef, viewRef, pickEvery, pickBest, offset }) {
|
|
21722
22036
|
const [state, setState] = useState({
|
|
21723
22037
|
ids: [],
|
|
21724
22038
|
best: null,
|
|
21725
|
-
inCanvas: false
|
|
21726
|
-
anchor: null
|
|
22039
|
+
inCanvas: false
|
|
21727
22040
|
});
|
|
22041
|
+
const { ref, style } = useHostAnchor(
|
|
22042
|
+
() => anchorRef?.current ?? canvasRef.current?.parentElement ?? canvasRef.current,
|
|
22043
|
+
{
|
|
22044
|
+
align: { x: "end", y: "start" },
|
|
22045
|
+
offset: { x: offset?.right ?? 8, y: offset?.top ?? 76 }
|
|
22046
|
+
}
|
|
22047
|
+
);
|
|
21728
22048
|
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
22049
|
const onMove = (e) => {
|
|
21737
22050
|
const canvas = canvasRef.current;
|
|
21738
22051
|
const view = viewRef.current;
|
|
21739
|
-
const anchor = readAnchor();
|
|
21740
22052
|
if (!canvas || !view) {
|
|
21741
|
-
setState({ ids: [], best: null, inCanvas: false
|
|
22053
|
+
setState({ ids: [], best: null, inCanvas: false });
|
|
21742
22054
|
return;
|
|
21743
22055
|
}
|
|
21744
22056
|
const rect = canvas.getBoundingClientRect();
|
|
21745
22057
|
const inCanvas = e.clientX >= rect.left && e.clientX <= rect.right && e.clientY >= rect.top && e.clientY <= rect.bottom;
|
|
21746
22058
|
if (!inCanvas) {
|
|
21747
|
-
setState({ ids: [], best: null, inCanvas: false
|
|
22059
|
+
setState({ ids: [], best: null, inCanvas: false });
|
|
21748
22060
|
return;
|
|
21749
22061
|
}
|
|
21750
22062
|
const worldX = (e.clientX - rect.left) / view.scale.x + view.x;
|
|
@@ -21763,24 +22075,15 @@ function PickHud({ canvasRef, viewRef, pickEvery, pickBest, offset }) {
|
|
|
21763
22075
|
best = null;
|
|
21764
22076
|
}
|
|
21765
22077
|
}
|
|
21766
|
-
setState({ ids, best, inCanvas: true
|
|
22078
|
+
setState({ ids, best, inCanvas: true });
|
|
21767
22079
|
};
|
|
21768
|
-
const onLayout = () => setState((s) => ({ ...s, anchor: readAnchor() }));
|
|
21769
22080
|
document.addEventListener("pointermove", onMove);
|
|
21770
|
-
window.addEventListener("scroll", onLayout, true);
|
|
21771
|
-
window.addEventListener("resize", onLayout);
|
|
21772
|
-
setState((s) => ({ ...s, anchor: readAnchor() }));
|
|
21773
22081
|
return () => {
|
|
21774
22082
|
document.removeEventListener("pointermove", onMove);
|
|
21775
|
-
window.removeEventListener("scroll", onLayout, true);
|
|
21776
|
-
window.removeEventListener("resize", onLayout);
|
|
21777
22083
|
};
|
|
21778
22084
|
}, [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: [
|
|
22085
|
+
if (!style) return null;
|
|
22086
|
+
return /* @__PURE__ */ jsxs("div", { ref, className: PickHud_default.hud, style, children: [
|
|
21784
22087
|
/* @__PURE__ */ jsxs("div", { className: PickHud_default.header, children: [
|
|
21785
22088
|
"pickEvery (",
|
|
21786
22089
|
state.ids.length,
|
|
@@ -21797,34 +22100,20 @@ function PickHud({ canvasRef, viewRef, pickEvery, pickBest, offset }) {
|
|
|
21797
22100
|
] });
|
|
21798
22101
|
}
|
|
21799
22102
|
var ModalityHud_default = {};
|
|
21800
|
-
function ModalityHud({ canvasRef, modeId, offset }) {
|
|
22103
|
+
function ModalityHud({ canvasRef, anchorRef, modeId, offset }) {
|
|
21801
22104
|
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 };
|
|
22105
|
+
const { ref, style } = useHostAnchor(
|
|
22106
|
+
() => anchorRef?.current ?? canvasRef.current?.parentElement ?? canvasRef.current,
|
|
22107
|
+
{
|
|
22108
|
+
align: { x: "end", y: "start" },
|
|
22109
|
+
offset: { x: offset?.right ?? 8, y: offset?.top ?? 220 }
|
|
22110
|
+
}
|
|
22111
|
+
);
|
|
22112
|
+
if (!style) return null;
|
|
21824
22113
|
const active = toolCtx?.active ?? null;
|
|
21825
22114
|
const hotkeys = toolCtx?.hotkeyStack ?? [];
|
|
21826
22115
|
const hotkeyTop = hotkeys.length > 0 ? hotkeys[hotkeys.length - 1] : null;
|
|
21827
|
-
return /* @__PURE__ */ jsxs("div", { className: ModalityHud_default.hud, style, children: [
|
|
22116
|
+
return /* @__PURE__ */ jsxs("div", { ref, className: ModalityHud_default.hud, style, children: [
|
|
21828
22117
|
/* @__PURE__ */ jsxs("div", { className: ModalityHud_default.row, children: [
|
|
21829
22118
|
/* @__PURE__ */ jsx("span", { className: ModalityHud_default.label, children: "mode" }),
|
|
21830
22119
|
/* @__PURE__ */ jsx("span", { className: modeId ? ModalityHud_default.value : ModalityHud_default.valueMuted, children: modeId ?? "\u2014" })
|
|
@@ -21955,6 +22244,8 @@ function CanvasInner(props, ref) {
|
|
|
21955
22244
|
boundsOf: boundsOf2,
|
|
21956
22245
|
pickEvery,
|
|
21957
22246
|
clientToWorld: clientToWorld2,
|
|
22247
|
+
paintInto,
|
|
22248
|
+
inputElement,
|
|
21958
22249
|
geometry = AUTO_POSE_DESCRIPTOR,
|
|
21959
22250
|
className,
|
|
21960
22251
|
style,
|
|
@@ -22000,6 +22291,15 @@ function CanvasInner(props, ref) {
|
|
|
22000
22291
|
debugSinkRefForCtx.current = debugSink;
|
|
22001
22292
|
const adapter = adapterProp;
|
|
22002
22293
|
const canvasRef = useRef(null);
|
|
22294
|
+
const ownCanvasRef = useRef(null);
|
|
22295
|
+
const detached = !!paintInto;
|
|
22296
|
+
if (detached) {
|
|
22297
|
+
canvasRef.current = inputElement ?? null;
|
|
22298
|
+
}
|
|
22299
|
+
const paintTargetRef = useRef(null);
|
|
22300
|
+
paintTargetRef.current = detached ? paintInto.canvas ?? null : null;
|
|
22301
|
+
const paintRectRef = useRef(null);
|
|
22302
|
+
paintRectRef.current = detached ? { x: paintInto.x, y: paintInto.y } : null;
|
|
22003
22303
|
const helpersForLayersRef = useRef(null);
|
|
22004
22304
|
const dimsRef = useRef({ width, height });
|
|
22005
22305
|
dimsRef.current = { width, height };
|
|
@@ -22087,7 +22387,10 @@ function CanvasInner(props, ref) {
|
|
|
22087
22387
|
};
|
|
22088
22388
|
}, []);
|
|
22089
22389
|
useImperativeHandle(ref, () => ({
|
|
22090
|
-
|
|
22390
|
+
// Named rather than read off `canvasRef` so the handle rebuilds when a
|
|
22391
|
+
// detached surface's input element arrives, which is a render later.
|
|
22392
|
+
element: detached ? inputElement ?? null : canvasRef.current,
|
|
22393
|
+
surface: detached ? paintInto?.canvas ?? null : ownCanvasRef.current,
|
|
22091
22394
|
requestRedraw,
|
|
22092
22395
|
subscribeFrame,
|
|
22093
22396
|
registerLayer,
|
|
@@ -22098,6 +22401,10 @@ function CanvasInner(props, ref) {
|
|
|
22098
22401
|
getPaintedVersion
|
|
22099
22402
|
}), [
|
|
22100
22403
|
canvasRef,
|
|
22404
|
+
ownCanvasRef,
|
|
22405
|
+
detached,
|
|
22406
|
+
inputElement,
|
|
22407
|
+
paintInto?.canvas,
|
|
22101
22408
|
requestRedraw,
|
|
22102
22409
|
subscribeFrame,
|
|
22103
22410
|
registerLayer,
|
|
@@ -22393,8 +22700,9 @@ function CanvasInner(props, ref) {
|
|
|
22393
22700
|
shaders
|
|
22394
22701
|
};
|
|
22395
22702
|
const paint = useCallback(() => {
|
|
22396
|
-
const c =
|
|
22703
|
+
const c = paintTargetRef.current ?? ownCanvasRef.current;
|
|
22397
22704
|
if (!c) return false;
|
|
22705
|
+
const rect = paintRectRef.current;
|
|
22398
22706
|
const {
|
|
22399
22707
|
layers: paintLayers,
|
|
22400
22708
|
width: w,
|
|
@@ -22423,7 +22731,9 @@ function CanvasInner(props, ref) {
|
|
|
22423
22731
|
try {
|
|
22424
22732
|
renderer = new WeaselRenderer({
|
|
22425
22733
|
gl,
|
|
22426
|
-
|
|
22734
|
+
// A shared buffer is the caller's to size. Handing the renderer the
|
|
22735
|
+
// element would have every co-tenant resize it to its own pane.
|
|
22736
|
+
...rect ? {} : { canvas: c },
|
|
22427
22737
|
width: w,
|
|
22428
22738
|
height: h,
|
|
22429
22739
|
dpr
|
|
@@ -22442,6 +22752,7 @@ function CanvasInner(props, ref) {
|
|
|
22442
22752
|
lastResizeRef.current = { w, h, dpr };
|
|
22443
22753
|
}
|
|
22444
22754
|
}
|
|
22755
|
+
renderer.setTarget(rect ? { origin: { x: rect.x, y: rect.y } } : null);
|
|
22445
22756
|
const view = viewRef.current;
|
|
22446
22757
|
const commands = drawLayers(
|
|
22447
22758
|
paintLayers,
|
|
@@ -22490,31 +22801,69 @@ function CanvasInner(props, ref) {
|
|
|
22490
22801
|
}, [shaderIdKey]);
|
|
22491
22802
|
const toolsCursor = tools ? resolveToolsCursor(tools, toolsCtxBase) : void 0;
|
|
22492
22803
|
const effectiveStyle = toolsCursor ? { ...style, cursor: toolsCursor } : style;
|
|
22493
|
-
|
|
22494
|
-
|
|
22495
|
-
|
|
22804
|
+
const layersForMoveRef = useRef(layersWithDebug);
|
|
22805
|
+
layersForMoveRef.current = layersWithDebug;
|
|
22806
|
+
useEffect(() => {
|
|
22807
|
+
if (!detached || !inputElement) return;
|
|
22808
|
+
const el = inputElement;
|
|
22809
|
+
const onDown = () => {
|
|
22810
|
+
if (autoFocusOnPointerDown) el.focus();
|
|
22811
|
+
pointerDownRef.current = true;
|
|
22812
|
+
};
|
|
22813
|
+
const onMove = (e) => {
|
|
22814
|
+
if (pointerDownRef.current) return;
|
|
22815
|
+
const view = viewRef.current;
|
|
22816
|
+
const [worldX, worldY] = toWorld(
|
|
22817
|
+
el,
|
|
22818
|
+
e.clientX,
|
|
22819
|
+
e.clientY,
|
|
22820
|
+
view,
|
|
22821
|
+
clientToWorldRef.current
|
|
22822
|
+
);
|
|
22823
|
+
const dims = dimsRef.current;
|
|
22824
|
+
for (const layer of layersForMoveRef.current) {
|
|
22825
|
+
layer.onUncapturedMove?.(worldX, worldY, e, view, dims);
|
|
22826
|
+
}
|
|
22827
|
+
};
|
|
22828
|
+
const onUp = () => {
|
|
22829
|
+
pointerDownRef.current = false;
|
|
22830
|
+
};
|
|
22831
|
+
const onLeave = () => {
|
|
22832
|
+
pointerDownRef.current = false;
|
|
22833
|
+
for (const layer of layersForMoveRef.current) layer.onUncapturedLeave?.();
|
|
22834
|
+
};
|
|
22835
|
+
const onMenu = (e) => e.preventDefault();
|
|
22836
|
+
el.addEventListener("pointerdown", onDown);
|
|
22837
|
+
el.addEventListener("pointermove", onMove);
|
|
22838
|
+
el.addEventListener("pointerup", onUp);
|
|
22839
|
+
el.addEventListener("pointerleave", onLeave);
|
|
22840
|
+
el.addEventListener("contextmenu", onMenu);
|
|
22841
|
+
return () => {
|
|
22842
|
+
el.removeEventListener("pointerdown", onDown);
|
|
22843
|
+
el.removeEventListener("pointermove", onMove);
|
|
22844
|
+
el.removeEventListener("pointerup", onUp);
|
|
22845
|
+
el.removeEventListener("pointerleave", onLeave);
|
|
22846
|
+
el.removeEventListener("contextmenu", onMenu);
|
|
22847
|
+
};
|
|
22848
|
+
}, [detached, inputElement, autoFocusOnPointerDown]);
|
|
22849
|
+
useEffect(() => {
|
|
22850
|
+
if (!detached || !inputElement) return;
|
|
22851
|
+
inputElement.style.cursor = toolsCursor ?? "";
|
|
22852
|
+
}, [detached, inputElement, toolsCursor]);
|
|
22853
|
+
const huds = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
22854
|
+
cursorCoordsHud && /* @__PURE__ */ jsx(
|
|
22855
|
+
CursorCoordsHud,
|
|
22496
22856
|
{
|
|
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()
|
|
22857
|
+
canvasRef,
|
|
22858
|
+
...detached ? { anchorRef: canvasRef } : {},
|
|
22859
|
+
viewRef
|
|
22511
22860
|
}
|
|
22512
22861
|
),
|
|
22513
|
-
cursorCoordsHud && /* @__PURE__ */ jsx(CursorCoordsHud, { canvasRef, viewRef }),
|
|
22514
22862
|
pickHud && /* @__PURE__ */ jsx(
|
|
22515
22863
|
PickHud,
|
|
22516
22864
|
{
|
|
22517
22865
|
canvasRef,
|
|
22866
|
+
...detached ? { anchorRef: canvasRef } : {},
|
|
22518
22867
|
viewRef,
|
|
22519
22868
|
pickEvery: stablePickEveryForHud,
|
|
22520
22869
|
pickBest: stablePickBestForHud
|
|
@@ -22524,10 +22873,37 @@ function CanvasInner(props, ref) {
|
|
|
22524
22873
|
ModalityHud,
|
|
22525
22874
|
{
|
|
22526
22875
|
canvasRef,
|
|
22876
|
+
...detached ? { anchorRef: canvasRef } : {},
|
|
22527
22877
|
modeId: typeof modalityHud === "object" ? modalityHud.modeId : void 0
|
|
22528
22878
|
}
|
|
22529
22879
|
)
|
|
22530
22880
|
] });
|
|
22881
|
+
if (detached) return inputElement ? huds : null;
|
|
22882
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
22883
|
+
/* @__PURE__ */ jsx(
|
|
22884
|
+
"canvas",
|
|
22885
|
+
{
|
|
22886
|
+
ref: (el) => {
|
|
22887
|
+
ownCanvasRef.current = el;
|
|
22888
|
+
canvasRef.current = el;
|
|
22889
|
+
},
|
|
22890
|
+
width,
|
|
22891
|
+
height,
|
|
22892
|
+
tabIndex,
|
|
22893
|
+
className,
|
|
22894
|
+
style: effectiveStyle,
|
|
22895
|
+
onFocus,
|
|
22896
|
+
onBlur,
|
|
22897
|
+
onPointerDown: handlePointerDown,
|
|
22898
|
+
onPointerMove: handlePointerMove,
|
|
22899
|
+
onPointerUp: handlePointerUp,
|
|
22900
|
+
onPointerCancel: handlePointerCancel,
|
|
22901
|
+
onPointerLeave: handlePointerLeave,
|
|
22902
|
+
onContextMenu: (e) => e.preventDefault()
|
|
22903
|
+
}
|
|
22904
|
+
),
|
|
22905
|
+
huds
|
|
22906
|
+
] });
|
|
22531
22907
|
}
|
|
22532
22908
|
var Canvas = forwardRef(CanvasInner);
|
|
22533
22909
|
function composeAlphaFor(scene, alphaFor) {
|
|
@@ -23656,6 +24032,32 @@ function sceneFromJSON(json, options) {
|
|
|
23656
24032
|
});
|
|
23657
24033
|
}
|
|
23658
24034
|
var SelectionContext = createContext(null);
|
|
24035
|
+
function SelectionContextProvider({ children }) {
|
|
24036
|
+
const [state, setState] = useState({ selection: [], kinds: void 0 });
|
|
24037
|
+
const lastSerializedRef = useRef("");
|
|
24038
|
+
const publishSelection = useCallback((ids, kinds) => {
|
|
24039
|
+
const next = JSON.stringify([ids, kinds]);
|
|
24040
|
+
if (next === lastSerializedRef.current) return;
|
|
24041
|
+
lastSerializedRef.current = next;
|
|
24042
|
+
setState({ selection: ids, kinds });
|
|
24043
|
+
}, []);
|
|
24044
|
+
const value = useMemo(
|
|
24045
|
+
() => ({
|
|
24046
|
+
selection: state.selection,
|
|
24047
|
+
...state.kinds !== void 0 ? { kinds: state.kinds } : {},
|
|
24048
|
+
publishSelection
|
|
24049
|
+
}),
|
|
24050
|
+
[state, publishSelection]
|
|
24051
|
+
);
|
|
24052
|
+
return /* @__PURE__ */ jsx(SelectionContext.Provider, { value, children });
|
|
24053
|
+
}
|
|
24054
|
+
function SelectionContextProviderIfRoot({
|
|
24055
|
+
children
|
|
24056
|
+
}) {
|
|
24057
|
+
const parent = useContext(SelectionContext);
|
|
24058
|
+
if (parent !== null) return /* @__PURE__ */ jsx(Fragment, { children });
|
|
24059
|
+
return /* @__PURE__ */ jsx(SelectionContextProvider, { children });
|
|
24060
|
+
}
|
|
23659
24061
|
function usePublishSelection(ids, kinds) {
|
|
23660
24062
|
const ctx = useContext(SelectionContext);
|
|
23661
24063
|
const idsRef = useRef(ids);
|
|
@@ -25113,7 +25515,7 @@ function useDispatcherOverlayLayer(args) {
|
|
|
25113
25515
|
break;
|
|
25114
25516
|
case "pencil": {
|
|
25115
25517
|
if (geom.samples.length < 2) break;
|
|
25116
|
-
pathCmd =
|
|
25518
|
+
pathCmd = polylineFromPoints(projectPoints(geom.samples));
|
|
25117
25519
|
break;
|
|
25118
25520
|
}
|
|
25119
25521
|
}
|
|
@@ -25125,7 +25527,7 @@ function useDispatcherOverlayLayer(args) {
|
|
|
25125
25527
|
stroke: { paint: { color: cfg.stroke }, width: cfg.lineWidth, dash: cfg.dash }
|
|
25126
25528
|
};
|
|
25127
25529
|
out.push(cmd);
|
|
25128
|
-
if (ov.anchorPoint) {
|
|
25530
|
+
if (ov.anchorPoint && ov.shape !== "pencil") {
|
|
25129
25531
|
const anchorScreen = projectPoint(ov.anchorPoint.x, ov.anchorPoint.y);
|
|
25130
25532
|
out.push({
|
|
25131
25533
|
kind: "path",
|
|
@@ -26994,7 +27396,7 @@ function SceneCanvasInner(props, ref) {
|
|
|
26994
27396
|
boundary: inertiaObj.boundary,
|
|
26995
27397
|
bounds: inertiaObj.bounds
|
|
26996
27398
|
} : void 0;
|
|
26997
|
-
const handTool = useHandTool(handToolInertia ? {
|
|
27399
|
+
const handTool = useHandTool(handToolInertia ? {} : {});
|
|
26998
27400
|
const viewportAmbient = [];
|
|
26999
27401
|
const baseRequestedTools = defaultTools ?? (toolBundle ? BUNDLE_TOOLS[toolBundle] : null) ?? (viewportRegistered ? ["select", "rotate", "hand"] : ["select", "rotate"]);
|
|
27000
27402
|
const KNOWN_BUILTIN_IDS = /* @__PURE__ */ new Set([
|
|
@@ -27719,14 +28121,12 @@ function StandardActionsRegistrar({
|
|
|
27719
28121
|
}, [registry22, actionsRegistryRef]);
|
|
27720
28122
|
useEffect(() => {
|
|
27721
28123
|
if (!registry22) return;
|
|
27722
|
-
registry22.setDispatcher(dispatcher);
|
|
27723
|
-
return () => registry22.setDispatcher(null);
|
|
28124
|
+
return registry22.setDispatcher(dispatcher);
|
|
27724
28125
|
}, [registry22, dispatcher]);
|
|
27725
28126
|
const wiredDepRegistry = useDepRegistry();
|
|
27726
28127
|
useEffect(() => {
|
|
27727
28128
|
if (!registry22) return;
|
|
27728
|
-
registry22.setDepRegistry(wiredDepRegistry);
|
|
27729
|
-
return () => registry22.setDepRegistry(null);
|
|
28129
|
+
return registry22.setDepRegistry(wiredDepRegistry);
|
|
27730
28130
|
}, [registry22, wiredDepRegistry]);
|
|
27731
28131
|
useEffect(() => {
|
|
27732
28132
|
if (!registry22) return;
|
|
@@ -27787,7 +28187,7 @@ var SceneCanvasInnerForwardRef = forwardRef(SceneCanvasInner);
|
|
|
27787
28187
|
function SceneCanvasWrapper(props, ref) {
|
|
27788
28188
|
return /* @__PURE__ */ jsx(ActiveToolContextProviderIfRoot, { children: /* @__PURE__ */ jsx(ViewRegistryProvider, { children: /* @__PURE__ */ jsx(SceneCanvasInnerForwardRef, { ...props, ref }) }) });
|
|
27789
28189
|
}
|
|
27790
|
-
forwardRef(SceneCanvasWrapper);
|
|
28190
|
+
var SceneCanvas = forwardRef(SceneCanvasWrapper);
|
|
27791
28191
|
var RAD_TO_DEG = 180 / Math.PI;
|
|
27792
28192
|
var rotationDegreesUnit = {
|
|
27793
28193
|
toDisplay: (rad) => Math.round(rad * RAD_TO_DEG * 10) / 10,
|
|
@@ -27919,9 +28319,9 @@ function shapeSchema(opts = {}) {
|
|
|
27919
28319
|
fontWeight: { kind: "number", name: "Weight", description: "Font weight, 100\u2013900.", default: 400, min: 100, max: 900, step: 100, pair: "Size / weight" },
|
|
27920
28320
|
fontStyle: { kind: "enum", name: "Style", description: "Upright or italic.", default: "normal", options: [{ value: "normal", label: "Normal" }, { value: "italic", label: "Italic" }] },
|
|
27921
28321
|
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 }
|
|
28322
|
+
underline: { kind: "boolean", name: "Underline", description: "Underline the text.", default: false, control: "toggle", short: "U", pair: "Decoration" },
|
|
28323
|
+
strikethrough: { kind: "boolean", name: "Strikethrough", description: "Strike through the text.", default: false, control: "toggle", short: "S", pair: "Decoration" },
|
|
28324
|
+
overline: { kind: "boolean", name: "Overline", description: "Rule the text above its ascent.", default: false, control: "toggle", short: "O", pair: "Decoration" }
|
|
27925
28325
|
}
|
|
27926
28326
|
},
|
|
27927
28327
|
paragraph: {
|
|
@@ -28274,6 +28674,125 @@ function MinimapCanvasInner(props) {
|
|
|
28274
28674
|
);
|
|
28275
28675
|
}
|
|
28276
28676
|
var MinimapCanvas = MinimapCanvasInner;
|
|
28677
|
+
function planPixelRender(args) {
|
|
28678
|
+
const { sourceRect, scale: scale2 } = args;
|
|
28679
|
+
for (const [label, v] of [
|
|
28680
|
+
["sourceRect.width", sourceRect.width],
|
|
28681
|
+
["sourceRect.height", sourceRect.height],
|
|
28682
|
+
["scale.x", scale2.x],
|
|
28683
|
+
["scale.y", scale2.y]
|
|
28684
|
+
]) {
|
|
28685
|
+
if (!Number.isFinite(v) || v <= 0) {
|
|
28686
|
+
throw new Error(`renderSceneToPixels: ${label} must be a positive finite number, got ${v}`);
|
|
28687
|
+
}
|
|
28688
|
+
}
|
|
28689
|
+
for (const [label, v] of [
|
|
28690
|
+
["sourceRect.x", sourceRect.x],
|
|
28691
|
+
["sourceRect.y", sourceRect.y]
|
|
28692
|
+
]) {
|
|
28693
|
+
if (!Number.isFinite(v)) {
|
|
28694
|
+
throw new Error(`renderSceneToPixels: ${label} must be a finite number, got ${v}`);
|
|
28695
|
+
}
|
|
28696
|
+
}
|
|
28697
|
+
const width = Math.max(1, Math.round(sourceRect.width * scale2.x));
|
|
28698
|
+
const height = Math.max(1, Math.round(sourceRect.height * scale2.y));
|
|
28699
|
+
const view = { x: sourceRect.x, y: sourceRect.y, scale: { x: scale2.x, y: scale2.y } };
|
|
28700
|
+
const resolveImage = args.resolveImage;
|
|
28701
|
+
const drawOne = args.drawOne ?? ((node, pose, view2, ctx) => defaultDrawOne(node, pose, view2, { ...ctx, resolveImage }));
|
|
28702
|
+
const commands = [];
|
|
28703
|
+
if (args.background !== void 0) {
|
|
28704
|
+
commands.push({
|
|
28705
|
+
kind: "path",
|
|
28706
|
+
path: { kind: "rect", x: 0, y: 0, width, height },
|
|
28707
|
+
fill: { fill: "solid", color: args.background }
|
|
28708
|
+
});
|
|
28709
|
+
}
|
|
28710
|
+
commands.push(...buildSceneViewCommands(args.scene, view, drawOne, void 0, args.alphaFor));
|
|
28711
|
+
return { width, height, view, commands };
|
|
28712
|
+
}
|
|
28713
|
+
function defaultCreateCanvas(width, height) {
|
|
28714
|
+
if (typeof OffscreenCanvas !== "undefined") {
|
|
28715
|
+
return new OffscreenCanvas(width, height);
|
|
28716
|
+
}
|
|
28717
|
+
if (typeof document !== "undefined") {
|
|
28718
|
+
const c = document.createElement("canvas");
|
|
28719
|
+
c.width = width;
|
|
28720
|
+
c.height = height;
|
|
28721
|
+
return c;
|
|
28722
|
+
}
|
|
28723
|
+
throw new Error("renderSceneToPixels: no canvas source in this environment \u2014 supply `gl` or `createCanvas`");
|
|
28724
|
+
}
|
|
28725
|
+
function flipRows(raw, width, height) {
|
|
28726
|
+
const rowBytes = width * 4;
|
|
28727
|
+
const out = new Uint8ClampedArray(raw.length);
|
|
28728
|
+
for (let y = 0; y < height; y++) {
|
|
28729
|
+
out.set(raw.subarray((height - 1 - y) * rowBytes, (height - y) * rowBytes), y * rowBytes);
|
|
28730
|
+
}
|
|
28731
|
+
return out;
|
|
28732
|
+
}
|
|
28733
|
+
function unpremultiply(data) {
|
|
28734
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
28735
|
+
const a = data[i + 3];
|
|
28736
|
+
if (a === 0 || a === 255) continue;
|
|
28737
|
+
const inv = 255 / a;
|
|
28738
|
+
data[i] = data[i] * inv;
|
|
28739
|
+
data[i + 1] = data[i + 1] * inv;
|
|
28740
|
+
data[i + 2] = data[i + 2] * inv;
|
|
28741
|
+
}
|
|
28742
|
+
}
|
|
28743
|
+
function renderSceneToPixels(args) {
|
|
28744
|
+
if (args.gl && args.createCanvas) {
|
|
28745
|
+
throw new Error("renderSceneToPixels: `gl` and `createCanvas` are mutually exclusive");
|
|
28746
|
+
}
|
|
28747
|
+
const plan = planPixelRender(args);
|
|
28748
|
+
const { width, height } = plan;
|
|
28749
|
+
let gl = args.gl;
|
|
28750
|
+
if (!gl) {
|
|
28751
|
+
const canvas = (args.createCanvas ?? defaultCreateCanvas)(width, height);
|
|
28752
|
+
canvas.width = width;
|
|
28753
|
+
canvas.height = height;
|
|
28754
|
+
gl = canvas.getContext("webgl2", { preserveDrawingBuffer: true, stencil: true }) ?? void 0;
|
|
28755
|
+
}
|
|
28756
|
+
if (!gl || typeof gl.enable !== "function") {
|
|
28757
|
+
throw new Error("renderSceneToPixels: WebGL2 is unavailable \u2014 supply `gl` or a WebGL2-capable `createCanvas`");
|
|
28758
|
+
}
|
|
28759
|
+
if (typeof gl.isContextLost === "function" && gl.isContextLost()) {
|
|
28760
|
+
throw new Error("renderSceneToPixels: the supplied WebGL2 context is lost");
|
|
28761
|
+
}
|
|
28762
|
+
const flattenTolerancePx = args.flattenTolerancePx ?? 0.25;
|
|
28763
|
+
const renderer = new WeaselRenderer({
|
|
28764
|
+
gl,
|
|
28765
|
+
width,
|
|
28766
|
+
height,
|
|
28767
|
+
dpr: 1,
|
|
28768
|
+
imageMinification: "mipmap",
|
|
28769
|
+
flattenTolerance: flattenTolerancePx / Math.max(args.scale.x, args.scale.y),
|
|
28770
|
+
// Dynamic canvas-SDF glyphs must all bake inline — this path is
|
|
28771
|
+
// synchronous with no notify-and-redraw, and print must be complete.
|
|
28772
|
+
bakeBudget: Infinity
|
|
28773
|
+
});
|
|
28774
|
+
try {
|
|
28775
|
+
renderer.render(plan.commands, viewToMat3(plan.view));
|
|
28776
|
+
if (typeof gl.isContextLost === "function" && gl.isContextLost()) {
|
|
28777
|
+
throw new Error("renderSceneToPixels: WebGL2 context was lost during render");
|
|
28778
|
+
}
|
|
28779
|
+
const raw = new Uint8Array(width * height * 4);
|
|
28780
|
+
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, raw);
|
|
28781
|
+
const data = flipRows(raw, width, height);
|
|
28782
|
+
unpremultiply(data);
|
|
28783
|
+
return { width, height, data };
|
|
28784
|
+
} finally {
|
|
28785
|
+
renderer.dispose();
|
|
28786
|
+
}
|
|
28787
|
+
}
|
|
28788
|
+
function WeaselProvider({ children, isolate = false }) {
|
|
28789
|
+
const Deps = isolate ? DepRegistryProvider : DepRegistryProviderIfRoot;
|
|
28790
|
+
const Actions = isolate ? ActionsProvider : ActionsProviderIfRoot;
|
|
28791
|
+
const ActiveTool = isolate ? ActiveToolContextProvider : ActiveToolContextProviderIfRoot;
|
|
28792
|
+
const Selection = isolate ? SelectionContextProvider : SelectionContextProviderIfRoot;
|
|
28793
|
+
const Pointer = isolate ? PointerContextProvider : PointerProviderIfRoot;
|
|
28794
|
+
return /* @__PURE__ */ jsx(Deps, { children: /* @__PURE__ */ jsx(Actions, { children: /* @__PURE__ */ jsx(ActiveTool, { children: /* @__PURE__ */ jsx(Selection, { children: /* @__PURE__ */ jsx(Pointer, { children }) }) }) }) });
|
|
28795
|
+
}
|
|
28277
28796
|
function createSetTextOp(args) {
|
|
28278
28797
|
const { id, from, to, label, coalesceKey = `setText:${id}` } = args;
|
|
28279
28798
|
return {
|
|
@@ -28410,6 +28929,6 @@ function oklchToOklab(L, C, h) {
|
|
|
28410
28929
|
return [L, C * Math.cos(h), C * Math.sin(h)];
|
|
28411
28930
|
}
|
|
28412
28931
|
|
|
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-
|
|
28932
|
+
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 };
|
|
28933
|
+
//# sourceMappingURL=chunk-L5QJOOLV.js.map
|
|
28934
|
+
//# sourceMappingURL=chunk-L5QJOOLV.js.map
|