@weasel-js/core 1.9.4 → 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 +918 -0
- package/README.md +38 -3
- package/dist/WeaselProvider.js +5 -7
- package/dist/WeaselProvider.js.map +1 -1
- package/dist/affordances/composeAffordanceLayer.js +92 -84
- package/dist/affordances/composeAffordanceLayer.js.map +1 -1
- package/dist/affordances/cornerResize.js +3 -2
- package/dist/affordances/cornerResize.js.map +1 -1
- package/dist/affordances/hitAffordanceRegions.js +71 -101
- 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 +44 -46
- package/dist/affordances/rotationHandle.js.map +1 -1
- package/dist/animation/behaviors/coast.js +21 -0
- package/dist/animation/behaviors/coast.js.map +1 -0
- package/dist/animation/behaviors/coastByWrite.js +107 -0
- package/dist/animation/behaviors/coastByWrite.js.map +1 -0
- package/dist/animation/behaviors/coastOnTargets.js +94 -0
- package/dist/animation/behaviors/coastOnTargets.js.map +1 -0
- package/dist/animation/behaviors/momentum.js +48 -136
- package/dist/animation/behaviors/momentum.js.map +1 -1
- package/dist/animation/clipTargets.js +12 -0
- package/dist/animation/clipTargets.js.map +1 -0
- package/dist/animation/index.js +15 -20
- package/dist/animation/poseHelpers.js +112 -33
- package/dist/animation/poseHelpers.js.map +1 -1
- package/dist/animation/poseTarget.js +115 -0
- package/dist/animation/poseTarget.js.map +1 -0
- package/dist/animation/reflow.js +113 -83
- package/dist/animation/reflow.js.map +1 -1
- package/dist/animation/rewind.js +66 -0
- package/dist/animation/rewind.js.map +1 -0
- package/dist/animation/rig/bindRig.js +85 -53
- package/dist/animation/rig/bindRig.js.map +1 -1
- package/dist/animation/rig/rigNode.js +99 -0
- package/dist/animation/rig/rigNode.js.map +1 -0
- package/dist/animation/rig/rigSeat.js +59 -0
- package/dist/animation/rig/rigSeat.js.map +1 -0
- package/dist/animation/rig/skinBinding.js +64 -0
- package/dist/animation/rig/skinBinding.js.map +1 -0
- package/dist/animation/rig/useRig.js +31 -16
- package/dist/animation/rig/useRig.js.map +1 -1
- package/dist/animation/wrappers/animateLifecycle.js +8 -7
- package/dist/animation/wrappers/animateLifecycle.js.map +1 -1
- package/dist/animation/wrappers/animateOnSetPose.js +31 -31
- package/dist/animation/wrappers/animateOnSetPose.js.map +1 -1
- package/dist/animation/wrappers/instantPose.js.map +1 -1
- package/dist/animation/writtenPoseTarget.js +33 -0
- package/dist/animation/writtenPoseTarget.js.map +1 -0
- package/dist/autoPoseDescriptor-DHg5KqaJ.d.ts +27 -0
- package/dist/barrel/canvas.js +32 -0
- package/dist/barrel/chrome.js +10 -10
- package/dist/barrel/input.js +16 -17
- package/dist/barrel/interactions.js +34 -37
- package/dist/barrel/paint.js +11 -18
- package/dist/barrel/paths.js +13 -19
- package/dist/barrel/renderer.js +14 -20
- package/dist/barrel/routing.js +54 -47
- package/dist/barrel/scene.js +37 -0
- package/dist/barrel/text.js +9 -18
- package/dist/barrel/viewport.js +44 -51
- package/dist/canvas/Canvas.js +270 -475
- package/dist/canvas/Canvas.js.map +1 -1
- package/dist/canvas/CanvasView.js +168 -190
- package/dist/canvas/CanvasView.js.map +1 -1
- package/dist/canvas/CursorCoordsHud.js +24 -25
- package/dist/canvas/CursorCoordsHud.js.map +1 -1
- package/dist/canvas/DrawCanvas.js +39 -56
- package/dist/canvas/DrawCanvas.js.map +1 -1
- package/dist/canvas/ModalityHud.js.map +1 -1
- package/dist/canvas/NodeShape.js +28 -29
- package/dist/canvas/NodeShape.js.map +1 -1
- package/dist/canvas/PickHud.js.map +1 -1
- package/dist/canvas/SceneCanvas/DevHuds.js +40 -0
- package/dist/canvas/SceneCanvas/DevHuds.js.map +1 -0
- package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js +66 -107
- package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js.map +1 -1
- package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +33 -36
- package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js.map +1 -1
- package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js +38 -50
- package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js.map +1 -1
- package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js +3 -3
- package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js.map +1 -1
- package/dist/canvas/SceneCanvas/coordTrace.js +37 -1
- package/dist/canvas/SceneCanvas/coordTrace.js.map +1 -1
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js +319 -270
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -1
- package/dist/canvas/SceneCanvas/defaultNodeRouting.js +1 -1
- package/dist/canvas/SceneCanvas/defaultNodeRouting.js.map +1 -1
- package/dist/canvas/SceneCanvas/dispatcherGestureBounds.js.map +1 -1
- package/dist/canvas/SceneCanvas/features.js +71 -62
- 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/isDev.js.map +1 -1
- package/dist/canvas/SceneCanvas/poseGeometry.js +33 -37
- package/dist/canvas/SceneCanvas/poseGeometry.js.map +1 -1
- package/dist/canvas/SceneCanvas/props.js +15 -14
- 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/toolRegistry.js +23 -0
- package/dist/canvas/SceneCanvas/toolRegistry.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/useActionsPropResolver.js +6 -1
- package/dist/canvas/SceneCanvas/useActionsPropResolver.js.map +1 -1
- package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js.map +1 -1
- package/dist/canvas/SceneCanvas/useBuiltinTools.js +21 -0
- package/dist/canvas/SceneCanvas/useBuiltinTools.js.map +1 -0
- package/dist/canvas/SceneCanvas/useCanvasCamera.js +46 -0
- package/dist/canvas/SceneCanvas/useCanvasCamera.js.map +1 -0
- package/dist/canvas/SceneCanvas/useCanvasDispatcher.js +20 -0
- package/dist/canvas/SceneCanvas/useCanvasDispatcher.js.map +1 -0
- package/dist/canvas/SceneCanvas/useCanvasSelection.js +16 -0
- package/dist/canvas/SceneCanvas/useCanvasSelection.js.map +1 -0
- package/dist/canvas/SceneCanvas/useCanvasTools.js +67 -0
- package/dist/canvas/SceneCanvas/useCanvasTools.js.map +1 -0
- package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js +49 -113
- package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js.map +1 -1
- package/dist/canvas/SceneCanvas/useHeldModifiers.js +20 -0
- package/dist/canvas/SceneCanvas/useHeldModifiers.js.map +1 -0
- package/dist/canvas/SceneCanvas/useNodeAtPoint.js +26 -0
- package/dist/canvas/SceneCanvas/useNodeAtPoint.js.map +1 -0
- package/dist/canvas/SceneCanvas/useNodeKinds.js +26 -0
- package/dist/canvas/SceneCanvas/useNodeKinds.js.map +1 -0
- package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +51 -41
- package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneCanvasHandle.js +47 -0
- package/dist/canvas/SceneCanvas/useSceneCanvasHandle.js.map +1 -0
- package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js +66 -0
- package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js.map +1 -0
- package/dist/canvas/SceneCanvas/useSceneChrome.js +59 -0
- package/dist/canvas/SceneCanvas/useSceneChrome.js.map +1 -0
- package/dist/canvas/SceneCanvas/useSceneRedrawSources.js +23 -0
- package/dist/canvas/SceneCanvas/useSceneRedrawSources.js.map +1 -0
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js +65 -101
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneSlotLayers.js +37 -0
- package/dist/canvas/SceneCanvas/useSceneSlotLayers.js.map +1 -0
- package/dist/canvas/SceneCanvas/useSelectionOverlayLayer.js +38 -0
- package/dist/canvas/SceneCanvas/useSelectionOverlayLayer.js.map +1 -0
- package/dist/canvas/SceneCanvas/useViewLayerGate.js +20 -0
- package/dist/canvas/SceneCanvas/useViewLayerGate.js.map +1 -0
- package/dist/canvas/SceneCanvas/useViewportActions.js +9 -1
- package/dist/canvas/SceneCanvas/useViewportActions.js.map +1 -1
- package/dist/canvas/SceneCanvas/worldPointAt.js +8 -0
- package/dist/canvas/SceneCanvas/worldPointAt.js.map +1 -0
- package/dist/canvas/SceneCanvas.js +301 -708
- package/dist/canvas/SceneCanvas.js.map +1 -1
- package/dist/canvas/SceneViewCanvas.js +41 -47
- 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 +26 -0
- package/dist/canvas/adapterDerivedPath.js.map +1 -0
- package/dist/canvas/adapterPickSource.js +34 -0
- package/dist/canvas/adapterPickSource.js.map +1 -0
- package/dist/canvas/affordanceAt.js +12 -2
- package/dist/canvas/affordanceAt.js.map +1 -1
- package/dist/canvas/buildSceneLayer.js +81 -61
- 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/canvasRenderer.js +40 -44
- package/dist/canvas/canvasRenderer.js.map +1 -1
- package/dist/canvas/colorOverrides.js.map +1 -1
- package/dist/canvas/copiesAbove.js +27 -0
- package/dist/canvas/copiesAbove.js.map +1 -0
- package/dist/canvas/defaultDrawOne.js +25 -24
- package/dist/canvas/defaultDrawOne.js.map +1 -1
- package/dist/canvas/deps/areaSelect.js +4 -4
- package/dist/canvas/deps/areaSelect.js.map +1 -1
- package/dist/canvas/deps/debug.js.map +1 -1
- package/dist/canvas/deps/editAnchors.js +47 -71
- package/dist/canvas/deps/editAnchors.js.map +1 -1
- package/dist/canvas/deps/geometryProjection.js.map +1 -1
- package/dist/canvas/deps/hitTestArea.js +45 -25
- package/dist/canvas/deps/hitTestArea.js.map +1 -1
- package/dist/canvas/deps/insert.js +149 -104
- package/dist/canvas/deps/insert.js.map +1 -1
- package/dist/canvas/deps/lassoSelect.js +5 -5
- package/dist/canvas/deps/lassoSelect.js.map +1 -1
- package/dist/canvas/deps/layout.js +9 -15
- package/dist/canvas/deps/layout.js.map +1 -1
- package/dist/canvas/deps/poseDescriptor.js +1 -1
- package/dist/canvas/deps/poseDescriptor.js.map +1 -1
- package/dist/canvas/deps/resizePolicy.js.map +1 -1
- package/dist/canvas/deps/slice.js +44 -45
- package/dist/canvas/deps/slice.js.map +1 -1
- package/dist/canvas/deps/textEdit.js +8 -8
- package/dist/canvas/deps/textEdit.js.map +1 -1
- package/dist/canvas/deps/view.js.map +1 -1
- package/dist/canvas/derivedPath.js +69 -43
- package/dist/canvas/derivedPath.js.map +1 -1
- package/dist/canvas/drawEnvelope.js +8 -4
- package/dist/canvas/drawEnvelope.js.map +1 -1
- package/dist/canvas/getNodeAtPoint.js +2 -6
- package/dist/canvas/getNodeAtPoint.js.map +1 -1
- package/dist/canvas/hud.module.js.map +1 -1
- package/dist/canvas/insertPreviewExtent.js +33 -31
- package/dist/canvas/insertPreviewExtent.js.map +1 -1
- package/dist/canvas/layerOrder.js.map +1 -1
- package/dist/canvas/layerSlots.js +6 -1
- package/dist/canvas/layerSlots.js.map +1 -1
- package/dist/canvas/nodeShapes/derivedPainter.js +12 -12
- package/dist/canvas/nodeShapes/derivedPainter.js.map +1 -1
- package/dist/canvas/nodeShapes/imagePainter.js +10 -10
- package/dist/canvas/nodeShapes/imagePainter.js.map +1 -1
- package/dist/canvas/nodeShapes/memo.js.map +1 -1
- package/dist/canvas/nodeShapes/nodePaint.js +34 -23
- package/dist/canvas/nodeShapes/nodePaint.js.map +1 -1
- package/dist/canvas/nodeShapes/pathPainter.js +23 -22
- package/dist/canvas/nodeShapes/pathPainter.js.map +1 -1
- package/dist/canvas/nodeShapes/poseBox.js +6 -6
- package/dist/canvas/nodeShapes/poseBox.js.map +1 -1
- package/dist/canvas/nodeShapes/rectFallbackPainter.js +8 -8
- package/dist/canvas/nodeShapes/rectFallbackPainter.js.map +1 -1
- package/dist/canvas/nodeShapes/shapePainter.js +16 -16
- package/dist/canvas/nodeShapes/shapePainter.js.map +1 -1
- package/dist/canvas/nodeShapes/textPainter.js +1 -1
- package/dist/canvas/nodeShapes/textPainter.js.map +1 -1
- package/dist/canvas/overChildren.js +29 -0
- package/dist/canvas/overChildren.js.map +1 -0
- package/dist/canvas/overlayRoleStrokes.js.map +1 -1
- package/dist/canvas/paintCull.js +6 -8
- package/dist/canvas/paintCull.js.map +1 -1
- package/dist/{features/cursor → canvas}/paintedCursorLayer.js +2 -2
- package/dist/canvas/paintedCursorLayer.js.map +1 -0
- package/dist/canvas/pickReach.js +23 -0
- package/dist/canvas/pickReach.js.map +1 -0
- package/dist/canvas/pickWalk.js +43 -70
- package/dist/canvas/pickWalk.js.map +1 -1
- package/dist/canvas/planeClips.js +18 -19
- package/dist/canvas/planeClips.js.map +1 -1
- package/dist/canvas/poseCascade.js +41 -0
- package/dist/canvas/poseCascade.js.map +1 -0
- package/dist/canvas/poseRotation.js +1 -3
- package/dist/canvas/poseRotation.js.map +1 -1
- package/dist/canvas/rasterReadback.js +22 -0
- package/dist/canvas/rasterReadback.js.map +1 -0
- package/dist/canvas/renderDebugSnapshot.js +12 -12
- package/dist/canvas/renderDebugSnapshot.js.map +1 -1
- package/dist/canvas/renderNeeds.js +3 -3
- package/dist/canvas/renderNeeds.js.map +1 -1
- package/dist/canvas/renderSceneToPixels.js +64 -83
- package/dist/canvas/renderSceneToPixels.js.map +1 -1
- package/dist/canvas/sceneAdapter.js +59 -144
- package/dist/canvas/sceneAdapter.js.map +1 -1
- package/dist/canvas/sceneClipboard.js +1 -1
- package/dist/canvas/sceneClipboard.js.map +1 -1
- package/dist/canvas/sceneLayerPaint.js +4 -4
- package/dist/canvas/sceneLayerPaint.js.map +1 -1
- package/dist/canvas/sceneSlotWiring.js +10 -9
- package/dist/canvas/sceneSlotWiring.js.map +1 -1
- package/dist/canvas/sceneViewRender.js +37 -42
- package/dist/canvas/sceneViewRender.js.map +1 -1
- package/dist/canvas/slopsDebugLayer.js +4 -4
- package/dist/canvas/slopsDebugLayer.js.map +1 -1
- package/dist/canvas/useCanvasRenderer.js +23 -11
- package/dist/canvas/useCanvasRenderer.js.map +1 -1
- package/dist/canvas/useCanvasSurface.js +31 -0
- package/dist/canvas/useCanvasSurface.js.map +1 -0
- package/dist/canvas/useCanvasView.js +51 -44
- package/dist/canvas/useCanvasView.js.map +1 -1
- package/dist/canvas/useFrameLoop.js +11 -12
- package/dist/canvas/useFrameLoop.js.map +1 -1
- package/dist/canvas/useHostAnchor.js +35 -33
- package/dist/canvas/useHostAnchor.js.map +1 -1
- package/dist/canvas/useLateContentRedraw.js +8 -8
- package/dist/canvas/useLateContentRedraw.js.map +1 -1
- package/dist/canvas/useSceneAdapter.js +22 -0
- package/dist/canvas/useSceneAdapter.js.map +1 -0
- package/dist/canvas/useSceneLayerList.js +4 -14
- package/dist/canvas/useSceneLayerList.js.map +1 -1
- package/dist/canvas/useSurfaceInput.js +39 -0
- package/dist/canvas/useSurfaceInput.js.map +1 -0
- package/dist/canvas/useToolCursor.js +29 -0
- package/dist/canvas/useToolCursor.js.map +1 -0
- package/dist/canvas/useViewHelpers.js +46 -85
- package/dist/canvas/useViewHelpers.js.map +1 -1
- package/dist/canvas/viewInputs.js.map +1 -1
- package/dist/canvas/viewRegistry.js +40 -34
- package/dist/canvas/viewRegistry.js.map +1 -1
- package/dist/canvas/watchElementMove.js +43 -0
- package/dist/canvas/watchElementMove.js.map +1 -0
- package/dist/canvas/wrapNodeOutput.js +7 -2
- package/dist/canvas/wrapNodeOutput.js.map +1 -1
- package/dist/clipboard.d.ts +7 -14
- package/dist/{types-B4iJRHC3.d.ts → clone-C0eADtS0.d.ts} +129 -84
- package/dist/clone.d.ts +4 -8
- package/dist/clone.js +0 -2
- package/dist/core/device/targets.js.map +1 -1
- package/dist/core/device/useDeviceProfile.js +13 -13
- package/dist/core/device/useDeviceProfile.js.map +1 -1
- package/dist/{interactions/actions/resize → core/geometry}/autoPoseDescriptor.js +8 -7
- package/dist/core/geometry/autoPoseDescriptor.js.map +1 -0
- package/dist/core/geometry/pathPoseDescriptor.js +88 -0
- package/dist/core/geometry/pathPoseDescriptor.js.map +1 -0
- package/dist/core/geometry/poseDescriptor.js +102 -29
- package/dist/core/geometry/poseDescriptor.js.map +1 -1
- package/dist/core/geometry/regionHit.js +35 -37
- package/dist/core/geometry/regionHit.js.map +1 -1
- package/dist/core/geometry/targetFrame.js +94 -0
- package/dist/core/geometry/targetFrame.js.map +1 -0
- package/dist/core/geometry/unionBounds.js +4 -5
- package/dist/core/geometry/unionBounds.js.map +1 -1
- package/dist/core/layers/backgroundFill.js +31 -0
- package/dist/core/layers/backgroundFill.js.map +1 -0
- package/dist/{features/groups → core/layers}/children.js +2 -4
- package/dist/core/layers/children.js.map +1 -0
- package/dist/{features/focus → core/layers}/gateLayer.js +2 -2
- package/dist/core/layers/gateLayer.js.map +1 -0
- package/dist/core/layers/layerGroup.js +40 -0
- package/dist/core/layers/layerGroup.js.map +1 -0
- package/dist/core/layers/render.js +50 -76
- package/dist/core/layers/render.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/createHistory.js +9 -9
- package/dist/core/ops/createHistory.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/meshKind.js +16 -0
- package/dist/core/paint/meshKind.js.map +1 -0
- package/dist/{features/meshPaint/lazyKind.js → core/paint/meshKindLazy.js} +104 -93
- package/dist/core/paint/meshKindLazy.js.map +1 -0
- package/dist/core/paint/paintKindEntry.js +8 -0
- package/dist/core/paint/paintKindEntry.js.map +1 -0
- package/dist/core/paint/paintKinds.js +144 -0
- package/dist/core/paint/paintKinds.js.map +1 -0
- package/dist/core/paint/registerMesh.js +7 -0
- package/dist/core/paint/registerMesh.js.map +1 -0
- package/dist/core/scene/NodeProperties.js.map +1 -1
- package/dist/core/scene/NodeRouting.js.map +1 -1
- package/dist/core/scene/arrivalWindow.js +65 -64
- package/dist/core/scene/arrivalWindow.js.map +1 -1
- package/dist/core/scene/boundOps.js +40 -0
- package/dist/core/scene/boundOps.js.map +1 -0
- package/dist/core/scene/composeFrame.js +9 -6
- package/dist/core/scene/composeFrame.js.map +1 -1
- package/dist/core/scene/composePose.js +105 -0
- package/dist/core/scene/composePose.js.map +1 -0
- package/dist/core/scene/depMemo.js +31 -6
- package/dist/core/scene/depMemo.js.map +1 -1
- package/dist/core/scene/derivedPath.js +19 -20
- package/dist/core/scene/derivedPath.js.map +1 -1
- package/dist/core/scene/editMode.js +26 -0
- package/dist/core/scene/editMode.js.map +1 -0
- package/dist/core/scene/effectivePose.js +42 -39
- package/dist/core/scene/effectivePose.js.map +1 -1
- package/dist/core/scene/fieldEdits.js +98 -0
- package/dist/core/scene/fieldEdits.js.map +1 -0
- package/dist/core/scene/historyFacade.js +122 -70
- package/dist/core/scene/historyFacade.js.map +1 -1
- package/dist/core/scene/historyForm.js +6 -0
- package/dist/core/scene/historyForm.js.map +1 -0
- package/dist/core/scene/kitOps.js +83 -71
- package/dist/core/scene/kitOps.js.map +1 -1
- package/dist/core/scene/kitRegistry.js.map +1 -1
- package/dist/core/scene/layerStack.js +105 -12
- package/dist/core/scene/layerStack.js.map +1 -1
- package/dist/core/scene/layoutPass.js +58 -59
- package/dist/core/scene/layoutPass.js.map +1 -1
- package/dist/{features/groups → core/scene}/nestedHit.js +3 -3
- package/dist/core/scene/nestedHit.js.map +1 -0
- package/dist/core/scene/nodeFnFields.js +16 -9
- package/dist/core/scene/nodeFnFields.js.map +1 -1
- package/dist/core/scene/nodeMemo.js.map +1 -1
- package/dist/core/scene/nodeStore.js +72 -71
- package/dist/core/scene/nodeStore.js.map +1 -1
- package/dist/core/scene/notifier.js +37 -0
- package/dist/core/scene/notifier.js.map +1 -0
- package/dist/core/scene/opTable.js +50 -0
- package/dist/core/scene/opTable.js.map +1 -0
- package/dist/core/scene/outerOps.js +67 -0
- package/dist/core/scene/outerOps.js.map +1 -0
- package/dist/core/scene/poseHold.js +39 -0
- package/dist/core/scene/poseHold.js.map +1 -0
- package/dist/core/scene/poseOverrides.js +44 -36
- package/dist/core/scene/poseOverrides.js.map +1 -1
- package/dist/core/scene/poseSnapshot.js.map +1 -1
- package/dist/core/scene/reconcileSpecs.js +4 -3
- package/dist/core/scene/reconcileSpecs.js.map +1 -1
- package/dist/core/scene/recorder.js +86 -0
- package/dist/core/scene/recorder.js.map +1 -0
- package/dist/core/scene/renderOrder.js.map +1 -1
- package/dist/core/scene/scene.js +81 -690
- package/dist/core/scene/scene.js.map +1 -1
- package/dist/core/scene/sceneEdits.js +58 -0
- package/dist/core/scene/sceneEdits.js.map +1 -0
- package/dist/core/scene/sceneMutators.js +49 -0
- package/dist/core/scene/sceneMutators.js.map +1 -0
- package/dist/core/scene/scenePoseAdapter.js +16 -0
- package/dist/core/scene/scenePoseAdapter.js.map +1 -0
- package/dist/core/scene/sceneRecording.js +91 -0
- package/dist/core/scene/sceneRecording.js.map +1 -0
- package/dist/core/scene/sceneSelection.js +28 -0
- package/dist/core/scene/sceneSelection.js.map +1 -0
- package/dist/core/scene/sceneState.js +49 -0
- package/dist/core/scene/sceneState.js.map +1 -0
- package/dist/core/scene/serialization.js +8 -5
- package/dist/core/scene/serialization.js.map +1 -1
- package/dist/core/scene/staleReplay.js +51 -0
- package/dist/core/scene/staleReplay.js.map +1 -0
- package/dist/core/scene/statedFields.js +9 -0
- package/dist/core/scene/statedFields.js.map +1 -0
- package/dist/core/scene/treeEdits.js +127 -0
- package/dist/core/scene/treeEdits.js.map +1 -0
- package/dist/core/scene/treeReads.js +26 -0
- package/dist/core/scene/treeReads.js.map +1 -0
- package/dist/core/scene/types.js.map +1 -1
- package/dist/{features/groups → core/scene}/unionOfChildren.js +3 -3
- package/dist/core/scene/unionOfChildren.js.map +1 -0
- package/dist/core/scene/unitScopes.js +13 -0
- package/dist/core/scene/unitScopes.js.map +1 -0
- package/dist/core/scene/useScene.js.map +1 -1
- package/dist/core/selection/readOnlySelection.js +32 -0
- package/dist/core/selection/readOnlySelection.js.map +1 -0
- package/dist/core/selection/usePublishSceneSelection.js +26 -0
- package/dist/core/selection/usePublishSceneSelection.js.map +1 -0
- package/dist/core/selection/useSelection.js +34 -25
- package/dist/core/selection/useSelection.js.map +1 -1
- package/dist/core/shapeKinds.js.map +1 -1
- package/dist/core/stylus/stylus.js.map +1 -1
- package/dist/core/stylus/usePointerStylus.js.map +1 -1
- package/dist/core/usePaintKinds.js +1 -1
- package/dist/core/usePaintKinds.js.map +1 -1
- package/dist/core/viewport/clientToWorld.js.map +1 -1
- package/dist/core/viewport/fitViewToBounds.js.map +1 -1
- package/dist/core/viewport/parallax.js.map +1 -1
- package/dist/core/viewport/screenSlop.js +11 -11
- package/dist/core/viewport/screenSlop.js.map +1 -1
- package/dist/core/viewport/useCanvasSize.js.map +1 -1
- package/dist/core/viewport/useDecayLoop.js +31 -33
- package/dist/core/viewport/useDecayLoop.js.map +1 -1
- package/dist/core/viewport/useNodeOverlayFrame.js +84 -0
- package/dist/core/viewport/useNodeOverlayFrame.js.map +1 -0
- package/dist/core/viewport/useViewAnimation.js +113 -53
- package/dist/core/viewport/useViewAnimation.js.map +1 -1
- package/dist/core/viewport/view.js +14 -11
- package/dist/core/viewport/view.js.map +1 -1
- package/dist/core/viewport/wheelHandler.js.map +1 -1
- package/dist/core/viewport/zoomAt.js +11 -2
- package/dist/core/viewport/zoomAt.js.map +1 -1
- package/dist/{cornerHandles-CtCb8a3G.d.ts → cornerHandles-BSKbyuvQ.d.ts} +11 -24
- package/dist/debug/createDebugOverlayLayer.js +100 -100
- package/dist/debug/createDebugOverlayLayer.js.map +1 -1
- package/dist/debug/createDebugSink.js.map +1 -1
- package/dist/debug/frameStats.js.map +1 -1
- package/dist/debug/useDebugSink.js +52 -0
- package/dist/debug/useDebugSink.js.map +1 -0
- package/dist/features/chrome-caps/buildChromeCtx.js.map +1 -1
- package/dist/features/chrome-caps/conditions.js.map +1 -1
- package/dist/features/chrome-caps/defaults.js.map +1 -1
- package/dist/features/chrome-caps/resolve.js.map +1 -1
- package/dist/features/chrome-caps/useChromeCaps.js +54 -0
- package/dist/features/chrome-caps/useChromeCaps.js.map +1 -0
- package/dist/features/chrome-caps/useHoverTracking.js.map +1 -1
- package/dist/features/ingestion/contentHandlers.js +25 -19
- package/dist/features/ingestion/contentHandlers.js.map +1 -1
- package/dist/features/ingestion/imageHandler.js +21 -24
- package/dist/features/ingestion/imageHandler.js.map +1 -1
- package/dist/features/ingestion/openFilePicker.js.map +1 -1
- package/dist/features/ingestion/placement.js +16 -0
- package/dist/features/ingestion/placement.js.map +1 -0
- package/dist/features/ingestion/svgHandler.js +5 -0
- package/dist/features/ingestion/svgHandler.js.map +1 -1
- package/dist/features/ingestion/textHandler.js +28 -0
- package/dist/features/ingestion/textHandler.js.map +1 -0
- package/dist/features/ingestion/useCanvasIngestion.js +48 -0
- package/dist/features/ingestion/useCanvasIngestion.js.map +1 -0
- package/dist/features/ingestion/weaselJsonHandler.js +5 -0
- package/dist/features/ingestion/weaselJsonHandler.js.map +1 -1
- package/dist/features/longPress/longPressFeedback.js.map +1 -1
- package/dist/features/modes/modeLayers.js +7 -7
- package/dist/features/modes/modeLayers.js.map +1 -1
- package/dist/features/paths/editablePath.js +63 -0
- package/dist/features/paths/editablePath.js.map +1 -0
- package/dist/features/paths/index.js +9 -16
- package/dist/features/paths/pathEditState.js +41 -0
- package/dist/features/paths/pathEditState.js.map +1 -0
- package/dist/features/paths/pathEditingOverlayLayer.js +36 -38
- package/dist/features/paths/pathEditingOverlayLayer.js.map +1 -1
- package/dist/features/paths/pathLayer.js +3 -2
- package/dist/features/paths/pathLayer.js.map +1 -1
- package/dist/features/paths/penPreviewLayer.js +86 -88
- package/dist/features/paths/penPreviewLayer.js.map +1 -1
- package/dist/features/paths/shapeGenerator.js +89 -0
- package/dist/features/paths/shapeGenerator.js.map +1 -0
- package/dist/features/paths/usePathEdit.js +34 -0
- package/dist/features/paths/usePathEdit.js.map +1 -0
- package/dist/features/poseRun/usePoseRun.js +44 -57
- package/dist/features/poseRun/usePoseRun.js.map +1 -1
- package/dist/features/selection/overlay.js +170 -178
- package/dist/features/selection/overlay.js.map +1 -1
- package/dist/features/text/index.js +6 -0
- package/dist/features/text/textLayer.js +1 -1
- package/dist/features/text/textLayer.js.map +1 -1
- package/dist/features/text/useSceneTextEdit.js +119 -88
- 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/features/viewports/viewportLayer.js +25 -36
- package/dist/features/viewports/viewportLayer.js.map +1 -1
- package/dist/icons/SliceIcon.js +24 -0
- package/dist/icons/SliceIcon.js.map +1 -0
- package/dist/index.d.ts +5200 -8777
- package/dist/index.js +284 -320
- package/dist/input/keyState.js +14 -14
- package/dist/interactions/actions/actionShortcuts.js.map +1 -1
- package/dist/interactions/actions/{defaults/align.js → align/action.js} +15 -16
- package/dist/interactions/actions/align/action.js.map +1 -0
- package/dist/interactions/actions/align/align.js +24 -24
- package/dist/interactions/actions/align/align.js.map +1 -1
- package/dist/interactions/actions/booleans/action.js +65 -0
- package/dist/interactions/actions/booleans/action.js.map +1 -0
- package/dist/interactions/actions/booleans/booleans.js +74 -83
- package/dist/interactions/actions/booleans/booleans.js.map +1 -1
- package/dist/interactions/actions/booleans/operands.js +40 -0
- package/dist/interactions/actions/booleans/operands.js.map +1 -0
- package/dist/interactions/actions/booleans/pieces.js +45 -0
- package/dist/interactions/actions/booleans/pieces.js.map +1 -0
- package/dist/interactions/actions/booleans/placement.js +24 -0
- package/dist/interactions/actions/booleans/placement.js.map +1 -0
- package/dist/interactions/actions/booleans/useBooleans.js +11 -9
- package/dist/interactions/actions/booleans/useBooleans.js.map +1 -1
- package/dist/interactions/actions/booleans/useBooleansAdapter.js.map +1 -1
- package/dist/interactions/actions/{defaults/clipboard.js → clipboard/action.js} +19 -19
- package/dist/interactions/actions/clipboard/action.js.map +1 -0
- package/dist/interactions/actions/clipboard/clipboardOps.js +15 -15
- package/dist/interactions/actions/clipboard/clipboardOps.js.map +1 -1
- package/dist/interactions/actions/clipboard/wireFormat.js.map +1 -1
- package/dist/interactions/actions/clone/action.js +103 -0
- package/dist/interactions/actions/clone/action.js.map +1 -0
- package/dist/interactions/actions/clone/behaviors.js +52 -0
- package/dist/interactions/actions/clone/behaviors.js.map +1 -0
- package/dist/interactions/actions/defaultCommitAdapter.js +10 -37
- package/dist/interactions/actions/defaultCommitAdapter.js.map +1 -1
- package/dist/interactions/actions/defaults/anchorEditing.js +69 -74
- 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/areaSelect.js.map +1 -1
- package/dist/interactions/actions/defaults/bendSegment.js +46 -0
- package/dist/interactions/actions/defaults/bendSegment.js.map +1 -0
- package/dist/interactions/actions/defaults/cancelGesture.js.map +1 -1
- package/dist/interactions/actions/defaults/clearSelection.js.map +1 -1
- package/dist/interactions/actions/defaults/copySubtree.js +1 -1
- package/dist/interactions/actions/defaults/copySubtree.js.map +1 -1
- package/dist/interactions/actions/defaults/createPaintAction.js.map +1 -1
- package/dist/interactions/actions/defaults/delete.js.map +1 -1
- package/dist/interactions/actions/defaults/duplicate.js +36 -21
- 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/enterTextEdit.js.map +1 -1
- package/dist/interactions/actions/defaults/group.js +35 -40
- package/dist/interactions/actions/defaults/group.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/booleanIcons.js +24 -1
- package/dist/interactions/actions/defaults/icons/booleanIcons.js.map +1 -1
- 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/icons/outlineIcons.js +39 -1
- package/dist/interactions/actions/defaults/icons/outlineIcons.js.map +1 -1
- package/dist/interactions/actions/defaults/ingest.js +19 -15
- package/dist/interactions/actions/defaults/ingest.js.map +1 -1
- package/dist/interactions/actions/defaults/insertPathAnchor.js +18 -34
- package/dist/interactions/actions/defaults/insertPathAnchor.js.map +1 -1
- package/dist/interactions/actions/defaults/nudge.js +43 -39
- 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/requiresSelection.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/setFill.js +9 -3
- package/dist/interactions/actions/defaults/setFill.js.map +1 -1
- package/dist/interactions/actions/defaults/setFillOpacity.js +4 -1
- package/dist/interactions/actions/defaults/setFillOpacity.js.map +1 -1
- package/dist/interactions/actions/defaults/setStroke.js.map +1 -1
- package/dist/interactions/actions/defaults/sliceOps.js +20 -22
- package/dist/interactions/actions/defaults/sliceOps.js.map +1 -1
- package/dist/interactions/actions/defaults/toolActivate.js.map +1 -1
- package/dist/interactions/actions/defaults/toolResetToDefault.js.map +1 -1
- package/dist/interactions/actions/defaults/viewportDragPan.js +1 -1
- package/dist/interactions/actions/defaults/viewportDragPan.js.map +1 -1
- package/dist/interactions/actions/defaults/viewportWheelPan.js.map +1 -1
- package/dist/interactions/actions/defaults/viewportZoom.js +82 -79
- package/dist/interactions/actions/defaults/viewportZoom.js.map +1 -1
- package/dist/interactions/actions/{defaults/distribute.js → distribute/action.js} +18 -19
- package/dist/interactions/actions/distribute/action.js.map +1 -0
- package/dist/interactions/actions/distribute/distribute.js +15 -15
- package/dist/interactions/actions/distribute/distribute.js.map +1 -1
- package/dist/interactions/actions/edit-anchors/action.js +101 -0
- package/dist/interactions/actions/edit-anchors/action.js.map +1 -0
- package/dist/interactions/actions/edit-anchors/geometry.js +2 -4
- package/dist/interactions/actions/edit-anchors/geometry.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 +124 -0
- package/dist/interactions/actions/flip/action.js.map +1 -0
- package/dist/interactions/actions/flip/helpers.js +1 -1
- package/dist/interactions/actions/flip/helpers.js.map +1 -1
- package/dist/interactions/actions/geometryProjection.js.map +1 -1
- package/dist/interactions/actions/gestureFrames.js +18 -0
- package/dist/interactions/actions/gestureFrames.js.map +1 -0
- package/dist/interactions/actions/gestureLifecycle.js +47 -20
- package/dist/interactions/actions/gestureLifecycle.js.map +1 -1
- package/dist/interactions/actions/insert/action.js +79 -0
- package/dist/interactions/actions/insert/action.js.map +1 -0
- package/dist/interactions/actions/insert/commit.js +28 -0
- package/dist/interactions/actions/insert/commit.js.map +1 -0
- package/dist/interactions/actions/insert/extras.js +65 -0
- package/dist/interactions/actions/insert/extras.js.map +1 -0
- package/dist/interactions/actions/insert/frame.js +55 -0
- package/dist/interactions/actions/insert/frame.js.map +1 -0
- package/dist/interactions/actions/insert/geometry.js +35 -0
- package/dist/interactions/actions/insert/geometry.js.map +1 -0
- package/dist/interactions/actions/insert/repositionAction.js +31 -0
- package/dist/interactions/actions/insert/repositionAction.js.map +1 -0
- package/dist/interactions/actions/insert/rotateAction.js +21 -0
- package/dist/interactions/actions/insert/rotateAction.js.map +1 -0
- package/dist/interactions/actions/insert/session.js +59 -0
- package/dist/interactions/actions/insert/session.js.map +1 -0
- package/dist/interactions/actions/insert/shape.js +34 -0
- package/dist/interactions/actions/insert/shape.js.map +1 -0
- package/dist/interactions/actions/lasso-select/action.js +143 -0
- package/dist/interactions/actions/lasso-select/action.js.map +1 -0
- package/dist/interactions/actions/move/action.js +91 -0
- package/dist/interactions/actions/move/action.js.map +1 -0
- package/dist/interactions/actions/move/behaviors/layoutDrop.js +51 -0
- package/dist/interactions/actions/move/behaviors/layoutDrop.js.map +1 -0
- package/dist/interactions/actions/move/behaviors/reparentOnDrop.js +15 -0
- package/dist/interactions/actions/move/behaviors/reparentOnDrop.js.map +1 -0
- package/dist/interactions/actions/move/behaviors/snapToContainer.js +35 -28
- package/dist/interactions/actions/move/behaviors/snapToContainer.js.map +1 -1
- package/dist/interactions/actions/move/capture.js +108 -0
- package/dist/interactions/actions/move/capture.js.map +1 -0
- package/dist/interactions/actions/move/commit/index.js +41 -0
- package/dist/interactions/actions/move/commit/index.js.map +1 -0
- package/dist/interactions/actions/move/commit/layoutDrop.js +44 -0
- package/dist/interactions/actions/move/commit/layoutDrop.js.map +1 -0
- package/dist/interactions/actions/move/commit/layoutRelease.js +100 -0
- package/dist/interactions/actions/move/commit/layoutRelease.js.map +1 -0
- package/dist/interactions/actions/move/commit/rebase.js +18 -0
- package/dist/interactions/actions/move/commit/rebase.js.map +1 -0
- package/dist/interactions/actions/move/commit/reparent.js +65 -0
- package/dist/interactions/actions/move/commit/reparent.js.map +1 -0
- package/dist/interactions/actions/move/delta.js +51 -0
- package/dist/interactions/actions/move/delta.js.map +1 -0
- package/dist/interactions/actions/move/frame.js +47 -0
- package/dist/interactions/actions/move/frame.js.map +1 -0
- package/dist/interactions/actions/move/gestureAdapter.js +15 -40
- package/dist/interactions/actions/move/gestureAdapter.js.map +1 -1
- package/dist/interactions/actions/move/landedDescendants.js +8 -8
- package/dist/interactions/actions/move/layout/container.js +94 -0
- package/dist/interactions/actions/move/layout/container.js.map +1 -0
- package/dist/interactions/actions/move/layout/dragged.js +58 -0
- package/dist/interactions/actions/move/layout/dragged.js.map +1 -0
- package/dist/interactions/actions/move/layout/dropPass.js +122 -0
- package/dist/interactions/actions/move/layout/dropPass.js.map +1 -0
- package/dist/interactions/actions/move/layout/exits.js +38 -0
- package/dist/interactions/actions/move/layout/exits.js.map +1 -0
- package/dist/interactions/actions/move/layout/glide.js +48 -0
- package/dist/interactions/actions/move/layout/glide.js.map +1 -0
- package/dist/interactions/actions/move/session.js +63 -0
- package/dist/interactions/actions/move/session.js.map +1 -0
- package/dist/interactions/actions/move/translate.js +61 -0
- package/dist/interactions/actions/move/translate.js.map +1 -0
- package/dist/interactions/actions/outlines/createOutlines.js +17 -64
- package/dist/interactions/actions/outlines/createOutlines.js.map +1 -1
- package/dist/interactions/actions/outlines/createOutlinesAction.js +51 -0
- package/dist/interactions/actions/outlines/createOutlinesAction.js.map +1 -0
- package/dist/interactions/actions/outlines/outlineStroke.js +72 -0
- package/dist/interactions/actions/outlines/outlineStroke.js.map +1 -0
- package/dist/interactions/actions/outlines/outlineStrokeAction.js +37 -0
- package/dist/interactions/actions/outlines/outlineStrokeAction.js.map +1 -0
- package/dist/interactions/actions/outlines/replaceWithPaths.js +54 -0
- package/dist/interactions/actions/outlines/replaceWithPaths.js.map +1 -0
- package/dist/interactions/actions/outlines/strokeRegion.js +27 -0
- package/dist/interactions/actions/outlines/strokeRegion.js.map +1 -0
- 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/planeInput.js.map +1 -1
- package/dist/interactions/actions/pointerState.js +12 -0
- package/dist/interactions/actions/pointerState.js.map +1 -0
- package/dist/interactions/actions/poseDescriptorDep.js +1 -1
- package/dist/interactions/actions/poseDescriptorDep.js.map +1 -1
- package/dist/interactions/actions/poseFrame.js +26 -26
- package/dist/interactions/actions/poseFrame.js.map +1 -1
- package/dist/interactions/actions/resize/action.js +66 -0
- package/dist/interactions/actions/resize/action.js.map +1 -0
- package/dist/interactions/actions/resize/behaviors/lockAspect.js.map +1 -1
- package/dist/interactions/actions/resize/boxFrame.js +16 -0
- package/dist/interactions/actions/resize/boxFrame.js.map +1 -0
- package/dist/interactions/actions/resize/capture.js +85 -0
- package/dist/interactions/actions/resize/capture.js.map +1 -0
- package/dist/interactions/actions/resize/commit.js +69 -0
- package/dist/interactions/actions/resize/commit.js.map +1 -0
- package/dist/interactions/actions/resize/frame.js +88 -0
- package/dist/interactions/actions/resize/frame.js.map +1 -0
- package/dist/interactions/actions/resize/pointSnap.js +111 -0
- package/dist/interactions/actions/resize/pointSnap.js.map +1 -0
- package/dist/interactions/actions/resize/replay.js +47 -0
- package/dist/interactions/actions/resize/replay.js.map +1 -0
- package/dist/interactions/actions/resize/ruleBounds.js +9 -0
- package/dist/interactions/actions/resize/ruleBounds.js.map +1 -0
- package/dist/interactions/actions/resize/session.js +63 -0
- package/dist/interactions/actions/resize/session.js.map +1 -0
- package/dist/interactions/actions/resolveOverlays.js +2 -1
- package/dist/interactions/actions/resolveOverlays.js.map +1 -1
- package/dist/interactions/actions/resolvePreviews.js.map +1 -1
- package/dist/interactions/actions/rotate/action.js +71 -0
- package/dist/interactions/actions/rotate/action.js.map +1 -0
- package/dist/interactions/actions/rotate/behaviors/index.js +7 -0
- package/dist/interactions/actions/rotate/behaviors/index.js.map +1 -0
- package/dist/interactions/actions/rotate/behaviors/snapRotation.js +12 -0
- package/dist/interactions/actions/rotate/behaviors/snapRotation.js.map +1 -0
- package/dist/interactions/actions/rotate/commit.js +40 -0
- package/dist/interactions/actions/rotate/commit.js.map +1 -0
- package/dist/interactions/actions/rotate/frame.js +65 -0
- package/dist/interactions/actions/rotate/frame.js.map +1 -0
- package/dist/interactions/actions/rotate/handle.js +12 -12
- package/dist/interactions/actions/rotate/handle.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 +102 -0
- package/dist/interactions/actions/rotate/session.js.map +1 -0
- package/dist/interactions/actions/spatialReference.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 +84 -61
- package/dist/interactions/actions/useStandardActions.js.map +1 -1
- package/dist/interactions/gestures/pointerDrag/pointerDrag.js +61 -42
- package/dist/interactions/gestures/pointerDrag/pointerDrag.js.map +1 -1
- package/dist/interactions/gestures/shared/originProjection.js +1 -1
- package/dist/interactions/gestures/shared/originProjection.js.map +1 -1
- package/dist/interactions/gestures/shared/screenTolerance.js +8 -2
- package/dist/interactions/gestures/shared/screenTolerance.js.map +1 -1
- package/dist/interactions/gestures/shared/snap.js.map +1 -1
- package/dist/math-CYUjoyyU.d.ts +33 -0
- package/dist/math.d.ts +5 -2
- package/dist/math.js +6 -6
- package/dist/mesh.d.ts +4 -268
- package/dist/mesh.js +3 -7
- package/dist/move.d.ts +6 -4
- package/dist/{originProjection-gHnOup4e.d.ts → originProjection-CoNVpITV.d.ts} +1 -1
- package/dist/patterns-builtin.d.ts +1 -118
- package/dist/patterns-builtin.js +2 -3
- package/dist/poseDescriptor-Bqk-11Rl.d.ts +73 -0
- package/dist/renderer.d.ts +1 -92
- package/dist/renderer.js +2 -19
- package/dist/resize.d.ts +11 -22
- package/dist/resize.js +1 -1
- package/dist/style.css +1 -1
- package/dist/test-hook/install.js.map +1 -1
- package/dist/test-hook/useTestHook.js +22 -0
- package/dist/test-hook/useTestHook.js.map +1 -0
- package/dist/test-seams-D0pyV3pR.d.ts +149 -0
- package/dist/test-seams.d.ts +4 -4
- package/dist/test-seams.js +2 -2
- package/dist/tools/builtin/bone/boneActions.js +130 -0
- package/dist/tools/builtin/bone/boneActions.js.map +1 -0
- package/dist/tools/builtin/bone/boneOverlay.js +58 -0
- package/dist/tools/builtin/bone/boneOverlay.js.map +1 -0
- package/dist/tools/builtin/bone/placedRig.js +24 -0
- package/dist/tools/builtin/bone/placedRig.js.map +1 -0
- package/dist/tools/builtin/bone/rigEditState.js +21 -0
- package/dist/tools/builtin/bone/rigEditState.js.map +1 -0
- package/dist/tools/builtin/bone/useBoneTool.js +98 -0
- package/dist/tools/builtin/bone/useBoneTool.js.map +1 -0
- package/dist/tools/builtin/ellipse/useEllipseTool.js +16 -15
- package/dist/tools/builtin/ellipse/useEllipseTool.js.map +1 -1
- package/dist/tools/builtin/eyedropper/useEyedropperTool.js.map +1 -1
- package/dist/tools/builtin/hand/useHandTool.js.map +1 -1
- package/dist/tools/builtin/image/useImageTool.js.map +1 -1
- package/dist/tools/builtin/lasso/useLassoTool.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 +162 -164
- package/dist/tools/builtin/pen/usePenTool.js.map +1 -1
- package/dist/tools/builtin/pencil/usePencilTool.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 +40 -0
- package/dist/tools/builtin/select/adapterPointQuery.js.map +1 -0
- package/dist/tools/builtin/select/selectionContributions.js +5 -5
- package/dist/tools/builtin/select/selectionContributions.js.map +1 -1
- package/dist/tools/builtin/select/useSelectTool.js +44 -71
- package/dist/tools/builtin/select/useSelectTool.js.map +1 -1
- package/dist/tools/builtin/shared/pointerFollower.js.map +1 -1
- package/dist/tools/builtin/slice/useSliceTool.js +69 -72
- 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 +10 -2
- package/dist/tools/builtin/text/useTextTool.js.map +1 -1
- package/dist/tools/builtin/weight/useWeightTool.js +77 -0
- package/dist/tools/builtin/weight/useWeightTool.js.map +1 -0
- package/dist/tools/builtin/weight/weightActions.js +112 -0
- package/dist/tools/builtin/weight/weightActions.js.map +1 -0
- package/dist/tools/builtin/weight/weightOverlay.js +61 -0
- package/dist/tools/builtin/weight/weightOverlay.js.map +1 -0
- package/dist/tools/overlayBinding.js.map +1 -1
- package/dist/tools/useKeybindings.js +20 -14
- package/dist/tools/useKeybindings.js.map +1 -1
- package/dist/{types-k-5Oqh-U.d.ts → types-DBbbCy0i.d.ts} +103 -176
- package/dist/util/paint.js +1 -1
- package/dist/util/paint.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +26 -21
- package/dist/animation/colorHelpers.js +0 -135
- package/dist/animation/colorHelpers.js.map +0 -1
- package/dist/animation/colorRegistry.js +0 -37
- package/dist/animation/colorRegistry.js.map +0 -1
- package/dist/animation/engine/axes.js +0 -36
- package/dist/animation/engine/axes.js.map +0 -1
- package/dist/animation/engine/codec.js +0 -170
- package/dist/animation/engine/codec.js.map +0 -1
- package/dist/animation/engine/integrator.js +0 -12
- package/dist/animation/engine/integrator.js.map +0 -1
- package/dist/animation/loop.js +0 -60
- package/dist/animation/loop.js.map +0 -1
- package/dist/animation/observe.js +0 -23
- package/dist/animation/observe.js.map +0 -1
- package/dist/animation/rig/blendPoses.js +0 -43
- package/dist/animation/rig/blendPoses.js.map +0 -1
- package/dist/animation/rig/mirrorPose.js +0 -19
- package/dist/animation/rig/mirrorPose.js.map +0 -1
- package/dist/animation/rig/resolveSkeleton.js +0 -33
- package/dist/animation/rig/resolveSkeleton.js.map +0 -1
- package/dist/animation/rig/solveIk.js +0 -103
- package/dist/animation/rig/solveIk.js.map +0 -1
- package/dist/animation/rig/types.js +0 -12
- package/dist/animation/rig/types.js.map +0 -1
- package/dist/animation/slew.js +0 -27
- package/dist/animation/slew.js.map +0 -1
- package/dist/animation/stagger.js +0 -146
- package/dist/animation/stagger.js.map +0 -1
- package/dist/animation/timeline/booking.js +0 -114
- package/dist/animation/timeline/booking.js.map +0 -1
- package/dist/animation/timeline/createTimeline.js +0 -125
- package/dist/animation/timeline/createTimeline.js.map +0 -1
- package/dist/animation/timeline/sampleTrack.js +0 -79
- package/dist/animation/timeline/sampleTrack.js.map +0 -1
- package/dist/animation/useAnimator.js +0 -388
- package/dist/animation/useAnimator.js.map +0 -1
- package/dist/autoPoseDescriptor-Ct7yqivU.d.ts +0 -108
- package/dist/builtins-DPcdghtB.d.ts +0 -1223
- package/dist/canvas/MinimapCanvas.js +0 -140
- package/dist/canvas/MinimapCanvas.js.map +0 -1
- package/dist/canvas/deps/poseComposition.js +0 -11
- package/dist/canvas/deps/poseComposition.js.map +0 -1
- package/dist/canvas/minimapMath.js +0 -82
- package/dist/canvas/minimapMath.js.map +0 -1
- package/dist/canvas/toolPreview.js +0 -39
- package/dist/canvas/toolPreview.js.map +0 -1
- package/dist/core/adapters/arrayAdapter.js +0 -94
- package/dist/core/adapters/arrayAdapter.js.map +0 -1
- package/dist/core/adapters/useArrayAdapter.js +0 -13
- package/dist/core/adapters/useArrayAdapter.js.map +0 -1
- package/dist/core/fillInPoseFrame.js +0 -102
- package/dist/core/fillInPoseFrame.js.map +0 -1
- package/dist/core/geometry/poseFrame.js +0 -44
- package/dist/core/geometry/poseFrame.js.map +0 -1
- package/dist/core/geometry/poseRotation.js +0 -58
- package/dist/core/geometry/poseRotation.js.map +0 -1
- package/dist/core/gradient.js +0 -136
- package/dist/core/gradient.js.map +0 -1
- package/dist/core/markerInset.js +0 -24
- package/dist/core/markerInset.js.map +0 -1
- package/dist/core/mixed.js +0 -6
- package/dist/core/mixed.js.map +0 -1
- package/dist/core/paintKinds.js +0 -156
- package/dist/core/paintKinds.js.map +0 -1
- package/dist/core/scene/pickability.js +0 -6
- package/dist/core/scene/pickability.js.map +0 -1
- package/dist/core/strokeMarkerShapes.js +0 -139
- package/dist/core/strokeMarkerShapes.js.map +0 -1
- package/dist/core/strokeMarkers.js +0 -28
- package/dist/core/strokeMarkers.js.map +0 -1
- package/dist/core/viewport/meanScale.js +0 -8
- package/dist/core/viewport/meanScale.js.map +0 -1
- package/dist/core/viewport/pxExtent.js +0 -42
- package/dist/core/viewport/pxExtent.js.map +0 -1
- package/dist/features/cursor/paintedCursorLayer.js.map +0 -1
- package/dist/features/focus/gateLayer.js.map +0 -1
- package/dist/features/focus/useCanvasFocus.js +0 -29
- package/dist/features/focus/useCanvasFocus.js.map +0 -1
- package/dist/features/groups/children.js.map +0 -1
- package/dist/features/groups/composePose.js +0 -67
- package/dist/features/groups/composePose.js.map +0 -1
- package/dist/features/groups/nestedHit.js.map +0 -1
- package/dist/features/groups/unionOfChildren.js.map +0 -1
- package/dist/features/images/imageCache.js +0 -104
- package/dist/features/images/imageCache.js.map +0 -1
- package/dist/features/ingestion/index.js +0 -8
- package/dist/features/meshPaint/bake.js +0 -79
- package/dist/features/meshPaint/bake.js.map +0 -1
- package/dist/features/meshPaint/bakeCache.js +0 -59
- package/dist/features/meshPaint/bakeCache.js.map +0 -1
- package/dist/features/meshPaint/handles.js +0 -86
- package/dist/features/meshPaint/handles.js.map +0 -1
- package/dist/features/meshPaint/lazyKind.js.map +0 -1
- package/dist/features/meshPaint/meshPaint.js +0 -239
- package/dist/features/meshPaint/meshPaint.js.map +0 -1
- package/dist/features/meshPaint/meshShader.js +0 -6
- package/dist/features/meshPaint/meshShader.js.map +0 -1
- package/dist/features/meshPaint/register.js +0 -7
- package/dist/features/meshPaint/register.js.map +0 -1
- package/dist/features/meshPaint/surface.js +0 -110
- package/dist/features/meshPaint/surface.js.map +0 -1
- package/dist/features/minimap/actions.js +0 -53
- package/dist/features/minimap/actions.js.map +0 -1
- package/dist/features/minimap/createMinimapContribution.js +0 -96
- package/dist/features/minimap/createMinimapContribution.js.map +0 -1
- package/dist/features/minimap/layers.js +0 -85
- package/dist/features/minimap/layers.js.map +0 -1
- package/dist/features/overlays/useNodeOverlayFrame.js +0 -103
- package/dist/features/overlays/useNodeOverlayFrame.js.map +0 -1
- package/dist/features/parallax/createParallaxLayer.js +0 -26
- package/dist/features/parallax/createParallaxLayer.js.map +0 -1
- package/dist/features/parallax/createParallaxPlane.js +0 -22
- package/dist/features/parallax/createParallaxPlane.js.map +0 -1
- package/dist/features/paths/anchorEdits.js +0 -167
- package/dist/features/paths/anchorEdits.js.map +0 -1
- package/dist/features/paths/anchors.js +0 -159
- package/dist/features/paths/anchors.js.map +0 -1
- package/dist/features/paths/booleans.js +0 -2
- package/dist/features/paths/markerCommands.js +0 -149
- package/dist/features/paths/markerCommands.js.map +0 -1
- package/dist/features/paths/markerSites.js +0 -59
- package/dist/features/paths/markerSites.js.map +0 -1
- package/dist/features/paths/markers.js +0 -95
- package/dist/features/paths/markers.js.map +0 -1
- package/dist/features/paths/nearestAnchor.js +0 -36
- package/dist/features/paths/nearestAnchor.js.map +0 -1
- package/dist/features/paths/pathInWorld.js +0 -41
- package/dist/features/paths/pathInWorld.js.map +0 -1
- package/dist/features/paths/poseDescriptor.js +0 -39
- package/dist/features/paths/poseDescriptor.js.map +0 -1
- package/dist/features/paths/strokeToPath.js +0 -40
- package/dist/features/paths/strokeToPath.js.map +0 -1
- package/dist/features/paths/tessellate/dash.js +0 -52
- package/dist/features/paths/tessellate/dash.js.map +0 -1
- package/dist/features/paths/tessellate/insets.js +0 -32
- package/dist/features/paths/tessellate/insets.js.map +0 -1
- package/dist/features/paths/tessellate/metric.js +0 -72
- package/dist/features/paths/tessellate/metric.js.map +0 -1
- package/dist/features/paths/tessellate/stroke.js +0 -170
- package/dist/features/paths/tessellate/stroke.js.map +0 -1
- package/dist/features/paths/tessellate/vertexWidths.js +0 -32
- package/dist/features/paths/tessellate/vertexWidths.js.map +0 -1
- package/dist/features/patterns/commandPaint.js +0 -18
- package/dist/features/patterns/commandPaint.js.map +0 -1
- package/dist/features/patterns/index.js +0 -11
- package/dist/features/patterns/index.js.map +0 -1
- package/dist/features/patterns/patterns-builtin.js +0 -38
- package/dist/features/patterns/patterns-builtin.js.map +0 -1
- package/dist/features/patterns/rasterizeTile.js +0 -17
- package/dist/features/patterns/rasterizeTile.js.map +0 -1
- package/dist/features/patterns/resolveSpec.js +0 -65
- package/dist/features/patterns/resolveSpec.js.map +0 -1
- package/dist/features/patterns/tileGeometry.js +0 -158
- package/dist/features/patterns/tileGeometry.js.map +0 -1
- package/dist/features/pointer/PointerContext.js +0 -45
- package/dist/features/pointer/PointerContext.js.map +0 -1
- package/dist/features/selection/SelectionContext.js +0 -51
- package/dist/features/selection/SelectionContext.js.map +0 -1
- package/dist/features/simulation/createSimulation.js +0 -61
- package/dist/features/simulation/createSimulation.js.map +0 -1
- package/dist/features/simulation/types.js +0 -6
- package/dist/features/simulation/types.js.map +0 -1
- package/dist/features/simulation/useSimulation.js +0 -74
- package/dist/features/simulation/useSimulation.js.map +0 -1
- package/dist/features/text/domOffsets.js +0 -82
- package/dist/features/text/domOffsets.js.map +0 -1
- package/dist/features/text/domRuns.js +0 -230
- package/dist/features/text/domRuns.js.map +0 -1
- package/dist/features/text/fitTextPose.js +0 -38
- package/dist/features/text/fitTextPose.js.map +0 -1
- package/dist/features/text/hitTest.js +0 -48
- package/dist/features/text/hitTest.js.map +0 -1
- package/dist/features/text/isTextData.js +0 -8
- package/dist/features/text/isTextData.js.map +0 -1
- package/dist/features/text/overlayDirection.js +0 -15
- package/dist/features/text/overlayDirection.js.map +0 -1
- package/dist/features/text/renderLabel.js +0 -14
- package/dist/features/text/renderLabel.js.map +0 -1
- package/dist/features/text/runs/effectiveRangeStyle.js +0 -66
- package/dist/features/text/runs/effectiveRangeStyle.js.map +0 -1
- package/dist/features/text/runs/flagRange.js +0 -53
- package/dist/features/text/runs/flagRange.js.map +0 -1
- package/dist/features/text/runs/rangeStyle.js +0 -133
- package/dist/features/text/runs/rangeStyle.js.map +0 -1
- package/dist/features/text/textCommand.js +0 -60
- package/dist/features/text/textCommand.js.map +0 -1
- package/dist/features/text/textToPath.js +0 -181
- package/dist/features/text/textToPath.js.map +0 -1
- package/dist/features/text/useTextEdit.js +0 -491
- package/dist/features/text/useTextEdit.js.map +0 -1
- package/dist/features/tiling/createTiledLayer.js +0 -65
- package/dist/features/tiling/createTiledLayer.js.map +0 -1
- package/dist/features/tiling/tiledProject.js +0 -14
- package/dist/features/tiling/tiledProject.js.map +0 -1
- package/dist/interactions/actions/clone/behaviors/cloneByAltDrag.js +0 -26
- package/dist/interactions/actions/clone/behaviors/cloneByAltDrag.js.map +0 -1
- package/dist/interactions/actions/defaults/align.js.map +0 -1
- package/dist/interactions/actions/defaults/booleans.js +0 -52
- package/dist/interactions/actions/defaults/booleans.js.map +0 -1
- package/dist/interactions/actions/defaults/clipboard.js.map +0 -1
- package/dist/interactions/actions/defaults/clone.js +0 -91
- package/dist/interactions/actions/defaults/clone.js.map +0 -1
- package/dist/interactions/actions/defaults/createOutlines.js +0 -47
- package/dist/interactions/actions/defaults/createOutlines.js.map +0 -1
- package/dist/interactions/actions/defaults/distribute.js.map +0 -1
- package/dist/interactions/actions/defaults/editAnchors.js +0 -100
- package/dist/interactions/actions/defaults/editAnchors.js.map +0 -1
- package/dist/interactions/actions/defaults/flip.js +0 -125
- package/dist/interactions/actions/defaults/flip.js.map +0 -1
- package/dist/interactions/actions/defaults/insert.js +0 -287
- package/dist/interactions/actions/defaults/insert.js.map +0 -1
- package/dist/interactions/actions/defaults/lassoSelect.js +0 -153
- package/dist/interactions/actions/defaults/lassoSelect.js.map +0 -1
- package/dist/interactions/actions/defaults/move.js +0 -778
- package/dist/interactions/actions/defaults/move.js.map +0 -1
- package/dist/interactions/actions/defaults/resize.js +0 -341
- package/dist/interactions/actions/defaults/resize.js.map +0 -1
- package/dist/interactions/actions/defaults/rotate.js +0 -185
- package/dist/interactions/actions/defaults/rotate.js.map +0 -1
- package/dist/interactions/actions/previewOverrides.js +0 -25
- package/dist/interactions/actions/previewOverrides.js.map +0 -1
- package/dist/interactions/actions/resize/autoPoseDescriptor.js.map +0 -1
- package/dist/layout/arrivals.js +0 -36
- package/dist/layout/arrivals.js.map +0 -1
- package/dist/math-J-ACHyEg.d.ts +0 -159
- package/dist/registerProgram-T9S_PfAX.d.ts +0 -208
- package/dist/renderer/DrawCommand.js +0 -6
- package/dist/renderer/DrawCommand.js.map +0 -1
- package/dist/renderer/WeaselRenderer.js +0 -333
- package/dist/renderer/WeaselRenderer.js.map +0 -1
- package/dist/renderer/batchClip.js +0 -46
- package/dist/renderer/batchClip.js.map +0 -1
- package/dist/renderer/cache/GLImageCache.js +0 -74
- package/dist/renderer/cache/GLImageCache.js.map +0 -1
- package/dist/renderer/cache/GLMeshCache.js +0 -102
- package/dist/renderer/cache/GLMeshCache.js.map +0 -1
- package/dist/renderer/cache/GLTextureCache.js +0 -68
- package/dist/renderer/cache/GLTextureCache.js.map +0 -1
- package/dist/renderer/cache/GradientRampAtlas.js +0 -82
- package/dist/renderer/cache/GradientRampAtlas.js.map +0 -1
- package/dist/renderer/cache/cache.js +0 -13
- package/dist/renderer/cache/cache.js.map +0 -1
- package/dist/renderer/cache/markerCommandCache.js +0 -63
- package/dist/renderer/cache/markerCommandCache.js.map +0 -1
- package/dist/renderer/cache/outlineMeshCache.js +0 -15
- package/dist/renderer/cache/outlineMeshCache.js.map +0 -1
- package/dist/renderer/cache/outlineStrokeMeshCache.js +0 -36
- package/dist/renderer/cache/outlineStrokeMeshCache.js.map +0 -1
- package/dist/renderer/cache/strokeMeshCache.js +0 -55
- package/dist/renderer/cache/strokeMeshCache.js.map +0 -1
- package/dist/renderer/cullDrawCommands.js +0 -90
- package/dist/renderer/cullDrawCommands.js.map +0 -1
- package/dist/renderer/draw/batch.js +0 -133
- package/dist/renderer/draw/batch.js.map +0 -1
- package/dist/renderer/draw/clip.js +0 -89
- package/dist/renderer/draw/clip.js.map +0 -1
- package/dist/renderer/draw/customShader.js +0 -230
- package/dist/renderer/draw/customShader.js.map +0 -1
- package/dist/renderer/draw/drawTriangles.js +0 -8
- package/dist/renderer/draw/drawTriangles.js.map +0 -1
- package/dist/renderer/draw/effects.js +0 -28
- package/dist/renderer/draw/effects.js.map +0 -1
- package/dist/renderer/draw/flushBatch.js +0 -35
- package/dist/renderer/draw/flushBatch.js.map +0 -1
- package/dist/renderer/draw/gradient.js +0 -90
- package/dist/renderer/draw/gradient.js.map +0 -1
- package/dist/renderer/draw/image.js +0 -38
- package/dist/renderer/draw/image.js.map +0 -1
- package/dist/renderer/draw/mesh.js +0 -16
- package/dist/renderer/draw/mesh.js.map +0 -1
- package/dist/renderer/draw/paintBind.js +0 -70
- package/dist/renderer/draw/paintBind.js.map +0 -1
- package/dist/renderer/draw/pathPaint.js +0 -142
- package/dist/renderer/draw/pathPaint.js.map +0 -1
- package/dist/renderer/draw/scratchPass.js +0 -83
- package/dist/renderer/draw/scratchPass.js.map +0 -1
- package/dist/renderer/draw/stencil.js +0 -28
- package/dist/renderer/draw/stencil.js.map +0 -1
- package/dist/renderer/draw/text.js +0 -167
- package/dist/renderer/draw/text.js.map +0 -1
- package/dist/renderer/draw/uniforms.js +0 -77
- package/dist/renderer/draw/uniforms.js.map +0 -1
- package/dist/renderer/draw.js +0 -79
- package/dist/renderer/draw.js.map +0 -1
- package/dist/renderer/drawBatch.js +0 -198
- package/dist/renderer/drawBatch.js.map +0 -1
- package/dist/renderer/effects/EffectTargets.js +0 -48
- package/dist/renderer/effects/EffectTargets.js.map +0 -1
- package/dist/renderer/effects/builtins.js +0 -31
- package/dist/renderer/effects/builtins.js.map +0 -1
- package/dist/renderer/effects/composite.js +0 -11
- package/dist/renderer/effects/composite.js.map +0 -1
- package/dist/renderer/effects/effectPrelude.js +0 -10
- package/dist/renderer/effects/effectPrelude.js.map +0 -1
- package/dist/renderer/effects/types.js +0 -10
- package/dist/renderer/effects/types.js.map +0 -1
- package/dist/renderer/glyphOutlineMesh.js +0 -67
- package/dist/renderer/glyphOutlineMesh.js.map +0 -1
- package/dist/renderer/index.js +0 -20
- package/dist/renderer/math/color.js +0 -321
- package/dist/renderer/math/color.js.map +0 -1
- package/dist/renderer/math/mat3.js +0 -80
- package/dist/renderer/math/mat3.js.map +0 -1
- package/dist/renderer/math/patternSpace.js +0 -22
- package/dist/renderer/math/patternSpace.js.map +0 -1
- package/dist/renderer/math/viewToMat3.js +0 -19
- package/dist/renderer/math/viewToMat3.js.map +0 -1
- package/dist/renderer/paintResources.js +0 -18
- package/dist/renderer/paintResources.js.map +0 -1
- package/dist/renderer/paintScratch.js +0 -37
- package/dist/renderer/paintScratch.js.map +0 -1
- package/dist/renderer/shaders/ShaderProgram.js +0 -74
- package/dist/renderer/shaders/ShaderProgram.js.map +0 -1
- package/dist/renderer/shaders/batchFill.js +0 -119
- package/dist/renderer/shaders/batchFill.js.map +0 -1
- package/dist/renderer/shaders/customPrelude.js +0 -34
- package/dist/renderer/shaders/customPrelude.js.map +0 -1
- package/dist/renderer/shaders/extractUniformNames.js +0 -184
- package/dist/renderer/shaders/extractUniformNames.js.map +0 -1
- package/dist/renderer/shaders/glyphPaint.js +0 -61
- package/dist/renderer/shaders/glyphPaint.js.map +0 -1
- package/dist/renderer/shaders/gradFill.js +0 -31
- package/dist/renderer/shaders/gradFill.js.map +0 -1
- package/dist/renderer/shaders/pathFill.js +0 -14
- package/dist/renderer/shaders/pathFill.js.map +0 -1
- package/dist/renderer/shaders/patternFill.js +0 -25
- package/dist/renderer/shaders/patternFill.js.map +0 -1
- package/dist/renderer/shaders/registerProgram.js +0 -18
- package/dist/renderer/shaders/registerProgram.js.map +0 -1
- package/dist/renderer/spriteSheet.js +0 -14
- package/dist/renderer/spriteSheet.js.map +0 -1
- package/dist/renderer/state/GroupState.js +0 -77
- package/dist/renderer/state/GroupState.js.map +0 -1
- package/dist/renderer/strokeLengths.js +0 -50
- package/dist/renderer/strokeLengths.js.map +0 -1
- package/dist/renderer/syntheticItalic.js +0 -6
- package/dist/renderer/syntheticItalic.js.map +0 -1
- package/dist/renderer/textures/registerTexture.js +0 -34
- package/dist/renderer/textures/registerTexture.js.map +0 -1
- package/dist/scheduling/useVisibleRaf.js +0 -69
- package/dist/scheduling/useVisibleRaf.js.map +0 -1
- package/dist/test-seams-DM2B87-g.d.ts +0 -356
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SceneCanvas.js","names":["useTools","clientToWorldHelper","DEFAULT_ALLOWED_CAPABILITIES","_Fragment","useTools$1","DEFAULT_ALLOWED_CAPABILITIES$1","COORD_DEV","coordTrace","canvasDebug","debug","_slops","rest","EMPTY_ID_SET","EMPTY_ANCHOR_SELECTION","isToolsApi","tools","SceneCanvasInner","sceneInput","selectToolOpts","selectionProp","toolsProp","viewDescriptors","getFocusedProp","props","descriptor","poseDescriptor","AUTO_POSE_DESCRIPTOR","deviceProfile","useDeviceProfile","device","chromeSizes","useMemo","targetSizesPx","isSerialized","s","bakedScene","useState","sceneFromJSON","scene","viewProp","onViewChangeProp","redrawOnProp","restProps","getActiveMode","modes","getActiveModeFor","redrawOn","internalCanvasRef","useRef","canvasApiRef","canvasReady","setCanvasReady","dlog","consumerHandlers","ingestion","useEffect","disposers","acquireKitContentHandlers","h","registerContentHandler","d","animator","useLateContentRedraw","useCallback","currentViewRef","normalizeView","defaultView","useInsertionEffect","api","v","handleViewChange","cameraAnimator","useAnimator","viewChannel","viewAnimation","useViewAnimationOn","notifyViewChange","animatedZoom","viewport","viewportZoomProp","resolvedViewportZoom","base","derivedSelectionOptions","selectionOptions","internalSelection","useSelection","baseSelection","baseAdapterMethods","readOnlyAdapterMethods","selection","selectable","noopSet","currentSelection","selectionKinds","out","id","node","describeKind","pose","pathEditingId","setPathEditingId","pathEditingIdRef","useLatest","anchorEditingAllowedRef","effectivePathEditingId","allowed","selectedAnchorsRef","anchorMarqueeRef","editAnchorsExternalState","next","rect","selectToolWithDefaults","selectionRef","kindClassifier","effective","routing","inferredNodeRouting","registry","createNodeRouting","k","data","kindOfNode","composedAlphaFor","composeAlphaFor","alphaFor","surfaceViewRegistry","useOptionalViewRegistry","layerPaintRef","sceneLayerGate","createSceneLayerGate","layerIsPainted","layerId","viewLayerGate","layerVisibility","layerOrder","framed","poseComposition","adapter","useSceneAdapter","insertTool","internalSelect","internalPickEvery","internalPickBest","internalBoundsOf","internalBoundsOfPose","internalPlaneOfNode","internalMoveOptions","useSceneSelectTool","planeOfNodeRef","getNodeAtPoint","makeGetNodeAtPoint","isPointerInteractive","hit","wx","wy","view","featuresKey","features","hasViewport","enabled","resolveFeatures","inertiaEnabled","inertiaObj","handToolInertia","handTool","useHandTool","baseRequestedTools","defaultTools","KNOWN_BUILTIN_IDS","NON_SHAPE_BUILTIN_TOOLS","KIT_SHAPE_KINDS","toolsPatchExtras","trueIds","value","IS_DEV","wants","shapeTools","useBuiltinShapeTools","toolOptions","defaultLongPressFeedback","createLongPressFeedbackContribution","feedbackOpt","longPress","pressFeedback","mergedAmbient","ambient","internalRegistry","toolsPatch","toolsTakeover","internalTools","initialActiveTool","liveToolsRef","getActiveModeRef","isToolEligible","getMode","caps","toolId","c","selectionMoveOptions","rotateOptions","featureContributions","selectionResizeContribution","selectionRotateContribution","selectionMoveContribution","standardActionsExclude","include","featureActionIds","bound","entry","b","KIT_STANDARD_ACTION_IDS","onToolsCreatedRef","onToolsCreated","getNodeAtPointRef","onDoubleClickObserver","useHitObserver","onDoubleClick","onClickObserver","onClick","mergedLayers","mergeLayersWithDefaults","layers","resolvedActions","actions","merged","getActionRef","dispatcherRef","createDispatcher","dispatcher","gestureSource","createGestureSource","createDispatcherPreviewSources","sceneSlot","slot","wireSceneSlotToScene","previewLayer","usePreviewGhostLayer","dispatcherOverlay","useDispatcherOverlayLayer","getNodeAtPointRefForHover","trackHoverOn","useHoverTracking","canvas","target","clientX","clientY","origin","x","y","clientToWorld","reg","r","chromeVisibility","selectionForCapsRef","getFocusedPropRef","effectiveChromeVisibility","defaults","never","chromeVisibilityRef","deviceProfileRef","resizablePredRef","buildRuleCtxFor","sel","inputs","modeInfo","ctx","buildChromeCtx","getHover","resizablePred","selectionResizable","viewZoom","currentRuleInputs","buildCurrentRuleCtx","anchorEditingAllowed","chromeCaps","resolveVisibility","getIsVisibleForCanvas","wantsPen","penPreviewLayer","createPenPreviewLayer","sceneRefForOverlay","slopsOn","selectionOverlayCfg","badgeOf","rotationBadgeOf","rotationBadge","chromeAffordancesRef","slopsLayer","createSlopsDebugLayer","livePathFor","touched","source","previews","previewIds","owns","pid","p","pathFromPlane","resolveEditablePathOf","pathEditingOverlayLayer","createPathEditingOverlayLayer","plane","rectFromPlane","getSuppressedSelectionIds","selectionOverlayLayer","selCfg","cfg","callerSuppress","getSuppressedIds","own","caller","createSelectionOverlayLayer","wiredLayers","actionsRegistryRef","ingestionClipboardReviver","ingestionClipboardEnabled","ingestionClipboardOmitted","ingestionClipboard","omitted","ingestImpl","items","input","itemsFromFiles","point","addedViews","setAddedViews","addView","list","outer","dims","mergedRef","extended","assignRef","ref","viewInputs","Canvas","testHookSceneRef","testHookSelectionRef","hook","installTestHookIfRequested","releaseTestHook","DeviceProfileProvider","ViewInputsProvider","Fragment","PointerProviderIfRoot","PointerPublisher","StandardActionsRegistrar","GestureDispatcherMounter","enableGestureDispatcher","enableKeybindings","ToolKeybindingsMounter","CanvasView","i","contributionEntries","children","SceneCanvasInnerForwardRef","forwardRef","SceneCanvasWrapper","InputScope","ViewRegistryProvider","SceneCanvas","BUILTIN_TOOL_IDS","DEFAULT_HANDLE_SIZE","SCENE_CANVAS_FEATURES","rotateAroundAABBCenter"],"sources":["../../src/canvas/SceneCanvas.tsx"],"sourcesContent":["/**\n * `<SceneCanvas>` — `<Canvas>` wired to a `Scene` primitive.\n *\n * Synthesizes a `MoveAdapter & ResizeAdapter & RotateAdapter & AreaSelectAdapter`\n * from the passed `scene` (via `sceneToAdapter`) and an internal `useTools`.\n * Bare, it only renders: behavior comes from the `features` presets\n * (`canvas/SceneCanvas/features.ts`), each of which registers its own actions,\n * tools, ambient bindings and chrome.\n *\n * If a consumer needs custom tools (e.g. `select` + `insert`), they can pass\n * `tools={useTools(...)}` directly and SceneCanvas forwards it as-is — the\n * internal tool registry is ignored in that case.\n *\n * Cascade: `Scene` stores absolute poses, so dragging a container has to\n * translate its descendants in the live overlay and again at commit. The move\n * action walks `scene.childrenOf` for both — see `cascadeIds` in\n * `interactions/actions/defaults/move.ts`.\n */\nimport type { PolygonPath } from '@weasel-js/geom';\nimport { getActiveModeFor } from '@weasel-js/modes';\nimport { assignRef, useLatest } from '@weasel-js/react';\nimport type { Action, ActionsProp, ActionsRegistry } from '@weasel-js/routing';\nimport { createDispatcher, type Dispatcher } from '@weasel-js/routing';\nimport { InputScope } from '@weasel-js/routing/react';\nimport type { Affordance } from 'affordances/types';\nimport type { InsertAdapter } from 'core/adapters/types';\nimport { sceneFromJSON } from 'core/scene/scene';\nimport type { Node, NodeId, Scene, SerializedScene } from 'core/scene/types';\nimport { useSelection, type SelectionApi, type UseSelectionOptions } from 'core/selection/useSelection';\nimport { KIT_SHAPE_KINDS } from 'core/shapeKinds';\nimport { clientToWorld as clientToWorldHelper } from 'core/viewport/clientToWorld';\nimport { rectFromPlane } from 'core/viewport/parallax';\nimport { useViewAnimationOn } from 'core/viewport/useViewAnimation';\nimport { normalizeView, viewZoom, type View } from 'core/viewport/view';\nimport type { RuleCtx } from 'features/chrome-caps';\nimport {\n DEFAULT_ALLOWED_CAPABILITIES,\n buildChromeCtx,\n never,\n resolveVisibility,\n useHoverTracking,\n} from 'features/chrome-caps';\nimport {\n acquireKitContentHandlers,\n itemsFromFiles,\n registerContentHandler,\n type IngestItem\n} from 'features/ingestion';\nimport { createPathEditingOverlayLayer } from 'features/paths/pathEditingOverlayLayer';\nimport { createPenPreviewLayer } from 'features/paths/penPreviewLayer';\nimport { usePublishSelection } from 'features/selection/SelectionContext';\nimport {\n createSelectionOverlayLayer,\n rotationBadgeOf,\n} from 'features/selection/overlay';\nimport type { ViewportZoomOptions } from 'interactions/actions/defaults/viewportZoom';\nimport type { ClipboardIngestCtx } from 'interactions/actions/depSchema';\nimport { AUTO_POSE_DESCRIPTOR } from 'interactions/actions/resize/autoPoseDescriptor';\nimport type { PoseDescriptor } from 'interactions/actions/resize/geometry';\nimport type { UseResizeOptions } from 'interactions/actions/resize/options';\nimport { KIT_STANDARD_ACTION_IDS } from 'interactions/actions/useStandardActions';\nimport type React from 'react';\nimport { forwardRef, useCallback, useEffect, useInsertionEffect, useMemo, useRef, useState } from 'react';\nimport { useHandTool } from 'tools/builtin/hand';\nimport type { PenScratch } from 'tools/builtin/pen';\nimport {\n selectionMoveContribution,\n selectionResizeContribution,\n selectionRotateContribution,\n} from 'tools/builtin/select';\nimport { useAnimator } from '../animation/useAnimator';\nimport { targetSizesPx } from '../core/device/targets';\nimport { DeviceProfileProvider, useDeviceProfile } from '../core/device/useDeviceProfile';\nimport { createNodeRouting } from '../core/scene/NodeRouting';\nimport { dwarn } from '../debug';\nimport { dlog } from '../debug/flag';\nimport type { DebugConfig } from '../debug/types';\nimport { createLongPressFeedbackContribution } from '../features/longPress/longPressFeedback';\nimport type { ReflowTransition } from '../layout/types';\nimport { installTestHookIfRequested, releaseTestHook } from '../test-hook/install';\nimport type { AnyTool, Contribution, Tool } from '../tools/overlayBinding';\nimport { useTools, type ToolsApi } from '../tools/overlayBinding';\nimport type { LayersMap, SceneSlotConfig, SelectionOverlaySlotConfig } from './Canvas';\nimport { Canvas } from './Canvas';\nimport { CanvasView, type CanvasViewProps } from './CanvasView';\nimport { GestureDispatcherMounter } from './SceneCanvas/GestureDispatcherMounter';\nimport { PointerProviderIfRoot, PointerPublisher } from './SceneCanvas/PointerProviderIfRoot';\nimport { StandardActionsRegistrar } from './SceneCanvas/StandardActionsRegistrar';\nimport { ToolKeybindingsMounter } from './SceneCanvas/ToolKeybindingsMounter';\nimport { COORD_DEV, coordTrace, type CoordTraceEntry } from './SceneCanvas/coordTrace';\nimport { inferredNodeRouting } from './SceneCanvas/defaultNodeRouting';\nimport { createDispatcherPreviewSources, createGestureSource } from './SceneCanvas/dispatcherGestureBounds';\nimport {\n featureActionIds,\n resolveFeatures\n} from './SceneCanvas/features';\nimport { IS_DEV } from './SceneCanvas/isDev';\nimport {\n NON_SHAPE_BUILTIN_TOOLS,\n mergeLayersWithDefaults,\n type BridgeAdapter,\n type BuiltinToolId,\n type SceneCanvasProps,\n} from './SceneCanvas/props';\nimport { useBuiltinShapeTools } from './SceneCanvas/useBuiltinShapeTools';\nimport { contributionEntries } from './SceneCanvas/useContributionRoles';\nimport { useDispatcherOverlayLayer } from './SceneCanvas/useDispatcherOverlayLayer';\nimport { usePreviewGhostLayer } from './SceneCanvas/usePreviewGhostLayer';\nimport type { PickView } from './SceneCanvas/useSceneSelectTool';\nimport { useSceneSelectTool } from './SceneCanvas/useSceneSelectTool';\nimport type { CanvasExtensionApi, CanvasViewHandle, SceneCanvasApi } from './canvasExtension';\nimport { resolveEditablePathOf } from './deps/editAnchors';\nimport type { GesturePreviewSource } from './gestureBounds';\nimport { makeGetNodeAtPoint } from './getNodeAtPoint';\nimport { pathFromPlane } from './planeClips';\nimport { useSceneAdapter } from './sceneAdapter';\nimport { createSceneLayerGate, type ViewLayerPaint } from './sceneLayerPaint';\nimport { composeAlphaFor, wireSceneSlotToScene } from './sceneSlotWiring';\nimport { createSlopsDebugLayer } from './slopsDebugLayer';\nimport { useHitObserver } from './useHitObserver';\nimport { useLateContentRedraw } from './useLateContentRedraw';\nimport { ViewInputsProvider, type SurfaceViewInputs, type ViewRuleInputs } from './viewInputs';\nimport { ViewRegistryProvider, useOptionalViewRegistry } from './viewRegistry';\nexport { SCENE_CANVAS_FEATURES } from './SceneCanvas/features';\nexport type { Feature } from './SceneCanvas/features';\nexport type { BuiltinToolOptions } from './SceneCanvas/useBuiltinShapeTools';\nexport { defaultDrawOne } from './defaultDrawOne';\nexport { rotateAroundAABBCenter } from './poseRotation';\n// ---------------------------------------------------------------------------\n// Dev-only coord trace\n// ---------------------------------------------------------------------------\nif (COORD_DEV && typeof window !== 'undefined') {\n (window as unknown as { __weaselCoordLog__: CoordTraceEntry[] }).__weaselCoordLog__ = coordTrace;\n}\n\n/** `<SceneCanvas debug>` minus the flag only SceneCanvas reads. */\nfunction canvasDebug(debug: (DebugConfig & { slops?: boolean }) | false): DebugConfig | false {\n if (debug === false) return false;\n const { slops: _slops, ...rest } = debug;\n return rest;\n}\n\n/** Discriminate the polymorphic `tools` prop: `ToolsApi` has `setActive`\n * / `active` / `registry`; the patch record shape has none of those. */\n/** Stable empty `Set` so `getSuppressedSelectionIds` doesn't allocate\n * a fresh empty Set on every read — selection-overlay's `draw` runs\n * every frame. */\nconst EMPTY_ID_SET: ReadonlySet<string> = new Set();\nconst EMPTY_ANCHOR_SELECTION: ReadonlySet<number> = new Set();\n\nfunction isToolsApi(\n tools: ToolsApi | Record<string, AnyTool | true | false>,\n): tools is ToolsApi {\n return typeof (tools as ToolsApi).setActive === 'function';\n}\n\nfunction SceneCanvasInner<TData, TLayer extends string, TPose>(\n props: SceneCanvasProps<TData, TLayer, TPose>,\n ref: React.ForwardedRef<SceneCanvasApi>,\n) {\n const {\n scene: sceneInput,\n geometry,\n poseDescriptor,\n selectTool: selectToolOpts,\n insertTool,\n insertNodeFactories,\n insertPaint,\n ingestion,\n layouts,\n layoutDropTarget,\n reflowTransition,\n poseComposition,\n geometryProjection,\n routing,\n selection: selectionProp,\n selectionOptions,\n selectable = true,\n tools: toolsProp,\n features,\n enableKeybindings = true,\n claimKeys = false,\n enableGestureDispatcher = true,\n onToolsCreated,\n defaultTools,\n toolOptions,\n initialActiveTool,\n ambient,\n versionCheck,\n longPress,\n viewport,\n layers,\n actions,\n actionDefaults,\n describeKind,\n animator,\n views: viewDescriptors,\n children,\n shaders,\n flattenTolerance,\n backgroundFill,\n cursorCoordsHud,\n pickHud,\n debug,\n modalityHud,\n alphaFor,\n layerVisibility,\n layerOrder,\n isPointerInteractive,\n onDoubleClick,\n onClick,\n chromeVisibility,\n modes,\n getFocused: getFocusedProp,\n device,\n ...rest\n } = props;\n\n const descriptor = (poseDescriptor ?? AUTO_POSE_DESCRIPTOR) as PoseDescriptor<unknown>;\n\n // Resolved once here and provided to the subtree, so overlays, affordances\n // and consumer chrome all read the same object rather than each running\n // their own media queries.\n const deviceProfile = useDeviceProfile(device);\n\n // How big grabbable chrome is for this pointer type. Paint (the selection\n // overlay), hit-test (`buildAffordanceAt`) and the slops debug overlay all\n // resolve from this one object — a size read from the base constants\n // directly is unscaled, and a coarse pointer then paints chrome it cannot\n // grab.\n const chromeSizes = useMemo(\n () => targetSizesPx(deviceProfile.targetScale),\n [deviceProfile.targetScale],\n );\n\n // `scene` accepts either a live `Scene` or a `SerializedScene` JSON\n // object. JSON is baked once via useState init; subsequent renders\n // ignore prop changes (use a `key` prop on `<SceneCanvas>` to force a\n // fresh canvas).\n const isSerialized = (s: unknown): boolean =>\n typeof s === 'object' && s != null && (s as { version?: unknown }).version === 1\n && Array.isArray((s as { nodes?: unknown }).nodes);\n const [bakedScene] = useState<Scene<TData, TLayer, TPose> | null>(\n () => isSerialized(sceneInput)\n ? sceneFromJSON(sceneInput as SerializedScene<TData, TLayer, TPose>, {})\n : null,\n );\n const scene = bakedScene ?? (sceneInput as Scene<TData, TLayer, TPose>);\n\n // Extract view-related props from rest so we can intercept them for the\n // controlled/uncontrolled pattern Canvas exposes without breaking it.\n const { view: viewProp, onViewChange: onViewChangeProp, defaultView, redrawOn: redrawOnProp, ...restProps } = rest;\n const getActiveMode = useMemo(() => (modes ? getActiveModeFor(modes) : undefined), [modes]);\n const redrawOn = useMemo(\n () => (modes ? [...(redrawOnProp ?? []), modes] : redrawOnProp),\n [modes, redrawOnProp],\n );\n\n // Internal canvas ref so the dispatcher can attach its input listeners\n // even when the consumer passes their own forwarded ref.\n const internalCanvasRef = useRef<HTMLElement | null>(null);\n // Holds the full `CanvasExtensionApi` so we can call `requestRedraw` after\n // dispatcher-side gesture pumps. Without this, dispatcher-only actions\n // (marquee, lasso, anything driven solely by `useGestureDispatcher`) never\n // trigger a re-paint between pointerdown and pointerup — the legacy tools\n // dispatcher's `onGestureChange` only fires for legacy `tool.drag.*` hooks,\n // which the migrated actions don't provide.\n const canvasApiRef = useRef<CanvasExtensionApi | null>(null);\n // Set from the merged ref callback, so effects needing the handle key off it\n // instead of assuming when React attaches it.\n const [canvasReady, setCanvasReady] = useState(false);\n\n useEffect(() => {\n dlog('scene-canvas', 'mount');\n return () => dlog('scene-canvas', 'unmount');\n }, []);\n\n // Content-handler registration: the kit's defaults are refcounted (they\n // stay registered while ANY SceneCanvas is mounted — see\n // `acquireKitContentHandlers`); consumer handlers from the `ingestion`\n // prop live for this canvas's lifetime.\n const consumerHandlers = ingestion?.handlers;\n useEffect(() => {\n const disposers = [acquireKitContentHandlers()];\n for (const h of consumerHandlers ?? []) disposers.push(registerContentHandler(h));\n return () => disposers.forEach((d) => d());\n }, [consumerHandlers]);\n\n // Animator subscription: when an animator is provided, request a redraw\n // on every active frame so consumer `drawOne` functions reading\n // `animator.colorOverrides` (or any other non-scene channel the\n // animator may mutate) reflect the latest values. The animator only\n // ticks while animations are active, so idle frames don't repaint.\n useEffect(() => {\n if (!animator) return;\n const unsubscribe = animator.onTick(() => {\n canvasApiRef.current?.requestRedraw?.();\n });\n return unsubscribe;\n }, [animator]);\n\n // Late decodes, deferred glyph bakes and late paint kinds each drew nothing\n // on the frame that asked for them.\n useLateContentRedraw(useCallback(() => { canvasApiRef.current?.requestRedraw?.(); }, []));\n\n // Override writes deliberately don't bump the scene version — that fanout is\n // what a frame loop is trying to avoid — so the repaint has to come from\n // here instead.\n useEffect(() => scene.overrides.subscribe(() => {\n canvasApiRef.current?.requestRedraw?.();\n }), [scene]);\n\n // A scene write repaints; it does not re-render this component. The layers\n // read the scene at paint time and `contentVersion` is a getter, so nothing\n // here needs a commit to draw the new content. Chrome rendering node data as\n // DOM subscribes for itself — `useScene`'s default, `SelectionPanel`, the\n // panels an app hangs beside the canvas — which is what lets a host driving\n // poses from a frame loop take `useScene(…, { subscribe: false })` and\n // actually get it.\n useEffect(() => scene.subscribe(() => {\n canvasApiRef.current?.requestRedraw?.();\n }), [scene]);\n\n // The mirror every HUD, pick and pinch path reads synchronously. Seeded here\n // because those reads start before the canvas's subscription lands.\n const currentViewRef = useRef<View>(\n normalizeView(viewProp ?? defaultView ?? { x: 0, y: 0, scale: { x: 1, y: 1 } }),\n );\n // Committed renders only, so an abandoned transition's view never reaches\n // the `view` dep, picks or the camera animator.\n useInsertionEffect(() => {\n if (viewProp !== undefined) currentViewRef.current = normalizeView(viewProp);\n });\n\n useEffect(() => {\n const api = canvasApiRef.current;\n if (!api) return;\n currentViewRef.current = api.getView();\n return api.subscribeView((v) => { currentViewRef.current = v; });\n }, [canvasReady]);\n\n // The dep registry's `view.set`. Uncontrolled it must not also call\n // `onViewChangeProp` — the canvas reports the write through `notifyViewChange`.\n const handleViewChange = useCallback((v: View) => {\n const api = canvasApiRef.current;\n if (viewProp === undefined && api) { api.setView(v); return; }\n onViewChangeProp?.(normalizeView(v));\n }, [viewProp, onViewChangeProp]);\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 cameraAnimator = useAnimator();\n const viewChannel = useMemo(\n () => ({ get: () => currentViewRef.current, set: handleViewChange }),\n [handleViewChange],\n );\n const viewAnimation = useViewAnimationOn(viewChannel, cameraAnimator);\n\n // Never writes back to the canvas — `handleViewChange` would recurse. Every\n // `Canvas.setView` lands here on both branches, so it is also the runner's\n // one interrupt feed.\n const notifyViewChange = useCallback((v: View) => {\n viewAnimation.stopIfExternal();\n onViewChangeProp?.(v);\n }, [onViewChangeProp, viewAnimation]);\n\n // `animatedZoom` is the SceneCanvas-level spelling of the zoom action's\n // `animate` option, the way `pinchZoom` is of the pinch tool's clamp.\n const animatedZoom = viewport?.animatedZoom;\n const viewportZoomProp = viewport?.zoom ?? true;\n const resolvedViewportZoom = useMemo<boolean | ViewportZoomOptions>(() => {\n if (viewportZoomProp === false) return false;\n const base = typeof viewportZoomProp === 'object' ? viewportZoomProp : {};\n if (!animatedZoom) return base;\n return { ...base, animate: animatedZoom === true ? {} : animatedZoom };\n }, [viewportZoomProp, animatedZoom]);\n\n // Selection: caller-supplied wins; otherwise build from selectionOptions.\n // Hooks always run unconditionally — when a caller supplies `selection`,\n // the internally-built one is unused but the hook still fires.\n // Bound to the scene, so the selection an edit was made under rides on the\n // scene's history entries and undo can put it back.\n const derivedSelectionOptions = useMemo<UseSelectionOptions>(\n () => ({ scene, ...(selectionOptions ?? {}) }),\n [scene, selectionOptions],\n );\n const internalSelection = useSelection(derivedSelectionOptions);\n const baseSelection = selectionProp ?? internalSelection;\n\n // Everything the kit writes selection through — the `selection` dep, the\n // adapter's `setSelection`, ops committed through either — reads this api,\n // so on an unselectable canvas every write path here is closed. The\n // consumer's own api is not wrapped and still writes.\n const baseAdapterMethods = baseSelection.adapterMethods;\n const readOnlyAdapterMethods = useMemo(() => ({\n getSelection: () => baseAdapterMethods.getSelection(),\n setSelection: () => {},\n }), [baseAdapterMethods]);\n const selection: SelectionApi = useMemo(() => {\n if (selectable) return baseSelection;\n const noopSet = () => {};\n return {\n get current() { return baseSelection.current; },\n get: baseSelection.get,\n contains: baseSelection.contains,\n set: noopSet,\n add: noopSet,\n remove: noopSet,\n toggle: noopSet,\n clear: noopSet,\n applyClick: noopSet,\n adapterMethods: readOnlyAdapterMethods,\n };\n }, [baseSelection, selectable, readOnlyAdapterMethods]);\n\n // Publish the current selection (with optional per-id kind labels) into any\n // surrounding `<SelectionContextProvider>` so non-canvas UI can read it.\n // No-op when no provider is in scope.\n const currentSelection = selection.current;\n const selectionKinds = useMemo<readonly (string | undefined)[] | undefined>(() => {\n if (currentSelection.length === 0) return undefined;\n const out: (string | undefined)[] = [];\n for (const id of currentSelection) {\n const node = scene.get(id);\n if (!node) { out.push(undefined); continue; }\n if (describeKind) { out.push(describeKind(node)); continue; }\n // Default heuristic: containers -> 'group', poses with .kind -> 'path',\n // everything else unlabelled (consumer can supply describeKind to fill in).\n if (node.kind === 'container') { out.push('group'); continue; }\n const pose = node.pose as unknown as { kind?: unknown } | null;\n if (pose && typeof pose === 'object' && 'kind' in pose && typeof pose.kind === 'string') {\n out.push('path');\n continue;\n }\n out.push(undefined);\n }\n return out;\n }, [currentSelection, scene, describeKind]);\n usePublishSelection(currentSelection, selectionKinds);\n\n // Path-editing edit-mode state. Owned here so it's reachable from both:\n // - the `pathEditingOverlay` chrome layer wired below\n // - `useEditAnchorsDepSource`, mounted in the child StandardActionsRegistrar\n // The state stays empty until `enterPathEditAction` (double-click on a\n // selected polygon) sets it, and clears on `exitPathEditAction` (Escape).\n // Until then, the chrome doesn't draw and the gesture doesn't route to\n // `editAnchorsAction` — both gate on `editingId !== ''`.\n const [pathEditingId, setPathEditingId] = useState<string>('');\n const pathEditingIdRef = useLatest(pathEditingId);\n // `anchorEditingAllowed` is declared below (it needs `getActiveModeRef`);\n // hold it in a ref so `effectivePathEditingId` — used by consumers\n // declared both above and below that point — can read it lazily.\n const anchorEditingAllowedRef = useRef<(() => boolean) | undefined>(undefined);\n /**\n * The edit target, masked by whether the host still permits anchor\n * editing.\n *\n * Every surface that cares — the overlay layer, the `editingAnchors`\n * rule input, the selection-overlay suppression set, the select tool's\n * extend-click lock — reads this rather than the raw state. Leaving\n * path-edit mode therefore tears all of them down at once, by any route.\n * That matters because `exitPathEditAction` is not the only way out:\n * a host's own mode machine can leave the mode without running it\n * (`apps/draw` binds Escape to one), and before this the raw id stayed\n * set — inert anchor squares kept drawing over the shape and the\n * selection outline stayed suppressed.\n *\n * Masking rather than clearing on purpose: the mode can change without\n * re-rendering this component, so there is no reliable moment to write\n * state. Read-time masking cannot go stale.\n */\n const effectivePathEditingId = useCallback((): string => {\n const allowed = anchorEditingAllowedRef.current;\n if (allowed && !allowed()) return '';\n return pathEditingIdRef.current;\n }, [pathEditingIdRef]);\n // Anchor selection + in-flight marquee. Both are per-frame inputs to\n // the overlay's draw(), never to a React render, so they live in refs\n // and request a repaint directly. Holding them in state would re-render\n // the whole SceneCanvas subtree on every pointermove of a marquee drag.\n const selectedAnchorsRef = useRef<ReadonlySet<number>>(EMPTY_ANCHOR_SELECTION);\n const anchorMarqueeRef = useRef<{ x: number; y: number; width: number; height: number } | null>(null);\n const editAnchorsExternalState = useMemo(() => ({\n getEditingId: () => effectivePathEditingId(),\n setEditingId: (id: string | null) => setPathEditingId(id ?? ''),\n getSelectedAnchors: () => selectedAnchorsRef.current,\n setSelectedAnchors: (next: ReadonlySet<number>) => {\n selectedAnchorsRef.current = next;\n canvasApiRef.current?.requestRedraw?.();\n },\n getMarquee: () => anchorMarqueeRef.current,\n setMarquee: (rect: { x: number; y: number; width: number; height: number } | null) => {\n anchorMarqueeRef.current = rect;\n canvasApiRef.current?.requestRedraw?.();\n },\n }), [effectivePathEditingId]);\n\n // Apply the handle-size fallback here so useSceneSelectTool always receives\n // a concrete radius even when the caller omits selectTool entirely.\n const selectToolWithDefaults = useMemo(() => ({\n handleHitRadius: chromeSizes.handle,\n // Shift-click belongs to the anchor selection while a path is being\n // anchor-edited; see `UseSelectToolOptions.extendClickLocked`.\n extendClickLocked: () => effectivePathEditingId() !== '',\n // `selectionAllowed` used to sit here, hand-checking the active mode for\n // `creates-selection` because the tool's pointerDown classifier was a\n // phase-table route and `Action.eligible` was never evaluated on that\n // pipeline (audit 3.4). The classifier is now `select.pick`, which\n // declares that capability itself — one rule, evaluated in one place.\n ...selectToolOpts,\n }), [selectToolOpts, chromeSizes.handle, effectivePathEditingId]);\n\n // Stable ref to the live selection; updated every render so the affordanceAt\n // and classifyTarget thunks (which live in an effect closure) always read\n // the latest selection without causing re-renders.\n const selectionRef = useLatest(selection);\n\n // Build a per-instance NodeRouting registry. When `routing` is unset, fall\n // back to `inferredNodeRouting` (data-shape inference: `data.text` →\n // `'text'`, `data.path` → `'path'`, `data.image` → `'image'`). Pass an\n // explicit `routing={[]}` to opt out entirely — the classifier becomes\n // undefined and every hit comes back as `kind: 'unknown'`.\n const kindClassifier = useMemo(() => {\n const effective = routing === undefined ? inferredNodeRouting : routing;\n if (effective.length === 0) return undefined;\n const registry = createNodeRouting();\n for (const k of effective) registry.register(k);\n return (data: TData) => registry.classify(data);\n }, [routing]);\n\n // Node id → routing-trait kind, for the body classifier. Reusing the routing\n // registry here is what makes `target: 'kind:text'` on a binding speak the\n // same vocabulary as `Hit.kind` and the routing tables, rather than a second\n // one invented for bindings. Undefined when `routing={[]}` opts out, which\n // leaves every `kind:` target form unmatchable.\n const kindOfNode = useMemo(() => {\n if (!kindClassifier) return undefined;\n return (id: string): string | undefined => {\n const node = scene.get(id as NodeId);\n return node ? kindClassifier(node.data) : undefined;\n };\n }, [kindClassifier, scene]);\n\n // The painted alpha of a node in this view: the caller's `alphaFor`\n // (scoping-dim, and anything else a consumer fades) times any per-node\n // override alpha. `<Canvas>` has no scene, so the override half is folded\n // in here — and the pick path reads the same number the painter does, or a\n // node faded to nothing stays clickable.\n const composedAlphaFor = useMemo(\n () => composeAlphaFor(scene, alphaFor),\n [scene, alphaFor],\n );\n\n // What this view paints of each scene layer, judged against the stack\n // `<Canvas>` composed and read at pick time — so a consumer slot anchored\n // between scene layers is weighed the way paint weighs it.\n const surfaceViewRegistry = useOptionalViewRegistry();\n const layerPaintRef = useLatest<ViewLayerPaint>({ layerVisibility, layerOrder });\n const [sceneLayerGate] = useState(createSceneLayerGate);\n const layerIsPainted = useCallback((layerId: string): boolean => (\n sceneLayerGate(surfaceViewRegistry?.surface()?.layers() ?? [], layerPaintRef.current)(layerId)\n ), [surfaceViewRegistry, sceneLayerGate, layerPaintRef]);\n // Absent when this view hides nothing, so the walk skips the gate.\n const viewLayerGate = layerVisibility !== undefined || layerOrder !== undefined\n ? layerIsPainted\n : undefined;\n\n // Under a frame a child's pose is already relative, so cascading a container\n // move would carry every descendant a second time.\n const framed = poseComposition !== undefined && poseComposition.closure !== 'identity';\n const adapter = useSceneAdapter(scene, {\n // `adapterMethods` is memoized; `selection` itself is a fresh object each render.\n selection: selection.adapterMethods,\n poseDescriptor: descriptor as PoseDescriptor<TPose>,\n commitInsert: insertTool?.create,\n insertLayer: insertTool?.layer,\n layouts,\n poseComposition,\n cascadeContainerPose: !framed,\n });\n\n const {\n selectTool: internalSelect, pickEvery: internalPickEvery, pickBest: internalPickBest,\n boundsOf: internalBoundsOf, boundsOfPose: internalBoundsOfPose, planeOfNode: internalPlaneOfNode,\n moveOptions: internalMoveOptions,\n } = useSceneSelectTool({\n scene,\n adapter,\n poseDescriptor: descriptor as PoseDescriptor<TPose>,\n geometry,\n // The pick tolerance is declared in screen pixels; this is what converts it.\n getView: () => currentViewRef.current,\n // Only when the consumer actually fades something. Without a prop the\n // composed function is just the override lookup, and the source resolves\n // that once per walk instead of once per candidate.\n ...(alphaFor ? { alphaOf: composedAlphaFor } : {}),\n ...(viewLayerGate ? { layerIsPainted: viewLayerGate } : {}),\n selectTool: selectToolWithDefaults,\n });\n // Read through a ref by the chrome layers, which are built once.\n const planeOfNodeRef = useLatest(internalPlaneOfNode);\n\n // Resolved through the select tool's own single-hit picker, so `onClick`,\n // `onDoubleClick`, hover, and tool routing all name the node a click selects.\n //\n // When isPointerInteractive is supplied, the result is filtered: ids for\n // which the predicate returns false cause getNodeAtPoint to return null,\n // suppressing pointer events for non-interactive nodes (e.g. scoping-dim).\n const getNodeAtPoint = useMemo(() => {\n if (!internalPickBest) return undefined;\n const nodeResolver = (id: string) => {\n // A caller's `geometry.pickEvery` can answer an id the scene does not hold.\n const node = adapter.getNode(id);\n if (!node) return null;\n const kind = kindClassifier ? kindClassifier(node.data) : 'unknown';\n return { kind, pose: adapter.getWorldPose(id), data: node };\n };\n const base = makeGetNodeAtPoint(internalPickBest, nodeResolver);\n if (!isPointerInteractive) return base;\n return (wx: number, wy: number, view?: PickView | null) => {\n const hit = base(wx, wy, view);\n if (hit == null) return null;\n if (isPointerInteractive(hit.id) === false) return null;\n return hit;\n };\n }, [adapter, internalPickBest, isPointerInteractive, kindClassifier]);\n\n // The presets this canvas runs with. Keyed on the ids, not the array, so an\n // inline `features={['draw']}` does not re-derive every render.\n const featuresKey = (features ?? []).join('|');\n const hasViewport = viewport !== undefined;\n const enabled = useMemo(\n () => resolveFeatures(features, { viewport: hasViewport }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [featuresKey, hasViewport],\n );\n\n const inertiaEnabled = !!viewport?.inertia;\n const inertiaObj = typeof viewport?.inertia === 'object' ? viewport.inertia : undefined;\n // `inertia: true` means \"on with kit defaults\", so an enabled-but-objectless\n // config still has to reach the tool — an empty object, not `undefined`,\n // which the tool reads as off.\n const handToolInertia = inertiaEnabled\n ? {\n friction: inertiaObj?.friction,\n minSpeed: inertiaObj?.minSpeed,\n boundary: inertiaObj?.boundary,\n bounds: inertiaObj?.bounds,\n }\n : undefined;\n // useHandTool must always be called (rules of hooks); it is a no-op when\n // viewport is absent — the tool is simply not added to the registry.\n const handTool = useHandTool(handToolInertia ? { inertia: handToolInertia } : {});\n\n // Built-ins to mount: what `defaultTools` lists, plus the tool each preset\n // brings — `select` the select tool, `view` the hand.\n const baseRequestedTools: readonly BuiltinToolId[] = [\n ...(defaultTools ?? []),\n ...(enabled.has('select') ? ['select' as const] : []),\n ...(enabled.has('view') ? ['hand' as const] : []),\n ];\n\n // Patch-form `tools` extras with value `true` widen the requested set\n // (\"pull in this built-in\"). Computed here so the rest of the if-ladder\n // treats them identically to ids that came in via `defaultTools`.\n const KNOWN_BUILTIN_IDS: ReadonlySet<BuiltinToolId> = new Set<BuiltinToolId>([\n ...NON_SHAPE_BUILTIN_TOOLS, ...KIT_SHAPE_KINDS,\n ]);\n const toolsPatchExtras = (() => {\n if (!toolsProp || isToolsApi(toolsProp)) return null;\n return toolsProp;\n })();\n const trueIds = new Set<BuiltinToolId>();\n if (toolsPatchExtras) {\n for (const [id, value] of Object.entries(toolsPatchExtras)) {\n if (value !== true) continue;\n if (!KNOWN_BUILTIN_IDS.has(id as BuiltinToolId)) {\n if (IS_DEV) {\n console.warn(`[SceneCanvas] tools.${id}=true is not a known built-in id; ignoring`);\n }\n continue;\n }\n trueIds.add(id as BuiltinToolId);\n }\n }\n const wants = (id: BuiltinToolId): boolean =>\n baseRequestedTools.includes(id) || trueIds.has(id);\n\n // Synthesize the shape/lasso/text/clone tools — always called per React\n // rules-of-hooks; only registered below when requested. Per-tool options\n // (lasso mode, clone-selection) thread through `toolOptions`.\n const shapeTools = useBuiltinShapeTools({ options: toolOptions });\n\n const defaultLongPressFeedback = useMemo(() => createLongPressFeedbackContribution(), []);\n const feedbackOpt = longPress?.feedback ?? true;\n const pressFeedback = feedbackOpt === true ? defaultLongPressFeedback : feedbackOpt || null;\n const mergedAmbient = useMemo(\n () => (pressFeedback ? [...(ambient ?? []), pressFeedback] : (ambient ?? [])),\n [ambient, pressFeedback],\n );\n\n const internalRegistry: Record<string, AnyTool> = {};\n if (wants('select')) internalRegistry.select = internalSelect;\n // `hand` stays in the registry (not ambient) so its H keybinding and its\n // Space hold both apply.\n if (wants('hand')) internalRegistry.hand = handTool;\n // Shape / lasso / text tools — registry entries with built-in\n // keybindings (R/E/G/N/L/T) routed via `useKeybindings`.\n if (wants('rect')) internalRegistry.rect = shapeTools.rect;\n if (wants('ellipse')) internalRegistry.ellipse = shapeTools.ellipse;\n if (wants('line')) internalRegistry.line = shapeTools.line;\n if (wants('polygon')) internalRegistry.polygon = shapeTools.polygon;\n if (wants('star')) internalRegistry.star = shapeTools.star;\n if (wants('pen')) internalRegistry.pen = shapeTools.pen;\n if (wants('pencil')) internalRegistry.pencil = shapeTools.pencil;\n if (wants('lasso')) internalRegistry.lasso = shapeTools.lasso;\n if (wants('text')) internalRegistry.text = shapeTools.text;\n\n // Patch-form `tools` prop: merge extras / overrides / omissions into the\n // internal registry. `false` drops a bundled tool; `true` is already\n // accounted for above via the `wants()` expansion; `AnyTool` adds or\n // replaces (dev-only warning on replace). Takeover form (full `ToolsApi`)\n // is handled below via `toolsProp ?? internalTools`.\n const toolsPatch = toolsPatchExtras;\n if (toolsPatch) {\n for (const [id, value] of Object.entries(toolsPatch)) {\n if (value === false) {\n delete internalRegistry[id];\n } else if (value === true) {\n // Already pulled in via the `wants()`-driven if-ladder above.\n continue;\n } else {\n if (IS_DEV && id in internalRegistry) {\n console.warn(`[SceneCanvas] tools prop overrides bundled \"${id}\" tool`);\n }\n internalRegistry[id] = value;\n }\n }\n }\n\n // Takeover form: only when toolsProp is the full ToolsApi shape.\n const toolsTakeover = toolsProp && isToolsApi(toolsProp) ? toolsProp : null;\n\n const internalTools = useTools({\n active: initialActiveTool ?? ('select' in internalRegistry ? 'select' : null),\n registry: internalRegistry,\n ...(mergedAmbient.length ? { ambient: mergedAmbient } : {}),\n ...(modes ? { modes } : {}),\n });\n\n // Auto-wire keybindings against whichever registry is live.\n //\n // Both calls fire unconditionally (rules of hooks); the inactive one is\n // silenced via the hook's own `disable` option:\n // - internal registry: disabled whenever the consumer passed `tools=`.\n // - consumer registry: disabled when `tools=` was omitted (nothing to\n // bind) or when the consumer opted out via `enableKeybindings={false}`.\n //\n // The `enableKeybindings` opt-out also silences the internal wiring, so\n // a consumer relying entirely on the internal tools can take over with\n // their own `useKeybindings(...)` call. The fallback `useTools` passed\n // to the second call when `toolsProp` is absent is a render-stable empty\n // stand-in just to keep the call site valid; it never actually fires\n // because `disable` is true on that branch.\n const liveToolsRef = useLatest<ToolsApi | null>(toolsTakeover ?? internalTools);\n const getActiveModeRef = useLatest(getActiveMode);\n //\n // `isToolEligible` mirrors `eligibleForMode` (packages/modes) — the same\n // predicate `ToolPalette` uses to grey a button out. Without a mode\n // registry every tool stays activatable.\n const isToolEligible = useCallback((toolId: string): boolean => {\n const getMode = getActiveModeRef.current;\n if (!getMode) return true;\n const registry = liveToolsRef.current?.registry;\n const caps = registry?.[toolId]?.eligibility.capabilities ?? [];\n if (caps.length === 0) return false;\n const allowed = getMode().allowedCapabilities;\n for (const c of caps) if (allowed.has(c)) return true;\n return false;\n }, [getActiveModeRef, liveToolsRef]);\n\n\n const tools = toolsTakeover ?? internalTools;\n\n // The selection's own ambient bindings: `move`, `resize` and `rotate`. They\n // are not tools and sit outside `tools`, so they apply under a takeover too.\n const selectionMoveOptions = useMemo(\n () => ({ move: internalMoveOptions }),\n [internalMoveOptions],\n );\n const rotateOptions = selectToolOpts?.rotate || undefined;\n // Handles first: a handle sits over the selected body, so the move binding\n // matches a handle drag too, and a tie goes to whichever is first.\n const featureContributions = useMemo<Contribution[]>(() => [\n ...(enabled.has('resize') ? [selectionResizeContribution()] : []),\n ...(enabled.has('rotate') ? [selectionRotateContribution({ rotate: rotateOptions })] : []),\n ...(enabled.has('move') ? [selectionMoveContribution(selectionMoveOptions)] : []),\n ], [enabled, selectionMoveOptions, rotateOptions]);\n\n // Kit-standard actions to register: every preset's own, plus whichever a\n // tool or contribution on this canvas binds — a tool brings the actions it\n // routes to, so `defaultTools={['rect']}` works under any preset.\n const standardActionsExclude = useMemo(() => {\n const include = featureActionIds(enabled);\n const bound = [\n ...Object.values(tools.registry),\n ...tools.ambient,\n ...featureContributions,\n ];\n for (const entry of bound) {\n for (const b of entry.bindings ?? []) include.add(b.actionId);\n }\n return KIT_STANDARD_ACTION_IDS.filter((id) => !include.has(id));\n }, [enabled, tools, featureContributions]);\n\n // Surface the resolved ToolsApi to the introspection callback (the\n // toolkit-builder dev surface uses this to walk `tools.registry` for\n // its live route table). Fires whenever the `tools` identity changes,\n // which is stable across most renders thanks to useTools' useMemo.\n const onToolsCreatedRef = useLatest(onToolsCreated);\n useEffect(() => { onToolsCreatedRef.current?.(tools); }, [tools, onToolsCreatedRef]);\n\n // `onDoubleClick` used to be backed by a native `dblclick` listener on the\n // canvas, which made it a THIRD independent definition of \"double click\"\n // alongside the tool dispatcher's 300ms/8px `dblTap` and the gesture\n // dispatcher's 600ms/8px synthesized event — so which double-click\n // behaviors a consumer got depended on the millisecond gap between the two\n // clicks. The other two are gone; this now observes the gesture\n // dispatcher's single definition and resolves the hit with the same\n // `getNodeAtPoint` picker the rest of the canvas uses.\n //\n // It rides the dispatcher as an OBSERVER rather than an Action binding\n // because the prop is a notification, not a behavior: as a binding it would\n // lose first-match-wins to `enterPathEdit` on every body hit and silently\n // stop firing.\n const getNodeAtPointRef = useLatest(getNodeAtPoint);\n const onDoubleClickObserver = useHitObserver(onDoubleClick, getNodeAtPointRef);\n const onClickObserver = useHitObserver(onClick, getNodeAtPointRef);\n\n // (Legacy `gestures` prop removed alongside the consumer-facing action\n // hooks; undo/redo and friends now register via the Actions Registry.)\n\n // Merge caller-supplied layers with kit defaults. When `layers` is omitted\n // the result is the full default set (scene + selectionOverlay). Partial\n // configs deep-merge; `null` slot values suppress a default explicitly.\n const mergedLayers = useMemo(\n () => mergeLayersWithDefaults(layers, deviceProfile.targetScale),\n [layers, deviceProfile.targetScale],\n );\n\n // `selectTool.rotate === false` disables rotation: drop the `rotate` action\n // (its rotation-handle chrome is hidden via effectiveChromeVisibility above).\n // A consumer-supplied `rotate` override still wins; `actions === null`\n // (all defaults disabled) is left untouched.\n const resolvedActions = useMemo<ActionsProp | undefined>(() => {\n if (selectToolOpts?.rotate !== false) return actions;\n if (actions === null) return null;\n const merged = { ...(actions ?? {}) } as Record<string, unknown>;\n if (!('rotate' in merged)) merged.rotate = null;\n return merged as ActionsProp;\n }, [actions, selectToolOpts?.rotate]);\n\n // Stable action-lookup getter threaded into the dispatcher so\n // beginUiOngoing can resolve action ids at call time. Populated by\n // StandardActionsRegistrar once it has the registry in scope.\n const getActionRef = useRef<((id: string) => Action | undefined) | null>(null);\n\n // Shared `Dispatcher` instance — created once per `<SceneCanvas>` and\n // threaded to both the gesture-dispatcher mounter (which pumps input\n // events into it) and the preview-ghost layer (which walks its\n // `getInFlightHandles()` for dispatcher-side gesture previews). Lazy\n // ref init keeps identity stable across renders without an effect.\n const dispatcherRef = useRef<Dispatcher | null>(null);\n if (!dispatcherRef.current) {\n dispatcherRef.current = createDispatcher({\n getAction: (id) => getActionRef.current?.(id),\n });\n }\n const dispatcher = dispatcherRef.current;\n\n // The dispatcher's contribution to `helpersRef` — in-flight preview ids,\n // nascent-insert bounds, and the pump signal. Reads through the ref so one\n // stable object keeps pointing at the live dispatcher.\n const gestureSource = useMemo(() => createGestureSource(() => dispatcherRef.current), []);\n\n // The dispatcher's half of this view's overlay-aware lookups: whose\n // committed paint a ghost hides, and the pose a handle proposes for an id.\n const { previewIdsExtra, previewPoseExtra } = useMemo(\n () => createDispatcherPreviewSources(() => dispatcherRef.current),\n [],\n );\n\n const sceneSlot = useMemo(() => {\n const slot = mergedLayers.scene;\n if (!slot || 'layer' in slot) return slot; // null or CustomLayerEntry — leave alone\n return wireSceneSlotToScene(\n slot as SceneSlotConfig<Node<TData, TLayer, TPose>, TPose>,\n scene,\n alphaFor,\n animator?.colorOverrides,\n poseComposition,\n );\n }, [mergedLayers.scene, alphaFor, scene, animator, poseComposition]);\n\n // Preview-ghost layer: renders in-flight gesture poses on top of the\n // committed scene using the scene slot's `drawOne`, from whichever view's\n // preview sources the draw envelope carries. It takes the scene-wired slot,\n // so a ghosted derived node still resolves its path.\n const previewLayer = usePreviewGhostLayer<TData, TLayer, TPose>({\n scene,\n sceneSlot,\n dispatcher,\n });\n\n // Dispatcher-driven chrome overlays — marquee rect + lasso polyline +\n // any other `OngoingHandle.overlay()` shapes the in-flight actions\n // publish. Screen-space; slotted after the preview-ghost so chrome\n // paints on top of any displaced ghost silhouettes.\n const dispatcherOverlay = useDispatcherOverlayLayer({ dispatcher });\n\n // Chrome-caps hover tracking: last-hovered NodeId fed into `ChromeCtx.hover`.\n // The hook attaches its own pointermove/leave listeners on the element\n // `mergedRef` hands it and\n // caches the topmost-id from `getNodeAtPoint` on a ref. No re-renders.\n\n const getNodeAtPointRefForHover = useLatest(getNodeAtPoint);\n const { getHover, canvasRef: trackHoverOn } = useHoverTracking({\n // One lookup, not a client→world thunk beside a picker: the point and the\n // camera its tolerance converts against have to come from the same view.\n // Hover has no pointer to capture, so it resolves fresh — whichever view\n // is under the cursor right now owns the point.\n nodeAtClientPoint: (clientX, clientY) => {\n const canvas = internalCanvasRef.current;\n if (!canvas) return null;\n const target = surfaceViewRegistry?.resolver.at(null, clientX, clientY);\n const origin = target?.origin ?? canvas.getBoundingClientRect();\n const view = target?.view ?? currentViewRef.current;\n const [x, y] = clientToWorldHelper(clientX, clientY, origin, view);\n // A view judges its own layers; the surface's gate is the picker's default.\n const reg = target?.id != null\n ? surfaceViewRegistry?.list().find((r) => r.id === target.id)\n : undefined;\n const hit = getNodeAtPointRefForHover.current?.(\n x, y, reg ? { scale: view.scale, layerIsPainted: reg.layerIsPainted } : view,\n );\n return hit ? { id: hit.id as NodeId } : null;\n },\n enabled: chromeVisibility !== undefined,\n });\n\n // Stable refs for the live selection / view / focus / suppression sources\n // that feed `buildChromeCtx`. The resolver factory below closes over these\n // and is called per draw / per hitTest from Canvas.\n const selectionForCapsRef = useLatest(selection.current as readonly NodeId[]);\n const getFocusedPropRef = useLatest(getFocusedProp);\n // Selection chrome belongs to the presets that turn it on: the outline to\n // `outline`, each handle to the preset that binds it. `never` also takes a handle out of\n // hit-testing, so a hidden handle cannot be grabbed.\n //\n // `selectable={false}` suppresses the marquee / lasso chrome by default:\n // every selection write no-ops then, so the select tool's\n // empty-drag binding still CLAIMS the gesture (keeping it from falling\n // through to other ambient drag actions like insert) but paints nothing.\n // An explicit consumer rule for either id still wins.\n const effectiveChromeVisibility = useMemo(() => {\n // Kit defaults first; consumer `chromeVisibility` spread last so it wins.\n const defaults: import('features/chrome-caps').VisibilityRules = {};\n if (!enabled.has('outline')) defaults['selection.outline'] = never;\n if (!enabled.has('resize')) defaults['selection.resize-handles'] = never;\n if (!enabled.has('rotate')) defaults['selection.rotation-handle'] = never;\n if (!selectable) {\n defaults['action.marquee'] = never;\n defaults['action.lasso'] = never;\n }\n // `selectTool.rotate === false` hides the rotation handle (its action is\n // also dropped below) so a non-rotatable consumer fully opts out.\n if (selectToolOpts?.rotate === false) defaults['selection.rotation-handle'] = never;\n if (Object.keys(defaults).length === 0) return chromeVisibility;\n return { ...defaults, ...chromeVisibility };\n }, [chromeVisibility, selectable, selectToolOpts?.rotate, enabled]);\n const chromeVisibilityRef = useLatest(effectiveChromeVisibility);\n // Read through a ref for the same reason as the others here:\n // `buildCurrentRuleCtx` is a stable `useCallback`, and adding the profile to\n // its deps would rebuild it whenever a media query changes.\n const deviceProfileRef = useLatest(deviceProfile);\n // Per-node resizability predicate from `selectTool.resize.resizable`, folded\n // over the live selection into the `selectionResizable` rule-ctx flag below.\n const resizablePredRef = useLatest(selectToolOpts?.resize?.resizable);\n\n // The visibility predicate factory passed to <Canvas>. Called fresh per\n // draw / hitTest; builds ChromeCtx from the live refs and resolves\n // against the merged rule table. Returns the universal predicate when\n // no consumer overrides are present AND no hover tracking is needed —\n // letting the kit's defaults still gate paint without forcing every\n // legacy consumer onto chrome-caps.\n /** Build the live RuleCtx — selection + view + modifiers + mode + capabilities\n * + active action. Consumed by chrome-caps' resolver and the dispatcher's\n * eligibility filter so both see the same view of the world. */\n const buildRuleCtxFor = useCallback((inputs: ViewRuleInputs) => {\n const sel = inputs.selection;\n // No mode registry wired → behave as normal mode, capabilities included.\n // An empty set here would make every `capability:` rule false and hide\n // the chrome those rules gate. See DEFAULT_ALLOWED_CAPABILITIES.\n const modeInfo = getActiveModeRef.current?.()\n ?? { id: 'normal', allowedCapabilities: DEFAULT_ALLOWED_CAPABILITIES };\n const ctx = buildChromeCtx({\n focused: getFocusedPropRef.current ? getFocusedPropRef.current() : true,\n selection: sel,\n multiActive: sel.length > 1,\n modifiers: { alt: false, ctrl: false, meta: false, shift: false },\n action: inputs.action,\n hover: getHover(),\n view: inputs.view,\n });\n // buildChromeCtx returns a ChromeCtx (legacy shape); resolveVisibility\n // accepts both ChromeCtx and RuleCtx and supplies defaults when mode/\n // allowedCapabilities are absent. We attach them inline so the\n // mode-gated default rules can read them.\n // `selectionResizable`: true only when every selected node is resizable\n // (per `selectTool.resize.resizable`); undefined when no predicate is\n // supplied → the `resizable:` selector treats it as resizable (back-compat).\n const resizablePred = resizablePredRef.current;\n const selectionResizable = resizablePred\n ? sel.every((id) => resizablePred(id as string))\n : undefined;\n return {\n ...ctx,\n zoom: viewZoom(inputs.view),\n mode: modeInfo.id,\n allowedCapabilities: modeInfo.allowedCapabilities,\n selectionResizable,\n editingAnchors: effectivePathEditingId() !== '',\n device: deviceProfileRef.current,\n };\n }, [getHover, effectivePathEditingId, getActiveModeRef, getFocusedPropRef, resizablePredRef, deviceProfileRef]);\n\n /** The surface's own view zero. */\n const currentRuleInputs = useCallback((): ViewRuleInputs => ({\n selection: selectionForCapsRef.current,\n view: currentViewRef.current,\n action: dispatcher.getActiveAction(),\n }), [dispatcher, selectionForCapsRef]);\n const buildCurrentRuleCtx = useCallback(\n () => buildRuleCtxFor(currentRuleInputs()),\n [buildRuleCtxFor, currentRuleInputs],\n );\n\n // Anchor editing survives only as long as the active mode permits it.\n // Deliberately undefined when no mode registry is wired: \"no modality\"\n // means nothing revokes edit mode, whereas a predicate built from the\n // fallback capability set would revoke it immediately (the default set\n // is NORMAL's, which doesn't include `edits-anchors`).\n const anchorEditingAllowed = useMemo(\n () =>\n getActiveMode\n ? () => getActiveModeRef.current!().allowedCapabilities.has('edits-anchors')\n : undefined,\n [getActiveMode, getActiveModeRef],\n );\n useInsertionEffect(() => {\n anchorEditingAllowedRef.current = anchorEditingAllowed;\n });\n\n /** The chrome-caps answers for one view: the surface's rule table evaluated\n * against that view's selection, camera and in-flight action. */\n const chromeCaps = useMemo(() => ({\n ruleCtx: (inputs: ViewRuleInputs) =>\n (getActiveModeRef.current ? buildRuleCtxFor(inputs) as RuleCtx : undefined),\n isVisible: (inputs: ViewRuleInputs) => resolveVisibility(\n chromeVisibilityRef.current,\n buildRuleCtxFor(inputs) as Parameters<typeof resolveVisibility>[1],\n ),\n }), [buildRuleCtxFor, getActiveModeRef, chromeVisibilityRef]);\n\n const getIsVisibleForCanvas = useCallback(\n (): ((id: string) => boolean) => chromeCaps.isVisible(currentRuleInputs()),\n [chromeCaps, currentRuleInputs],\n );\n\n // Pen preview overlay — reads the pen tool's persistent scratch and draws\n // the in-progress path (anchors, handles, rubber-band, close hint). Only\n // wired when the pen tool is actually registered; otherwise null.\n const wantsPen = wants('pen');\n const penPreviewLayer = useMemo(\n () => (wantsPen\n ? createPenPreviewLayer({ penTool: shapeTools.pen as Tool<PenScratch> })\n : null),\n [shapeTools.pen, wantsPen],\n );\n\n // Bump the canvas's redraw whenever edit-mode changes — the chrome layer\n // reads `editingId` via a ref, so without an explicit redraw signal a\n // dirty-render canvas (no animation in flight) sits with stale frames\n // and the user sees no chrome until something else triggers a paint.\n useEffect(() => {\n canvasApiRef.current?.requestRedraw?.();\n }, [pathEditingId]);\n\n // Path-editing overlay — anchor squares, tangent lines, control-point\n // dots for the polygon currently in edit mode. Reads the same state the\n // dep does, so chrome appears exactly when (and only when) the gesture\n // path is also active.\n //\n // `getPose` walks the dispatcher's in-flight handles first so the chrome\n // tracks the live `previewPose` while editAnchorsAction is dragging; only\n // falls back to the committed scene pose between gestures. This is what\n // makes the dragged anchor / handle move under the cursor instead of\n // staying pinned to its committed position until the drag commits.\n const sceneRefForOverlay = useLatest(scene);\n const slopsOn = debug !== undefined && debug !== false && debug.slops === true;\n const selectionOverlayCfg = mergedLayers.selectionOverlay as\n | SelectionOverlaySlotConfig<TPose> | null | undefined;\n const badgeOf = selectionOverlayCfg ? rotationBadgeOf(selectionOverlayCfg) : null;\n // Kept by value so the layers and hit-testers keyed on it don't rebuild\n // every render.\n const rotationBadge = useMemo(\n () => badgeOf,\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [badgeOf?.distancePx, badgeOf?.sizePx],\n );\n // Debug: slops viz layer (off by default). Draws the affordances the\n // gesture mounter hit-tests, which it publishes here, so the halos are the\n // hit regions rather than a copy of them.\n const chromeAffordancesRef = useRef<readonly Affordance[]>([]);\n const slopsLayer = useMemo(\n () => createSlopsDebugLayer({ getAffordances: () => chromeAffordancesRef.current }),\n [],\n );\n\n // Resolve the live (preview-aware) world polygon for `id`. Reads from\n // the dispatcher's in-flight handles first — whichever handle owns\n // the gesture (editAnchors anchor-drag, move-the-whole-path, etc.)\n // contributes the previewPose / previewData that we'd otherwise\n // dispatch separately. Synthesizes a (pose, data) pair and routes it\n // through `resolveEditablePathOf` so chrome and slops viz follow\n // *any* in-flight gesture that previews state for the editing id.\n const livePathFor = (\n id: string,\n previews: readonly GesturePreviewSource[],\n view: View,\n ): PolygonPath | null => {\n const node = sceneRefForOverlay.current?.get(id as never);\n if (!node) return null;\n let pose = node.pose as unknown;\n let data = node.data as unknown;\n let touched = false;\n for (const source of previews) {\n const previewIds = source.previewIds?.();\n if (!previewIds) continue;\n let owns = false;\n for (const pid of previewIds) {\n if (pid === id) { owns = true; break; }\n }\n if (!owns) continue;\n const p = source.previewPose?.(id);\n if (p != null && !touched) { pose = p; touched = true; }\n const d = source.previewData?.(id);\n if (d != null) { data = d; touched = true; }\n }\n // In the drawing camera's world: a path on a parallax plane is stored in\n // the plane's.\n return pathFromPlane(\n resolveEditablePathOf({ pose, data } as { pose: unknown; data: unknown }),\n planeOfNodeRef.current(id, view),\n );\n };\n\n const pathEditingOverlayLayer = useMemo(\n () => createPathEditingOverlayLayer({\n getEditingId: () => effectivePathEditingId() || null,\n getPose: (id, previews, view) => livePathFor(id, previews, view) as never,\n getSelectedAnchors: () => selectedAnchorsRef.current,\n // Drawn by an action that ran in the edited path's plane.\n getMarquee: (view) => {\n const rect = anchorMarqueeRef.current;\n const plane = rect ? planeOfNodeRef.current(effectivePathEditingId(), view) : null;\n return rect && plane ? rectFromPlane(plane, rect) : rect;\n },\n }),\n // Stable identity — closure reads live state through refs.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n );\n\n // Suppress the standard selection overlay (outline + corner/rotate\n // handles) on the node currently in path-edit mode — the per-anchor\n // chrome takes over.\n const getSuppressedSelectionIds = useCallback((): ReadonlySet<string> => {\n const id = effectivePathEditingId();\n return id ? new Set([id]) : EMPTY_ID_SET;\n }, [effectivePathEditingId]);\n\n // Selection overlay — constructed here (scene-aware) per main's seam refactor.\n // Layered on top: path-edit suppression from HEAD's branch.\n const selectionOverlayLayer = useMemo(() => {\n const selCfg = mergedLayers.selectionOverlay as\n | SelectionOverlaySlotConfig<TPose>\n | null\n | undefined;\n if (selCfg === null) return null;\n const cfg = (selCfg ?? {}) as SelectionOverlaySlotConfig<TPose>;\n\n const callerSuppress = cfg.getSuppressedIds;\n const getSuppressedIds = (): ReadonlySet<string> => {\n const own = getSuppressedSelectionIds();\n const caller = callerSuppress?.();\n if (!caller || caller.size === 0) return own;\n if (own.size === 0) return caller;\n const merged = new Set<string>(caller);\n for (const id of own) merged.add(id);\n return merged;\n };\n\n return createSelectionOverlayLayer<TPose>({\n ...cfg,\n getSuppressedIds,\n ...(cfg.poseById\n ? {\n getPose: cfg.poseById,\n poseDescriptor: cfg.poseDescriptor ?? (descriptor as PoseDescriptor<TPose>),\n }\n : {}),\n });\n }, [mergedLayers.selectionOverlay, getSuppressedSelectionIds, descriptor]);\n\n const wiredLayers = useMemo<LayersMap<Node<TData, TLayer, TPose>, TPose>>(() => ({\n ...mergedLayers,\n ...(sceneSlot ? { scene: sceneSlot } : {}),\n // Pass the pre-built selection overlay layer so Canvas receives a\n // CustomLayerEntry and skips its own factory construction for this slot.\n selectionOverlay: selectionOverlayLayer\n ? { layer: selectionOverlayLayer }\n : mergedLayers.selectionOverlay === null ? null : undefined,\n previewGhost: { layer: previewLayer, after: 'scene' },\n dispatcherOverlay: { layer: dispatcherOverlay, after: 'previewGhost' },\n ...(penPreviewLayer ? { penPreview: { layer: penPreviewLayer, after: 'dispatcherOverlay' } } : {}),\n pathEditingOverlay: { layer: pathEditingOverlayLayer, after: 'selectionOverlay' },\n ...(slopsOn ? { slopsDebug: { layer: slopsLayer, after: 'pathEditingOverlay' } } : {}),\n }), [mergedLayers, sceneSlot, selectionOverlayLayer, previewLayer, dispatcherOverlay, penPreviewLayer, pathEditingOverlayLayer, slopsOn, slopsLayer]);\n\n // Standard-action deps: closures over the live scene / selection / adapter\n // so the resolved actions always read current state. `useStandardActions`\n // stabilizes via refs internally — these closures are passed every render\n // but the registered Action descriptors are not re-registered.\n // `CanvasExtensionApi.ingest` — imperative entry into the same\n // content-handler pipeline OS drop / clipboard paste hit. Routed through\n // `registry.trigger('ingest', …)` so the action's `requires` deps\n // (insert, ingestion, …) are resolved exactly as on the dispatcher path.\n // `StandardActionsRegistrar` stashes the registry into this ref.\n const actionsRegistryRef = useRef<ActionsRegistry | null>(null);\n\n // Clipboard-paste ctx for the kit weasel-JSON content handler\n // (`IngestCtx.clipboard`). Built from THIS canvas's synthesized adapter so\n // OS-arriving pastes re-materialize through the same `commitPaste` path\n // `useClipboardOps` uses. Absent (⇒ the handler declines) when the\n // consumer set `ingestion.clipboard.enabled: false` or the adapter lacks\n // `commitPaste` (always present on the synthesized adapter; guarded for\n // future adapter overrides).\n const ingestionClipboardReviver = ingestion?.clipboard?.reviver;\n const ingestionClipboardEnabled = ingestion?.clipboard?.enabled !== false;\n const ingestionClipboardOmitted = useLatest(ingestion?.clipboard?.onOmitted);\n const ingestionClipboard = useMemo<ClipboardIngestCtx | undefined>(() => {\n if (!ingestionClipboardEnabled || !adapter?.commitPaste) return undefined;\n return {\n adapter: adapter as unknown as InsertAdapter<{ id: string }>,\n ...(ingestionClipboardReviver ? { reviver: ingestionClipboardReviver } : {}),\n onOmitted: (omitted) => ingestionClipboardOmitted.current?.(omitted),\n };\n }, [adapter, ingestionClipboardEnabled, ingestionClipboardReviver, ingestionClipboardOmitted]);\n const ingestImpl = useCallback(\n (input: File[] | IngestItem[], point?: { x: number; y: number }) => {\n const items: IngestItem[] = (input as (File | IngestItem)[]).map((entry) =>\n entry instanceof File ? itemsFromFiles([entry])[0] : entry,\n );\n if (items.length === 0) return;\n if (!actionsRegistryRef.current) {\n // The registry is stashed by a descendant effect — a consumer calling\n // ingest() from its own ref callback / layout effect lands here.\n dwarn('ingest', 'CanvasExtensionApi.ingest called before the action registry mounted — call ignored. Defer to an effect or event handler.');\n return;\n }\n actionsRegistryRef.current.trigger('ingest', {\n items,\n ...(point ? { worldX: point.x, worldY: point.y } : {}),\n });\n },\n [],\n );\n\n // Views added through the handle rather than declared as props or children.\n const [addedViews, setAddedViews] = useState<readonly CanvasViewProps[]>([]);\n const addView = useCallback((props: CanvasViewProps): CanvasViewHandle => {\n setAddedViews((list) => [...list.filter((v) => v.id !== props.id), props]);\n return {\n id: props.id,\n draw: (data, outer, dims) =>\n surfaceViewRegistry?.list().find((r) => r.id === props.id)?.layer.draw(data, outer, dims) ?? [],\n remove: () => setAddedViews((list) => list.filter((v) => v !== props)),\n };\n }, [surfaceViewRegistry]);\n\n // Merge the forwarded ref with our internalCanvasRef so the dispatcher can\n // read the canvas element even when the consumer also forwards a ref.\n // The handle exposed to consumers extends the primitive's with `ingest`\n // (SceneCanvas-only — it needs the action stack).\n const mergedRef = useCallback(\n (node: CanvasExtensionApi | null) => {\n internalCanvasRef.current = node?.element ?? null;\n trackHoverOn(internalCanvasRef.current);\n const extended: SceneCanvasApi | null = node\n ? {\n ...node,\n ingest: ingestImpl,\n animateView: viewAnimation.animate,\n stopViewAnimation: viewAnimation.stop,\n isViewAnimating: viewAnimation.isAnimating,\n addView,\n }\n : null;\n canvasApiRef.current = extended;\n setCanvasReady(extended !== null);\n assignRef(ref, extended);\n },\n [ref, ingestImpl, viewAnimation, addView, trackHoverOn],\n );\n\n // What a view needs to build its own overlay-aware state. `geometry` is the\n // same descriptor handed to `<Canvas>`, so the two cannot diverge.\n const viewInputs = useMemo<SurfaceViewInputs>(() => ({\n adapter: adapter as unknown as { getPose(id: string): unknown },\n geometry: descriptor,\n boundsOf: internalBoundsOf,\n boundsOfPose: internalBoundsOfPose as SurfaceViewInputs['boundsOfPose'],\n planeOfNode: internalPlaneOfNode,\n tools,\n pickEvery: internalPickEvery,\n pickBest: internalPickBest,\n kindOfNode,\n chromeCaps,\n selectionApi: selection,\n rotationBadge,\n }), [adapter, descriptor, internalBoundsOf, internalBoundsOfPose, internalPlaneOfNode, tools,\n internalPickEvery, internalPickBest, kindOfNode, chromeCaps, selection, rotationBadge]);\n\n const canvas = (\n <Canvas<Node<TData, TLayer, TPose>, TPose>\n ref={mergedRef}\n adapter={adapter}\n selection={selection}\n poseDescriptor={descriptor as PoseDescriptor<TPose>}\n tools={tools}\n layers={wiredLayers}\n pickEvery={internalPickEvery}\n // The chrome's bounds are the picker's: a node on a parallax plane is\n // boxed where the plane draws it, and a `geometry.boundsOf` reaches both.\n boundsOf={internalBoundsOf}\n boundsOfPose={internalBoundsOfPose}\n getIsVisible={getIsVisibleForCanvas}\n previewIdsExtra={previewIdsExtra}\n // The gesture surface behind `helpersRef.getGestureBounds()` /\n // `subscribeGestures()` — Canvas has no dispatcher of its own.\n gestureSource={gestureSource}\n previewPoseExtra={previewPoseExtra}\n backgroundFill={backgroundFill}\n cursorCoordsHud={cursorCoordsHud}\n pickHud={pickHud}\n modalityHud={modalityHud}\n {...(debug !== undefined ? { debug: canvasDebug(debug) } : {})}\n pickBest={internalPickBest}\n contentVersion={scene.getVersion}\n layerVisibility={layerVisibility}\n layerOrder={layerOrder}\n {...(viewProp !== undefined ? { view: viewProp } : { defaultView })}\n onViewChange={notifyViewChange}\n shaders={shaders}\n flattenTolerance={flattenTolerance}\n // onBackgroundClick is intentionally NOT wired here. The `clearSelection`\n // action binding in the select tool handles \"click on empty background clears\n // selection\" for all SceneCanvas consumers. Wiring a separate background-click\n // callback would interfere with the gesture dispatcher (which handles lasso,\n // marquee, etc.) since tools.dispatcher.hasActiveGesture() only covers the\n // legacy tool channel, not the gesture dispatcher channel.\n {...(redrawOn ? { redrawOn } : {})}\n {...restProps}\n />\n );\n\n // Test hook: opt-in via ?test=1, never in production builds. See src/test-hook.\n const testHookSceneRef = useLatest(scene);\n const testHookSelectionRef = useLatest(selection);\n\n useEffect(() => {\n // Call-site gate: in a consumer's production build, esbuild/webpack/Vite\n // constant-fold `process.env.NODE_ENV` to `\"production\"` and DCE this\n // block, dropping the test-hook references. Same dev-only pattern as\n // React's invariant warnings. Gating only inside `installTestHookIfRequested`\n // is not enough — a called function can't be tree-shaken even if its body\n // is dead, so the gate must sit at the call site too.\n if (process.env.NODE_ENV !== 'production') {\n const hook = installTestHookIfRequested({\n getScene: () => testHookSceneRef.current as never,\n getSelectionIds: () =>\n (testHookSelectionRef.current?.current as readonly string[] | undefined) ?? [],\n getView: () => currentViewRef.current,\n getActiveToolId: () => liveToolsRef.current?.active ?? null,\n });\n if (hook) {\n hook._markReady();\n return () => releaseTestHook(hook);\n }\n }\n return undefined;\n }, [testHookSceneRef, testHookSelectionRef, liveToolsRef]);\n\n return (\n <DeviceProfileProvider value={device}>\n <ViewInputsProvider value={viewInputs}>\n <>\n <PointerProviderIfRoot>\n <>\n {canvas}\n <PointerPublisher canvasRef={internalCanvasRef} />\n <StandardActionsRegistrar\n selection={selection}\n scene={scene}\n adapter={adapter as unknown as BridgeAdapter}\n actionDefaults={actionDefaults}\n actions={resolvedActions}\n excludeActions={standardActionsExclude}\n currentViewRef={currentViewRef}\n onViewChange={handleViewChange}\n resizeOptions={selectToolOpts?.resize as UseResizeOptions<unknown> | undefined}\n poseDescriptor={descriptor}\n geometryProjection={geometryProjection}\n dispatcher={dispatcher}\n getActionRef={getActionRef}\n pickEvery={internalPickEvery}\n layerIsPainted={viewLayerGate}\n alphaOf={alphaFor ? composedAlphaFor : undefined}\n viewportPanEnabled={enabled.has('view') ? (viewport?.pan ?? true) : false}\n viewportZoom={enabled.has('view') ? resolvedViewportZoom : false}\n viewportPinchZoom={enabled.has('view') ? (viewport?.pinchZoom ?? true) : false}\n viewportRecenter={viewport?.recenter}\n viewAnimation={viewAnimation}\n editAnchorsExternalState={editAnchorsExternalState}\n anchorEditingAllowed={anchorEditingAllowed}\n layouts={layouts as SceneCanvasProps<unknown, string, unknown>['layouts']}\n layoutDropTarget={layoutDropTarget}\n reflowTransition={reflowTransition as ReflowTransition<unknown> | null | undefined}\n poseComposition={poseComposition as SceneCanvasProps<unknown, string, unknown>['poseComposition']}\n insertNodeFactories={insertNodeFactories}\n insertPaint={insertPaint}\n snapPoint={toolOptions?.snapPoint}\n canvasRef={internalCanvasRef}\n canvasApiRef={canvasApiRef}\n ingestionResolveSrc={ingestion?.resolveSrc}\n ingestionSvg={ingestion?.svg}\n ingestionClipboard={ingestionClipboard}\n actionsRegistryRef={actionsRegistryRef}\n />\n <GestureDispatcherMounter\n canvasRef={internalCanvasRef}\n canvasApiRef={canvasApiRef}\n tools={tools}\n contributions={featureContributions}\n enabled={enableGestureDispatcher}\n keyboard={enableKeybindings}\n claimKeys={claimKeys}\n selectionRef={selectionRef}\n boundsOf={internalBoundsOf}\n planeOfNode={internalPlaneOfNode}\n pickEvery={internalPickEvery}\n pickBest={internalPickBest}\n kindOfNode={kindOfNode}\n viewRef={currentViewRef}\n dispatcher={dispatcher}\n getIsVisibleForCanvas={getIsVisibleForCanvas}\n getRuleCtx={getActiveMode ? buildCurrentRuleCtx : undefined}\n targetScale={deviceProfile.targetScale}\n handleHitRadius={selectToolOpts?.handleHitRadius}\n rotationBadge={rotationBadge}\n chromeAffordancesRef={chromeAffordancesRef}\n onDoubleClick={onDoubleClickObserver}\n onClick={onClickObserver}\n longPress={longPress}\n />\n <ToolKeybindingsMounter\n internalTools={internalTools}\n toolsTakeover={toolsTakeover ?? undefined}\n enableKeybindings={enableKeybindings}\n isToolEligible={isToolEligible}\n canvasApi={canvasReady ? canvasApiRef.current : null}\n versionCheck={versionCheck}\n />\n {viewDescriptors?.map((v, i) => (\n <CanvasView key={v.id} {...v} order={v.order ?? i} />\n ))}\n {contributionEntries(tools).flatMap((e) => e.views ?? []).map((v) => (\n <CanvasView key={`contribution:${v.id}`} {...v} />\n ))}\n {addedViews.map((v) => <CanvasView key={`added:${v.id}`} {...v} />)}\n {children}\n </>\n </PointerProviderIfRoot>\n </>\n </ViewInputsProvider>\n </DeviceProfileProvider>\n );\n}\n\nconst SceneCanvasInnerForwardRef = forwardRef(SceneCanvasInner);\n\n// The canvas's input scope sits above `SceneCanvasInner`, whose own hooks\n// (`useTools` among them) must already read this canvas's tool and registries.\nfunction SceneCanvasWrapper<TData, TLayer extends string, TPose>(\n props: SceneCanvasProps<TData, TLayer, TPose>,\n ref: React.ForwardedRef<SceneCanvasApi>,\n) {\n return (\n <InputScope yoke={props.yoke}>\n <ViewRegistryProvider>\n <SceneCanvasInnerForwardRef {...(props as SceneCanvasProps<unknown, string, unknown>)} ref={ref} />\n </ViewRegistryProvider>\n </InputScope>\n );\n}\n\n/**\n * The canvas component: renders a `Scene` and wires the interaction stack\n * around it.\n *\n * Mounted bare it renders the scene, keeps a selection no input sets, and\n * runs a gesture dispatcher for whatever bindings the consumer adds. The\n * `features` presets turn the kit's behavior on — `features={['draw']}` is the\n * whole editor: tools, standard actions and their keys, selection chrome,\n * undo. This is the intended entry point; the lower-level primitives it\n * composes are not part of the public surface.\n *\n * Its ref exposes a `SceneCanvasApi` for the imperative operations that do not\n * fit a prop (view control, hit queries, redraw requests).\n */\nexport const SceneCanvas = forwardRef(SceneCanvasWrapper) as <\n TData, TLayer extends string, TPose,\n>(\n props: SceneCanvasProps<TData, TLayer, TPose> & { ref?: React.Ref<SceneCanvasApi> },\n) => ReturnType<typeof SceneCanvasInner>;\n\nexport { DEFAULT_HANDLE_SIZE, mergeLayersWithDefaults, BUILTIN_TOOL_IDS } from './SceneCanvas/props';\nexport type {\n SceneCanvasProps,\n SceneCanvasHit,\n SceneCanvasLayers,\n SceneCanvasLongPress,\n BuiltinToolId,\n} from './SceneCanvas/props';\nexport type { CoordTraceEntry } from './SceneCanvas/coordTrace';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SceneCanvas.js","names":["canvasDebug","debug","_slops","rest","SceneCanvasInner","sceneInput","selectToolOpts","selectionProp","toolsProp","viewDescriptors","getFocusedProp","redrawOnProp","restProps","props","descriptor","poseDescriptor","AUTO_POSE_DESCRIPTOR","deviceProfile","useDeviceProfile","bakedScene","useState","isSerializedScene","sceneFromJSON","scene","getActiveMode","useMemo","modes","getActiveModeFor","heldModifiers","useHeldModifiers","redrawOn","useSceneRedrawSources","internalCanvasRef","useRef","canvasApiRef","dlog","useCanvasCamera","viewState","viewportZoomProp","viewport","animatedZoom","resolvedViewportZoom","viewportZoomOption","selection","useCanvasSelection","selectionOptions","pathEditState","usePathEditState","pathEdit","isSelectedNode","id","selectToolWithDefaults","selectionRef","useLatest","useNodeKinds","routing","composedAlphaFor","composeAlphaFor","alphaFor","viewLayerGate","useViewLayerGate","layerVisibility","layerOrder","adapter","useSceneAdapter","internalSelect","internalPickEvery","internalPickBest","internalBoundsOf","internalBoundsOfPose","internalPlaneOfNode","internalMoveOptions","useSceneSelectTool","viewRef","getNodeAtPoint","useNodeAtPoint","enabled","useEnabledFeatures","features","internalTools","toolsTakeover","useCanvasTools","longPress","featureContributions","useFeatureBindings","getNodeAtPointRef","onDoubleClickObserver","useHitObserver","onDoubleClick","onClickObserver","onClick","rotateOff","resolvedActions","actionsMuting","actions","actionsRegistry","useActionsRegistry","useCanvasDispatcher","wiredLayers","useSceneCanvasLayers","animator","previewIdsExtra","trackHoverOn","useSceneHover","chromeVisibility","chromeRules","useChromeRules","getIsVisibleForCanvas","getRuleCtxForCanvas","useSurfaceChromeCaps","ingestionClipboard","useCanvasIngestion","ingestion","addedViews","useAddedViews","canvasReady","useSceneCanvasHandle","viewInputs","kindOfNode","chromeCaps","rotationBadge","useTestHook","tools","ViewInputsProvider","PointerProviderIfRoot","Canvas","handleRef","DevHuds","cursorCoordsHud","pickHud","modalityHud","PointerPublisher","StandardActionsRegistrar","standardActionsExclude","toolOptions","GestureDispatcherMounter","enableGestureDispatcher","enableKeybindings","ToolKeybindingsMounter","CanvasView","v","i","contributionEntries","children","SceneCanvasInnerForwardRef","forwardRef","SceneCanvasWrapper","InputScope","DeviceProfileProvider","device","ViewRegistryProvider","SceneCanvas","BUILTIN_TOOL_IDS","DEFAULT_HANDLE_SIZE","SCENE_CANVAS_FEATURES","rotateAroundAABBCenter"],"sources":["../../src/canvas/SceneCanvas.tsx"],"sourcesContent":["/**\n * `<SceneCanvas>` — `<Canvas>` wired to a `Scene` primitive. Bare, it only renders: behavior\n * comes from the `features` presets (`canvas/SceneCanvas/features.ts`), each of which turns on\n * its own actions, tools, ambient bindings, and chrome.\n *\n * A consumer needing custom tools can pass `tools={useTools(...)}` and SceneCanvas forwards it\n * as-is — the internal tool registry is ignored in that case.\n */\nimport { getActiveModeFor } from '@weasel-js/modes';\nimport { useLatest } from '@weasel-js/react';\nimport type { ActionsProp } from '@weasel-js/routing';\nimport { InputScope, useActionsRegistry } from '@weasel-js/routing/react';\nimport { sceneFromJSON } from 'core/scene/scene';\nimport { isSerializedScene } from 'core/scene/serialization';\nimport type { NodeId, Scene } from 'core/scene/types';\nimport { useCanvasCamera } from './SceneCanvas/useCanvasCamera';\nimport { useHeldModifiers } from './SceneCanvas/useHeldModifiers';\nimport { useCanvasIngestion } from 'features/ingestion/useCanvasIngestion';\nimport { isSelectedNode } from 'features/paths/pathEditState';\nimport { usePathEditState } from 'features/paths/usePathEdit';\nimport { AUTO_POSE_DESCRIPTOR } from 'core/geometry/autoPoseDescriptor';\nimport type { PoseDescriptor } from 'interactions/actions/resize/geometry';\nimport type { UseResizeOptions } from 'interactions/actions/resize/options';\nimport type React from 'react';\nimport { forwardRef, useEffect, useMemo, useRef, useState } from 'react';\nimport { DeviceProfileProvider, useDeviceProfile } from '../core/device/useDeviceProfile';\nimport { dlog } from '../debug/flag';\nimport type { DebugConfig } from '../debug/types';\nimport type { ReflowTransition } from '../layout/types';\nimport { useTestHook } from '../test-hook/useTestHook';\nimport { Canvas } from './Canvas';\nimport { CanvasView } from './CanvasView';\nimport { DevHuds } from './SceneCanvas/DevHuds';\nimport { GestureDispatcherMounter } from './SceneCanvas/GestureDispatcherMounter';\nimport { PointerProviderIfRoot, PointerPublisher } from './SceneCanvas/PointerProviderIfRoot';\nimport { StandardActionsRegistrar } from './SceneCanvas/StandardActionsRegistrar';\nimport { ToolKeybindingsMounter } from './SceneCanvas/ToolKeybindingsMounter';\nimport type { FeatureBindingOptions } from './SceneCanvas/features';\nimport type { BridgeAdapter, SceneCanvasProps } from './SceneCanvas/props';\nimport { actionsMuting } from './SceneCanvas/useActionsPropResolver';\nimport { useCanvasDispatcher } from './SceneCanvas/useCanvasDispatcher';\nimport { useCanvasSelection } from './SceneCanvas/useCanvasSelection';\nimport { useCanvasTools, useEnabledFeatures, useFeatureBindings } from './SceneCanvas/useCanvasTools';\nimport { contributionEntries } from './SceneCanvas/useContributionRoles';\nimport { useNodeAtPoint } from './SceneCanvas/useNodeAtPoint';\nimport { useNodeKinds } from './SceneCanvas/useNodeKinds';\nimport { useAddedViews, useSceneCanvasHandle } from './SceneCanvas/useSceneCanvasHandle';\nimport { useSceneCanvasLayers } from './SceneCanvas/useSceneCanvasLayers';\nimport { useChromeRules, useSceneHover, useSurfaceChromeCaps } from './SceneCanvas/useSceneChrome';\nimport { useSceneRedrawSources } from './SceneCanvas/useSceneRedrawSources';\nimport { useSceneSelectTool } from './SceneCanvas/useSceneSelectTool';\nimport { useViewLayerGate } from './SceneCanvas/useViewLayerGate';\nimport { viewportZoomOption } from './SceneCanvas/useViewportActions';\nimport type { CanvasExtensionApi, SceneCanvasApi } from './canvasExtension';\nimport { useSceneAdapter } from './useSceneAdapter';\nimport { composeAlphaFor } from './sceneSlotWiring';\nimport { useHitObserver } from './useHitObserver';\nimport { ViewInputsProvider, type SurfaceViewInputs } from './viewInputs';\nimport { ViewRegistryProvider } from './viewRegistry';\nexport { SCENE_CANVAS_FEATURES } from './SceneCanvas/features';\nexport type { Feature } from './SceneCanvas/features';\nexport type { BuiltinToolOptions } from './SceneCanvas/useBuiltinShapeTools';\nexport { defaultDrawOne } from './defaultDrawOne';\nexport { rotateAroundAABBCenter } from './poseRotation';\n\n/** `<SceneCanvas debug>` minus the flag only SceneCanvas reads. */\nfunction canvasDebug(debug: (DebugConfig & { slops?: boolean }) | false): DebugConfig | false {\n if (debug === false) return false;\n const { slops: _slops, ...rest } = debug;\n return rest;\n}\n\nfunction SceneCanvasInner<TData, TLayer extends string, TPose>(\n props: SceneCanvasProps<TData, TLayer, TPose>,\n ref: React.ForwardedRef<SceneCanvasApi>,\n) {\n const {\n scene: sceneInput,\n geometry,\n poseDescriptor,\n selectTool: selectToolOpts,\n insertNodeFactories,\n insertPaint,\n ingestion,\n layoutDropTarget,\n reflowTransition,\n geometryProjection,\n routing,\n selection: selectionProp,\n selectionOptions,\n selectable = true,\n tools: toolsProp,\n features,\n enableKeybindings = true,\n claimKeys = false,\n enableGestureDispatcher = true,\n onToolsCreated,\n defaultTools,\n toolOptions,\n initialActiveTool,\n ambient,\n versionCheck,\n longPress,\n viewport,\n layers,\n actions, tune,\n describeKind,\n animator,\n views: viewDescriptors,\n children,\n debug,\n alphaFor,\n layerVisibility,\n layerOrder,\n isPointerInteractive,\n onDoubleClick,\n onClick,\n chromeVisibility,\n modes,\n pathEdit,\n getFocused: getFocusedProp,\n cursorCoordsHud, pickHud, modalityHud,\n view, onViewChange, defaultView, viewBounds, redrawOn: redrawOnProp,\n ...restProps\n } = props;\n\n const descriptor = (poseDescriptor ?? AUTO_POSE_DESCRIPTOR) as PoseDescriptor<TPose>;\n const deviceProfile = useDeviceProfile();\n\n // `scene` accepts either a live `Scene` or a `SerializedScene` JSON object. JSON is baked\n // once; later prop changes are ignored (use a `key` on `<SceneCanvas>` to force a fresh canvas).\n const [bakedScene] = useState<Scene<TData, TLayer, TPose> | null>(\n () => (isSerializedScene<TData, TLayer, TPose>(sceneInput) ? sceneFromJSON(sceneInput, {}) : null),\n );\n const scene = bakedScene ?? (sceneInput as Scene<TData, TLayer, TPose>);\n\n const getActiveMode = useMemo(() => (modes ? getActiveModeFor(modes) : undefined), [modes]);\n const heldModifiers = useHeldModifiers();\n const redrawOn = useSceneRedrawSources({ supplied: redrawOnProp, scene, heldModifiers, animator, modes });\n\n // The canvas element, kept here so the dispatcher can attach its input listeners even when\n // the consumer passes their own forwarded ref, and the full handle, for `requestRedraw`.\n const internalCanvasRef = useRef<HTMLElement | null>(null);\n const canvasApiRef = useRef<CanvasExtensionApi | null>(null);\n\n useEffect(() => {\n dlog('scene-canvas', 'mount');\n return () => dlog('scene-canvas', 'unmount');\n }, []);\n\n const { viewState, viewAnimation, camera } = useCanvasCamera({\n view, defaultView, onViewChange, viewBounds,\n width: restProps.width,\n height: restProps.height,\n requestRedraw: () => { canvasApiRef.current?.requestRedraw(); },\n });\n const { viewRef } = viewState;\n\n const viewportZoomProp = viewport?.zoom;\n const animatedZoom = viewport?.animatedZoom;\n const resolvedViewportZoom = useMemo(\n () => viewportZoomOption(viewportZoomProp, animatedZoom),\n [viewportZoomProp, animatedZoom],\n );\n\n const selection = useCanvasSelection({\n scene, supplied: selectionProp, options: selectionOptions, selectable, describeKind,\n });\n\n // `isAllowed` is absent, not a predicate, when no mode registry is wired:\n // see `PathEditSource.isAllowed`.\n const pathEditState = usePathEditState({\n host: pathEdit,\n isAllowed: getActiveMode\n ? () => getActiveMode().allowedCapabilities.has('edits-anchors')\n : undefined,\n isSelectedNode: (id) => isSelectedNode(scene, selection, id),\n });\n\n const selectToolWithDefaults = useMemo(() => ({\n // Shift-click belongs to the anchor selection while a path is being\n // anchor-edited; see `UseSelectToolOptions.extendClickLocked`.\n extendClickLocked: () => pathEditState.getEditingId() !== '',\n ...selectToolOpts,\n }), [selectToolOpts, pathEditState]);\n\n const selectionRef = useLatest(selection);\n const { kindOfData, kindOfNode } = useNodeKinds(scene, routing);\n\n // The painted alpha of a node in this view: the caller's `alphaFor` times any per-node\n // override alpha. The pick path reads the same number the painter does, or a node faded\n // to nothing stays clickable.\n const composedAlphaFor = useMemo(\n () => composeAlphaFor(scene, alphaFor),\n [scene, alphaFor],\n );\n const viewLayerGate = useViewLayerGate(layerVisibility, layerOrder);\n\n const adapter = useSceneAdapter(scene, {\n // `adapterMethods` is memoized; `selection` itself is a fresh object each render.\n selection: selection.adapterMethods,\n poseDescriptor: descriptor,\n });\n\n const {\n selectTool: internalSelect, pickEvery: internalPickEvery, pickBest: internalPickBest,\n boundsOf: internalBoundsOf, boundsOfPose: internalBoundsOfPose, planeOfNode: internalPlaneOfNode,\n moveOptions: internalMoveOptions,\n } = useSceneSelectTool({\n scene,\n adapter,\n poseDescriptor: descriptor,\n geometry,\n // The pick tolerance is declared in screen pixels; this is what converts it.\n getView: () => viewRef.current,\n // Only when the consumer actually fades something. Without a prop the\n // composed function is just the override lookup, and the source resolves\n // that once per walk instead of once per candidate.\n ...(alphaFor ? { alphaOf: composedAlphaFor } : {}),\n ...(viewLayerGate ? { layerIsPainted: viewLayerGate } : {}),\n selectTool: selectToolWithDefaults,\n });\n\n const getNodeAtPoint = useNodeAtPoint({\n pickBest: internalPickBest, nodes: adapter, kindOfData, isPointerInteractive,\n });\n\n const enabled = useEnabledFeatures(features, viewport !== undefined);\n const { tools, internal: internalTools, takeover: toolsTakeover } = useCanvasTools({\n select: internalSelect,\n enabled,\n tools: toolsProp,\n defaultTools,\n toolOptions,\n inertia: viewport?.inertia,\n ambient,\n pressFeedback: longPress?.feedback,\n initialActiveTool,\n modes,\n onToolsCreated,\n });\n const { contributions: featureContributions, standardActionsExclude } = useFeatureBindings({\n enabled,\n tools,\n move: internalMoveOptions as FeatureBindingOptions['move'],\n rotate: (selectToolOpts?.rotate || undefined) as FeatureBindingOptions['rotate'],\n });\n\n // Rides the gesture dispatcher as an OBSERVER rather than an Action binding because the\n // prop is a notification, not a behavior: as a binding it would lose first-match-wins to\n // `enterPathEdit` on every body hit and silently stop firing.\n const getNodeAtPointRef = useLatest(getNodeAtPoint);\n const onDoubleClickObserver = useHitObserver(onDoubleClick, getNodeAtPointRef);\n const onClickObserver = useHitObserver(onClick, getNodeAtPointRef);\n\n // `selectTool.rotate === false` disables rotation: its action is muted here and its\n // handle hidden by `useChromeRules`.\n const rotateOff = selectToolOpts?.rotate === false;\n const resolvedActions = useMemo<ActionsProp | undefined>(\n () => (rotateOff ? actionsMuting(actions, 'rotate') : actions),\n [actions, rotateOff],\n );\n\n // The wrapper's `<InputScope>` provides it.\n const actionsRegistry = useActionsRegistry();\n const { dispatcher, gestureSource, previewIdsExtra, previewPoseExtra } = useCanvasDispatcher(actionsRegistry);\n\n const { layers: wiredLayers, rotationBadge, chromeAffordancesRef } = useSceneCanvasLayers({\n layers,\n targetScale: deviceProfile.targetScale,\n scene,\n adapter,\n poseDescriptor: descriptor,\n alphaFor,\n colorOverrides: animator?.colorOverrides,\n boundsOf: internalBoundsOf,\n planeOfNode: internalPlaneOfNode,\n previewIds: previewIdsExtra,\n dispatcher,\n pathEditState,\n slops: debug !== undefined && debug !== false && debug.slops === true,\n });\n\n const { getHover, canvasRef: trackHoverOn } = useSceneHover({\n canvasApiRef, viewRef, nodeAtPointRef: getNodeAtPointRef, enabled: chromeVisibility !== undefined,\n });\n const chromeRules = useChromeRules({ enabled, selectable, rotateOff, chromeVisibility });\n const { chromeCaps, getIsVisible: getIsVisibleForCanvas, getRuleCtx: getRuleCtxForCanvas } = useSurfaceChromeCaps({\n source: {\n rules: chromeRules,\n getMode: getActiveMode,\n getFocused: getFocusedProp,\n getHover,\n getModifiers: heldModifiers.get,\n resizable: selectToolOpts?.resize?.resizable,\n editingAnchors: () => pathEditState.getEditingId() !== '',\n device: deviceProfile,\n },\n selection: selection.current as readonly NodeId[],\n viewRef,\n dispatcher,\n });\n\n const { ingest, clipboard: ingestionClipboard } = useCanvasIngestion(\n adapter, () => actionsRegistry, ingestion,\n );\n\n const { views: addedViews, addView } = useAddedViews();\n // The consumer's handle extends the primitive's with `ingest`, which needs the action stack.\n const { handleRef, ready: canvasReady } = useSceneCanvasHandle({\n ref, elementRef: internalCanvasRef, apiRef: canvasApiRef, onElement: trackHoverOn,\n ingest, viewAnimation, camera, addView,\n });\n\n // What a view needs to build its own overlay-aware state. `geometry` is the\n // same descriptor handed to `<Canvas>`, so the two cannot diverge.\n const viewInputs = useMemo<SurfaceViewInputs>(() => ({\n adapter: adapter as unknown as { getPose(id: string): unknown },\n geometry: descriptor as PoseDescriptor<unknown>,\n boundsOf: internalBoundsOf,\n boundsOfPose: internalBoundsOfPose as SurfaceViewInputs['boundsOfPose'],\n planeOfNode: internalPlaneOfNode,\n pickEvery: internalPickEvery,\n pickBest: internalPickBest,\n kindOfNode,\n chromeCaps,\n selectionApi: selection,\n rotationBadge,\n }), [adapter, descriptor, internalBoundsOf, internalBoundsOfPose, internalPlaneOfNode,\n internalPickEvery, internalPickBest, kindOfNode, chromeCaps, selection, rotationBadge]);\n\n useTestHook({\n getScene: () => scene as never,\n getSelectionIds: () => (selection.current as readonly string[] | undefined) ?? [],\n getView: () => viewRef.current,\n getActiveToolId: () => tools.active ?? null,\n });\n\n return (\n <ViewInputsProvider value={viewInputs}>\n <PointerProviderIfRoot>\n <Canvas<TPose>\n ref={handleRef}\n adapter={adapter}\n selection={selection}\n poseDescriptor={descriptor}\n tools={tools}\n layers={wiredLayers}\n // The chrome's bounds are the picker's: a node on a parallax plane is\n // boxed where the plane draws it, and a `geometry.boundsOf` reaches both.\n boundsOf={internalBoundsOf}\n boundsOfPose={internalBoundsOfPose}\n getIsVisible={getIsVisibleForCanvas}\n // The gesture surface behind `helpersRef.getGestureBounds()` /\n // `subscribeGestures()` — Canvas has no dispatcher of its own.\n gestureSource={gestureSource}\n previewPoseExtra={previewPoseExtra}\n {...(debug !== undefined ? { debug: canvasDebug(debug) } : {})}\n contentVersion={scene.getVersion}\n layerVisibility={layerVisibility}\n layerOrder={layerOrder}\n viewState={viewState}\n redrawOn={redrawOn}\n {...restProps}\n />\n <DevHuds\n cursorCoords={cursorCoordsHud}\n pick={pickHud}\n modality={modalityHud}\n canvasRef={internalCanvasRef}\n canvasApiRef={canvasApiRef}\n detachedInput={restProps.paintInto ? restProps.inputElement ?? null : undefined}\n viewRef={viewRef}\n pickEvery={internalPickEvery}\n pickBest={internalPickBest}\n />\n <PointerPublisher canvasRef={internalCanvasRef} canvasApiRef={canvasApiRef} />\n <StandardActionsRegistrar\n selection={selection}\n scene={scene}\n adapter={adapter as unknown as BridgeAdapter}\n actions={resolvedActions} tune={tune}\n excludeActions={standardActionsExclude}\n currentViewRef={viewRef}\n onViewChange={viewState.setViewFromInput}\n resizeOptions={selectToolOpts?.resize as UseResizeOptions<unknown> | undefined}\n poseDescriptor={descriptor as PoseDescriptor<unknown>}\n geometryProjection={geometryProjection}\n dispatcher={dispatcher}\n pickEvery={internalPickEvery}\n layerIsPainted={viewLayerGate}\n alphaOf={alphaFor ? composedAlphaFor : undefined}\n viewportPanEnabled={enabled.has('view') ? (viewport?.pan ?? true) : false}\n viewportZoom={enabled.has('view') ? resolvedViewportZoom : false}\n viewportPinchZoom={enabled.has('view') ? (viewport?.pinchZoom ?? true) : false}\n viewportRecenter={viewport?.recenter}\n viewAnimation={viewAnimation}\n editAnchorsExternalState={pathEditState}\n layoutDropTarget={layoutDropTarget}\n reflowTransition={reflowTransition as ReflowTransition<unknown> | null | undefined}\n insertNodeFactories={insertNodeFactories}\n insertPaint={insertPaint}\n snapPoint={toolOptions?.snapPoint}\n canvasRef={internalCanvasRef}\n canvasApiRef={canvasApiRef}\n ingestionResolveSrc={ingestion?.resolveSrc}\n ingestionSvg={ingestion?.svg}\n ingestionClipboard={ingestionClipboard}\n />\n <GestureDispatcherMounter\n canvasRef={internalCanvasRef}\n canvasApiRef={canvasApiRef}\n tools={tools}\n contributions={featureContributions}\n enabled={enableGestureDispatcher}\n keyboard={enableKeybindings}\n claimKeys={claimKeys}\n selectionRef={selectionRef}\n boundsOf={internalBoundsOf}\n planeOfNode={internalPlaneOfNode}\n pickEvery={internalPickEvery}\n pickBest={internalPickBest}\n kindOfNode={kindOfNode}\n viewRef={viewRef}\n dispatcher={dispatcher}\n getIsVisibleForCanvas={getIsVisibleForCanvas}\n getRuleCtx={getRuleCtxForCanvas}\n targetScale={deviceProfile.targetScale}\n handleHitRadius={selectToolOpts?.handleHitRadius}\n rotationBadge={rotationBadge}\n chromeAffordancesRef={chromeAffordancesRef}\n onDoubleClick={onDoubleClickObserver}\n onClick={onClickObserver}\n longPress={longPress}\n />\n <ToolKeybindingsMounter\n internalTools={internalTools}\n toolsTakeover={toolsTakeover ?? undefined}\n enableKeybindings={enableKeybindings}\n modes={modes}\n canvasApi={canvasReady ? canvasApiRef.current : null}\n versionCheck={versionCheck}\n />\n {viewDescriptors?.map((v, i) => (\n <CanvasView key={v.id} {...v} order={v.order ?? i} />\n ))}\n {contributionEntries(tools).flatMap((e) => e.views ?? []).map((v) => (\n <CanvasView key={`contribution:${v.id}`} {...v} />\n ))}\n {addedViews.map((v) => <CanvasView key={`added:${v.id}`} {...v} />)}\n {children}\n </PointerProviderIfRoot>\n </ViewInputsProvider>\n );\n}\n\nconst SceneCanvasInnerForwardRef = forwardRef(SceneCanvasInner);\n\n// The canvas's input scope sits above `SceneCanvasInner`, whose own hooks\n// (`useTools` among them) must already read this canvas's tool and registries.\n// Its device profile too, so the canvas and everything under it share one.\nfunction SceneCanvasWrapper<TData, TLayer extends string, TPose>(\n { device, ...props }: SceneCanvasProps<TData, TLayer, TPose>,\n ref: React.ForwardedRef<SceneCanvasApi>,\n) {\n return (\n <InputScope yoke={props.yoke}>\n <DeviceProfileProvider value={device}>\n <ViewRegistryProvider>\n <SceneCanvasInnerForwardRef {...(props as SceneCanvasProps<unknown, string, unknown>)} ref={ref} />\n </ViewRegistryProvider>\n </DeviceProfileProvider>\n </InputScope>\n );\n}\n\n/**\n * The canvas component: renders a `Scene` and wires the interaction stack\n * around it.\n *\n * Mounted bare it renders the scene, keeps a selection no input sets, and\n * runs a gesture dispatcher for whatever bindings the consumer adds. The\n * `features` presets turn the kit's behavior on — `features={['draw']}` is the\n * whole editor: tools, standard actions and their keys, selection chrome,\n * undo. This is the intended entry point; the lower-level primitives it\n * composes are not part of the public surface.\n *\n * Its ref exposes a `SceneCanvasApi` for the imperative operations that do not\n * fit a prop (view control, hit queries, redraw requests).\n */\nexport const SceneCanvas = forwardRef(SceneCanvasWrapper) as <\n TData, TLayer extends string, TPose,\n>(\n props: SceneCanvasProps<TData, TLayer, TPose> & { ref?: React.Ref<SceneCanvasApi> },\n) => ReturnType<typeof SceneCanvasInner>;\n\nexport { DEFAULT_HANDLE_SIZE, mergeLayersWithDefaults, BUILTIN_TOOL_IDS } from './SceneCanvas/props';\nexport type {\n SceneCanvasProps,\n SceneCanvasHit,\n SceneCanvasLayers,\n SceneCanvasLongPress,\n BuiltinToolId,\n} from './SceneCanvas/props';\nexport type { CoordTraceEntry } from './SceneCanvas/coordTrace';\n"],"mappings":"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"}
|
|
@@ -1,56 +1,50 @@
|
|
|
1
1
|
import { normalizeView as e } from "../core/viewport/view.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { jsx as m } from "react/jsx-runtime";
|
|
2
|
+
import { useCanvasSurface as t } from "./useCanvasSurface.js";
|
|
3
|
+
import { SurfaceCanvas as n } from "./SurfaceCanvas.js";
|
|
4
|
+
import { sceneViewFrame as r } from "./sceneViewRender.js";
|
|
5
|
+
import { useCallback as i, useEffect as a, useRef as o, useSyncExternalStore as s } from "react";
|
|
6
|
+
import { assignRef as c } from "@weasel-js/react";
|
|
7
|
+
import { jsx as l } from "react/jsx-runtime";
|
|
9
8
|
//#region src/canvas/SceneViewCanvas.tsx
|
|
10
|
-
function
|
|
11
|
-
let { scene:
|
|
12
|
-
d
|
|
13
|
-
let
|
|
14
|
-
|
|
15
|
-
}, [
|
|
16
|
-
let
|
|
17
|
-
if (!
|
|
18
|
-
let
|
|
19
|
-
scene:
|
|
20
|
-
view:
|
|
21
|
-
width:
|
|
22
|
-
height:
|
|
23
|
-
drawOne:
|
|
24
|
-
extraCommands:
|
|
25
|
-
alphaFor:
|
|
26
|
-
layerVisibility:
|
|
27
|
-
layerOrder:
|
|
28
|
-
colorOverrides:
|
|
29
|
-
cull:
|
|
30
|
-
paintBounds:
|
|
9
|
+
function u(u) {
|
|
10
|
+
let { scene: d, width: f, height: p, drawOne: m, extraCommands: h, alphaFor: g, layerVisibility: _, layerOrder: v, animator: y, className: b, canvasRef: x, cull: S, paintBounds: C } = u, w = e(u.view);
|
|
11
|
+
s(d.subscribe, d.getVersion, d.getVersion);
|
|
12
|
+
let T = o(null), E = i((e) => {
|
|
13
|
+
T.current = e, c(x, e);
|
|
14
|
+
}, [x]), { requestRedraw: D } = t((e) => {
|
|
15
|
+
let t = T.current;
|
|
16
|
+
if (!t) return !1;
|
|
17
|
+
let n = r({
|
|
18
|
+
scene: d,
|
|
19
|
+
view: w,
|
|
20
|
+
width: f,
|
|
21
|
+
height: p,
|
|
22
|
+
drawOne: m,
|
|
23
|
+
extraCommands: h,
|
|
24
|
+
alphaFor: g,
|
|
25
|
+
layerVisibility: _,
|
|
26
|
+
layerOrder: v,
|
|
27
|
+
colorOverrides: y?.colorOverrides,
|
|
28
|
+
cull: S,
|
|
29
|
+
paintBounds: C
|
|
31
30
|
});
|
|
32
|
-
return
|
|
33
|
-
width:
|
|
34
|
-
height:
|
|
31
|
+
return e.paint(t, n, w, {
|
|
32
|
+
width: f,
|
|
33
|
+
height: p
|
|
35
34
|
});
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}, []), /* @__PURE__ */ m("canvas", {
|
|
46
|
-
ref: j,
|
|
47
|
-
width: _,
|
|
48
|
-
height: v,
|
|
49
|
-
className: T
|
|
35
|
+
}, {
|
|
36
|
+
target: T,
|
|
37
|
+
paintOnCommit: !0
|
|
38
|
+
});
|
|
39
|
+
return a(() => d.overrides.subscribe(D), [d, D]), a(() => y?.onTick(D), [y, D]), /* @__PURE__ */ l(n, {
|
|
40
|
+
ref: E,
|
|
41
|
+
width: f,
|
|
42
|
+
height: p,
|
|
43
|
+
className: b
|
|
50
44
|
});
|
|
51
45
|
}
|
|
52
|
-
var
|
|
46
|
+
var d = u;
|
|
53
47
|
//#endregion
|
|
54
|
-
export {
|
|
48
|
+
export { d as SceneViewCanvas };
|
|
55
49
|
|
|
56
50
|
//# sourceMappingURL=SceneViewCanvas.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SceneViewCanvas.js","names":["SceneViewCanvasInner","props","view","normalizeView","scene","localRef","useRef","setCanvasRef","useCallback","el","assignRef","canvasRef","lease","useCanvasRenderer","paintRef","useLatest","canvas","commands","sceneViewFrame","animator","useFrameLoop","paintedRef","useLayoutEffect","requestRedraw","useEffect","useLateContentRedraw","useRedrawOnRestore","useRedrawOnDensityChange","SceneViewCanvas"],"sources":["../../src/canvas/SceneViewCanvas.tsx"],"sourcesContent":["/**\n * `<SceneViewCanvas>` — pointer-inert, read-only render of a `Scene` at a\n * given `View` into its own `<canvas>` DOM element.\n *\n * The component:\n * - mounts its own `<canvas>`,\n * - subscribes to the scene via `useSyncExternalStore(scene.subscribe,\n * scene.getVersion)` so any scene mutation triggers a re-render,\n * - subscribes to `scene.overrides` as well, since override writes never\n * bump the scene version — without this the view would paint document\n * poses while `<SceneCanvas>` paints overridden ones,\n * - paints through `useFrameLoop` rather than from React, so both a render\n * (prop change or version bump) and an override commit just mark the\n * surface dirty and one `requestAnimationFrame` coalesces them. The mount\n * paint is synchronous so the first frame the user sees is the scene, not\n * a blank canvas, and nothing paints while the canvas is off screen or the\n * tab is hidden,\n * - attaches **no** event listeners (consumers attach their own via\n * `canvasRef`),\n * - frees its renderer and every GL object it owns on unmount\n * (`useCanvasRenderer`).\n *\n * Sizing follows `<SceneCanvas>`'s convention: the consumer passes `width` /\n * `height` in CSS pixels. The HTML `width` / `height` attributes of the\n * `<canvas>` (drawing-buffer size) are set to `width × dpr` and `height × dpr`\n * by the canvas renderer (via the underlying renderer's `resize`), which also\n * writes the element's inline `width` and `height` style in CSS pixels. That\n * beats a size set through `className`, so the class positions the canvas and\n * the `width` / `height` props size it.\n */\nimport {\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useSyncExternalStore,\n} from 'react';\nimport type { Ref } from 'react';\nimport { assignRef, useLatest } from '@weasel-js/react';\nimport { useFrameLoop } from './useFrameLoop';\nimport { useLateContentRedraw } from './useLateContentRedraw';\nimport { useCanvasRenderer, useRedrawOnDensityChange, useRedrawOnRestore } from './useCanvasRenderer';\nimport { sceneViewFrame } from './sceneViewRender';\nimport type { RenderSceneToCanvasArgs, SceneViewDrawOne, SceneViewLayers } from './sceneViewRender';\nimport type { DrawCommand } from '../renderer/DrawCommand';\nimport { normalizeView, type View } from '../core/viewport/view';\nimport type { Scene } from '../core/scene/types';\nimport type { Animator } from '../animation/types';\n\n/** Props for `<SceneViewCanvas>`. */\nexport interface SceneViewCanvasProps<TData, TLayer extends string, TPose> {\n /** Scene to render. Must be the same `Scene` instance passed to whoever\n * is mutating it; the component subscribes to its version stream and\n * repaints when the version advances. */\n scene: Scene<TData, TLayer, TPose>;\n /** Camera. Applied to scene + `extraCommands` via the renderer's group\n * transform. */\n view: View;\n /** CSS-pixel width. Drives both layout (via the rendered drawing-buffer\n * size) and the renderer's coordinate space. */\n width: number;\n /** CSS-pixel height. */\n height: number;\n /** Per-node draw callback. See `SceneViewDrawOne`. The consumer is\n * responsible for what gets painted — there is no AABB-fill default. */\n drawOne: SceneViewDrawOne<TData, TLayer, TPose>;\n /** Optional extra commands appended after scene commands, inside the same\n * view transform. Used by `<MinimapCanvas>` for its visible-window\n * indicator; available to other consumers that want to overlay a\n * world-space annotation. */\n extraCommands?: ReadonlyArray<DrawCommand>;\n /** Optional per-id alpha multiplier, mirroring `<SceneCanvas>`'s scene-slot\n * `alphaFor`. Pass the same function the main canvas uses to keep a\n * scoping-dim treatment consistent across both. Defaults to `() => 1`. */\n alphaFor?: (id: string) => number;\n /** Hide scene layers in this view only, keyed `scene:<layerId>` as on\n * `<SceneCanvas>` — pass the main canvas's map to keep the two in step. */\n layerVisibility?: SceneViewLayers['layerVisibility'];\n /** Paint order for this view, keyed as `layerVisibility`. */\n layerOrder?: SceneViewLayers['layerOrder'];\n /** Skip nodes and commands that cannot reach this view — the scene slot's\n * `cull`. Off by default; worth it when the view shows a small part of a\n * large scene. */\n cull?: boolean;\n /** Where `drawOne`'s output for a node can reach — the scene slot's\n * `paintBounds`. Defaults to `defaultPaintBounds` when `drawOne` is\n * `defaultDrawOne`. */\n paintBounds?: RenderSceneToCanvasArgs<TData, TLayer, TPose>['paintBounds'];\n /** Optional animator, as on `<SceneCanvas>`: the view repaints on its ticks\n * and paints its `colorOverrides`. Pass the main canvas's animator so both\n * show the same colors. */\n animator?: Animator;\n /** Optional CSS class for positioning the `<canvas>`. Its size is `width` ×\n * `height`, which the renderer writes as inline style. */\n className?: string;\n /** Forwarded ref to the underlying `<canvas>`. Consumers attach their own\n * pointer listeners or call `toBlob` for snapshots through this. */\n canvasRef?: Ref<HTMLCanvasElement>;\n}\n\nfunction SceneViewCanvasInner<TData, TLayer extends string, TPose>(\n props: SceneViewCanvasProps<TData, TLayer, TPose>,\n) {\n const {\n scene, width, height, drawOne, extraCommands, alphaFor, layerVisibility, layerOrder,\n animator, className, canvasRef, cull, paintBounds,\n } = props;\n const view = normalizeView(props.view);\n\n // Subscribe to scene version. The snapshot value isn't used directly —\n // we only need React to re-render the component when the scene mutates.\n useSyncExternalStore(scene.subscribe, scene.getVersion, scene.getVersion);\n\n const localRef = useRef<HTMLCanvasElement | null>(null);\n\n const setCanvasRef = useCallback((el: HTMLCanvasElement | null): void => {\n localRef.current = el;\n assignRef(canvasRef, el);\n }, [canvasRef]);\n\n // The frame loop paints, not React — so an override commit can repaint\n // without a render. The thunk defers to `paintRef`, which every committed\n // render republishes from an insertion effect — ahead of the layout effect\n // below, and never from a render React abandoned.\n const lease = useCanvasRenderer();\n const paint = (): boolean => {\n const canvas = localRef.current;\n if (!canvas) return false;\n const commands = sceneViewFrame({\n scene,\n view,\n width,\n height,\n drawOne,\n extraCommands: extraCommands as DrawCommand[] | undefined,\n alphaFor,\n layerVisibility,\n layerOrder,\n colorOverrides: animator?.colorOverrides,\n cull,\n paintBounds,\n });\n return lease.paint(canvas, commands, view, { width, height });\n };\n const paintRef = useLatest(paint);\n\n const { requestRedraw } = useFrameLoop(\n useCallback(() => paintRef.current(), [paintRef]),\n { target: localRef },\n );\n\n // Every render — a prop change or a scene-version bump — marks the surface\n // dirty. No dependency array: the paint reads all of them.\n //\n // The mount paint is the exception: it runs here, in the caller's stack, so\n // the first frame the user sees is the scene rather than a blank canvas.\n const paintedRef = useRef(false);\n useLayoutEffect(() => {\n if (paintedRef.current) { requestRedraw(); return; }\n paintedRef.current = paintRef.current();\n if (!paintedRef.current) requestRedraw();\n });\n\n // Override writes never bump the scene version, so the version subscription\n // above cannot see them.\n useEffect(() => scene.overrides.subscribe(requestRedraw), [scene, requestRedraw]);\n useEffect(() => animator?.onTick(requestRedraw), [animator, requestRedraw]);\n useLateContentRedraw(requestRedraw);\n useRedrawOnRestore(lease, requestRedraw);\n useRedrawOnDensityChange(requestRedraw);\n\n // A remount (StrictMode) paints its first frame in place again.\n useEffect(() => () => { paintedRef.current = false; }, []);\n\n return (\n <canvas\n ref={setCanvasRef}\n width={width}\n height={height}\n className={className}\n />\n );\n}\n\n/**\n * Pointer-inert read-only scene view. See `SceneViewCanvasProps` for the\n * full surface and the module docstring for the rendering model.\n *\n * `forwardRef` is not used because the component is generic over `<TData,\n * TLayer, TPose>` and React's `forwardRef` erases generics. The\n * `canvasRef` prop is the plain-prop equivalent (the spec calls it out as\n * the public surface).\n */\nexport const SceneViewCanvas = SceneViewCanvasInner;\n"],"mappings":";;;;;;;;;AAoGA,SAASA,EACP,GACA;CACA,IAAM,EACJ,UAAO,UAAO,WAAQ,YAAS,kBAAe,aAAU,oBAAiB,eACzE,aAAU,cAAW,cAAW,SAAM,mBACpCC,GACEC,IAAOC,EAAcF,EAAM,IAAI;CAIrC,EAAqBG,EAAM,WAAWA,EAAM,YAAYA,EAAM,UAAU;CAExE,IAAMC,IAAWC,EAAiC,IAAI,GAEhDC,IAAeC,GAAa,MAAuC;EAEvE,AADA,EAAS,UAAUC,GACnBC,EAAUC,GAAWF,CAAE;CACzB,GAAG,CAACE,CAAS,CAAC,GAMRC,IAAQC,EAAkB,GAoB1BC,IAAWC,QAnBY;EAC3B,IAAMC,IAASX,EAAS;EACxB,IAAI,CAACW,GAAQ,OAAO;EACpB,IAAMC,IAAWC,EAAe;GAC9B;GACA;GACA;GACA;GACA;GACe;GACf;GACA;GACA;GACA,gBAAgBC,GAAU;GAC1B;GACA;EACF,CAAC;EACD,OAAOP,EAAM,MAAMI,GAAQC,GAAUf,GAAM;GAAE;GAAO;EAAO,CAAC;CAC9D,CACgC,GAE1B,EAAE,qBAAkBkB,EACxBZ,QAAkBM,EAAS,QAAQ,GAAG,CAACA,CAAQ,CAAC,GAChD,EAAE,QAAQT,EAAS,CACrB,GAOMgB,IAAaf,EAAO,EAAK;CAkB/B,OAjBAgB,QAAsB;EACpB,IAAID,EAAW,SAAS;GAAE,EAAc;GAAG;EAAQ;EAEnD,AADA,EAAW,UAAUP,EAAS,QAAQ,GACjCO,EAAW,WAASE,EAAc;CACzC,CAAC,GAIDC,QAAgBpB,EAAM,UAAU,UAAUmB,CAAa,GAAG,CAACnB,GAAOmB,CAAa,CAAC,GAChFC,QAAgBL,GAAU,OAAOI,CAAa,GAAG,CAACJ,GAAUI,CAAa,CAAC,GAC1EE,EAAqBF,CAAa,GAClCG,EAAmBd,GAAOW,CAAa,GACvCI,EAAyBJ,CAAa,GAGtCC,cAAsB;EAAE,EAAW,UAAU;CAAO,GAAG,CAAC,CAAC,GAGvD,kBAAC,UAAD;EACE,KAAKjB;EACE;EACC;EACG;CACZ,CAAA;AAEL;AAWA,IAAaqB,IAAkB5B"}
|
|
1
|
+
{"version":3,"file":"SceneViewCanvas.js","names":["SceneViewCanvasInner","props","view","normalizeView","scene","localRef","useRef","setCanvasRef","useCallback","el","assignRef","canvasRef","useCanvasSurface","canvas","commands","sceneViewFrame","animator","lease","useEffect","requestRedraw","SurfaceCanvas","SceneViewCanvas"],"sources":["../../src/canvas/SceneViewCanvas.tsx"],"sourcesContent":["/**\n * `<SceneViewCanvas>` — pointer-inert, read-only render of a `Scene` at a\n * given `View` into its own `<canvas>` DOM element.\n *\n * It paints through `useFrameLoop` rather than from React: a render and an\n * override commit both just mark the surface dirty. The mount paint is\n * synchronous, so the first frame the user sees is the scene, and nothing\n * paints while the canvas is off screen or the tab is hidden.\n */\nimport {\n useCallback,\n useEffect,\n useRef,\n useSyncExternalStore,\n} from 'react';\nimport type { Ref } from 'react';\nimport { assignRef } from '@weasel-js/react';\nimport { useCanvasSurface } from './useCanvasSurface';\nimport type { CanvasRendererLease } from './canvasRenderer';\nimport { SurfaceCanvas } from './SurfaceCanvas';\nimport { sceneViewFrame } from './sceneViewRender';\nimport type { RenderSceneToCanvasArgs, SceneViewDrawOne, SceneViewLayers } from './sceneViewRender';\nimport type { DrawCommand } from '@weasel-js/renderer';\nimport { normalizeView, type View } from '../core/viewport/view';\nimport type { Scene } from '../core/scene/types';\nimport type { Animator } from '@weasel-js/animator';\n\n/** Props for `<SceneViewCanvas>`. */\nexport interface SceneViewCanvasProps<TData, TLayer extends string, TPose> {\n /** Scene to render. The component subscribes to it and repaints when it\n * changes. */\n scene: Scene<TData, TLayer, TPose>;\n /** Camera. Applied to scene + `extraCommands` via the renderer's group\n * transform. */\n view: View;\n /** CSS-pixel width. Drives both layout (via the rendered drawing-buffer\n * size) and the renderer's coordinate space. */\n width: number;\n /** CSS-pixel height. */\n height: number;\n /** Per-node draw callback. See `SceneViewDrawOne`. The consumer is\n * responsible for what gets painted — there is no AABB-fill default. */\n drawOne: SceneViewDrawOne<TData, TLayer, TPose>;\n /** Optional extra commands appended after scene commands, inside the same\n * view transform — a world-space annotation over the scene. */\n extraCommands?: ReadonlyArray<DrawCommand>;\n /** Optional per-id alpha multiplier, mirroring `<SceneCanvas>`'s scene-slot\n * `alphaFor`. Pass the same function the main canvas uses to keep a\n * scoping-dim treatment consistent across both. Defaults to `() => 1`. */\n alphaFor?: (id: string) => number;\n /** Hide scene layers in this view only, keyed `scene:<layerId>` as on\n * `<SceneCanvas>` — pass the main canvas's map to keep the two in step. */\n layerVisibility?: SceneViewLayers['layerVisibility'];\n /** Paint order for this view, keyed as `layerVisibility`. */\n layerOrder?: SceneViewLayers['layerOrder'];\n /** Skip nodes and commands that cannot reach this view — the scene slot's\n * `cull`. Off by default; worth it when the view shows a small part of a\n * large scene. */\n cull?: boolean;\n /** Where `drawOne`'s output for a node can reach — the scene slot's\n * `paintBounds`. Defaults to `defaultPaintBounds` when `drawOne` is\n * `defaultDrawOne`. */\n paintBounds?: RenderSceneToCanvasArgs<TData, TLayer, TPose>['paintBounds'];\n /** Optional animator, as on `<SceneCanvas>`: the view repaints on its ticks\n * and paints its `colorOverrides`. Pass the main canvas's animator so both\n * show the same colors. */\n animator?: Animator;\n /** Optional CSS class for the `<canvas>`. Its size is `width` × `height`\n * unless a rule on this class sizes it. */\n className?: string;\n /** Forwarded ref to the underlying `<canvas>`. Consumers attach their own\n * pointer listeners or call `toBlob` for snapshots through this. */\n canvasRef?: Ref<HTMLCanvasElement>;\n}\n\nfunction SceneViewCanvasInner<TData, TLayer extends string, TPose>(\n props: SceneViewCanvasProps<TData, TLayer, TPose>,\n) {\n const {\n scene, width, height, drawOne, extraCommands, alphaFor, layerVisibility, layerOrder,\n animator, className, canvasRef, cull, paintBounds,\n } = props;\n const view = normalizeView(props.view);\n\n // Subscribe to scene version. The snapshot value isn't used directly —\n // we only need React to re-render the component when the scene mutates.\n useSyncExternalStore(scene.subscribe, scene.getVersion, scene.getVersion);\n\n const localRef = useRef<HTMLCanvasElement | null>(null);\n\n const setCanvasRef = useCallback((el: HTMLCanvasElement | null): void => {\n localRef.current = el;\n assignRef(canvasRef, el);\n }, [canvasRef]);\n\n const paint = (lease: CanvasRendererLease): boolean => {\n const canvas = localRef.current;\n if (!canvas) return false;\n const commands = sceneViewFrame({\n scene,\n view,\n width,\n height,\n drawOne,\n extraCommands: extraCommands as DrawCommand[] | undefined,\n alphaFor,\n layerVisibility,\n layerOrder,\n colorOverrides: animator?.colorOverrides,\n cull,\n paintBounds,\n });\n return lease.paint(canvas, commands, view, { width, height });\n };\n const { requestRedraw } = useCanvasSurface(paint, { target: localRef, paintOnCommit: true });\n\n // Override writes never bump the scene version, so the version subscription\n // above cannot see them.\n useEffect(() => scene.overrides.subscribe(requestRedraw), [scene, requestRedraw]);\n useEffect(() => animator?.onTick(requestRedraw), [animator, requestRedraw]);\n\n return (\n <SurfaceCanvas\n ref={setCanvasRef}\n width={width}\n height={height}\n className={className}\n />\n );\n}\n\n/**\n * Pointer-inert read-only scene view. It attaches no event listeners;\n * consumers attach their own through `canvasRef`, a plain prop because\n * `forwardRef` erases the component's generics. `width` and `height` are CSS\n * pixels and size the drawing buffer; a `className` rule that sizes the\n * element stretches that buffer to fit.\n */\nexport const SceneViewCanvas = SceneViewCanvasInner;\n"],"mappings":";;;;;;;;AA2EA,SAASA,EACP,GACA;CACA,IAAM,EACJ,UAAO,UAAO,WAAQ,YAAS,kBAAe,aAAU,oBAAiB,eACzE,aAAU,cAAW,cAAW,SAAM,mBACpCC,GACEC,IAAOC,EAAcF,EAAM,IAAI;CAIrC,EAAqBG,EAAM,WAAWA,EAAM,YAAYA,EAAM,UAAU;CAExE,IAAMC,IAAWC,EAAiC,IAAI,GAEhDC,IAAeC,GAAa,MAAuC;EAEvE,AADA,EAAS,UAAUC,GACnBC,EAAUC,GAAWF,CAAE;CACzB,GAAG,CAACE,CAAS,CAAC,GAqBR,EAAE,qBAAkBC,GAnBX,MAAwC;EACrD,IAAMC,IAASR,EAAS;EACxB,IAAI,CAACQ,GAAQ,OAAO;EACpB,IAAMC,IAAWC,EAAe;GAC9B;GACA;GACA;GACA;GACA;GACe;GACf;GACA;GACA;GACA,gBAAgBC,GAAU;GAC1B;GACA;EACF,CAAC;EACD,OAAOC,EAAM,MAAMJ,GAAQC,GAAUZ,GAAM;GAAE;GAAO;EAAO,CAAC;CAC9D,GACkD;EAAE,QAAQG;EAAU,eAAe;CAAK,CAAC;CAO3F,OAHAa,QAAgBd,EAAM,UAAU,UAAUe,CAAa,GAAG,CAACf,GAAOe,CAAa,CAAC,GAChFD,QAAgBF,GAAU,OAAOG,CAAa,GAAG,CAACH,GAAUG,CAAa,CAAC,GAGxE,kBAACC,GAAD;EACE,KAAKb;EACE;EACC;EACG;CACZ,CAAA;AAEL;AASA,IAAac,IAAkBrB"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { forwardRef as e, useCallback as t } from "react";
|
|
2
|
+
import { assignRef as n } from "@weasel-js/react";
|
|
3
|
+
import { jsx as r } from "react/jsx-runtime";
|
|
4
|
+
//#region src/canvas/SurfaceCanvas.tsx
|
|
5
|
+
var i = ":where([data-wzl-surface]) { width: var(--wzl-surface-width); height: var(--wzl-surface-height); }", a = /* @__PURE__ */ new WeakSet();
|
|
6
|
+
function o(e) {
|
|
7
|
+
let t = e.ownerDocument, n = e.getRootNode(), r = "host" in n ? n : t;
|
|
8
|
+
if (a.has(r)) return;
|
|
9
|
+
a.add(r);
|
|
10
|
+
let o = t.defaultView?.CSSStyleSheet;
|
|
11
|
+
if (o && "replaceSync" in o.prototype && Array.isArray(r.adoptedStyleSheets)) {
|
|
12
|
+
let e = new o();
|
|
13
|
+
e.replaceSync(i), r.adoptedStyleSheets = [...r.adoptedStyleSheets, e];
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
let s = t.createElement("style");
|
|
17
|
+
s.textContent = i, ("host" in r ? r : r.head).appendChild(s);
|
|
18
|
+
}
|
|
19
|
+
var s = e(function({ width: e, height: i, className: a, style: s, tabIndex: c }, l) {
|
|
20
|
+
let u = t((e) => {
|
|
21
|
+
e && o(e), n(l, e);
|
|
22
|
+
}, [l]), d = {
|
|
23
|
+
...s,
|
|
24
|
+
"--wzl-surface-width": `${e}px`,
|
|
25
|
+
"--wzl-surface-height": `${i}px`
|
|
26
|
+
};
|
|
27
|
+
return /* @__PURE__ */ r("canvas", {
|
|
28
|
+
ref: u,
|
|
29
|
+
width: e,
|
|
30
|
+
height: i,
|
|
31
|
+
tabIndex: c,
|
|
32
|
+
className: a,
|
|
33
|
+
style: d,
|
|
34
|
+
"data-wzl-surface": ""
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
//#endregion
|
|
38
|
+
export { i as SURFACE_RULE, s as SurfaceCanvas, o as adoptSurfaceRule };
|
|
39
|
+
|
|
40
|
+
//# sourceMappingURL=SurfaceCanvas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SurfaceCanvas.js","names":["SURFACE_RULE","adopted","adoptSurfaceRule","doc","el","node","root","Sheet","sheet","style","SurfaceCanvas","forwardRef","setRef","useCallback","assignRef","ref","sized","width","height"],"sources":["../../src/canvas/SurfaceCanvas.tsx"],"sourcesContent":["import { forwardRef, useCallback, type CSSProperties } from 'react';\nimport { assignRef } from '@weasel-js/react';\n\n/** Where an element's styles come from. */\ntype StyleRoot = Document | ShadowRoot;\n\n/** The CSS size of a canvas the kit renders: its `width` and `height` props.\n * Zero specificity, so a class the consumer passes resizes the element. */\nexport const SURFACE_RULE =\n ':where([data-wzl-surface]) { width: var(--wzl-surface-width); height: var(--wzl-surface-height); }';\n\nlet adopted = new WeakSet<StyleRoot>();\n\n/**\n * Hold {@link SURFACE_RULE} in the root `el`'s styles come from: its shadow\n * root, else its document. Once per root, and never taken back out.\n */\nexport function adoptSurfaceRule(el: Element): void {\n const doc = el.ownerDocument;\n const node = el.getRootNode();\n const root: StyleRoot = 'host' in node ? (node as ShadowRoot) : doc;\n if (adopted.has(root)) return;\n adopted.add(root);\n const Sheet = doc.defaultView?.CSSStyleSheet;\n if (Sheet && 'replaceSync' in Sheet.prototype && Array.isArray(root.adoptedStyleSheets)) {\n // From the root's own window: a constructed sheet cannot be adopted across documents.\n const sheet = new Sheet();\n sheet.replaceSync(SURFACE_RULE);\n root.adoptedStyleSheets = [...root.adoptedStyleSheets, sheet];\n return;\n }\n const style = doc.createElement('style');\n style.textContent = SURFACE_RULE;\n ('host' in root ? root : root.head).appendChild(style);\n}\n\n/** Test seam: forgets which roots hold the rule. */\nexport function __resetSurfaceRule(): void {\n adopted = new WeakSet();\n}\n\nexport interface SurfaceCanvasProps {\n /** CSS pixels. The renderer sizes only the drawing buffer, so without the\n * rule this element holds it is as large as its buffer: `dpr` times too big. */\n width: number;\n height: number;\n className?: string;\n style?: CSSProperties;\n tabIndex?: number;\n}\n\n/** The `<canvas>` a kit component paints into, `width` × `height` CSS pixels. */\nexport const SurfaceCanvas = forwardRef<HTMLCanvasElement, SurfaceCanvasProps>(\n function SurfaceCanvas({ width, height, className, style, tabIndex }, ref) {\n // Stable while `ref` is, so a commit does not detach the element.\n const setRef = useCallback((el: HTMLCanvasElement | null) => {\n if (el) adoptSurfaceRule(el);\n assignRef(ref, el);\n }, [ref]);\n const sized = { ...style, '--wzl-surface-width': `${width}px`, '--wzl-surface-height': `${height}px` };\n return (\n <canvas\n ref={setRef}\n width={width}\n height={height}\n tabIndex={tabIndex}\n className={className}\n style={sized as CSSProperties}\n data-wzl-surface=\"\"\n />\n );\n },\n);\n"],"mappings":";;;;AAQA,IAAaA,IACX,sGAEEC,oBAAU,IAAI,QAAmB;AAMrC,SAAgBC,EAAiB,GAAmB;CAClD,IAAMC,IAAMC,EAAG,eACTC,IAAOD,EAAG,YAAY,GACtBE,IAAkB,UAAUD,IAAQA,IAAsBF;CAChE,IAAIF,EAAQ,IAAIK,CAAI,GAAG;CACvB,EAAQ,IAAIA,CAAI;CAChB,IAAMC,IAAQJ,EAAI,aAAa;CAC/B,IAAII,KAAS,iBAAiBA,EAAM,aAAa,MAAM,QAAQD,EAAK,kBAAkB,GAAG;EAEvF,IAAME,IAAQ,IAAID,EAAM;EAExB,AADAC,EAAM,YAAYR,CAAY,GAC9B,EAAK,qBAAqB,CAAC,GAAGM,EAAK,oBAAoBE,CAAK;EAC5D;CACF;CACA,IAAMC,IAAQN,EAAI,cAAc,OAAO;CAEvC,AADA,EAAM,cAAcH,IACnB,UAAUM,IAAOA,IAAOA,EAAK,KAAA,CAAM,YAAYG,CAAK;AACvD;AAkBA,IAAaC,IAAgBC,EAC3B,SAAuB,EAAE,UAAO,WAAQ,cAAW,UAAO,eAAY,GAAK;CAEzE,IAAMC,IAASC,GAAa,MAAiC;EAE3D,AADIT,KAAIF,EAAiBE,CAAE,GAC3BU,EAAUC,GAAKX,CAAE;CACnB,GAAG,CAACW,CAAG,CAAC,GACFC,IAAQ;EAAE,GAAGP;EAAO,uBAAuB,GAAGQ,EAAM;EAAK,wBAAwB,GAAGC,EAAO;CAAI;CACrG,OACE,kBAAC,UAAD;EACE,KAAKN;EACE;EACC;EACE;EACC;EACX,OAAOI;EACP,oBAAiB;CAClB,CAAA;AAEL,CACF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createNodeMemoScope as e } from "../core/scene/nodeMemo.js";
|
|
2
|
+
import { resolveDerivedPath as t } from "../core/scene/derivedPath.js";
|
|
3
|
+
//#region src/canvas/adapterDerivedPath.ts
|
|
4
|
+
var n = /* @__PURE__ */ new WeakMap();
|
|
5
|
+
function r(r) {
|
|
6
|
+
let i = n.get(r);
|
|
7
|
+
i === void 0 && (i = e(), n.set(r, i));
|
|
8
|
+
let a = i, o = (e) => typeof r.getWorldPose == "function" ? r.getWorldPose(e) : r.getPose(e), s = (e) => r.getChildren(e), c = (e) => {
|
|
9
|
+
let t = r.getNode(e);
|
|
10
|
+
if (t != null) return {
|
|
11
|
+
node: t,
|
|
12
|
+
pose: o(e),
|
|
13
|
+
get path() {
|
|
14
|
+
return l(e);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
}, l = (e) => {
|
|
18
|
+
let n = r.getNode(e);
|
|
19
|
+
return !n || n.dependsOn === void 0 || n.derivePath === void 0 ? null : t(n, c, s, a);
|
|
20
|
+
};
|
|
21
|
+
return l;
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { r as adapterDerivedPathOf };
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=adapterDerivedPath.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapterDerivedPath.js","names":["scopes","adapterDerivedPathOf","scope","adapter","createNodeMemoScope","slot","poseOf","id","childrenOf","depOf","node","pathOf","resolveDerivedPath"],"sources":["../../src/canvas/adapterDerivedPath.ts"],"sourcesContent":["/**\n * A derived node's path, resolved through an adapter with no scene in scope.\n *\n * A derivation reads its dependencies' nodes and where they are drawn, and\n * every adapter already answers both by id. Nothing pushes an invalidation\n * here, so freshness is the memo's own re-check of what the adapter answers.\n */\nimport type { Path } from '@weasel-js/geom';\nimport { resolveDerivedPath, type PathDerivingNode } from 'core/scene/derivedPath';\nimport { createNodeMemoScope, type NodeMemoScope } from 'core/scene/nodeMemo';\nimport type { DerivedDep, Node, NodeId } from 'core/scene/types';\n\n/** What deriving reads of an adapter. */\nexport interface DerivingAdapter<TPose> {\n getNode(id: string): unknown;\n getPose(id: string): TPose;\n /** Where the node is drawn, when the adapter composes poses. */\n getWorldPose?(id: string): TPose;\n getChildren(parentId: string | null): readonly string[];\n}\n\nconst scopes = new WeakMap<object, NodeMemoScope>();\n\n/**\n * The path the node `id` computes from its dependencies, or `null` when it\n * derives none. Memoized against `adapter`, so every reader of one adapter\n * shares a route.\n */\nexport function adapterDerivedPathOf<TPose>(\n adapter: DerivingAdapter<TPose>,\n): (id: string) => Path | null {\n let scope = scopes.get(adapter);\n if (scope === undefined) {\n scope = createNodeMemoScope();\n scopes.set(adapter, scope);\n }\n const slot = scope;\n const poseOf = (id: string): TPose =>\n (typeof adapter.getWorldPose === 'function' ? adapter.getWorldPose(id) : adapter.getPose(id));\n const childrenOf = (id: NodeId): readonly NodeId[] =>\n adapter.getChildren(id) as readonly NodeId[];\n const depOf = (id: NodeId): DerivedDep<TPose> | undefined => {\n const node = adapter.getNode(id);\n if (node === undefined || node === null) return undefined;\n return {\n node: node as Node<unknown, string, TPose>,\n pose: poseOf(id),\n get path(): Path | null { return pathOf(id); },\n };\n };\n const pathOf = (id: string): Path | null => {\n const node = adapter.getNode(id) as PathDerivingNode<TPose> | undefined | null;\n if (!node || node.dependsOn === undefined || node.derivePath === undefined) return null;\n return resolveDerivedPath(node, depOf, childrenOf, slot);\n };\n return pathOf;\n}\n"],"mappings":";;;AAqBA,IAAMA,oBAAS,IAAI,QAA+B;AAOlD,SAAgBC,EACd,GAC6B;CAC7B,IAAIC,IAAQF,EAAO,IAAIG,CAAO;CAC9B,AAAID,MAAU,KAAA,MACZ,IAAQE,EAAoB,GAC5BJ,EAAO,IAAIG,GAASD,CAAK;CAE3B,IAAMG,IAAOH,GACPI,KAAU,MACb,OAAOH,EAAQ,gBAAiB,aAAaA,EAAQ,aAAaI,CAAE,IAAIJ,EAAQ,QAAQI,CAAE,GACvFC,KAAc,MAClBL,EAAQ,YAAYI,CAAE,GAClBE,KAAS,MAA8C;EAC3D,IAAMC,IAAOP,EAAQ,QAAQI,CAAE;EAC/B,IAAIG,KAA+B,MACnC,OAAO;GACC;GACN,MAAMJ,EAAOC,CAAE;GACf,IAAI,OAAoB;IAAE,OAAOI,EAAOJ,CAAE;GAAG;EAC/C;CACF,GACMI,KAAU,MAA4B;EAC1C,IAAMD,IAAOP,EAAQ,QAAQI,CAAE;EAE/B,OADI,CAACG,KAAQA,EAAK,cAAc,KAAA,KAAaA,EAAK,eAAe,KAAA,IAAkB,OAC5EE,EAAmBF,GAAMD,GAAOD,GAAYH,CAAI;CACzD;CACA,OAAOM;AACT"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { adapterDerivedPathOf as e } from "./adapterDerivedPath.js";
|
|
2
|
+
//#region src/canvas/adapterPickSource.ts
|
|
3
|
+
function t(t, n = {}) {
|
|
4
|
+
let r = /* @__PURE__ */ new Map(), i = (e) => typeof t.getWorldPose == "function" ? t.getWorldPose(e) : t.getPose(e), a = e(t), o = (e) => ({
|
|
5
|
+
...t.getNode(e),
|
|
6
|
+
id: e,
|
|
7
|
+
pose: i(e)
|
|
8
|
+
});
|
|
9
|
+
return {
|
|
10
|
+
order() {
|
|
11
|
+
let e = [], n = /* @__PURE__ */ new Map(), i = (r, a) => {
|
|
12
|
+
for (let s of t.getChildren(r)) {
|
|
13
|
+
let t = o(s);
|
|
14
|
+
a && n.set(s, a), e.push(t), i(s, t);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
return i(null, null), r = n, e;
|
|
18
|
+
},
|
|
19
|
+
...n.alphaOf ? { alphaOf: n.alphaOf } : {},
|
|
20
|
+
...n.layerIsPainted ? { layerIsPainted: n.layerIsPainted } : {},
|
|
21
|
+
...n.planeOf ? { planeOf: n.planeOf } : {},
|
|
22
|
+
poseOf: (e) => i(e.id),
|
|
23
|
+
derivedPathOf: (e) => a(e.id),
|
|
24
|
+
parentsOf(e) {
|
|
25
|
+
let t = [], n = r.get(e.id), i = /* @__PURE__ */ new Set();
|
|
26
|
+
for (; n && !i.has(n.id);) i.add(n.id), t.push(n), n = r.get(n.id);
|
|
27
|
+
return t;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { t as adapterPickSource };
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=adapterPickSource.js.map
|