@weasel-js/core 1.10.0 → 1.10.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/CHANGELOG.md +168 -0
- package/README.md +33 -0
- package/dist/affordances/composeAffordanceLayer.js +21 -21
- package/dist/affordances/composeAffordanceLayer.js.map +1 -1
- package/dist/affordances/hitAffordanceRegions.js +48 -32
- package/dist/affordances/hitAffordanceRegions.js.map +1 -1
- package/dist/affordances/pathAnchors.js +50 -28
- package/dist/affordances/pathAnchors.js.map +1 -1
- package/dist/affordances/rotateCursor.js +12 -0
- package/dist/affordances/rotateCursor.js.map +1 -0
- package/dist/affordances/rotationHandle.js +40 -43
- package/dist/affordances/rotationHandle.js.map +1 -1
- package/dist/animation/rig/rigNode.js +9 -3
- package/dist/animation/rig/rigNode.js.map +1 -1
- package/dist/animation/rig/rigSeat.js +46 -13
- package/dist/animation/rig/rigSeat.js.map +1 -1
- package/dist/animation/rig/skinBinding.js +22 -14
- package/dist/animation/rig/skinBinding.js.map +1 -1
- package/dist/barrel/canvas.js +29 -28
- package/dist/barrel/interactions.js +33 -32
- package/dist/barrel/paths.js +11 -10
- package/dist/barrel/routing.js +49 -48
- package/dist/barrel/scene.js +10 -10
- package/dist/barrel/viewport.js +24 -21
- package/dist/canvas/Canvas.js +6 -17
- package/dist/canvas/Canvas.js.map +1 -1
- package/dist/canvas/CanvasView.js +34 -37
- package/dist/canvas/CanvasView.js.map +1 -1
- package/dist/canvas/CursorCoordsHud.js +3 -3
- package/dist/canvas/CursorCoordsHud.js.map +1 -1
- package/dist/canvas/DrawCanvas.js +3 -3
- package/dist/canvas/DrawCanvas.js.map +1 -1
- package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +24 -23
- package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js.map +1 -1
- package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js +40 -49
- package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js.map +1 -1
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js +297 -259
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -1
- package/dist/canvas/SceneCanvas/features.js +3 -24
- package/dist/canvas/SceneCanvas/features.js.map +1 -1
- package/dist/canvas/SceneCanvas/insertPreviewCommands.js +97 -0
- package/dist/canvas/SceneCanvas/insertPreviewCommands.js.map +1 -0
- package/dist/canvas/SceneCanvas/poseGeometry.js.map +1 -1
- package/dist/canvas/SceneCanvas/props.js.map +1 -1
- package/dist/canvas/SceneCanvas/scenePointQuery.js +50 -0
- package/dist/canvas/SceneCanvas/scenePointQuery.js.map +1 -0
- package/dist/canvas/SceneCanvas/shapeGeneratorProperties.js +52 -0
- package/dist/canvas/SceneCanvas/shapeGeneratorProperties.js.map +1 -0
- package/dist/canvas/SceneCanvas/useActionTunings.js +17 -0
- package/dist/canvas/SceneCanvas/useActionTunings.js.map +1 -0
- package/dist/canvas/SceneCanvas/useCanvasCamera.js +37 -29
- package/dist/canvas/SceneCanvas/useCanvasCamera.js.map +1 -1
- package/dist/canvas/SceneCanvas/useCanvasDispatcher.js +11 -11
- package/dist/canvas/SceneCanvas/useCanvasDispatcher.js.map +1 -1
- package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js +45 -109
- package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js.map +1 -1
- package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +49 -41
- package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js +64 -96
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
- package/dist/canvas/SceneCanvas/worldPointAt.js +3 -4
- package/dist/canvas/SceneCanvas/worldPointAt.js.map +1 -1
- package/dist/canvas/SceneCanvas.js +77 -80
- package/dist/canvas/SceneCanvas.js.map +1 -1
- package/dist/canvas/SceneViewCanvas.js +3 -3
- package/dist/canvas/SceneViewCanvas.js.map +1 -1
- package/dist/canvas/SurfaceCanvas.js +40 -0
- package/dist/canvas/SurfaceCanvas.js.map +1 -0
- package/dist/canvas/adapterDerivedPath.js +13 -13
- package/dist/canvas/adapterDerivedPath.js.map +1 -1
- package/dist/canvas/adapterPickSource.js +34 -0
- package/dist/canvas/adapterPickSource.js.map +1 -0
- package/dist/canvas/affordanceAt.js +1 -1
- package/dist/canvas/affordanceAt.js.map +1 -1
- package/dist/canvas/buildSceneLayer.js.map +1 -1
- package/dist/canvas/buildSceneTree.js +56 -34
- package/dist/canvas/buildSceneTree.js.map +1 -1
- package/dist/canvas/copiesAbove.js +27 -0
- package/dist/canvas/copiesAbove.js.map +1 -0
- package/dist/canvas/defaultDrawOne.js +24 -23
- package/dist/canvas/defaultDrawOne.js.map +1 -1
- package/dist/canvas/deps/editAnchors.js +45 -50
- package/dist/canvas/deps/editAnchors.js.map +1 -1
- package/dist/canvas/deps/hitTestArea.js +30 -15
- package/dist/canvas/deps/hitTestArea.js.map +1 -1
- package/dist/canvas/deps/insert.js +134 -100
- package/dist/canvas/deps/insert.js.map +1 -1
- package/dist/canvas/deps/layout.js +9 -15
- package/dist/canvas/deps/layout.js.map +1 -1
- package/dist/canvas/derivedPath.js +53 -29
- package/dist/canvas/derivedPath.js.map +1 -1
- package/dist/canvas/insertPreviewExtent.js +33 -31
- package/dist/canvas/insertPreviewExtent.js.map +1 -1
- package/dist/canvas/overChildren.js +29 -0
- package/dist/canvas/overChildren.js.map +1 -0
- package/dist/canvas/paintedCursorLayer.js.map +1 -1
- package/dist/canvas/pickReach.js +23 -0
- package/dist/canvas/pickReach.js.map +1 -0
- package/dist/canvas/pickWalk.js +51 -80
- package/dist/canvas/pickWalk.js.map +1 -1
- package/dist/canvas/sceneAdapter.js +14 -35
- package/dist/canvas/sceneAdapter.js.map +1 -1
- package/dist/canvas/sceneSlotWiring.js +11 -10
- package/dist/canvas/sceneSlotWiring.js.map +1 -1
- package/dist/canvas/sceneViewRender.js +38 -44
- package/dist/canvas/sceneViewRender.js.map +1 -1
- package/dist/canvas/useCanvasView.js +42 -44
- package/dist/canvas/useCanvasView.js.map +1 -1
- package/dist/canvas/useSceneAdapter.js +22 -0
- package/dist/canvas/useSceneAdapter.js.map +1 -0
- package/dist/canvas/useSurfaceInput.js +13 -16
- package/dist/canvas/useSurfaceInput.js.map +1 -1
- package/dist/canvas/viewRegistry.js +31 -23
- package/dist/canvas/viewRegistry.js.map +1 -1
- package/dist/canvas/wrapNodeOutput.js +7 -2
- package/dist/canvas/wrapNodeOutput.js.map +1 -1
- package/dist/clipboard.d.ts +1 -1
- package/dist/{clone-2a5hVbBd.d.ts → clone-C0eADtS0.d.ts} +13 -13
- package/dist/clone.d.ts +2 -2
- package/dist/core/geometry/poseDescriptor.js +49 -23
- package/dist/core/geometry/poseDescriptor.js.map +1 -1
- package/dist/core/geometry/regionHit.js +2 -2
- package/dist/core/geometry/regionHit.js.map +1 -1
- package/dist/core/geometry/targetFrame.js.map +1 -1
- package/dist/core/layers/children.js +1 -3
- package/dist/core/layers/children.js.map +1 -1
- package/dist/core/ops/create.js +2 -2
- package/dist/core/ops/create.js.map +1 -1
- package/dist/core/ops/delete.js +19 -23
- package/dist/core/ops/delete.js.map +1 -1
- package/dist/core/ops/reorder/index.js +3 -7
- package/dist/core/ops/reorder/index.js.map +1 -1
- package/dist/core/ops/reorder/setChildOrder.js +2 -4
- package/dist/core/ops/reorder/setChildOrder.js.map +1 -1
- package/dist/core/ops/reparent.js +0 -1
- package/dist/core/ops/reparent.js.map +1 -1
- package/dist/core/ops/slot.js +3 -6
- package/dist/core/ops/slot.js.map +1 -1
- package/dist/core/pages/fitViewToPage.js +15 -0
- package/dist/core/pages/fitViewToPage.js.map +1 -0
- package/dist/core/pages/pages.js +65 -0
- package/dist/core/pages/pages.js.map +1 -0
- package/dist/core/pages/pagesLayer.js +27 -0
- package/dist/core/pages/pagesLayer.js.map +1 -0
- package/dist/core/paint/meshKindLazy.js +2 -2
- package/dist/core/paint/meshKindLazy.js.map +1 -1
- package/dist/core/scene/NodeProperties.js.map +1 -1
- package/dist/core/scene/composeFrame.js.map +1 -1
- package/dist/core/scene/composePose.js +58 -20
- package/dist/core/scene/composePose.js.map +1 -1
- package/dist/core/scene/effectivePose.js +5 -1
- package/dist/core/scene/effectivePose.js.map +1 -1
- package/dist/core/scene/historyFacade.js +19 -13
- package/dist/core/scene/historyFacade.js.map +1 -1
- package/dist/core/scene/nodeFnFields.js +7 -0
- package/dist/core/scene/nodeFnFields.js.map +1 -1
- package/dist/core/scene/outerOps.js +2 -1
- package/dist/core/scene/outerOps.js.map +1 -1
- package/dist/core/scene/reconcileSpecs.js +1 -1
- package/dist/core/scene/reconcileSpecs.js.map +1 -1
- package/dist/core/scene/sceneRecording.js +2 -1
- package/dist/core/scene/sceneRecording.js.map +1 -1
- package/dist/core/scene/types.js.map +1 -1
- package/dist/core/viewport/screenSlop.js.map +1 -1
- package/dist/core/viewport/useDecayLoop.js +28 -30
- package/dist/core/viewport/useDecayLoop.js.map +1 -1
- package/dist/core/viewport/useNodeOverlayFrame.js.map +1 -1
- package/dist/core/viewport/useViewAnimation.js +70 -69
- package/dist/core/viewport/useViewAnimation.js.map +1 -1
- package/dist/core/viewport/view.js +8 -5
- package/dist/core/viewport/view.js.map +1 -1
- package/dist/core/viewport/zoomAt.js +11 -2
- package/dist/core/viewport/zoomAt.js.map +1 -1
- package/dist/{cornerHandles-BEshc4z3.d.ts → cornerHandles-BSKbyuvQ.d.ts} +1 -1
- package/dist/features/paths/editablePath.js +24 -8
- package/dist/features/paths/editablePath.js.map +1 -1
- package/dist/features/paths/index.js +4 -4
- package/dist/features/paths/shapeGenerator.js +89 -0
- package/dist/features/paths/shapeGenerator.js.map +1 -0
- package/dist/features/paths/usePathEdit.js +13 -13
- package/dist/features/poseRun/usePoseRun.js +25 -25
- package/dist/features/poseRun/usePoseRun.js.map +1 -1
- package/dist/features/text/useSceneTextEdit.js +82 -64
- package/dist/features/text/useSceneTextEdit.js.map +1 -1
- package/dist/features/viewports/viewResolver.js +28 -24
- package/dist/features/viewports/viewResolver.js.map +1 -1
- package/dist/icons/SliceIcon.js +24 -0
- package/dist/icons/SliceIcon.js.map +1 -0
- package/dist/index.d.ts +956 -581
- package/dist/index.js +260 -251
- package/dist/interactions/actions/align/align.js +9 -9
- package/dist/interactions/actions/align/align.js.map +1 -1
- package/dist/interactions/actions/booleans/booleans.js +18 -18
- package/dist/interactions/actions/booleans/booleans.js.map +1 -1
- package/dist/interactions/actions/booleans/operands.js.map +1 -1
- package/dist/interactions/actions/clone/action.js +35 -30
- package/dist/interactions/actions/clone/action.js.map +1 -1
- package/dist/interactions/actions/defaults/anchorEditing.js +56 -59
- package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -1
- package/dist/interactions/actions/defaults/anchorHandles.js +42 -0
- package/dist/interactions/actions/defaults/anchorHandles.js.map +1 -0
- package/dist/interactions/actions/defaults/anchorJoin.js +92 -0
- package/dist/interactions/actions/defaults/anchorJoin.js.map +1 -0
- package/dist/interactions/actions/defaults/bendSegment.js +46 -0
- package/dist/interactions/actions/defaults/bendSegment.js.map +1 -0
- package/dist/interactions/actions/defaults/copySubtree.js +1 -1
- package/dist/interactions/actions/defaults/copySubtree.js.map +1 -1
- package/dist/interactions/actions/defaults/duplicate.js +32 -17
- package/dist/interactions/actions/defaults/duplicate.js.map +1 -1
- package/dist/interactions/actions/defaults/enterPathEdit.js +19 -7
- package/dist/interactions/actions/defaults/enterPathEdit.js.map +1 -1
- package/dist/interactions/actions/defaults/icons/anchorIcons.js +75 -0
- package/dist/interactions/actions/defaults/icons/anchorIcons.js.map +1 -0
- package/dist/interactions/actions/defaults/icons/editIcons.js +35 -8
- package/dist/interactions/actions/defaults/icons/editIcons.js.map +1 -1
- package/dist/interactions/actions/defaults/insertPathAnchor.js +16 -31
- package/dist/interactions/actions/defaults/insertPathAnchor.js.map +1 -1
- package/dist/interactions/actions/defaults/nudge.js +28 -23
- package/dist/interactions/actions/defaults/nudge.js.map +1 -1
- package/dist/interactions/actions/defaults/pinchZoom.js +29 -29
- package/dist/interactions/actions/defaults/pinchZoom.js.map +1 -1
- package/dist/interactions/actions/defaults/segmentUnder.js +22 -0
- package/dist/interactions/actions/defaults/segmentUnder.js.map +1 -0
- package/dist/interactions/actions/defaults/viewportZoom.js +82 -79
- package/dist/interactions/actions/defaults/viewportZoom.js.map +1 -1
- package/dist/interactions/actions/distribute/distribute.js +8 -8
- package/dist/interactions/actions/distribute/distribute.js.map +1 -1
- package/dist/interactions/actions/edit-anchors/action.js +58 -55
- package/dist/interactions/actions/edit-anchors/action.js.map +1 -1
- package/dist/interactions/actions/edit-anchors/preview.js +26 -0
- package/dist/interactions/actions/edit-anchors/preview.js.map +1 -0
- package/dist/interactions/actions/edit-anchors/symmetry.js +11 -0
- package/dist/interactions/actions/edit-anchors/symmetry.js.map +1 -0
- package/dist/interactions/actions/flip/action.js.map +1 -1
- package/dist/interactions/actions/geometryProjection.js.map +1 -1
- package/dist/interactions/actions/insert/action.js +37 -30
- package/dist/interactions/actions/insert/action.js.map +1 -1
- package/dist/interactions/actions/insert/frame.js +9 -2
- package/dist/interactions/actions/insert/frame.js.map +1 -1
- package/dist/interactions/actions/insert/repositionAction.js +31 -0
- package/dist/interactions/actions/insert/repositionAction.js.map +1 -0
- package/dist/interactions/actions/lasso-select/action.js +32 -32
- package/dist/interactions/actions/move/action.js +29 -25
- package/dist/interactions/actions/move/action.js.map +1 -1
- package/dist/interactions/actions/move/behaviors/snapToContainer.js +12 -6
- package/dist/interactions/actions/move/behaviors/snapToContainer.js.map +1 -1
- package/dist/interactions/actions/move/capture.js +32 -23
- package/dist/interactions/actions/move/capture.js.map +1 -1
- package/dist/interactions/actions/move/frame.js +2 -14
- package/dist/interactions/actions/move/frame.js.map +1 -1
- package/dist/interactions/actions/move/session.js +1 -1
- package/dist/interactions/actions/move/session.js.map +1 -1
- package/dist/interactions/actions/move/translate.js.map +1 -1
- package/dist/interactions/actions/outlines/createOutlines.js.map +1 -1
- package/dist/interactions/actions/outlines/replaceWithPaths.js +13 -13
- package/dist/interactions/actions/outlines/replaceWithPaths.js.map +1 -1
- package/dist/interactions/actions/outlines/strokeRegion.js.map +1 -1
- package/dist/interactions/actions/pathCommands/cutJoin.js +102 -0
- package/dist/interactions/actions/pathCommands/cutJoin.js.map +1 -0
- package/dist/interactions/actions/pathCommands/livePathEdit.js +64 -0
- package/dist/interactions/actions/pathCommands/livePathEdit.js.map +1 -0
- package/dist/interactions/actions/pathCommands/pathNodes.js +99 -0
- package/dist/interactions/actions/pathCommands/pathNodes.js.map +1 -0
- package/dist/interactions/actions/pathCommands/simplifyOffset.js +42 -0
- package/dist/interactions/actions/pathCommands/simplifyOffset.js.map +1 -0
- package/dist/interactions/actions/resize/action.js +31 -20
- package/dist/interactions/actions/resize/action.js.map +1 -1
- package/dist/interactions/actions/resize/commit.js.map +1 -1
- package/dist/interactions/actions/resize/frame.js +29 -15
- package/dist/interactions/actions/resize/frame.js.map +1 -1
- package/dist/interactions/actions/resize/replay.js +47 -0
- package/dist/interactions/actions/resize/replay.js.map +1 -0
- package/dist/interactions/actions/resize/session.js +49 -35
- package/dist/interactions/actions/resize/session.js.map +1 -1
- package/dist/interactions/actions/resolveOverlays.js +2 -1
- package/dist/interactions/actions/resolveOverlays.js.map +1 -1
- package/dist/interactions/actions/rotate/action.js +40 -25
- package/dist/interactions/actions/rotate/action.js.map +1 -1
- package/dist/interactions/actions/rotate/frame.js +1 -1
- package/dist/interactions/actions/rotate/frame.js.map +1 -1
- package/dist/interactions/actions/rotate/replay.js +22 -0
- package/dist/interactions/actions/rotate/replay.js.map +1 -0
- package/dist/interactions/actions/rotate/session.js +42 -32
- package/dist/interactions/actions/rotate/session.js.map +1 -1
- package/dist/interactions/actions/transform-again/action.js +63 -0
- package/dist/interactions/actions/transform-again/action.js.map +1 -0
- package/dist/interactions/actions/transform-again/memory.js +35 -0
- package/dist/interactions/actions/transform-again/memory.js.map +1 -0
- package/dist/interactions/actions/useStandardActions.js +101 -83
- package/dist/interactions/actions/useStandardActions.js.map +1 -1
- package/dist/move.d.ts +4 -4
- package/dist/{originProjection-PPT88jZv.d.ts → originProjection-CoNVpITV.d.ts} +1 -1
- package/dist/resize.d.ts +3 -3
- package/dist/style.css +1 -1
- package/dist/tools/builtin/ellipse/useEllipseTool.js +16 -15
- package/dist/tools/builtin/ellipse/useEllipseTool.js.map +1 -1
- package/dist/tools/builtin/line/useLineTool.js +16 -15
- package/dist/tools/builtin/line/useLineTool.js.map +1 -1
- package/dist/tools/builtin/pen/usePenTool.js +111 -111
- package/dist/tools/builtin/pen/usePenTool.js.map +1 -1
- package/dist/tools/builtin/pickTopMostHit.js +11 -14
- package/dist/tools/builtin/pickTopMostHit.js.map +1 -1
- package/dist/tools/builtin/polygon/usePolygonTool.js +17 -15
- package/dist/tools/builtin/polygon/usePolygonTool.js.map +1 -1
- package/dist/tools/builtin/rect/useRectTool.js +15 -14
- package/dist/tools/builtin/rect/useRectTool.js.map +1 -1
- package/dist/tools/builtin/select/adapterPointQuery.js +22 -18
- package/dist/tools/builtin/select/adapterPointQuery.js.map +1 -1
- package/dist/tools/builtin/select/selectionContributions.js +1 -1
- package/dist/tools/builtin/select/selectionContributions.js.map +1 -1
- package/dist/tools/builtin/select/useSelectTool.js +2 -1
- package/dist/tools/builtin/select/useSelectTool.js.map +1 -1
- package/dist/tools/builtin/slice/useSliceTool.js +42 -40
- package/dist/tools/builtin/slice/useSliceTool.js.map +1 -1
- package/dist/tools/builtin/star/useStarTool.js +18 -16
- package/dist/tools/builtin/star/useStarTool.js.map +1 -1
- package/dist/tools/builtin/text/useTextTool.js +2 -2
- package/dist/tools/builtin/text/useTextTool.js.map +1 -1
- package/dist/{types-CIKDwlsP.d.ts → types-DBbbCy0i.d.ts} +22 -15
- package/dist/version.js +1 -1
- package/package.json +22 -22
- package/dist/canvas/surface.module.js +0 -6
- package/dist/canvas/surface.module.js.map +0 -1
- package/dist/canvas/surfaceBox.js +0 -16
- package/dist/canvas/surfaceBox.js.map +0 -1
- package/dist/layout/arrivals.js +0 -33
- package/dist/layout/arrivals.js.map +0 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { toPlane as e } from "../../core/viewport/parallax.js";
|
|
2
|
+
import { findShapeInk as t, shapeCoversPoint as n } from "../NodeShape.js";
|
|
3
|
+
import { poseContains as r, poseContainsRotated as i } from "./poseGeometry.js";
|
|
4
|
+
import { applyToPoint as a, meanScale as o, pathContainsPoint as s } from "@weasel-js/geom";
|
|
5
|
+
//#region src/canvas/SceneCanvas/scenePointQuery.ts
|
|
6
|
+
function c(c, l, u) {
|
|
7
|
+
let d = (f, p, m) => {
|
|
8
|
+
let h = o(m), g = {
|
|
9
|
+
px: u,
|
|
10
|
+
scale: m
|
|
11
|
+
};
|
|
12
|
+
return {
|
|
13
|
+
hits: (e, a, o) => {
|
|
14
|
+
let s = l ? t(e, a, { scale: h }) : null, u = {
|
|
15
|
+
...g,
|
|
16
|
+
px: g.px + (s?.outsetPx ?? 0),
|
|
17
|
+
reach: s?.outset ?? 0
|
|
18
|
+
};
|
|
19
|
+
return (o ? r(o, f, p, u, c) : i(a, f, p, u, c)) ? !l || n(e, a, f, p, {
|
|
20
|
+
tolerance: g,
|
|
21
|
+
scale: h,
|
|
22
|
+
derivedPath: o
|
|
23
|
+
}) : !1;
|
|
24
|
+
},
|
|
25
|
+
clipAdmits: (e) => s(e, f, p),
|
|
26
|
+
inPlane: (t) => {
|
|
27
|
+
let n = e(t, {
|
|
28
|
+
x: f,
|
|
29
|
+
y: p
|
|
30
|
+
});
|
|
31
|
+
return d(n.x, n.y, {
|
|
32
|
+
x: m.x / t.scale.x,
|
|
33
|
+
y: m.y / t.scale.y
|
|
34
|
+
});
|
|
35
|
+
},
|
|
36
|
+
inCopy: (e) => {
|
|
37
|
+
let [t, n] = a(e, f, p), r = Math.sqrt(Math.abs(e[0] * e[3] - e[1] * e[2]));
|
|
38
|
+
return d(t, n, {
|
|
39
|
+
x: m.x / r,
|
|
40
|
+
y: m.y / r
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
return d;
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
export { c as scenePointQuery };
|
|
49
|
+
|
|
50
|
+
//# sourceMappingURL=scenePointQuery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scenePointQuery.js","names":["scenePointQuery","pointQuery","scale","meanScale","s","tolerance","pickTolerancePx","ink","shapePicking","findShapeInk","n","pose","slop","derived","poseContains","px","py","d","poseContainsRotated","shapeCoversPoint","pathContainsPoint","clip","p","toPlane","m","x","y","applyToPoint","k"],"sources":["../../../src/canvas/SceneCanvas/scenePointQuery.ts"],"sourcesContent":["import { applyToPoint, meanScale, pathContainsPoint } from '@weasel-js/geom';\nimport type { PickQuery } from 'canvas/pickWalk';\nimport { findShapeInk, shapeCoversPoint } from 'canvas/NodeShape';\nimport { toPlane } from 'core/viewport/parallax';\nimport type { PoseDescriptor } from 'interactions/actions/resize/geometry';\nimport { poseContains, poseContainsRotated } from './poseGeometry';\n\n/** The point query `<SceneCanvas>`'s default pick asks: a world point with\n * `pickTolerancePx` of screen slop, refined to the painter's ink when\n * `shapePicking` is on. */\nexport function scenePointQuery<TPose>(\n d: PoseDescriptor<unknown>,\n shapePicking: boolean,\n pickTolerancePx: number,\n): (px: number, py: number, s: { x: number; y: number }) => PickQuery<TPose> {\n // `s` makes the slop a screen distance, so the grab zone stays the same\n // apparent thickness at any zoom and on every axis. A `{ px }` stroke's\n // reach is on screen too, and joins the slop there.\n const pointQuery = (px: number, py: number, s: { x: number; y: number }): PickQuery<TPose> => {\n const scale = meanScale(s);\n const tolerance = { px: pickTolerancePx, scale: s };\n return {\n hits: (n, pose, derived) => {\n // The pre-filter has to be at least as generous as the refinement\n // that follows it, or it rejects points the refinement would have\n // claimed. A stroke reaches past the pose box by `outset` — a whole\n // stroke width for an outer align — on top of the pointer slop.\n const ink = shapePicking ? findShapeInk(n as never, pose, { scale }) : null;\n // A derived node's pose is a placeholder — typically zero-sized at\n // the origin — so its own box rejects every point the path covers.\n // The path is the region to test instead, and `poseContains` already\n // reads a path-like pose as one.\n const slop = { ...tolerance, px: tolerance.px + (ink?.outsetPx ?? 0), reach: ink?.outset ?? 0 };\n const admitted = derived\n ? poseContains(derived as never, px, py, slop, d as PoseDescriptor<unknown>)\n : poseContainsRotated(pose, px, py, slop, d as PoseDescriptor<unknown>);\n if (!admitted) return false;\n // `shapeCoversPoint` narrows the rect to the ink the painter actually\n // lays down (and answers `true` for painters that have no silhouette,\n // so nothing becomes unpickable).\n return !shapePicking\n || shapeCoversPoint(n as never, pose, px, py, {\n tolerance, scale, derivedPath: derived,\n });\n },\n clipAdmits: (clip) => pathContainsPoint(clip, px, py),\n inPlane: (m) => {\n const p = toPlane(m, { x: px, y: py });\n return pointQuery(p.x, p.y, { x: s.x / m.scale.x, y: s.y / m.scale.y });\n },\n inCopy: (m) => {\n const [x, y] = applyToPoint(m, px, py);\n const k = Math.sqrt(Math.abs(m[0] * m[3] - m[1] * m[2]));\n return pointQuery(x, y, { x: s.x / k, y: s.y / k });\n },\n };\n };\n return pointQuery;\n}\n"],"mappings":";;;;;AAUA,SAAgBA,EACd,GACA,GACA,GAC2E;CAI3E,IAAMC,KAAc,GAAY,GAAY,MAAkD;EAC5F,IAAMC,IAAQC,EAAUC,CAAC,GACnBC,IAAY;GAAE,IAAIC;GAAiB,OAAOF;EAAE;EAClD,OAAO;GACL,OAAO,GAAG,GAAM,MAAY;IAK1B,IAAMG,IAAMC,IAAeC,EAAaC,GAAYC,GAAM,EAAE,SAAM,CAAC,IAAI,MAKjEC,IAAO;KAAE,GAAGP;KAAW,IAAIA,EAAU,MAAME,GAAK,YAAY;KAAI,OAAOA,GAAK,UAAU;IAAE;IAQ9F,QAPiBM,IACbC,EAAaD,GAAkBE,GAAIC,GAAIJ,GAAMK,CAA4B,IACzEC,EAAoBP,GAAMI,GAAIC,GAAIJ,GAAMK,CAA4B,KAKjE,CAACT,KACHW,EAAiBT,GAAYC,GAAMI,GAAIC,GAAI;KAC5C;KAAW;KAAO,aAAaH;IACjC,CAAC,IAPmB;GAQxB;GACA,aAAa,MAASO,EAAkBC,GAAMN,GAAIC,CAAE;GACpD,UAAU,MAAM;IACd,IAAMM,IAAIC,EAAQC,GAAG;KAAE,GAAGT;KAAI,GAAGC;IAAG,CAAC;IACrC,OAAOf,EAAWqB,EAAE,GAAGA,EAAE,GAAG;KAAE,GAAGlB,EAAE,IAAIoB,EAAE,MAAM;KAAG,GAAGpB,EAAE,IAAIoB,EAAE,MAAM;IAAE,CAAC;GACxE;GACA,SAAS,MAAM;IACb,IAAM,CAACC,GAAGC,KAAKC,EAAaH,GAAGT,GAAIC,CAAE,GAC/BY,IAAI,KAAK,KAAK,KAAK,IAAIJ,EAAE,KAAKA,EAAE,KAAKA,EAAE,KAAKA,EAAE,EAAE,CAAC;IACvD,OAAOvB,EAAWwB,GAAGC,GAAG;KAAE,GAAGtB,EAAE,IAAIwB;KAAG,GAAGxB,EAAE,IAAIwB;IAAE,CAAC;GACpD;EACF;CACF;CACA,OAAO3B;AACT"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { SHAPE_COUNT_RANGE as e, STAR_RATIO_RANGE as t } from "../../features/paths/shapeGenerator.js";
|
|
2
|
+
import { decimal as n } from "@weasel-js/quantity";
|
|
3
|
+
//#region src/canvas/SceneCanvas/shapeGeneratorProperties.ts
|
|
4
|
+
var r = n({
|
|
5
|
+
maxPlaces: 2,
|
|
6
|
+
grouping: !1
|
|
7
|
+
}), i = {
|
|
8
|
+
polygon: {
|
|
9
|
+
name: "Polygon",
|
|
10
|
+
showIf: { path: "data.generator.sides" },
|
|
11
|
+
members: { "data.generator.sides": {
|
|
12
|
+
kind: "number",
|
|
13
|
+
display: r,
|
|
14
|
+
name: "Sides",
|
|
15
|
+
description: "Number of sides.",
|
|
16
|
+
default: 6,
|
|
17
|
+
min: e.min,
|
|
18
|
+
max: e.max,
|
|
19
|
+
step: 1
|
|
20
|
+
} }
|
|
21
|
+
},
|
|
22
|
+
star: {
|
|
23
|
+
name: "Star",
|
|
24
|
+
showIf: { path: "data.generator.points" },
|
|
25
|
+
members: {
|
|
26
|
+
"data.generator.points": {
|
|
27
|
+
kind: "number",
|
|
28
|
+
display: r,
|
|
29
|
+
name: "Points",
|
|
30
|
+
description: "Number of points.",
|
|
31
|
+
default: 5,
|
|
32
|
+
min: e.min,
|
|
33
|
+
max: e.max,
|
|
34
|
+
step: 1
|
|
35
|
+
},
|
|
36
|
+
"data.generator.innerRadiusRatio": {
|
|
37
|
+
kind: "number",
|
|
38
|
+
name: "Inner",
|
|
39
|
+
description: "Inner radius as a fraction of the outer one.",
|
|
40
|
+
default: .5,
|
|
41
|
+
min: t.min,
|
|
42
|
+
max: t.max,
|
|
43
|
+
step: .01,
|
|
44
|
+
control: "slider"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
//#endregion
|
|
50
|
+
export { i as SHAPE_GENERATOR_SECTIONS };
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=shapeGeneratorProperties.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shapeGeneratorProperties.js","names":["WHOLE","decimal","SHAPE_GENERATOR_SECTIONS","SHAPE_COUNT_RANGE","STAR_RATIO_RANGE"],"sources":["../../../src/canvas/SceneCanvas/shapeGeneratorProperties.ts"],"sourcesContent":["import type { PrefSection } from '@weasel-js/prefs';\nimport { decimal } from '@weasel-js/quantity';\nimport { SHAPE_COUNT_RANGE, STAR_RATIO_RANGE } from 'features/paths/shapeGenerator';\n\nconst WHOLE = decimal({ maxPlaces: 2, grouping: false });\n\n/**\n * The rows that edit a polygon's or a star's `data.generator`, each shown only\n * on a node holding that kind's generator. A write to one regenerates the\n * shape through the entry's `settle` (`settleShapeGenerator`).\n */\nexport const SHAPE_GENERATOR_SECTIONS: Record<string, PrefSection> = {\n polygon: {\n name: 'Polygon',\n showIf: { path: 'data.generator.sides' },\n members: {\n 'data.generator.sides': {\n kind: 'number', display: WHOLE, name: 'Sides', description: 'Number of sides.',\n default: 6, min: SHAPE_COUNT_RANGE.min, max: SHAPE_COUNT_RANGE.max, step: 1,\n },\n },\n },\n star: {\n name: 'Star',\n showIf: { path: 'data.generator.points' },\n members: {\n 'data.generator.points': {\n kind: 'number', display: WHOLE, name: 'Points', description: 'Number of points.',\n default: 5, min: SHAPE_COUNT_RANGE.min, max: SHAPE_COUNT_RANGE.max, step: 1,\n },\n 'data.generator.innerRadiusRatio': {\n kind: 'number', name: 'Inner', description: 'Inner radius as a fraction of the outer one.',\n default: 0.5, min: STAR_RATIO_RANGE.min, max: STAR_RATIO_RANGE.max, step: 0.01, control: 'slider',\n },\n },\n },\n};\n"],"mappings":";;;AAIA,IAAMA,IAAQC,EAAQ;CAAE,WAAW;CAAG,UAAU;AAAM,CAAC,GAO1CC,IAAwD;CACnE,SAAS;EACP,MAAM;EACN,QAAQ,EAAE,MAAM,uBAAuB;EACvC,SAAS,EACP,wBAAwB;GACtB,MAAM;GAAU,SAASF;GAAO,MAAM;GAAS,aAAa;GAC5D,SAAS;GAAG,KAAKG,EAAkB;GAAK,KAAKA,EAAkB;GAAK,MAAM;EAC5E,EACF;CACF;CACA,MAAM;EACJ,MAAM;EACN,QAAQ,EAAE,MAAM,wBAAwB;EACxC,SAAS;GACP,yBAAyB;IACvB,MAAM;IAAU,SAASH;IAAO,MAAM;IAAU,aAAa;IAC7D,SAAS;IAAG,KAAKG,EAAkB;IAAK,KAAKA,EAAkB;IAAK,MAAM;GAC5E;GACA,mCAAmC;IACjC,MAAM;IAAU,MAAM;IAAS,aAAa;IAC5C,SAAS;IAAK,KAAKC,EAAiB;IAAK,KAAKA,EAAiB;IAAK,MAAM;IAAM,SAAS;GAC3F;EACF;CACF;AACF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useEffect as e } from "react";
|
|
2
|
+
import { useActionsRegistry as t } from "@weasel-js/routing/react";
|
|
3
|
+
//#region src/canvas/SceneCanvas/useActionTunings.ts
|
|
4
|
+
function n(n) {
|
|
5
|
+
let r = t();
|
|
6
|
+
e(() => {
|
|
7
|
+
if (!r || !n) return;
|
|
8
|
+
let e = Object.entries(n).flatMap(([e, t]) => t ? [r.tune(e, t)] : []);
|
|
9
|
+
return () => {
|
|
10
|
+
for (let t of e) t();
|
|
11
|
+
};
|
|
12
|
+
}, [r, n]);
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { n as useActionTunings };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=useActionTunings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useActionTunings.js","names":["useActionTunings","reg","useActionsRegistry","tune","releases","id","release"],"sources":["../../../src/canvas/SceneCanvas/useActionTunings.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport type { ActionTuning, ActionTunings } from '@weasel-js/routing';\nimport { useActionsRegistry } from '@weasel-js/routing/react';\n\n/** Hold `tune`'s tunings on the registry in scope for as long as the object\n * is the same one. */\nexport function useActionTunings(tune: ActionTunings | undefined): void {\n const reg = useActionsRegistry();\n useEffect(() => {\n if (!reg || !tune) return;\n const releases = Object.entries(tune).flatMap(([id, t]) => (t ? [reg.tune(id, t as ActionTuning)] : []));\n return () => { for (const release of releases) release(); };\n }, [reg, tune]);\n}\n"],"mappings":";;;AAMA,SAAgBA,EAAiB,GAAuC;CACtE,IAAMC,IAAMC,EAAmB;CAC/B,QAAgB;EACd,IAAI,CAACD,KAAO,CAACE,GAAM;EACnB,IAAMC,IAAW,OAAO,QAAQD,CAAI,CAAC,CAAC,SAAS,CAACE,GAAI,OAAQ,IAAI,CAACJ,EAAI,KAAKI,GAAI,CAAiB,CAAC,IAAI,CAAC,CAAE;EACvG,aAAa;GAAE,KAAK,IAAMC,KAAWF,GAAU,EAAQ;EAAG;CAC5D,GAAG,CAACH,GAAKE,CAAI,CAAC;AAChB"}
|
|
@@ -1,38 +1,46 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { sameView as e } from "../../core/viewport/view.js";
|
|
2
|
+
import { useViewAnimationOn as t } from "../../core/viewport/useViewAnimation.js";
|
|
3
|
+
import { useCanvasView as n } from "../useCanvasView.js";
|
|
4
|
+
import { useInsertionEffect as r, useMemo as i, useRef as a } from "react";
|
|
5
|
+
import { useLatest as o } from "@weasel-js/react";
|
|
6
|
+
import { useAnimator as s } from "@weasel-js/animator";
|
|
6
7
|
//#region src/canvas/SceneCanvas/useCanvasCamera.ts
|
|
7
|
-
function
|
|
8
|
-
let { view:
|
|
9
|
-
width:
|
|
10
|
-
height:
|
|
11
|
-
}),
|
|
12
|
-
view:
|
|
13
|
-
defaultView:
|
|
8
|
+
function c(c) {
|
|
9
|
+
let { view: l, defaultView: u, onViewChange: d, viewBounds: f, width: p, height: m, requestRedraw: h } = c, g = o({
|
|
10
|
+
width: p,
|
|
11
|
+
height: m
|
|
12
|
+
}), _ = a(null), v = a(!1), y = n({
|
|
13
|
+
view: l,
|
|
14
|
+
defaultView: u,
|
|
14
15
|
onViewChange: (e) => {
|
|
15
|
-
|
|
16
|
+
_.current?.stopIfExternal(), d?.(e);
|
|
16
17
|
},
|
|
17
|
-
viewBounds:
|
|
18
|
-
dims: () =>
|
|
19
|
-
requestRedraw:
|
|
20
|
-
}),
|
|
21
|
-
get: () =>
|
|
22
|
-
set:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
viewBounds: f,
|
|
19
|
+
dims: () => g.current,
|
|
20
|
+
requestRedraw: h
|
|
21
|
+
}), b = s(), { viewRef: x, setViewFromInput: S, controlled: C } = y, w = i(() => ({
|
|
22
|
+
get: () => x.current,
|
|
23
|
+
set: (e) => {
|
|
24
|
+
v.current = !0, S(e);
|
|
25
|
+
}
|
|
26
|
+
}), [x, S]), T = t(w, b);
|
|
27
|
+
r(() => {
|
|
28
|
+
_.current = T;
|
|
29
|
+
});
|
|
30
|
+
let E = a(C);
|
|
31
|
+
return r(() => {
|
|
32
|
+
let t = E.current;
|
|
33
|
+
E.current = C, C && t && !e(t, C) && (v.current ? v.current = !1 : T.stopIfExternal());
|
|
26
34
|
}), {
|
|
27
|
-
viewState:
|
|
28
|
-
viewAnimation:
|
|
29
|
-
camera:
|
|
30
|
-
target:
|
|
31
|
-
animator:
|
|
32
|
-
}), [
|
|
35
|
+
viewState: y,
|
|
36
|
+
viewAnimation: T,
|
|
37
|
+
camera: i(() => ({
|
|
38
|
+
target: T.viewTarget,
|
|
39
|
+
animator: b
|
|
40
|
+
}), [T, b])
|
|
33
41
|
};
|
|
34
42
|
}
|
|
35
43
|
//#endregion
|
|
36
|
-
export {
|
|
44
|
+
export { c as useCanvasCamera };
|
|
37
45
|
|
|
38
46
|
//# sourceMappingURL=useCanvasCamera.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCanvasCamera.js","names":["useCanvasCamera","opts","size","useLatest","animationRef","useRef","viewState","useCanvasView","onViewChange","next","animator","useAnimator","channel","useMemo","viewRef","setViewFromInput","viewAnimation","useViewAnimationOn","useInsertionEffect"],"sources":["../../../src/canvas/SceneCanvas/useCanvasCamera.ts"],"sourcesContent":["import { useInsertionEffect, useMemo, useRef } from 'react';\nimport { useAnimator } from '@weasel-js/animator';\nimport { useLatest } from '@weasel-js/react';\nimport { useViewAnimationOn, type ViewAnimationApi } from 'core/viewport/useViewAnimation';\nimport type { SceneCanvasApi } from '../canvasExtension';\nimport { useCanvasView, type CameraProps, type CanvasViewState } from '../useCanvasView';\n\n/**\n * The canvas's camera: the view `<Canvas>` looks through, the runner behind\n * `animateView`, and the target and animator it runs on.\n */\nexport function useCanvasCamera(opts: CameraProps & {\n /** The size the camera looks through, which `viewBounds` clamps against. */\n width: number;\n height: number;\n requestRedraw: () => void;\n}): {\n viewState: CanvasViewState;\n viewAnimation: ViewAnimationApi;\n camera: SceneCanvasApi['camera'];\n} {\n const { view, defaultView, onViewChange, viewBounds, width, height, requestRedraw } = opts;\n const size = useLatest({ width, height });\n const animationRef = useRef<ViewAnimationApi | null>(null);\n const viewState = useCanvasView({\n view,\n defaultView,\n // Every write to the view is reported here, so it is the runner's one\n // interrupt feed.\n onViewChange: (next) => {\n animationRef.current?.stopIfExternal();\n onViewChange?.(next);\n },\n viewBounds,\n dims: () => size.current,\n requestRedraw,\n });\n\n // The camera runs on its own animator, never the `animator` prop's: that prop\n // is the consumer's scene animator, and their `cancelAll()` or `pause()` must\n // not strand a zoom half-finished or freeze the camera.\n const animator = useAnimator();\n const { viewRef, setViewFromInput } = viewState;\n const channel = useMemo(\n () => ({
|
|
1
|
+
{"version":3,"file":"useCanvasCamera.js","names":["useCanvasCamera","opts","size","useLatest","animationRef","useRef","runnerWroteRef","viewState","useCanvasView","onViewChange","next","animator","useAnimator","channel","useMemo","viewRef","setViewFromInput","viewAnimation","useViewAnimationOn","lastControlledRef","controlled","useInsertionEffect","was"],"sources":["../../../src/canvas/SceneCanvas/useCanvasCamera.ts"],"sourcesContent":["import { useInsertionEffect, useMemo, useRef } from 'react';\nimport { useAnimator } from '@weasel-js/animator';\nimport { useLatest } from '@weasel-js/react';\nimport { useViewAnimationOn, type ViewAnimationApi } from 'core/viewport/useViewAnimation';\nimport { sameView, type View } from 'core/viewport/view';\nimport type { SceneCanvasApi } from '../canvasExtension';\nimport { useCanvasView, type CameraProps, type CanvasViewState } from '../useCanvasView';\n\n/**\n * The canvas's camera: the view `<Canvas>` looks through, the runner behind\n * `animateView`, and the target and animator it runs on.\n */\nexport function useCanvasCamera(opts: CameraProps & {\n /** The size the camera looks through, which `viewBounds` clamps against. */\n width: number;\n height: number;\n requestRedraw: () => void;\n}): {\n viewState: CanvasViewState;\n viewAnimation: ViewAnimationApi;\n camera: SceneCanvasApi['camera'];\n} {\n const { view, defaultView, onViewChange, viewBounds, width, height, requestRedraw } = opts;\n const size = useLatest({ width, height });\n const animationRef = useRef<ViewAnimationApi | null>(null);\n /** The runner has written a frame since the controlled view last moved. */\n const runnerWroteRef = useRef(false);\n const viewState = useCanvasView({\n view,\n defaultView,\n // Every write to the view is reported here, so it is the runner's one\n // interrupt feed.\n onViewChange: (next) => {\n animationRef.current?.stopIfExternal();\n onViewChange?.(next);\n },\n viewBounds,\n dims: () => size.current,\n requestRedraw,\n });\n\n // The camera runs on its own animator, never the `animator` prop's: that prop\n // is the consumer's scene animator, and their `cancelAll()` or `pause()` must\n // not strand a zoom half-finished or freeze the camera.\n const animator = useAnimator();\n const { viewRef, setViewFromInput, controlled } = viewState;\n const channel = useMemo(\n () => ({\n get: () => viewRef.current,\n set: (next: View) => {\n runnerWroteRef.current = true;\n setViewFromInput(next);\n },\n }),\n [viewRef, setViewFromInput],\n );\n const viewAnimation = useViewAnimationOn(channel, animator);\n useInsertionEffect(() => { animationRef.current = viewAnimation; });\n\n // A controlled consumer writing `view` in their own state never passes\n // through `onViewChange`. Their handling of a frame cannot be told from such\n // a write by value, since they may clamp or round what they are handed, so it\n // is told by order: a prop that moves with no frame written since it last\n // moved is theirs. One that lands in the same render as a frame's is missed.\n const lastControlledRef = useRef(controlled);\n useInsertionEffect(() => {\n const was = lastControlledRef.current;\n lastControlledRef.current = controlled;\n if (!controlled || !was || sameView(was, controlled)) return;\n if (runnerWroteRef.current) runnerWroteRef.current = false;\n else viewAnimation.stopIfExternal();\n });\n const camera = useMemo(() => ({ target: viewAnimation.viewTarget, animator }), [viewAnimation, animator]);\n return { viewState, viewAnimation, camera };\n}\n"],"mappings":";;;;;;;AAYA,SAAgBA,EAAgB,GAS9B;CACA,IAAM,EAAE,SAAM,gBAAa,iBAAc,eAAY,UAAO,WAAQ,qBAAkBC,GAChFC,IAAOC,EAAU;EAAE;EAAO;CAAO,CAAC,GAClCC,IAAeC,EAAgC,IAAI,GAEnDC,IAAiBD,EAAO,EAAK,GAC7BE,IAAYC,EAAc;EAC9B;EACA;EAGA,eAAe,MAAS;GAEtB,AADAJ,EAAa,SAAS,eAAe,GACrCK,IAAeC,CAAI;EACrB;EACA;EACA,YAAYR,EAAK;EACjB;CACF,CAAC,GAKKS,IAAWC,EAAY,GACvB,EAAE,YAAS,qBAAkB,kBAAeL,GAC5CM,IAAUC,SACP;EACL,WAAWC,EAAQ;EACnB,MAAM,MAAe;GAEnB,AADA,EAAe,UAAU,IACzBC,EAAiBN,CAAI;EACvB;CACF,IACA,CAACK,GAASC,CAAgB,CAC5B,GACMC,IAAgBC,EAAmBL,GAASF,CAAQ;CAC1D,QAAyB;EAAE,EAAa,UAAUM;CAAe,CAAC;CAOlE,IAAME,IAAoBd,EAAOe,CAAU;CAS3C,OARAC,QAAyB;EACvB,IAAMC,IAAMH,EAAkB;EAE9B,AADA,EAAkB,UAAUC,GACvBA,KAAeE,KAAO,GAASA,GAAKF,CAAU,MAC/Cd,EAAe,UAAS,EAAe,UAAU,KAChDW,EAAc,eAAe;CACpC,CAAC,GAEM;EAAE;EAAW;EAAe,QADpBH,SAAe;GAAE,QAAQG,EAAc;GAAY;EAAS,IAAI,CAACA,GAAeN,CAAQ,CACpE;CAAO;AAC5C"}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { createDispatcherPreviewSources as e, createGestureSource as t } from "./dispatcherGestureBounds.js";
|
|
2
2
|
import { useRef as n, useState as r } from "react";
|
|
3
|
-
import {
|
|
3
|
+
import { useLatest as i } from "@weasel-js/react";
|
|
4
|
+
import { createDispatcher as a } from "@weasel-js/routing";
|
|
4
5
|
//#region src/canvas/SceneCanvas/useCanvasDispatcher.ts
|
|
5
|
-
function
|
|
6
|
-
let
|
|
7
|
-
|
|
8
|
-
let
|
|
6
|
+
function o(o) {
|
|
7
|
+
let s = i(o), c = n(null);
|
|
8
|
+
c.current ||= a({ getAction: (e) => s.current?.list().find((t) => t.id === e) });
|
|
9
|
+
let l = c.current, [u] = r(() => t(() => c.current)), [{ previewIdsExtra: d, previewPoseExtra: f }] = r(() => e(() => c.current));
|
|
9
10
|
return {
|
|
10
|
-
dispatcher:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
previewPoseExtra: u
|
|
11
|
+
dispatcher: l,
|
|
12
|
+
gestureSource: u,
|
|
13
|
+
previewIdsExtra: d,
|
|
14
|
+
previewPoseExtra: f
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
17
|
//#endregion
|
|
18
|
-
export {
|
|
18
|
+
export { o as useCanvasDispatcher };
|
|
19
19
|
|
|
20
20
|
//# sourceMappingURL=useCanvasDispatcher.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCanvasDispatcher.js","names":["useCanvasDispatcher","
|
|
1
|
+
{"version":3,"file":"useCanvasDispatcher.js","names":["useCanvasDispatcher","registryRef","useLatest","registry","dispatcherRef","useRef","createDispatcher","a","id","dispatcher","gestureSource","useState","createGestureSource","createDispatcherPreviewSources"],"sources":["../../../src/canvas/SceneCanvas/useCanvasDispatcher.ts"],"sourcesContent":["import { useRef, useState } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport { createDispatcher, type ActionsRegistry, type Dispatcher } from '@weasel-js/routing';\nimport type { GestureSource } from '../gestureBounds';\nimport { createDispatcherPreviewSources, createGestureSource } from './dispatcherGestureBounds';\n\n/**\n * One `Dispatcher` for the life of a `<SceneCanvas>`, shared by the gesture\n * mounter that pumps input into it and the layers that walk its in-flight\n * handles, with the lookups those layers and `<Canvas>` read it through. It\n * resolves an action id in `registry`, read at call time.\n */\nexport function useCanvasDispatcher(registry: ActionsRegistry | null): {\n dispatcher: Dispatcher;\n /** In-flight preview ids, nascent-insert bounds, and the pump signal. */\n gestureSource: GestureSource;\n /** Ids whose committed paint an in-flight ghost hides. */\n previewIdsExtra: () => string[];\n /** The pose an in-flight handle proposes for an id. */\n previewPoseExtra: (id: string) => unknown;\n} {\n const registryRef = useLatest(registry);\n const dispatcherRef = useRef<Dispatcher | null>(null);\n if (!dispatcherRef.current) {\n dispatcherRef.current = createDispatcher({\n getAction: (id) => registryRef.current?.list().find((a) => a.id === id),\n });\n }\n const dispatcher = dispatcherRef.current;\n const [gestureSource] = useState(() => createGestureSource(() => dispatcherRef.current));\n const [{ previewIdsExtra, previewPoseExtra }] = useState(\n () => createDispatcherPreviewSources(() => dispatcherRef.current),\n );\n return { dispatcher, gestureSource, previewIdsExtra, previewPoseExtra };\n}\n"],"mappings":";;;;;AAYA,SAAgBA,EAAoB,GAQlC;CACA,IAAMC,IAAcC,EAAUC,CAAQ,GAChCC,IAAgBC,EAA0B,IAAI;CACpD,AACED,EAAc,YAAUE,EAAiB,EACvC,YAAY,MAAOL,EAAY,SAAS,KAAK,CAAC,CAAC,MAAM,MAAMM,EAAE,OAAOC,CAAE,EACxE,CAAC;CAEH,IAAMC,IAAaL,EAAc,SAC3B,CAACM,KAAiBC,QAAeC,QAA0BR,EAAc,OAAO,CAAC,GACjF,CAAC,EAAE,oBAAiB,yBAAsBO,QACxCE,QAAqCT,EAAc,OAAO,CAClE;CACA,OAAO;EAAE;EAAY;EAAe;EAAiB;CAAiB;AACxE"}
|
|
@@ -3,126 +3,62 @@ import { worldToScreen as t } from "../../core/viewport/viewTransform.js";
|
|
|
3
3
|
import { OVERLAY_ROLE_STROKES as n } from "../overlayRoleStrokes.js";
|
|
4
4
|
import { gestureOverlaysFrom as r, isVisibleFrom as i } from "../drawEnvelope.js";
|
|
5
5
|
import { resolveOverlays as a } from "../../interactions/actions/resolveOverlays.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { useEffect as
|
|
9
|
-
import { useLatest as
|
|
6
|
+
import { insertPreviewCommands as o } from "./insertPreviewCommands.js";
|
|
7
|
+
import { polygonFromPoints as s, polylineFromPoints as c } from "@weasel-js/geom";
|
|
8
|
+
import { useEffect as l, useMemo as u, useReducer as d } from "react";
|
|
9
|
+
import { useLatest as f } from "@weasel-js/react";
|
|
10
10
|
//#region src/canvas/SceneCanvas/useDispatcherOverlayLayer.ts
|
|
11
|
-
var
|
|
11
|
+
var p = {
|
|
12
12
|
fill: "rgba(164, 139, 212, 0.18)",
|
|
13
13
|
stroke: "#a48bd4",
|
|
14
14
|
dash: [3, 3],
|
|
15
15
|
lineWidth: 1
|
|
16
|
-
}
|
|
17
|
-
function
|
|
18
|
-
let { dispatcher:
|
|
19
|
-
return
|
|
20
|
-
if (
|
|
21
|
-
}, [
|
|
16
|
+
};
|
|
17
|
+
function m(m) {
|
|
18
|
+
let { dispatcher: h, style: g } = m, _ = f(g), [, v] = d((e) => e + 1, 0);
|
|
19
|
+
return l(() => {
|
|
20
|
+
if (h) return h.subscribe(v);
|
|
21
|
+
}, [h]), u(() => ({
|
|
22
22
|
id: "dispatcher-overlay",
|
|
23
23
|
label: "Dispatcher overlay",
|
|
24
24
|
space: "screen",
|
|
25
|
-
draw: (
|
|
26
|
-
let
|
|
27
|
-
...
|
|
28
|
-
...
|
|
29
|
-
},
|
|
25
|
+
draw: (l, u) => {
|
|
26
|
+
let d = {
|
|
27
|
+
...p,
|
|
28
|
+
..._.current ?? {}
|
|
29
|
+
}, f = {
|
|
30
30
|
...n,
|
|
31
|
-
...
|
|
32
|
-
},
|
|
33
|
-
for (let e of a(r(
|
|
31
|
+
..._.current?.roles ?? {}
|
|
32
|
+
}, m = e(u), h = [], g = i(l), v = (e) => !g || g(e);
|
|
33
|
+
for (let e of a(r(l))) if (v(e.visibilityId)) {
|
|
34
34
|
if (e.kind === "marquee") {
|
|
35
|
-
let n = e.bounds, [r, i] = t(n.x, n.y,
|
|
35
|
+
let n = e.bounds, [r, i] = t(n.x, n.y, m), a = {
|
|
36
36
|
kind: "path",
|
|
37
37
|
path: {
|
|
38
38
|
kind: "rect",
|
|
39
39
|
x: r,
|
|
40
40
|
y: i,
|
|
41
|
-
width: n.width *
|
|
42
|
-
height: n.height *
|
|
41
|
+
width: n.width * u.scale.x,
|
|
42
|
+
height: n.height * u.scale.y
|
|
43
43
|
},
|
|
44
|
-
fill: { paint: { color:
|
|
44
|
+
fill: { paint: { color: d.fill } },
|
|
45
45
|
stroke: {
|
|
46
|
-
paint: { color:
|
|
47
|
-
width:
|
|
48
|
-
dash:
|
|
46
|
+
paint: { color: d.stroke },
|
|
47
|
+
width: d.lineWidth,
|
|
48
|
+
dash: d.dash
|
|
49
49
|
}
|
|
50
50
|
};
|
|
51
|
-
|
|
51
|
+
h.push(a);
|
|
52
52
|
continue;
|
|
53
53
|
}
|
|
54
54
|
if (e.kind === "insertPreview") {
|
|
55
|
-
let
|
|
56
|
-
let [r, i] = t(e, n, b);
|
|
57
|
-
return {
|
|
58
|
-
x: r,
|
|
59
|
-
y: i
|
|
60
|
-
};
|
|
61
|
-
}, i = (e) => e.map((e) => r(e.x, e.y)), a = (h.scale.x + h.scale.y) / 2, l = null, m = e.geometry;
|
|
62
|
-
switch (m.kind) {
|
|
63
|
-
case "box": {
|
|
64
|
-
let [r, i] = t(n.x, n.y, b), a = n.width * h.scale.x, c = n.height * h.scale.y;
|
|
65
|
-
if (e.shape === "image") {
|
|
66
|
-
let t = e.extras, n = t.preview === "outline" || !t.src ? void 0 : o(t.src);
|
|
67
|
-
n && x.push({
|
|
68
|
-
kind: "image",
|
|
69
|
-
image: n,
|
|
70
|
-
x: r,
|
|
71
|
-
y: i,
|
|
72
|
-
w: a,
|
|
73
|
-
h: c,
|
|
74
|
-
opacity: y
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
l = e.shape === "ellipse" ? s({
|
|
78
|
-
x: r,
|
|
79
|
-
y: i,
|
|
80
|
-
width: a,
|
|
81
|
-
height: c
|
|
82
|
-
}) : d(r, i, a, c);
|
|
83
|
-
break;
|
|
84
|
-
}
|
|
85
|
-
case "line":
|
|
86
|
-
l = c(r(m.a.x, m.a.y), r(m.b.x, m.b.y));
|
|
87
|
-
break;
|
|
88
|
-
case "polygon":
|
|
89
|
-
l = f(r(m.center.x, m.center.y), m.radius * a, m.sides, m.rotation);
|
|
90
|
-
break;
|
|
91
|
-
case "star":
|
|
92
|
-
l = p(r(m.center.x, m.center.y), m.outerRadius * a, m.points, m.innerRadius * a, m.rotation);
|
|
93
|
-
break;
|
|
94
|
-
case "pencil": l = u(i(m.samples));
|
|
95
|
-
}
|
|
96
|
-
if (!l) continue;
|
|
97
|
-
let _ = {
|
|
98
|
-
kind: "path",
|
|
99
|
-
path: l,
|
|
100
|
-
fill: e.shape === "line" || e.shape === "pencil" || e.shape === "image" ? void 0 : { paint: { color: g.fill } },
|
|
101
|
-
stroke: {
|
|
102
|
-
paint: { color: g.stroke },
|
|
103
|
-
width: g.lineWidth,
|
|
104
|
-
dash: g.dash
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
if (x.push(_), e.anchorPoint) {
|
|
108
|
-
let t = r(e.anchorPoint.x, e.anchorPoint.y);
|
|
109
|
-
x.push({
|
|
110
|
-
kind: "path",
|
|
111
|
-
path: s({
|
|
112
|
-
x: t.x - 4,
|
|
113
|
-
y: t.y - 4,
|
|
114
|
-
width: 8,
|
|
115
|
-
height: 8
|
|
116
|
-
}),
|
|
117
|
-
fill: { paint: { color: g.stroke } }
|
|
118
|
-
});
|
|
119
|
-
}
|
|
55
|
+
for (let t of o(e, u, d)) h.push(t);
|
|
120
56
|
continue;
|
|
121
57
|
}
|
|
122
58
|
if (e.kind === "lasso") {
|
|
123
59
|
let n = [];
|
|
124
60
|
for (let r of e.vertices) {
|
|
125
|
-
let [e, i] = t(r.x, r.y,
|
|
61
|
+
let [e, i] = t(r.x, r.y, m);
|
|
126
62
|
n.push({
|
|
127
63
|
x: e,
|
|
128
64
|
y: i
|
|
@@ -130,43 +66,43 @@ function b(b) {
|
|
|
130
66
|
}
|
|
131
67
|
let r = {
|
|
132
68
|
kind: "path",
|
|
133
|
-
path:
|
|
134
|
-
fill: { paint: { color:
|
|
69
|
+
path: s(n),
|
|
70
|
+
fill: { paint: { color: d.fill } },
|
|
135
71
|
stroke: {
|
|
136
|
-
paint: { color:
|
|
137
|
-
width:
|
|
138
|
-
dash:
|
|
72
|
+
paint: { color: d.stroke },
|
|
73
|
+
width: d.lineWidth,
|
|
74
|
+
dash: d.dash
|
|
139
75
|
}
|
|
140
76
|
};
|
|
141
|
-
|
|
77
|
+
h.push(r);
|
|
142
78
|
continue;
|
|
143
79
|
}
|
|
144
80
|
if (e.kind === "polyline") {
|
|
145
|
-
let n =
|
|
146
|
-
paint: { color:
|
|
147
|
-
width:
|
|
148
|
-
dash:
|
|
81
|
+
let n = f[e.role] ?? {
|
|
82
|
+
paint: { color: d.stroke },
|
|
83
|
+
width: d.lineWidth,
|
|
84
|
+
dash: d.dash
|
|
149
85
|
}, r = [];
|
|
150
86
|
for (let n of e.points) {
|
|
151
|
-
let [e, i] = t(n.x, n.y,
|
|
87
|
+
let [e, i] = t(n.x, n.y, m);
|
|
152
88
|
r.push({
|
|
153
89
|
x: e,
|
|
154
90
|
y: i
|
|
155
91
|
});
|
|
156
92
|
}
|
|
157
|
-
|
|
93
|
+
h.push({
|
|
158
94
|
kind: "path",
|
|
159
|
-
path:
|
|
95
|
+
path: c(r),
|
|
160
96
|
stroke: n
|
|
161
97
|
});
|
|
162
98
|
continue;
|
|
163
99
|
}
|
|
164
100
|
}
|
|
165
|
-
return
|
|
101
|
+
return h.length === 0 ? [] : h;
|
|
166
102
|
}
|
|
167
|
-
}), [
|
|
103
|
+
}), [_]);
|
|
168
104
|
}
|
|
169
105
|
//#endregion
|
|
170
|
-
export {
|
|
106
|
+
export { m as useDispatcherOverlayLayer };
|
|
171
107
|
|
|
172
108
|
//# sourceMappingURL=useDispatcherOverlayLayer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDispatcherOverlayLayer.js","names":["DEFAULT_STYLE","PREVIEW_CONTENT_OPACITY","useDispatcherOverlayLayer","args","styleRef","useLatest","style","forceRerender","useReducer","n","useEffect","dispatcher","useMemo","cfg","roles","OVERLAY_ROLE_STROKES","t","viewToTransform","view","out","isVisible","isVisibleFrom","data","passes","id","ov","resolveOverlays","gestureOverlaysFrom","b","sx","sy","worldToScreen","cmd","projectPoint","wx","wy","projectPoints","pts","p","radialScale","pathCmd","geom","sw","sh","e","bmp","getImageBitmap","ellipsePath","rectPath","linePath","regularPolygonPath","starPath","polylineFromPoints","anchorScreen","screenPts","v","polygonFromPoints","stroke","pt"],"sources":["../../../src/canvas/SceneCanvas/useDispatcherOverlayLayer.ts"],"sourcesContent":["/**\n * Dispatcher overlay render layer for `<SceneCanvas>`.\n *\n * Paints the overlay shapes the drawing view's in-flight handles publish,\n * taken off the draw envelope so a panel shows its own gesture rather than\n * the surface's. `resolveOverlays` does the reading; everything here is\n * painting.\n *\n * Distinct from `usePreviewGhostLayer`, which paints displaced scene-node\n * silhouettes. This layer is for gestures whose visual feedback isn't a moved\n * scene node — a marquee rect, a lasso polyline, an insert preview.\n */\nimport { useEffect, useMemo, useReducer } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport type { DrawCommand, PathDrawCommand } from '@weasel-js/renderer';\nimport type { CommandStroke } from '@weasel-js/paint';\nimport type { RenderLayer } from 'core/layers/render';\nimport { viewToTransform } from 'core/viewport/view';\nimport { worldToScreen } from 'core/viewport/viewTransform';\nimport type { Dispatcher } from '@weasel-js/routing';\nimport {\n polygonFromPoints,\n polylineFromPoints,\n rectPath,\n ellipsePath,\n linePath,\n regularPolygonPath,\n starPath,\n} from '@weasel-js/geom';\nimport { getImageBitmap } from '@weasel-js/renderer';\nimport { resolveOverlays } from 'interactions/actions/resolveOverlays';\nimport { gestureOverlaysFrom, isVisibleFrom } from '../drawEnvelope';\nimport { OVERLAY_ROLE_STROKES } from '../overlayRoleStrokes';\n\n/** Style knobs for the dispatcher-overlay layer's marquee + lasso paints. */\nexport interface DispatcherOverlayStyle {\n fill?: string;\n stroke?: string;\n dash?: number[];\n lineWidth?: number;\n /** Stroke per `polyline` overlay role, merged over the kit's. A role with\n * no entry here and none of the kit's paints as plain chrome — the\n * `stroke` / `lineWidth` / `dash` above. */\n roles?: Readonly<Record<string, CommandStroke>>;\n}\n\nconst DEFAULT_STYLE: Required<Omit<DispatcherOverlayStyle, 'roles'>> = {\n fill: 'rgba(164, 139, 212, 0.18)',\n stroke: '#a48bd4',\n dash: [3, 3],\n lineWidth: 1,\n};\n\n/** Alpha for content previewed inside an in-flight gesture. Matches the\n * preview-ghost layer, so a dragged node and an uncommitted insert read as\n * equally provisional. */\nconst PREVIEW_CONTENT_OPACITY = 0.85;\n\n\nexport function useDispatcherOverlayLayer(args: {\n /** The surface's dispatcher, subscribed to only so a pump repaints. What\n * gets painted is the drawing view's own `getGestureOverlays()`. */\n dispatcher: Dispatcher | null | undefined;\n style?: DispatcherOverlayStyle;\n}): RenderLayer<unknown> {\n const { dispatcher, style } = args;\n\n const styleRef = useLatest(style);\n\n // Re-render on every dispatcher pump so live overlay (marquee, lasso\n // polyline) tracks pointermove instead of freezing on the first frame.\n const [, forceRerender] = useReducer((n: number) => n + 1, 0);\n useEffect(() => {\n if (!dispatcher) return;\n return dispatcher.subscribe(forceRerender);\n }, [dispatcher]);\n\n return useMemo<RenderLayer<unknown>>(\n () => ({\n id: 'dispatcher-overlay',\n label: 'Dispatcher overlay',\n space: 'screen',\n draw: (data, view) => {\n const cfg = { ...DEFAULT_STYLE, ...(styleRef.current ?? {}) };\n // Merged rather than replaced: naming one role must not delete the\n // kit's others.\n const roles = { ...OVERLAY_ROLE_STROKES, ...(styleRef.current?.roles ?? {}) };\n const t = viewToTransform(view);\n const out: DrawCommand[] = [];\n\n // Chrome-caps gate. Absent envelope → every overlay paints. This stays\n // on the painting side: the predicate is a property of the view's\n // envelope, and two views of one surface may answer differently for\n // the same in-flight gesture.\n const isVisible = isVisibleFrom(data);\n const passes = (id: string) => (isVisible ? isVisible(id) : true);\n\n for (const ov of resolveOverlays(gestureOverlaysFrom(data))) {\n if (!passes(ov.visibilityId)) continue;\n\n if (ov.kind === 'marquee') {\n const b = ov.bounds;\n const [sx, sy] = worldToScreen(b.x, b.y, t);\n const sw = b.width * view.scale.x;\n const sh = b.height * view.scale.y;\n const cmd: PathDrawCommand = {\n kind: 'path',\n path: { kind: 'rect', x: sx, y: sy, width: sw, height: sh },\n fill: { paint: { color: cfg.fill } },\n stroke: { paint: { color: cfg.stroke }, width: cfg.lineWidth, dash: cfg.dash },\n };\n out.push(cmd);\n continue;\n }\n\n if (ov.kind === 'insertPreview') {\n const b = ov.bounds;\n const projectPoint = (wx: number, wy: number): { x: number; y: number } => {\n const [sx, sy] = worldToScreen(wx, wy, t);\n return { x: sx, y: sy };\n };\n const projectPoints = (\n pts: ReadonlyArray<{ x: number; y: number }>,\n ): { x: number; y: number }[] => pts.map((p) => projectPoint(p.x, p.y));\n // Radial shapes inscribe in a square, so a single screen-space\n // radius needs one scale factor; average the axes.\n const radialScale = (view.scale.x + view.scale.y) / 2;\n\n let pathCmd: PathDrawCommand['path'] | null = null;\n const geom = ov.geometry;\n switch (geom.kind) {\n case 'box': {\n const [sx, sy] = worldToScreen(b.x, b.y, t);\n const sw = b.width * view.scale.x;\n const sh = b.height * view.scale.y;\n if (ov.shape === 'image') {\n const e = ov.extras as Partial<{ src: string; preview: string }>;\n // The bitmap when it has decoded, the bare outline until then\n // (or when the tool opted out) — the outline is drawn either\n // way, so the drag always has an edge to read.\n const bmp = e.preview === 'outline' || !e.src\n ? undefined\n : getImageBitmap(e.src);\n if (bmp) {\n out.push({\n kind: 'image',\n image: bmp,\n x: sx, y: sy, w: sw, h: sh,\n opacity: PREVIEW_CONTENT_OPACITY,\n });\n }\n }\n pathCmd = ov.shape === 'ellipse'\n ? ellipsePath({ x: sx, y: sy, width: sw, height: sh })\n : rectPath(sx, sy, sw, sh);\n break;\n }\n case 'line':\n pathCmd = linePath(projectPoint(geom.a.x, geom.a.y), projectPoint(geom.b.x, geom.b.y));\n break;\n case 'polygon':\n pathCmd = regularPolygonPath(\n projectPoint(geom.center.x, geom.center.y),\n geom.radius * radialScale,\n geom.sides,\n geom.rotation,\n );\n break;\n case 'star':\n pathCmd = starPath(\n projectPoint(geom.center.x, geom.center.y),\n geom.outerRadius * radialScale,\n geom.points,\n geom.innerRadius * radialScale,\n geom.rotation,\n );\n break;\n case 'pencil':\n // Genuinely open: `polygonFromPoints` closes the path, and the\n // closing edge from the last sample back to the first reads as\n // a marquee rather than as the stroke being drawn.\n pathCmd = polylineFromPoints(projectPoints(geom.samples));\n break;\n }\n\n if (!pathCmd) continue;\n const cmd: PathDrawCommand = {\n kind: 'path',\n path: pathCmd,\n fill: ov.shape === 'line' || ov.shape === 'pencil' || ov.shape === 'image'\n ? undefined\n : { paint: { color: cfg.fill } },\n stroke: { paint: { color: cfg.stroke }, width: cfg.lineWidth, dash: cfg.dash },\n };\n out.push(cmd);\n // Anchor dot at the drag's click point: for radial shapes no\n // vertex sits at the AABB corner, and in center mode the dot marks\n // the growth axis.\n if (ov.anchorPoint) {\n const anchorScreen = projectPoint(ov.anchorPoint.x, ov.anchorPoint.y);\n out.push({\n kind: 'path',\n path: ellipsePath({\n x: anchorScreen.x - 4,\n y: anchorScreen.y - 4,\n width: 8,\n height: 8,\n }),\n fill: { paint: { color: cfg.stroke } },\n });\n }\n continue;\n }\n\n if (ov.kind === 'lasso') {\n // `polygonFromPoints` closes the path, which draws the dashed\n // close-line back to the first vertex.\n const screenPts: { x: number; y: number }[] = [];\n for (const v of ov.vertices) {\n const [sx, sy] = worldToScreen(v.x, v.y, t);\n screenPts.push({ x: sx, y: sy });\n }\n const cmd: PathDrawCommand = {\n kind: 'path',\n path: polygonFromPoints(screenPts),\n fill: { paint: { color: cfg.fill } },\n stroke: { paint: { color: cfg.stroke }, width: cfg.lineWidth, dash: cfg.dash },\n };\n out.push(cmd);\n continue;\n }\n\n if (ov.kind === 'polyline') {\n const stroke =\n roles[ov.role] ??\n { paint: { color: cfg.stroke }, width: cfg.lineWidth, dash: cfg.dash };\n const screenPts: { x: number; y: number }[] = [];\n for (const pt of ov.points) {\n const [sx, sy] = worldToScreen(pt.x, pt.y, t);\n screenPts.push({ x: sx, y: sy });\n }\n out.push({\n kind: 'path',\n path: polylineFromPoints(screenPts),\n stroke,\n } satisfies PathDrawCommand);\n continue;\n }\n }\n\n if (out.length === 0) return [];\n return out;\n },\n }),\n [styleRef],\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useDispatcherOverlayLayer.js","names":["DEFAULT_STYLE","useDispatcherOverlayLayer","args","styleRef","useLatest","style","forceRerender","useReducer","n","useEffect","dispatcher","useMemo","cfg","roles","OVERLAY_ROLE_STROKES","t","viewToTransform","view","out","isVisible","isVisibleFrom","data","passes","id","ov","resolveOverlays","gestureOverlaysFrom","b","sx","sy","worldToScreen","cmd","insertPreviewCommands","screenPts","v","polygonFromPoints","stroke","pt","polylineFromPoints"],"sources":["../../../src/canvas/SceneCanvas/useDispatcherOverlayLayer.ts"],"sourcesContent":["/**\n * Dispatcher overlay render layer for `<SceneCanvas>`.\n *\n * Paints the overlay shapes the drawing view's in-flight handles publish,\n * taken off the draw envelope so a panel shows its own gesture rather than\n * the surface's. `resolveOverlays` does the reading; everything here is\n * painting.\n *\n * Distinct from `usePreviewGhostLayer`, which paints displaced scene-node\n * silhouettes. This layer is for gestures whose visual feedback isn't a moved\n * scene node — a marquee rect, a lasso polyline, an insert preview.\n */\nimport { useEffect, useMemo, useReducer } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport type { DrawCommand, PathDrawCommand } from '@weasel-js/renderer';\nimport type { CommandStroke } from '@weasel-js/paint';\nimport type { RenderLayer } from 'core/layers/render';\nimport { viewToTransform } from 'core/viewport/view';\nimport { worldToScreen } from 'core/viewport/viewTransform';\nimport type { Dispatcher } from '@weasel-js/routing';\nimport { polygonFromPoints, polylineFromPoints } from '@weasel-js/geom';\nimport { resolveOverlays } from 'interactions/actions/resolveOverlays';\nimport { gestureOverlaysFrom, isVisibleFrom } from '../drawEnvelope';\nimport { insertPreviewCommands } from './insertPreviewCommands';\nimport { OVERLAY_ROLE_STROKES } from '../overlayRoleStrokes';\n\n/** Style knobs for the dispatcher-overlay layer's marquee + lasso paints. */\nexport interface DispatcherOverlayStyle {\n fill?: string;\n stroke?: string;\n dash?: number[];\n lineWidth?: number;\n /** Stroke per `polyline` overlay role, merged over the kit's. A role with\n * no entry here and none of the kit's paints as plain chrome — the\n * `stroke` / `lineWidth` / `dash` above. */\n roles?: Readonly<Record<string, CommandStroke>>;\n}\n\nconst DEFAULT_STYLE: Required<Omit<DispatcherOverlayStyle, 'roles'>> = {\n fill: 'rgba(164, 139, 212, 0.18)',\n stroke: '#a48bd4',\n dash: [3, 3],\n lineWidth: 1,\n};\n\n\n\nexport function useDispatcherOverlayLayer(args: {\n /** The surface's dispatcher, subscribed to only so a pump repaints. What\n * gets painted is the drawing view's own `getGestureOverlays()`. */\n dispatcher: Dispatcher | null | undefined;\n style?: DispatcherOverlayStyle;\n}): RenderLayer<unknown> {\n const { dispatcher, style } = args;\n\n const styleRef = useLatest(style);\n\n // Re-render on every dispatcher pump so live overlay (marquee, lasso\n // polyline) tracks pointermove instead of freezing on the first frame.\n const [, forceRerender] = useReducer((n: number) => n + 1, 0);\n useEffect(() => {\n if (!dispatcher) return;\n return dispatcher.subscribe(forceRerender);\n }, [dispatcher]);\n\n return useMemo<RenderLayer<unknown>>(\n () => ({\n id: 'dispatcher-overlay',\n label: 'Dispatcher overlay',\n space: 'screen',\n draw: (data, view) => {\n const cfg = { ...DEFAULT_STYLE, ...(styleRef.current ?? {}) };\n // Merged rather than replaced: naming one role must not delete the\n // kit's others.\n const roles = { ...OVERLAY_ROLE_STROKES, ...(styleRef.current?.roles ?? {}) };\n const t = viewToTransform(view);\n const out: DrawCommand[] = [];\n\n // Chrome-caps gate. Absent envelope → every overlay paints. This stays\n // on the painting side: the predicate is a property of the view's\n // envelope, and two views of one surface may answer differently for\n // the same in-flight gesture.\n const isVisible = isVisibleFrom(data);\n const passes = (id: string) => (isVisible ? isVisible(id) : true);\n\n for (const ov of resolveOverlays(gestureOverlaysFrom(data))) {\n if (!passes(ov.visibilityId)) continue;\n\n if (ov.kind === 'marquee') {\n const b = ov.bounds;\n const [sx, sy] = worldToScreen(b.x, b.y, t);\n const sw = b.width * view.scale.x;\n const sh = b.height * view.scale.y;\n const cmd: PathDrawCommand = {\n kind: 'path',\n path: { kind: 'rect', x: sx, y: sy, width: sw, height: sh },\n fill: { paint: { color: cfg.fill } },\n stroke: { paint: { color: cfg.stroke }, width: cfg.lineWidth, dash: cfg.dash },\n };\n out.push(cmd);\n continue;\n }\n\n if (ov.kind === 'insertPreview') {\n for (const cmd of insertPreviewCommands(ov, view, cfg)) out.push(cmd);\n continue;\n }\n\n if (ov.kind === 'lasso') {\n // `polygonFromPoints` closes the path, which draws the dashed\n // close-line back to the first vertex.\n const screenPts: { x: number; y: number }[] = [];\n for (const v of ov.vertices) {\n const [sx, sy] = worldToScreen(v.x, v.y, t);\n screenPts.push({ x: sx, y: sy });\n }\n const cmd: PathDrawCommand = {\n kind: 'path',\n path: polygonFromPoints(screenPts),\n fill: { paint: { color: cfg.fill } },\n stroke: { paint: { color: cfg.stroke }, width: cfg.lineWidth, dash: cfg.dash },\n };\n out.push(cmd);\n continue;\n }\n\n if (ov.kind === 'polyline') {\n const stroke =\n roles[ov.role] ??\n { paint: { color: cfg.stroke }, width: cfg.lineWidth, dash: cfg.dash };\n const screenPts: { x: number; y: number }[] = [];\n for (const pt of ov.points) {\n const [sx, sy] = worldToScreen(pt.x, pt.y, t);\n screenPts.push({ x: sx, y: sy });\n }\n out.push({\n kind: 'path',\n path: polylineFromPoints(screenPts),\n stroke,\n } satisfies PathDrawCommand);\n continue;\n }\n }\n\n if (out.length === 0) return [];\n return out;\n },\n }),\n [styleRef],\n );\n}\n"],"mappings":"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"}
|