@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":"sceneAdapter.js","names":["sceneToAdapter","visibleLayers","out","layer","scene","sel","options","getSelection","setSelection","d","AUTO_POSE_DESCRIPTOR","poseBounds","visualBoundsViaDescriptor","p","poseDescriptorForNode","node","translate","translatePoseViaDescriptor","dx","dy","composition","composes","pickOpts","pickOptsFor","view","regionPickOptions","clipboardEnv","adapter","id","frameAtOrAbove","asNodeId","visible","nid","effectivePose","n","definesFrame","composeWorldPose","g","before","after","pose","descIds","collect","cid","rootId","cn","parentId","i","ids","l","declared","label","applyOpsTo","ops","index","pickability","fnFieldsOfNode","layout","hitTestArea","rect","hitTestLassoPolygon","polygon","mode","created","bounds","snapshotSceneSelection","pasteSceneSnapshot","clipboard","offset","ctx","useSceneAdapter","useMemo","selection","commitInsert","insertLayer","layouts","poseDescriptor","cascadeContainerPose","poseComposition"],"sources":["../../src/canvas/sceneAdapter.ts"],"sourcesContent":["/**\n * Synthesize a `<Canvas>`-compatible adapter from a `Scene` primitive.\n *\n * The Scene owns nodes/poses/parenting and auto-records ops on every mutation.\n * `<SceneCanvas>` calls `sceneToAdapter(scene)` and forwards the result to\n * `<Canvas>`'s `adapter` prop. Selection and hit-testing are not part of the\n * Scene model — Canvas's internal `useSelection` and pose-derived pickEvery\n * cover those.\n *\n * Pose semantics match the rest of the kit: `getPose` / `setPose` return /\n * write **local** coordinates (relative to parent). The Scene stores pose on\n * each node directly; world composition (when needed) is the renderer's job\n * via `composeWorldPose`, not the adapter's.\n */\nimport { useMemo } from 'react';\nimport type {\n AreaSelectAdapter,\n ClipboardSnapshot,\n InsertAdapter,\n PasteCtx,\n LassoHitMode,\n LassoSelectAdapter,\n RegionPickView,\n LayerEnumerableAdapter,\n MoveAdapter,\n ResizeAdapter,\n RotateAdapter,\n} from 'core/adapters/types';\nimport type { LayoutStrategy } from '../layout/types';\nimport type { Op } from 'core/ops/types';\nimport type { Node, Scene } from 'core/scene/types';\nimport { definesFrame, effectivePose } from 'core/scene/effectivePose';\nimport { fnFieldsOfNode } from 'core/scene/nodeFnFields';\nimport { pickability } from 'core/scene/pickability';\nimport { asNodeId } from 'core/scene/types';\nimport { applyOpsTo } from 'core/applyOps';\nimport { hitTestArea, hitTestLassoPolygon, regionPickOptions } from 'canvas/deps/hitTestArea';\nimport type { ScenePickSourceOptions } from 'canvas/pickWalk';\nimport {\n poseDescriptorForNode,\n translatePoseViaDescriptor,\n visualBoundsViaDescriptor,\n type PoseDescriptor,\n} from 'interactions/actions/resize/geometry';\nimport { AUTO_POSE_DESCRIPTOR } from 'interactions/actions/resize/autoPoseDescriptor';\nimport { composeWorldPose, frameAtOrAbove, type PoseComposition } from 'features/groups/composePose';\nimport type { Bounds } from '../core/viewport/fitViewToBounds';\nimport { pasteSceneSnapshot, snapshotSceneSelection, type SceneClipboardEnv } from './sceneClipboard';\n\n/** Minimal selection contract `sceneToAdapter` needs to wire `getSelection` /\n * `setSelection`. Matches `useSelection().adapterMethods` plus an imperative\n * read; pass `useSelection()` itself or `selection.adapterMethods`. */\nexport interface SceneAdapterSelection {\n get?(): string[];\n set?(ids: string[]): void;\n getSelection?(): string[];\n setSelection?(ids: string[]): void;\n}\n\n/** Sibling z-order surface used by reorder ops. Inlined here (rather than\n * pulled from `core/ops/reorder` to avoid import cycles); the `null` parent\n * channel addresses the root sibling list. */\n/** @internal */\ninterface ReorderAdapter {\n getChildren(parentId: string | null): string[];\n setChildOrder(parentId: string | null, ids: string[]): void;\n}\n\n/** Everything the interaction layer can ask of a scene, as one type: the\n * move, resize, rotate, selection, layer and reorder contracts combined.\n * `<SceneCanvas>` synthesizes one of these, which is why most consumers never\n * touch an adapter directly. */\nexport type SceneCanvasAdapter<TData, TLayer extends string, TPose> =\n & MoveAdapter<Node<TData, TLayer, TPose>, TPose>\n & ResizeAdapter<Node<TData, TLayer, TPose>, TPose>\n & RotateAdapter<Node<TData, TLayer, TPose>, TPose>\n & AreaSelectAdapter\n & LassoSelectAdapter\n & LayerEnumerableAdapter<TLayer>\n & ReorderAdapter\n & Partial<InsertAdapter<Node<TData, TLayer, TPose>>>\n // Tighten the parts that are optional on the underlying adapter contracts\n // but unconditionally provided by a scene-backed adapter. Anything that\n // routes scene mutations through this adapter (kit InsertOps, hierarchical\n // hooks like useNest, etc.) can rely on these being present.\n & {\n getParent(id: string): string | null;\n /** The node's pose with every ancestor's frame folded in. Equal to\n * `getPose` unless a `poseComposition` is configured. */\n getWorldPose(id: string): TPose;\n /** Whether `id`'s pose is a frame its children are expressed in — see\n * `definesFrame`. */\n definesFrame(id: string): boolean;\n /** Present only when a composing strategy is configured; the render\n * walk feature-detects it. */\n composePose?(parent: TPose, child: TPose): TPose;\n getSelection(): string[];\n setSelection(ids: string[]): void;\n insertNode(node: Node<TData, TLayer, TPose>, index?: number): void;\n removeNode(id: string): void;\n /** Replace a node's `data` — what a `setData` op writes through. */\n setData(id: string, data: TData): void;\n /** Swap a container's layout — what a `setLayout` op writes through. */\n setLayout(id: string, layout: LayoutStrategy<TPose> | string | null): void;\n getRemovalClosure(ids: readonly string[]): string[];\n applyOps(ops: Op[], label?: string): void;\n snapshotSelection(ids: string[]): ClipboardSnapshot;\n commitPaste(\n clipboard: ClipboardSnapshot,\n offset: { dx: number; dy: number },\n ctx?: PasteCtx,\n ): Node<TData, TLayer, TPose>[];\n getPasteOffset(clipboard: ClipboardSnapshot): { dx: number; dy: number };\n };\n\n/** Optional extras for the synthesized adapter. Pass `commitInsert` to wire\n * the insert gesture into a Scene-owned canvas; the returned object becomes\n * a leaf on the layer named by `layer` (default `'default'`). */\nexport interface SceneToAdapterOptions<TData, TLayer extends string, TPose> {\n /** Factory for new objects. Returning `null` aborts the insert. */\n commitInsert?: (bounds: Bounds) => {\n pose: TPose;\n data: TData;\n id?: string;\n } | null;\n /** Layer to place inserted nodes on. Defaults to the trivial-form layer. */\n insertLayer?: TLayer;\n /** Selection source for `AreaSelectAdapter.getSelection` / `setSelection`.\n * Pass the result of `useSelection()` (or its `adapterMethods`). When\n * omitted, `getSelection` returns `[]` and `setSelection` is a noop —\n * fine for read-only or selection-less canvases, but the marquee gesture\n * won't update any external selection state. */\n selection?: SceneAdapterSelection;\n /** How to read and rewrite this scene's poses. Default `AUTO_POSE_DESCRIPTOR`. */\n poseDescriptor?: PoseDescriptor<TPose>;\n /** Layout strategies keyed by container node id, for containers whose\n * scene node declares none (`ContainerNode.layout` wins). `move` runs its\n * layout-aware pass on them; for inserts, deletes and resizes to reach\n * them too, install them with `useLayoutArrivals`. Pass either a static\n * map, or a `getLayout(id)` function for dynamic resolution. */\n layouts?:\n | Record<string, LayoutStrategy<TPose>>\n | ((containerId: string) => LayoutStrategy<TPose> | null);\n /** When true, `setPose` on a container translates every descendant by the\n * same delta, through the pose descriptor. Scene v1 stores absolute poses,\n * so without it children stay behind. */\n cascadeContainerPose?: boolean;\n /** How a child's stored pose folds into its parent's frame. Omit for the\n * absolute-pose model, where a parent contributes no transform. Supplying a\n * composing strategy makes a container's pose a **frame**: rotating the\n * container rotates its contents, and `setPose` on it must not also\n * translate them, so it cannot be combined with `cascadeContainerPose`. */\n poseComposition?: PoseComposition<TPose>;\n}\n\n/** Derive the adapter for a scene. Reads go straight to the scene; writes are\n * ops applied through its history, so anything done through the adapter is\n * undoable. */\nexport function sceneToAdapter<TData, TLayer extends string, TPose>(\n scene: Scene<TData, TLayer, TPose>,\n options: SceneToAdapterOptions<TData, TLayer, TPose> = {},\n): SceneCanvasAdapter<TData, TLayer, TPose> {\n const visibleLayers = (): Set<TLayer> => {\n const out = new Set<TLayer>();\n for (const layer of scene.layers) {\n if (layer.visible) out.add(layer.id);\n }\n return out;\n };\n\n const sel = options.selection;\n const getSelection = sel?.getSelection ?? sel?.get ?? (() => [] as string[]);\n const setSelection = sel?.setSelection ?? sel?.set ?? (() => {});\n const d = (options.poseDescriptor ?? AUTO_POSE_DESCRIPTOR) as PoseDescriptor<TPose>;\n const poseBounds = (p: TPose, node: unknown): Bounds =>\n visualBoundsViaDescriptor(p, poseDescriptorForNode(d, node));\n const translate = (p: TPose, dx: number, dy: number, node?: unknown): TPose =>\n translatePoseViaDescriptor(\n p, dx, dy, node === undefined ? d : poseDescriptorForNode(d, node),\n );\n\n const composition = options.poseComposition;\n const composes = composition !== undefined && composition.closure !== 'identity';\n const pickOpts: ScenePickSourceOptions<unknown> = composition\n ? { poseComposition: composition as PoseComposition<unknown> }\n : {};\n // The asking view's layer gate and camera, over the adapter's own options.\n const pickOptsFor = (view: RegionPickView | undefined): ScenePickSourceOptions<unknown> =>\n (view ? { ...pickOpts, ...regionPickOptions(view, undefined, undefined) } : pickOpts);\n if (composes && options.cascadeContainerPose) {\n throw new Error(\n 'sceneToAdapter: poseComposition and cascadeContainerPose contradict each other. ' +\n 'Under a composing strategy a child\\'s pose is already relative to its parent, so ' +\n 'the cascade would move every descendant twice. Drop cascadeContainerPose.',\n );\n }\n\n const clipboardEnv: SceneClipboardEnv<TData, TLayer, TPose> = {\n scene,\n composes,\n worldPoseOf: (id) => adapter.getWorldPose(id),\n frameAtOrAbove: (id) => frameAtOrAbove(adapter, id),\n poseBounds,\n translate,\n };\n\n const adapter: SceneCanvasAdapter<TData, TLayer, TPose> = {\n getNode(id) {\n return scene.get(asNodeId(id));\n },\n getNodes() {\n const visible = visibleLayers();\n const out: Node<TData, TLayer, TPose>[] = [];\n for (const n of scene.renderOrderNodes()) {\n if (visible.has(n.layer)) out.push(n);\n }\n return out;\n },\n getPose(id) {\n const nid = asNodeId(id);\n const n = scene.get(nid);\n if (!n) throw new Error(`sceneToAdapter: unknown node \"${id}\"`);\n return effectivePose(scene, n);\n },\n getParent(id) {\n const n = scene.get(asNodeId(id));\n return n?.parent ?? null;\n },\n definesFrame(id) {\n const n = scene.get(asNodeId(id));\n return n === undefined || definesFrame(n);\n },\n getWorldPose(id) {\n if (!composes) return adapter.getPose(id);\n return composeWorldPose(adapter, id, composition!.compose);\n },\n // Only present when it would do something: the render walk skips the fold\n // entirely when this is absent, which is the absolute-pose path.\n ...(composes ? { composePose: composition!.compose } : {}),\n setPose(id, pose) {\n // Container cascade (opt-in): under scene v1's absolute-pose semantics,\n // moving a container needs to translate every descendant by the same\n // delta so children visually stay attached. The whole cascade lands as\n // one scene.batch so undo collapses to a single step.\n if (options.cascadeContainerPose) {\n const node = scene.get(asNodeId(id));\n if (node && node.kind === 'container') {\n const g = poseDescriptorForNode(d, node);\n const before = g.getBounds(node.pose);\n const after = g.getBounds(pose);\n const dx = after.x - before.x;\n const dy = after.y - before.y;\n if (dx !== 0 || dy !== 0) {\n const descIds: string[] = [];\n const collect = (rootId: string): void => {\n for (const cid of scene.childrenOf(asNodeId(rootId))) {\n descIds.push(cid);\n collect(cid);\n }\n };\n collect(id);\n scene.batch('move container', () => {\n scene.setPose(asNodeId(id), pose);\n for (const cid of descIds) {\n const cn = scene.get(asNodeId(cid));\n if (!cn) continue;\n scene.setPose(asNodeId(cid), translate(cn.pose, dx, dy, cn));\n }\n });\n return;\n }\n }\n }\n scene.setPose(asNodeId(id), pose);\n },\n setParent(id, parentId) {\n scene.move(asNodeId(id), parentId === null ? null : asNodeId(parentId));\n },\n getChildren(id) {\n // Reorder ops call this with parentId === null to mean \"root siblings.\"\n // The kit's existing callers always pass a string, so this widening is\n // additive — falls through to scene.childrenOf for the typed path and\n // returns scene.roots for the null path.\n if (id === null) return [...scene.roots];\n return [...scene.childrenOf(asNodeId(id))];\n },\n setChildOrder(parentId, ids) {\n // Batched reorder: each scene.reorder call is its own kit:move log\n // entry, but scene.batch wraps them into one undo unit + one notify.\n scene.batch('Reorder', () => {\n for (let i = 0; i < ids.length; i++) {\n // Skip ids that are already in the target slot to avoid useless\n // log entries.\n const current = parentId === null\n ? scene.roots\n : scene.childrenOf(asNodeId(parentId));\n if (current[i] === ids[i]) continue;\n scene.reorder(asNodeId(ids[i]), i);\n }\n });\n },\n getLayers() {\n return scene.layers.map((l) => ({ id: l.id, visible: l.visible, parallax: l.parallax }));\n },\n getLayout(id) {\n const declared = scene.layoutOf(asNodeId(id));\n if (declared !== null || !options.layouts) return declared;\n return typeof options.layouts === 'function'\n ? options.layouts(id)\n : options.layouts[id] ?? null;\n },\n // Unified applyOps: when a label is supplied the ops are wrapped in a\n // batch checkpoint (history-aware path used by Move/Resize/Rotate/Insert/\n // Delete tools). When a journal is active (via scene's getActiveJournal\n // option), scene.applyBatch routes to the journal instead of recording a\n // new parent-history entry. Without a label the ops are applied transiently\n // via applyOpsTo (AreaSelectAdapter contract — no checkpoint).\n applyOps(ops: Op[], label?: string) {\n if (label !== undefined) {\n scene.applyBatch(ops, label, this);\n } else {\n applyOpsTo(this, ops);\n }\n },\n // Node-mutation surface used by kit InsertOps / DeleteOps (e.g.\n // useNest wrapping the selection in a new container node, or its\n // inverse). Re-adds via the full structural spec so the round-trip\n // survives undo/redo; removes by id.\n insertNode(node: Node<TData, TLayer, TPose>, index?: number) {\n scene.add({\n kind: node.kind,\n layer: node.layer,\n pose: node.pose,\n data: node.data,\n id: node.id,\n ...(index !== undefined ? { index } : {}),\n ...(node.parent !== null ? { parent: node.parent } : {}),\n // Derivation travels with the node, or undo of a delete brings an\n // edge back as a static path that never follows its endpoints again.\n ...(node.dependsOn !== undefined ? { dependsOn: node.dependsOn } : {}),\n ...pickability(node),\n ...fnFieldsOfNode(node),\n });\n },\n removeNode(id: string) {\n scene.remove(asNodeId(id));\n },\n setData(id: string, data: TData) {\n scene.update(asNodeId(id), { data });\n },\n setLayout(id: string, layout: LayoutStrategy<TPose> | string | null) {\n scene.setLayout(asNodeId(id), layout);\n },\n getRemovalClosure(ids: readonly string[]): string[] {\n return [...scene.removalClosure(ids.map(asNodeId))];\n },\n // AreaSelectAdapter surface — included unconditionally so plain\n // `useSelectTool(sceneToAdapter(scene, { selection }))` Just Works for the\n // marquee gesture. `applyOps` (above) dispatches transiently when called\n // without a label, matching the AreaSelectAdapter contract.\n getSelection,\n setSelection,\n // The live marquee's and lasso's own hit-tests. Containers come back:\n // this adapter's consumer has nothing to fold children into them.\n hitTestArea(rect: Bounds, view?: RegionPickView) {\n return hitTestArea(\n scene,\n rect,\n pickOptsFor(view),\n d as PoseDescriptor<unknown>,\n { includeContainers: true },\n );\n },\n hitTestLasso(polygon, mode: LassoHitMode, view?: RegionPickView) {\n return hitTestLassoPolygon(\n scene,\n polygon,\n mode,\n pickOptsFor(view),\n d as PoseDescriptor<unknown>,\n { includeContainers: true },\n );\n },\n // commitInsert (gesture-time leaf insert) is opt-in: present only when\n // `options.commitInsert` is. The full insertNode/removeNode mutators\n // above are always present so kit-side InsertOp / DeleteOp round-trip\n // through scene.add / scene.remove regardless.\n //\n // Contract: this is a pure factory — it constructs a Node spec but does\n // NOT touch the scene. `useInsert`'s onEnd dispatches an `InsertOp`\n // whose apply() calls `adapter.insertNode` → `scene.add`, which is the\n // sole insertion path. Calling `scene.add` here too would double-insert,\n // and the second add throws on id collision (silently dropping the\n // gesture's pointer-up cleanup and breaking the next drag).\n ...(options.commitInsert\n ? {\n commitInsert: (bounds: { x: number; y: number; width: number; height: number }) => {\n const created = options.commitInsert!(bounds);\n if (!created) return null;\n const layer = (options.insertLayer ?? ('default' as TLayer));\n const id = created.id === undefined ? scene.mintId() : asNodeId(created.id);\n return {\n kind: 'leaf',\n id,\n layer,\n pose: created.pose,\n data: created.data,\n parent: null,\n } as Node<TData, TLayer, TPose>;\n },\n }\n : {}),\n // Clipboard seam (`useClipboardOps` / the paste ingestion path).\n snapshotSelection(ids: string[]): ClipboardSnapshot {\n return snapshotSceneSelection(clipboardEnv, ids);\n },\n commitPaste(\n clipboard: ClipboardSnapshot,\n offset: { dx: number; dy: number },\n ctx?: PasteCtx,\n ): Node<TData, TLayer, TPose>[] {\n return pasteSceneSnapshot(clipboardEnv, clipboard, offset, ctx);\n },\n // Constant cascade: the hook re-snapshots the just-created items, so\n // repeated pastes stack +12/+12 each time.\n getPasteOffset(): { dx: number; dy: number } {\n return { dx: 12, dy: 12 };\n },\n };\n\n return adapter;\n}\n\n/**\n * React-hook wrapper around `sceneToAdapter`. Memoizes on every option, so\n * the adapter keeps its identity across renders unless one of them changes.\n */\nexport function useSceneAdapter<TData, TLayer extends string, TPose>(\n scene: Scene<TData, TLayer, TPose>,\n options: SceneToAdapterOptions<TData, TLayer, TPose> = {},\n): SceneCanvasAdapter<TData, TLayer, TPose> {\n const {\n selection, commitInsert, insertLayer, layouts, poseDescriptor, cascadeContainerPose, poseComposition,\n } = options;\n return useMemo(\n () => sceneToAdapter(scene, {\n selection, commitInsert, insertLayer, layouts, poseDescriptor, cascadeContainerPose, poseComposition,\n }),\n [scene, selection, commitInsert, insertLayer, layouts, poseDescriptor, cascadeContainerPose, poseComposition],\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sceneAdapter.js","names":["sceneToAdapter","visibleLayers","out","layer","scene","sel","options","getSelection","setSelection","d","AUTO_POSE_DESCRIPTOR","poseBounds","visualBoundsViaDescriptor","p","poseDescriptorForNode","node","translate","translatePoseViaDescriptor","dx","dy","composition","composes","composesFrames","pickOpts","pickOptsFor","view","regionPickOptions","cascade","cascadingSetPose","clipboardEnv","adapter","id","frameAtOrAbove","sceneMutators","visible","nid","asNodeId","effectivePose","n","definesFrame","composeWorldPose","pose","scenePoseTarget","descriptor","carried","containerCascade","l","listener","label","applyOpsTo","ops","hitTestArea","rect","hitTestLassoPolygon","polygon","mode","created","bounds","snapshotSceneSelection","ids","pasteSceneSnapshot","clipboard","offset","ctx"],"sources":["../../src/canvas/sceneAdapter.ts"],"sourcesContent":["/**\n * Synthesize a `<Canvas>`-compatible adapter from a `Scene` primitive.\n * `getPose` / `setPose` return / write **local** coordinates (relative to\n * parent); world composition is the renderer's job via `composeWorldPose`.\n */\nimport type {\n AreaSelectAdapter,\n ClipboardSnapshot,\n InsertAdapter,\n PasteCtx,\n LassoHitMode,\n LassoSelectAdapter,\n RegionPickView,\n LayerEnumerableAdapter,\n MoveAdapter,\n ResizeAdapter,\n RotateAdapter,\n} from 'core/adapters/types';\nimport type { LayoutStrategy } from '../layout/types';\nimport type { Op } from 'core/ops/types';\nimport type { Node, Scene } from 'core/scene/types';\nimport { definesFrame, effectivePose } from 'core/scene/effectivePose';\nimport { sceneMutators } from 'core/scene/sceneMutators';\nimport { asNodeId } from 'core/scene/types';\nimport { applyOpsTo } from 'core/applyOps';\nimport { hitTestArea, hitTestLassoPolygon, regionPickOptions } from 'canvas/deps/hitTestArea';\nimport type { ScenePickSourceOptions } from 'canvas/pickWalk';\nimport {\n poseDescriptorForNode,\n translatePoseViaDescriptor,\n visualBoundsViaDescriptor,\n type PoseDescriptor,\n} from 'interactions/actions/resize/geometry';\nimport { AUTO_POSE_DESCRIPTOR } from 'core/geometry/autoPoseDescriptor';\nimport { composesFrames, composeWorldPose, frameAtOrAbove } from 'core/scene/composePose';\nimport type { Bounds } from '../core/viewport/fitViewToBounds';\nimport { scenePoseTarget } from '../animation/poseTarget';\nimport { cascadingSetPose, containerCascade } from './poseCascade';\nimport { pasteSceneSnapshot, snapshotSceneSelection, type SceneClipboardEnv } from './sceneClipboard';\n\n/** Minimal selection contract `sceneToAdapter` needs to wire `getSelection` /\n * `setSelection`. Matches `useSelection().adapterMethods` plus an imperative\n * read; pass `useSelection()` itself or `selection.adapterMethods`. */\nexport interface SceneAdapterSelection {\n get?(): string[];\n set?(ids: string[]): void;\n getSelection?(): string[];\n setSelection?(ids: string[]): void;\n}\n\n/** Sibling z-order surface used by reorder ops. Inlined here (rather than\n * pulled from `core/ops/reorder` to avoid import cycles); the `null` parent\n * channel addresses the root sibling list. */\n/** @internal */\ninterface ReorderAdapter {\n getChildren(parentId: string | null): string[];\n setChildOrder(parentId: string | null, ids: string[]): void;\n}\n\n/** Everything the interaction layer can ask of a scene, as one type: the\n * move, resize, rotate, selection, layer and reorder contracts combined.\n * `<SceneCanvas>` synthesizes one of these, which is why most consumers never\n * touch an adapter directly. */\nexport type SceneCanvasAdapter<TData, TLayer extends string, TPose> =\n & MoveAdapter<Node<TData, TLayer, TPose>, TPose>\n & ResizeAdapter<Node<TData, TLayer, TPose>, TPose>\n & RotateAdapter<Node<TData, TLayer, TPose>, TPose>\n & AreaSelectAdapter\n & LassoSelectAdapter\n & LayerEnumerableAdapter<TLayer>\n & ReorderAdapter\n & Partial<InsertAdapter<Node<TData, TLayer, TPose>>>\n // Optional on the underlying adapter contracts, but unconditionally\n // provided by a scene-backed adapter.\n & {\n getParent(id: string): string | null;\n getLayers: NonNullable<LayerEnumerableAdapter<TLayer>['getLayers']>;\n /** The node's pose with every ancestor's frame folded in. Equal to\n * `getPose` unless the scene composes poses. */\n getWorldPose(id: string): TPose;\n /** Whether `id`'s pose is a frame its children are expressed in — see\n * `definesFrame`. */\n definesFrame(id: string): boolean;\n /** Present only when a composing strategy is configured; the render\n * walk feature-detects it. */\n composePose?(parent: TPose, child: TPose): TPose;\n getSelection(): string[];\n setSelection(ids: string[]): void;\n insertNode(node: Node<TData, TLayer, TPose>, index?: number): void;\n removeNode(id: string): void;\n /** Replace a node's `data` — what a `setData` op writes through. */\n setData(id: string, data: TData): void;\n /** Swap a container's layout — what a `setLayout` op writes through. */\n setLayout(id: string, layout: LayoutStrategy<TPose> | string | null): void;\n /** Move a node to another layer — what a `setLayer` op writes through. */\n setLayer(id: string, layer: TLayer): void;\n getRemovalClosure(ids: readonly string[]): string[];\n applyOps(ops: Op[], label?: string): void;\n snapshotSelection(ids: string[]): ClipboardSnapshot;\n commitPaste(\n clipboard: ClipboardSnapshot,\n offset: { dx: number; dy: number },\n ctx?: PasteCtx,\n ): Node<TData, TLayer, TPose>[];\n getPasteOffset(clipboard: ClipboardSnapshot): { dx: number; dy: number };\n };\n\n/** Optional extras for the synthesized adapter. Pass `commitInsert` to wire\n * the insert gesture into a Scene-owned canvas; the returned object becomes\n * a leaf on the layer named by `layer` (default `'default'`). */\nexport interface SceneToAdapterOptions<TData, TLayer extends string, TPose> {\n /** Factory for new objects. Returning `null` aborts the insert. */\n commitInsert?: (bounds: Bounds) => {\n pose: TPose;\n data: TData;\n id?: string;\n } | null;\n /** Layer to place inserted nodes on. Defaults to the trivial-form layer. */\n insertLayer?: TLayer;\n /** Selection source: the result of `useSelection()` (or its\n * `adapterMethods`). When omitted, `getSelection` returns `[]` and\n * `setSelection` is a noop, so the marquee gesture updates nothing. */\n selection?: SceneAdapterSelection;\n /** How to read and rewrite this scene's poses. Default `AUTO_POSE_DESCRIPTOR`. */\n poseDescriptor?: PoseDescriptor<TPose>;\n}\n\n/** Derive the adapter for a scene. Reads go straight to the scene; writes are\n * ops applied through its history, so anything done through the adapter is\n * undoable.\n *\n * Moving a container carries its contents either way the scene composes\n * poses. Under a frame (`scene.composition`) the one pose written moves them.\n * Under the absolute-pose model `setPose` on a container translates every\n * descendant by the same delta, and a batch that poses descendants too undoes\n * exactly only when it goes through this adapter's `applyOps`. */\nexport function sceneToAdapter<TData, TLayer extends string, TPose>(\n scene: Scene<TData, TLayer, TPose>,\n options: SceneToAdapterOptions<TData, TLayer, TPose> = {},\n): SceneCanvasAdapter<TData, TLayer, TPose> {\n const visibleLayers = (): Set<TLayer> => {\n const out = new Set<TLayer>();\n for (const layer of scene.layers) {\n if (layer.visible) out.add(layer.id);\n }\n return out;\n };\n\n const sel = options.selection;\n const getSelection = sel?.getSelection ?? sel?.get ?? (() => [] as string[]);\n const setSelection = sel?.setSelection ?? sel?.set ?? (() => {});\n const d = (options.poseDescriptor ?? AUTO_POSE_DESCRIPTOR) as PoseDescriptor<TPose>;\n const poseBounds = (p: TPose, node: unknown): Bounds =>\n visualBoundsViaDescriptor(p, poseDescriptorForNode(d, node));\n const translate = (p: TPose, dx: number, dy: number, node?: unknown): TPose =>\n translatePoseViaDescriptor(\n p, dx, dy, node === undefined ? d : poseDescriptorForNode(d, node),\n );\n\n const composition = scene.composition;\n const composes = composesFrames(composition);\n const pickOpts: ScenePickSourceOptions<unknown> = {};\n // The asking view's layer gate and camera, over the adapter's own options.\n const pickOptsFor = (view: RegionPickView | undefined): ScenePickSourceOptions<unknown> =>\n (view ? { ...pickOpts, ...regionPickOptions(view, undefined) } : pickOpts);\n\n const cascade = composes ? null : { setPose: cascadingSetPose(scene, d) };\n\n const clipboardEnv: SceneClipboardEnv<TData, TLayer, TPose> = {\n scene,\n composes,\n worldPoseOf: (id) => adapter.getWorldPose(id),\n frameAtOrAbove: (id) => frameAtOrAbove(adapter, id),\n poseBounds,\n translate,\n };\n\n const adapter: SceneCanvasAdapter<TData, TLayer, TPose> = {\n ...sceneMutators(scene),\n // What is shown, where the mutators' other users read the document:\n // visible layers only, and the effective pose.\n getNodes() {\n const visible = visibleLayers();\n const out: Node<TData, TLayer, TPose>[] = [];\n for (const n of scene.renderOrderNodes()) {\n if (visible.has(n.layer)) out.push(n);\n }\n return out;\n },\n getPose(id) {\n const nid = asNodeId(id);\n const n = scene.get(nid);\n if (!n) throw new Error(`sceneToAdapter: unknown node \"${id}\"`);\n return effectivePose(scene, n);\n },\n definesFrame(id) {\n const n = scene.get(asNodeId(id));\n return n === undefined || definesFrame(n);\n },\n getWorldPose(id) {\n if (!composes) return adapter.getPose(id);\n return composeWorldPose(adapter, id, composition.compose);\n },\n // Only present when it would do something: the render walk skips the fold\n // entirely when this is absent, which is the absolute-pose path.\n ...(composes ? { composePose: composition.compose } : {}),\n ...(cascade ? { setPose: (id: string, pose: TPose) => cascade.setPose(asNodeId(id), pose) } : {}),\n poseTarget(id, descriptor) {\n if (cascade === null || scene.get(asNodeId(id))?.kind !== 'container') {\n return scenePoseTarget(scene, id, descriptor ?? d);\n }\n // Its descendants hold poses of their own: a commit moves them, and they are shown beside it.\n const carried = containerCascade(scene, asNodeId(id), d, (pose) => adapter.setPose(id, pose));\n return scenePoseTarget(scene, id, descriptor ?? d, carried);\n },\n getLayers: () => scene.layers.map((l) => ({ id: l.id, visible: l.visible, parallax: l.parallax })),\n subscribeLayers: (listener) => scene.subscribe(listener),\n getLayout: (id) => scene.layoutOf(asNodeId(id)),\n // With a label the ops are one batch checkpoint; without one they are\n // applied transiently, with no checkpoint (the AreaSelectAdapter contract).\n applyOps(ops: Op[], label?: string) {\n if (label !== undefined) {\n scene.applyBatch(ops, label, this);\n } else {\n applyOpsTo(this, ops);\n }\n },\n getSelection,\n setSelection,\n // The live marquee's and lasso's own hit-tests. Containers come back:\n // this adapter's consumer has nothing to fold children into them.\n hitTestArea(rect: Bounds, view?: RegionPickView) {\n return hitTestArea(\n scene,\n rect,\n pickOptsFor(view),\n d as PoseDescriptor<unknown>,\n { includeContainers: true },\n );\n },\n hitTestLasso(polygon, mode: LassoHitMode, view?: RegionPickView) {\n return hitTestLassoPolygon(\n scene,\n polygon,\n mode,\n pickOptsFor(view),\n d as PoseDescriptor<unknown>,\n { includeContainers: true },\n );\n },\n // A pure factory: it constructs a Node spec but does NOT touch the scene.\n // The `InsertOp` → `adapter.insertNode` → `scene.add` path is the sole\n // insertion path. Calling `scene.add` here too would double-insert, and\n // the second add throws on id collision.\n ...(options.commitInsert\n ? {\n commitInsert: (bounds: { x: number; y: number; width: number; height: number }) => {\n const created = options.commitInsert!(bounds);\n if (!created) return null;\n const layer = (options.insertLayer ?? ('default' as TLayer));\n const id = created.id === undefined ? scene.mintId() : asNodeId(created.id);\n return {\n kind: 'leaf',\n id,\n layer,\n pose: created.pose,\n data: created.data,\n parent: null,\n } as Node<TData, TLayer, TPose>;\n },\n }\n : {}),\n // Clipboard seam (`useClipboardOps` / the paste ingestion path).\n snapshotSelection(ids: string[]): ClipboardSnapshot {\n return snapshotSceneSelection(clipboardEnv, ids);\n },\n commitPaste(\n clipboard: ClipboardSnapshot,\n offset: { dx: number; dy: number },\n ctx?: PasteCtx,\n ): Node<TData, TLayer, TPose>[] {\n return pasteSceneSnapshot(clipboardEnv, clipboard, offset, ctx);\n },\n // Constant cascade: the hook re-snapshots the just-created items, so\n // repeated pastes stack +12/+12 each time.\n getPasteOffset(): { dx: number; dy: number } {\n return { dx: 12, dy: 12 };\n },\n };\n\n return adapter;\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { definesFrame as e } from "../core/scene/effectivePose.js";
|
|
2
2
|
import { asNodeId as t } from "../core/scene/types.js";
|
|
3
3
|
import { NODE_FN_FIELDS as n, createNodeFnFields as r, fnFieldsOfNode as i, fnKeysOf as a } from "../core/scene/nodeFnFields.js";
|
|
4
|
-
import {
|
|
4
|
+
import { statedFields as o } from "../core/scene/statedFields.js";
|
|
5
5
|
//#region src/canvas/sceneClipboard.ts
|
|
6
6
|
function s(e) {
|
|
7
7
|
return Array.isArray(e) ? [...e] : typeof e == "object" && e ? { ...e } : e;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sceneClipboard.js","names":["copyField","value","dependencyList","item","snapshotSceneSelection","env","fnFields","createNodeFnFields","scene","idSet","ids","taken","items","poseFor","n","isRoot","frame","capture","id","asNodeId","pickability","fnFieldsOfNode","fnKeysOf","cid","a","isLive","member","restoredFnFields","out","registry","spec","NODE_FN_FIELDS","key","fn","omissions","present","src","changed","omission","deps","missing","dep","fns","pasteSceneSnapshot","all","clipboard","omitted","ctx","idMap","byId","ridesPastedFrame","p","definesFrame","dx","offset","dy","minX","minY","b","c"],"sources":["../../src/canvas/sceneClipboard.ts"],"sourcesContent":["/**\n * The scene adapter's clipboard seam: what a copy captures and what a paste\n * mints from it.\n *\n * `snapshotSceneSelection` captures adapter-shaped node copies;\n * `pasteSceneSnapshot` is a pure factory — it mints fresh nodes and never\n * touches the scene. Insertion happens through the caller's InsertOps (one per\n * created node, parents before children), which is what makes a whole paste a\n * single undo entry.\n *\n * A snapshot item carries its node's function fields twice: live, for a paste\n * in the same session, and as the scene's registry keys, for a snapshot that\n * crossed JSON on the way back.\n */\nimport type { ClipboardSnapshot, PasteCtx, PasteOmission } from 'core/adapters/types';\nimport type { Node, NodeId, Scene } from 'core/scene/types';\nimport { asNodeId } from 'core/scene/types';\nimport { definesFrame } from 'core/scene/effectivePose';\nimport {\n NODE_FN_FIELDS, createNodeFnFields, fnFieldsOfNode, fnKeysOf, type FnBearingNode,\n} from 'core/scene/nodeFnFields';\nimport { pickability } from 'core/scene/pickability';\nimport type { Bounds } from '../core/viewport/fitViewToBounds';\n\n/** What the seam needs from the adapter it serves. */\nexport interface SceneClipboardEnv<TData, TLayer extends string, TPose> {\n scene: Scene<TData, TLayer, TPose>;\n /** Whether a stored pose is relative to its container's frame. */\n composes: boolean;\n worldPoseOf(id: string): TPose;\n /** The nearest frame-defining container at or above `id`. */\n frameAtOrAbove(id: string | null): string | null;\n poseBounds(pose: TPose, node: unknown): Bounds;\n translate(pose: TPose, dx: number, dy: number, node?: unknown): TPose;\n}\n\n// Spread-level copy per the clipboard contract: mutating a snapshot's\n// pose/data/children must not touch the scene.\nfunction copyField<T>(value: T): T {\n if (Array.isArray(value)) return [...value] as T;\n if (value !== null && typeof value === 'object') return { ...(value as object) } as T;\n return value;\n}\n\ntype Item<TData, TLayer extends string, TPose> =\n Node<TData, TLayer, TPose> & Record<string, unknown>;\n\nconst dependencyList = (item: { dependsOn?: readonly NodeId[] | 'children' }): readonly NodeId[] =>\n (Array.isArray(item.dependsOn) ? item.dependsOn : []);\n\nexport function snapshotSceneSelection<TData, TLayer extends string, TPose>(\n env: SceneClipboardEnv<TData, TLayer, TPose>,\n ids: string[],\n): ClipboardSnapshot {\n const { scene } = env;\n const fnFields = createNodeFnFields<TPose>(scene.registry as never);\n const idSet = new Set(ids);\n const taken = new Set<string>();\n const items: Node<TData, TLayer, TPose>[] = [];\n // A stored pose is relative to its frame, and a node whose frame is not\n // copied with it lands somewhere else entirely on paste. Capture those in\n // world coordinates: every root, and under an envelope root, the nodes\n // sharing the frame the root left behind.\n const poseFor = (n: Node<TData, TLayer, TPose>, isRoot: boolean): TPose => {\n if (!env.composes) return n.pose;\n if (isRoot) return env.worldPoseOf(n.id);\n const frame = env.frameAtOrAbove(n.parent);\n return frame !== null && taken.has(frame) ? n.pose : env.worldPoseOf(n.id);\n };\n\n // DFS from one snapshot root: push the node, then its subtree —\n // parents-before-children, so paste can re-insert in array order.\n const capture = (id: string, isRoot = false): void => {\n if (taken.has(id)) return;\n const n = scene.get(asNodeId(id));\n if (!n) return;\n taken.add(id);\n items.push({\n kind: n.kind,\n id: n.id,\n layer: n.layer,\n parent: n.parent,\n pose: copyField(poseFor(n, isRoot)),\n data: copyField(n.data),\n ...(n.kind === 'container' ? { children: [...n.children] } : {}),\n ...pickability(n),\n ...(n.dependsOn !== undefined ? { dependsOn: copyField(n.dependsOn) } : {}),\n ...fnFieldsOfNode(n),\n ...fnKeysOf(fnFields, n as unknown as FnBearingNode, 'jsonKey'),\n } as Node<TData, TLayer, TPose>);\n if (n.kind === 'container') {\n for (const cid of scene.childrenOf(asNodeId(id))) capture(cid);\n }\n };\n for (const id of ids) {\n // Dedupe: an id whose ancestor is also selected is already covered\n // by that ancestor's subtree walk.\n if (scene.ancestorsOf(asNodeId(id)).some((a) => idSet.has(a))) continue;\n capture(id, true);\n }\n return { items };\n}\n\n// JSON drops a function, and turns a layout strategy into an object with no\n// methods on it: neither is something a pasted node can run.\nconst isLive = (value: unknown): boolean =>\n typeof value === 'function'\n || (typeof value === 'object' && value !== null\n && Object.values(value).some((member) => typeof member === 'function'));\n\n/**\n * The item's function fields: for each, what its registry key names in this\n * scene, else the live one it carries, else nothing.\n */\nfunction restoredFnFields<TData, TLayer extends string, TPose>(\n scene: Scene<TData, TLayer, TPose>,\n item: Item<TData, TLayer, TPose>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n const registry = scene.registry as Record<string, Record<string, unknown> | undefined>;\n for (const spec of NODE_FN_FIELDS) {\n if (spec.containersOnly && item.kind !== 'container') continue;\n const key = item[spec.jsonKey];\n const registered = typeof key === 'string' ? registry[spec.field]?.[key] : undefined;\n const fn = registered ?? (isLive(item[spec.field]) ? item[spec.field] : undefined);\n if (fn !== undefined) out[spec.field] = fn;\n }\n return out;\n}\n\n/**\n * Which items a paste leaves out, and why. A node deriving from an id list is\n * pasted only with everything it depends on, since a copy still naming the\n * originals would follow them rather than the copies beside it; and only with\n * a derivation to run, since without one it is a placeholder that paints\n * nothing. Leaving one out can strand another, so this runs to a fixed point.\n */\nfunction omissions<TData, TLayer extends string, TPose>(\n src: readonly Item<TData, TLayer, TPose>[],\n fns: ReadonlyMap<string, Record<string, unknown>>,\n): Map<string, PasteOmission> {\n const out = new Map<string, PasteOmission>();\n const present = new Set(src.map((item) => item.id as string));\n for (let changed = true; changed;) {\n changed = false;\n for (const item of src) {\n if (out.has(item.id)) continue;\n let omission: PasteOmission | undefined;\n const deps = dependencyList(item);\n const missing = deps.filter((dep) => !present.has(dep));\n const fn = fns.get(item.id)!;\n if (item.parent !== null && out.has(item.parent)) {\n omission = { id: item.id, reason: 'container-not-pasted' };\n } else if (missing.length > 0) {\n omission = { id: item.id, reason: 'dependency-not-copied', missing };\n } else if (deps.length > 0 && fn.derivePath === undefined && fn.derivePose === undefined) {\n omission = { id: item.id, reason: 'derivation-not-registered' };\n }\n if (omission === undefined) continue;\n out.set(item.id, omission);\n present.delete(item.id);\n changed = true;\n }\n }\n return out;\n}\n\nexport function pasteSceneSnapshot<TData, TLayer extends string, TPose>(\n env: SceneClipboardEnv<TData, TLayer, TPose>,\n clipboard: ClipboardSnapshot,\n offset: { dx: number; dy: number },\n ctx?: PasteCtx,\n): Node<TData, TLayer, TPose>[] {\n // Snapshot items are adapter-shaped node copies: what the snapshot captures,\n // and what this returns (`useClipboardOps` feeds `created` back in as the\n // next cascade source).\n const all = clipboard.items as Item<TData, TLayer, TPose>[];\n if (all.length === 0) return [];\n const fns = new Map(all.map((item) => [item.id as string, restoredFnFields(env.scene, item)]));\n const omitted = omissions(all, fns);\n if (ctx?.onOmit) for (const item of all) {\n const omission = omitted.get(item.id);\n if (omission) ctx.onOmit(omission);\n }\n const src = omitted.size === 0 ? all : all.filter((item) => !omitted.has(item.id));\n\n const idMap = new Map<string, NodeId>();\n for (const item of src) idMap.set(item.id, env.scene.mintId());\n // Items whose captured parent isn't part of the snapshot become roots\n // of the pasted cluster.\n const isRoot = (item: Node<TData, TLayer, TPose>): boolean =>\n item.parent === null || !idMap.has(item.parent);\n // Under a composing strategy a node inside a pasted frame rides it, and\n // offsetting it as well would move it twice.\n const byId = new Map(src.map((item) => [item.id as string, item]));\n const ridesPastedFrame = (item: Node<TData, TLayer, TPose>): boolean => {\n if (!env.composes) return false;\n let p = item.parent === null ? undefined : byId.get(item.parent);\n while (p !== undefined) {\n if (definesFrame(p)) return true;\n p = p.parent === null ? undefined : byId.get(p.parent);\n }\n return false;\n };\n // Without composition poses are absolute, so the delta applies to EVERY\n // pasted node — the cluster translates rigidly, descendants staying\n // attached to their parents.\n let dx = offset.dx;\n let dy = offset.dy;\n if (ctx?.dropPoint) {\n // Drop-point policy: land the cluster origin (min corner of the root\n // items' bounds) on the drop point; `offset` is ignored.\n let minX = Infinity;\n let minY = Infinity;\n for (const item of src) {\n if (!isRoot(item)) continue;\n const b = env.poseBounds(item.pose, item);\n if (b.x < minX) minX = b.x;\n if (b.y < minY) minY = b.y;\n }\n if (Number.isFinite(minX) && Number.isFinite(minY)) {\n dx = ctx.dropPoint.worldX - minX;\n dy = ctx.dropPoint.worldY - minY;\n }\n }\n // `src` is parents-before-children and this keeps it, so children re-attach\n // to freshly inserted parents when the caller's InsertOps apply in order.\n return src.map((item) => ({\n id: idMap.get(item.id)!,\n kind: item.kind,\n layer: item.layer,\n parent: isRoot(item) ? null : idMap.get(item.parent as string)!,\n pose: ridesPastedFrame(item)\n ? copyField(item.pose)\n : env.translate(copyField(item.pose), dx, dy, item),\n data: copyField(item.data),\n ...pickability(item),\n ...(item.kind === 'container'\n ? { children: item.children.filter((c) => idMap.has(c)).map((c) => idMap.get(c)!) }\n : {}),\n ...(item.dependsOn === 'children'\n ? { dependsOn: 'children' as const }\n : dependencyList(item).length > 0\n ? { dependsOn: dependencyList(item).map((dep) => idMap.get(dep)!) }\n : {}),\n ...fns.get(item.id),\n } as Node<TData, TLayer, TPose>));\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sceneClipboard.js","names":["copyField","value","dependencyList","item","snapshotSceneSelection","env","fnFields","createNodeFnFields","scene","idSet","ids","taken","items","poseFor","n","isRoot","frame","capture","id","asNodeId","statedFields","fnFieldsOfNode","fnKeysOf","cid","a","isLive","member","restoredFnFields","out","registry","spec","NODE_FN_FIELDS","key","fn","omissions","present","src","changed","omission","deps","missing","dep","fns","pasteSceneSnapshot","all","clipboard","omitted","ctx","idMap","byId","ridesPastedFrame","p","definesFrame","dx","offset","dy","minX","minY","b","c"],"sources":["../../src/canvas/sceneClipboard.ts"],"sourcesContent":["/**\n * The scene adapter's clipboard seam: what a copy captures and what a paste\n * mints from it.\n *\n * `pasteSceneSnapshot` is a pure factory — it mints fresh nodes and never\n * touches the scene. Insertion happens through the caller's InsertOps (one per\n * created node, parents before children).\n *\n * A snapshot item carries its node's function fields twice: live, for a paste\n * in the same session, and as the scene's registry keys, for a snapshot that\n * crossed JSON on the way back.\n */\nimport type { ClipboardSnapshot, PasteCtx, PasteOmission } from 'core/adapters/types';\nimport type { Node, NodeId, Scene } from 'core/scene/types';\nimport { asNodeId } from 'core/scene/types';\nimport { definesFrame } from 'core/scene/effectivePose';\nimport {\n NODE_FN_FIELDS, createNodeFnFields, fnFieldsOfNode, fnKeysOf, type FnBearingNode,\n} from 'core/scene/nodeFnFields';\nimport { statedFields } from 'core/scene/statedFields';\nimport type { Bounds } from '../core/viewport/fitViewToBounds';\n\n/** What the seam needs from the adapter it serves. */\nexport interface SceneClipboardEnv<TData, TLayer extends string, TPose> {\n scene: Scene<TData, TLayer, TPose>;\n /** Whether a stored pose is relative to its container's frame. */\n composes: boolean;\n worldPoseOf(id: string): TPose;\n /** The nearest frame-defining container at or above `id`. */\n frameAtOrAbove(id: string | null): string | null;\n poseBounds(pose: TPose, node: unknown): Bounds;\n translate(pose: TPose, dx: number, dy: number, node?: unknown): TPose;\n}\n\n// Spread-level copy per the clipboard contract: mutating a snapshot's\n// pose/data/children must not touch the scene.\nfunction copyField<T>(value: T): T {\n if (Array.isArray(value)) return [...value] as T;\n if (value !== null && typeof value === 'object') return { ...(value as object) } as T;\n return value;\n}\n\ntype Item<TData, TLayer extends string, TPose> =\n Node<TData, TLayer, TPose> & Record<string, unknown>;\n\nconst dependencyList = (item: { dependsOn?: readonly NodeId[] | 'children' }): readonly NodeId[] =>\n (Array.isArray(item.dependsOn) ? item.dependsOn : []);\n\nexport function snapshotSceneSelection<TData, TLayer extends string, TPose>(\n env: SceneClipboardEnv<TData, TLayer, TPose>,\n ids: string[],\n): ClipboardSnapshot {\n const { scene } = env;\n const fnFields = createNodeFnFields<TPose>(scene.registry as never);\n const idSet = new Set(ids);\n const taken = new Set<string>();\n const items: Node<TData, TLayer, TPose>[] = [];\n // A stored pose is relative to its frame, and a node whose frame is not\n // copied with it lands somewhere else entirely on paste. Capture those in\n // world coordinates: every root, and under an envelope root, the nodes\n // sharing the frame the root left behind.\n const poseFor = (n: Node<TData, TLayer, TPose>, isRoot: boolean): TPose => {\n if (!env.composes) return n.pose;\n if (isRoot) return env.worldPoseOf(n.id);\n const frame = env.frameAtOrAbove(n.parent);\n return frame !== null && taken.has(frame) ? n.pose : env.worldPoseOf(n.id);\n };\n\n // DFS from one snapshot root: push the node, then its subtree —\n // parents-before-children, so paste can re-insert in array order.\n const capture = (id: string, isRoot = false): void => {\n if (taken.has(id)) return;\n const n = scene.get(asNodeId(id));\n if (!n) return;\n taken.add(id);\n items.push({\n kind: n.kind,\n id: n.id,\n layer: n.layer,\n parent: n.parent,\n pose: copyField(poseFor(n, isRoot)),\n data: copyField(n.data),\n ...(n.kind === 'container' ? { children: [...n.children] } : {}),\n ...statedFields(n),\n ...(n.dependsOn !== undefined ? { dependsOn: copyField(n.dependsOn) } : {}),\n ...fnFieldsOfNode(n),\n ...fnKeysOf(fnFields, n as unknown as FnBearingNode, 'jsonKey'),\n } as Node<TData, TLayer, TPose>);\n if (n.kind === 'container') {\n for (const cid of scene.childrenOf(asNodeId(id))) capture(cid);\n }\n };\n for (const id of ids) {\n // Dedupe: an id whose ancestor is also selected is already covered\n // by that ancestor's subtree walk.\n if (scene.ancestorsOf(asNodeId(id)).some((a) => idSet.has(a))) continue;\n capture(id, true);\n }\n return { items };\n}\n\n// JSON drops a function, and turns a layout strategy into an object with no\n// methods on it: neither is something a pasted node can run.\nconst isLive = (value: unknown): boolean =>\n typeof value === 'function'\n || (typeof value === 'object' && value !== null\n && Object.values(value).some((member) => typeof member === 'function'));\n\n/**\n * The item's function fields: for each, what its registry key names in this\n * scene, else the live one it carries, else nothing.\n */\nfunction restoredFnFields<TData, TLayer extends string, TPose>(\n scene: Scene<TData, TLayer, TPose>,\n item: Item<TData, TLayer, TPose>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n const registry = scene.registry as Record<string, Record<string, unknown> | undefined>;\n for (const spec of NODE_FN_FIELDS) {\n if (spec.containersOnly && item.kind !== 'container') continue;\n const key = item[spec.jsonKey];\n const registered = typeof key === 'string' ? registry[spec.field]?.[key] : undefined;\n const fn = registered ?? (isLive(item[spec.field]) ? item[spec.field] : undefined);\n if (fn !== undefined) out[spec.field] = fn;\n }\n return out;\n}\n\n/**\n * Which items a paste leaves out, and why. A node deriving from an id list is\n * pasted only with everything it depends on, since a copy still naming the\n * originals would follow them rather than the copies beside it; and only with\n * a derivation to run, since without one it is a placeholder that paints\n * nothing. Leaving one out can strand another, so this runs to a fixed point.\n */\nfunction omissions<TData, TLayer extends string, TPose>(\n src: readonly Item<TData, TLayer, TPose>[],\n fns: ReadonlyMap<string, Record<string, unknown>>,\n): Map<string, PasteOmission> {\n const out = new Map<string, PasteOmission>();\n const present = new Set(src.map((item) => item.id as string));\n for (let changed = true; changed;) {\n changed = false;\n for (const item of src) {\n if (out.has(item.id)) continue;\n let omission: PasteOmission | undefined;\n const deps = dependencyList(item);\n const missing = deps.filter((dep) => !present.has(dep));\n const fn = fns.get(item.id)!;\n if (item.parent !== null && out.has(item.parent)) {\n omission = { id: item.id, reason: 'container-not-pasted' };\n } else if (missing.length > 0) {\n omission = { id: item.id, reason: 'dependency-not-copied', missing };\n } else if (deps.length > 0 && fn.derivePath === undefined && fn.derivePose === undefined) {\n omission = { id: item.id, reason: 'derivation-not-registered' };\n }\n if (omission === undefined) continue;\n out.set(item.id, omission);\n present.delete(item.id);\n changed = true;\n }\n }\n return out;\n}\n\nexport function pasteSceneSnapshot<TData, TLayer extends string, TPose>(\n env: SceneClipboardEnv<TData, TLayer, TPose>,\n clipboard: ClipboardSnapshot,\n offset: { dx: number; dy: number },\n ctx?: PasteCtx,\n): Node<TData, TLayer, TPose>[] {\n const all = clipboard.items as Item<TData, TLayer, TPose>[];\n if (all.length === 0) return [];\n const fns = new Map(all.map((item) => [item.id as string, restoredFnFields(env.scene, item)]));\n const omitted = omissions(all, fns);\n if (ctx?.onOmit) for (const item of all) {\n const omission = omitted.get(item.id);\n if (omission) ctx.onOmit(omission);\n }\n const src = omitted.size === 0 ? all : all.filter((item) => !omitted.has(item.id));\n\n const idMap = new Map<string, NodeId>();\n for (const item of src) idMap.set(item.id, env.scene.mintId());\n // Items whose captured parent isn't part of the snapshot become roots\n // of the pasted cluster.\n const isRoot = (item: Node<TData, TLayer, TPose>): boolean =>\n item.parent === null || !idMap.has(item.parent);\n // Under a composing strategy a node inside a pasted frame rides it, and\n // offsetting it as well would move it twice.\n const byId = new Map(src.map((item) => [item.id as string, item]));\n const ridesPastedFrame = (item: Node<TData, TLayer, TPose>): boolean => {\n if (!env.composes) return false;\n let p = item.parent === null ? undefined : byId.get(item.parent);\n while (p !== undefined) {\n if (definesFrame(p)) return true;\n p = p.parent === null ? undefined : byId.get(p.parent);\n }\n return false;\n };\n // Without composition poses are absolute, so the delta applies to EVERY\n // pasted node.\n let dx = offset.dx;\n let dy = offset.dy;\n if (ctx?.dropPoint) {\n // Drop-point policy: land the cluster origin (min corner of the root\n // items' bounds) on the drop point; `offset` is ignored.\n let minX = Infinity;\n let minY = Infinity;\n for (const item of src) {\n if (!isRoot(item)) continue;\n const b = env.poseBounds(item.pose, item);\n if (b.x < minX) minX = b.x;\n if (b.y < minY) minY = b.y;\n }\n if (Number.isFinite(minX) && Number.isFinite(minY)) {\n dx = ctx.dropPoint.worldX - minX;\n dy = ctx.dropPoint.worldY - minY;\n }\n }\n // `src` is parents-before-children and this keeps it, so children re-attach\n // to freshly inserted parents when the caller's InsertOps apply in order.\n return src.map((item) => ({\n id: idMap.get(item.id)!,\n kind: item.kind,\n layer: item.layer,\n parent: isRoot(item) ? null : idMap.get(item.parent as string)!,\n pose: ridesPastedFrame(item)\n ? copyField(item.pose)\n : env.translate(copyField(item.pose), dx, dy, item),\n data: copyField(item.data),\n ...statedFields(item),\n ...(item.kind === 'container'\n ? { children: item.children.filter((c) => idMap.has(c)).map((c) => idMap.get(c)!) }\n : {}),\n ...(item.dependsOn === 'children'\n ? { dependsOn: 'children' as const }\n : dependencyList(item).length > 0\n ? { dependsOn: dependencyList(item).map((dep) => idMap.get(dep)!) }\n : {}),\n ...fns.get(item.id),\n } as Node<TData, TLayer, TPose>));\n}\n"],"mappings":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { paintedLayers as e } from "../core/layers/render.js";
|
|
2
2
|
//#region src/canvas/sceneLayerPaint.ts
|
|
3
3
|
function t(e) {
|
|
4
4
|
return `scene:${e}`;
|
|
5
5
|
}
|
|
6
6
|
function n(t, n) {
|
|
7
|
-
let r = n.layers ? n.layers(t) : t
|
|
8
|
-
return
|
|
7
|
+
let r = n.layers ? n.layers(t) : t;
|
|
8
|
+
return e(r, n.layerVisibility ?? {}, n.layerOrder);
|
|
9
9
|
}
|
|
10
10
|
function r() {
|
|
11
11
|
let e = null;
|
|
@@ -32,6 +32,6 @@ function i(e, n) {
|
|
|
32
32
|
return r === void 0 && i === void 0 ? e : (i ? i.map((n) => e.find((e) => t(e.id) === n)).filter((e) => e !== void 0) : e).filter((e) => r?.[t(e.id)] !== !1);
|
|
33
33
|
}
|
|
34
34
|
//#endregion
|
|
35
|
-
export { r as createSceneLayerGate,
|
|
35
|
+
export { r as createSceneLayerGate, i as paintedSceneLayers, t as sceneLayerKey, n as viewPaintedLayers };
|
|
36
36
|
|
|
37
37
|
//# sourceMappingURL=sceneLayerPaint.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sceneLayerPaint.js","names":["sceneLayerKey","layerId","
|
|
1
|
+
{"version":3,"file":"sceneLayerPaint.js","names":["sceneLayerKey","layerId","viewPaintedLayers","narrowed","view","surface","paintedLayers","createSceneLayerGate","last","inputs","v","i","byId","l","drawn","gate","carrier","paintedSceneLayers","layerVisibility","layerOrder","layers","key"],"sources":["../../src/canvas/sceneLayerPaint.ts"],"sourcesContent":["/**\n * Which scene layers a view paints.\n *\n * A view's `layerVisibility` / `layerOrder` name render layers, and `<Canvas>`\n * paints a scene as one render layer per scene layer, keyed `scene:<layerId>`.\n * Picking, marquee and select-all ask about scene layers, so this is where one\n * namespace is read in terms of the other.\n */\nimport { paintedLayers, type RenderLayer } from 'core/layers/render';\n\n/** The render-layer id a scene layer paints under. */\nexport function sceneLayerKey(layerId: string): string {\n return `scene:${layerId}`;\n}\n\n/** Per-view layer settings, in `<Canvas>`'s vocabulary. */\nexport interface ViewLayerPaint {\n /** Narrows the surface's stack before the other two apply. */\n layers?: (surface: readonly RenderLayer<unknown>[]) => readonly RenderLayer<unknown>[];\n layerVisibility?: Record<string, boolean>;\n layerOrder?: readonly string[];\n}\n\n/** The layers a view draws, in the order it draws them: what `drawLayers`\n * would paint of whatever `layers` narrowed to. */\nexport function viewPaintedLayers(\n surface: readonly RenderLayer<unknown>[],\n view: ViewLayerPaint,\n): readonly RenderLayer<unknown>[] {\n const narrowed = view.layers ? view.layers(surface) : surface;\n return paintedLayers(narrowed, view.layerVisibility ?? {}, view.layerOrder);\n}\n\n/**\n * A gate answering \"does this scene layer reach the screen in this view\",\n * rebuilt only when the surface's stack or the view's settings change — it is\n * asked once per pick candidate.\n *\n * A scene layer is painted when the render layer carrying it is: its own\n * `scene:<id>`, or the bundled `scene` layer an adapter without layers gets.\n * A surface carrying neither paints the scene some other way, which is not\n * this gate's to judge, so it passes.\n */\nexport function createSceneLayerGate(): (\n surface: readonly RenderLayer<unknown>[],\n view: ViewLayerPaint,\n) => (layerId: string) => boolean {\n let last: { inputs: readonly unknown[]; gate: (layerId: string) => boolean } | null = null;\n return (surface, view) => {\n const inputs = [surface, view.layers, view.layerVisibility, view.layerOrder];\n if (last && last.inputs.every((v, i) => v === inputs[i])) return last.gate;\n const byId = new Map(surface.map((l) => [l.id, l]));\n const drawn = new Set(viewPaintedLayers(surface, view));\n const gate = (layerId: string): boolean => {\n const carrier = byId.get(sceneLayerKey(layerId)) ?? byId.get('scene');\n return carrier === undefined || drawn.has(carrier);\n };\n last = { inputs, gate };\n return gate;\n };\n}\n\n/** Scene layers in the order a view paints them, for a view that walks the\n * scene itself rather than a render-layer stack. Keyed as `<SceneCanvas>`\n * keys them, so one map serves both. */\nexport function paintedSceneLayers<T extends { id: string }>(\n layers: readonly T[],\n view: Pick<ViewLayerPaint, 'layerVisibility' | 'layerOrder'>,\n): readonly T[] {\n const { layerVisibility, layerOrder } = view;\n if (layerVisibility === undefined && layerOrder === undefined) return layers;\n const sequence = layerOrder\n ? layerOrder\n .map((key) => layers.find((l) => sceneLayerKey(l.id) === key))\n .filter((l): l is T => l !== undefined)\n : layers;\n return sequence.filter((l) => layerVisibility?.[sceneLayerKey(l.id)] !== false);\n}\n"],"mappings":";;AAWA,SAAgBA,EAAc,GAAyB;CACrD,OAAO,SAASC;AAClB;AAYA,SAAgBC,EACd,GACA,GACiC;CACjC,IAAMC,IAAWC,EAAK,SAASA,EAAK,OAAOC,CAAO,IAAIA;CACtD,OAAOC,EAAcH,GAAUC,EAAK,mBAAmB,CAAC,GAAGA,EAAK,UAAU;AAC5E;AAYA,SAAgBG,IAGkB;CAChC,IAAIC,IAAkF;CACtF,QAAQ,GAAS,MAAS;EACxB,IAAMC,IAAS;GAACJ;GAASD,EAAK;GAAQA,EAAK;GAAiBA,EAAK;EAAU;EAC3E,IAAII,KAAQA,EAAK,OAAO,OAAO,GAAG,MAAME,MAAMD,EAAOE,EAAE,GAAG,OAAOH,EAAK;EACtE,IAAMI,IAAO,IAAI,IAAIP,EAAQ,KAAK,MAAM,CAACQ,EAAE,IAAIA,CAAC,CAAC,CAAC,GAC5CC,IAAQ,IAAI,IAAIZ,EAAkBG,GAASD,CAAI,CAAC,GAChDW,KAAQ,MAA6B;GACzC,IAAMC,IAAUJ,EAAK,IAAIZ,EAAcC,CAAO,CAAC,KAAKW,EAAK,IAAI,OAAO;GACpE,OAAOI,MAAY,KAAA,KAAaF,EAAM,IAAIE,CAAO;EACnD;EAEA,OADA,IAAO;GAAE;GAAQ;EAAK,GACfD;CACT;AACF;AAKA,SAAgBE,EACd,GACA,GACc;CACd,IAAM,EAAE,oBAAiB,kBAAeb;CAOxC,OANIc,MAAoB,KAAA,KAAaC,MAAe,KAAA,IAAkBC,KACrDD,IACbA,EACC,KAAK,MAAQC,EAAO,MAAM,MAAMpB,EAAca,EAAE,EAAE,MAAMQ,CAAG,CAAC,CAAC,CAC7D,QAAQ,MAAcR,MAAM,KAAA,CAAS,IACtCO,EAAA,CACY,QAAQ,MAAMF,IAAkBlB,EAAca,EAAE,EAAE,OAAO,EAAK;AAChF"}
|
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import { sceneDerivedPathOf as e,
|
|
2
|
-
import { withColorOverrides as
|
|
1
|
+
import { sceneDerivedPathOf as e, sceneShownToPose as t, withDerivedPaths as n } from "./derivedPath.js";
|
|
2
|
+
import { withColorOverrides as r } from "./colorOverrides.js";
|
|
3
3
|
//#region src/canvas/sceneSlotWiring.ts
|
|
4
|
-
function
|
|
4
|
+
function i(e, t) {
|
|
5
5
|
let n = (t) => e.overrides.read(t)?.alpha ?? 1;
|
|
6
6
|
return t ? (e) => t(e) * n(e) : n;
|
|
7
7
|
}
|
|
8
|
-
function
|
|
9
|
-
let l =
|
|
8
|
+
function a(a, o, s, c) {
|
|
9
|
+
let l = n(o, a.drawOne, a.toPose), u = e(o, a.toPose);
|
|
10
10
|
return {
|
|
11
|
-
...
|
|
12
|
-
|
|
11
|
+
...a,
|
|
12
|
+
...a.toPose ? { toPose: t(o, a.toPose) } : {},
|
|
13
|
+
drawOne: c ? r(c, l) : l,
|
|
13
14
|
derivedPathOf: u,
|
|
14
|
-
alphaFor:
|
|
15
|
+
alphaFor: i(o, s)
|
|
15
16
|
};
|
|
16
17
|
}
|
|
17
18
|
//#endregion
|
|
18
|
-
export {
|
|
19
|
+
export { i as composeAlphaFor, a as wireSceneSlotToScene };
|
|
19
20
|
|
|
20
21
|
//# sourceMappingURL=sceneSlotWiring.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sceneSlotWiring.js","names":["composeAlphaFor","overrideAlphaFor","scene","id","alphaFor","wireSceneSlotToScene","derived","withDerivedPaths","slot","
|
|
1
|
+
{"version":3,"file":"sceneSlotWiring.js","names":["composeAlphaFor","overrideAlphaFor","scene","id","alphaFor","wireSceneSlotToScene","derived","withDerivedPaths","slot","derivedPathOf","sceneDerivedPathOf","sceneShownToPose","colorOverrides","withColorOverrides"],"sources":["../../src/canvas/sceneSlotWiring.ts"],"sourcesContent":["/**\n * What the scene slot needs from the `Scene` that `<Canvas>` cannot see.\n *\n * `<Canvas>` is scene-agnostic: it walks an adapter. Three things a node is\n * painted with are therefore invisible to it — an ephemeral override's alpha, a\n * derived path, which needs other nodes' poses to resolve, and animated vertex\n * colors, which live in an animator. `<SceneCanvas>` folds them into the slot\n * here; `buildSceneViewCommands` does the same for the headless walk.\n */\nimport type { SceneSlotConfig } from './buildSceneLayer';\nimport type { Node, NodeId, Scene } from 'core/scene/types';\nimport { withDerivedPaths, sceneDerivedPathOf, sceneShownToPose } from './derivedPath';\nimport { withColorOverrides } from './colorOverrides';\nimport type { ColorOverrideRegistry } from '@weasel-js/animator';\n\n/**\n * The alpha a view paints a node at: the view's own `alphaFor` times any\n * ephemeral override alpha.\n *\n * The hit path asks this too — a node painted at alpha 0 is not on screen and\n * must not claim clicks — so it is one function rather than the painter's and\n * picking's separate readings of the same two inputs.\n */\nexport function composeAlphaFor<TData, TLayer extends string, TPose>(\n scene: Scene<TData, TLayer, TPose>,\n alphaFor?: (id: string) => number,\n): (id: string) => number {\n const overrideAlphaFor = (id: string) => scene.overrides.read(id as NodeId)?.alpha ?? 1;\n return alphaFor ? (id: string) => alphaFor(id) * overrideAlphaFor(id) : overrideAlphaFor;\n}\n\nexport function wireSceneSlotToScene<TData, TLayer extends string, TPose>(\n slot: SceneSlotConfig<Node<TData, TLayer, TPose>, TPose>,\n scene: Scene<TData, TLayer, TPose>,\n alphaFor?: (id: string) => number,\n colorOverrides?: ColorOverrideRegistry,\n): SceneSlotConfig<Node<TData, TLayer, TPose>, TPose> {\n const derived = withDerivedPaths(scene, slot.drawOne, slot.toPose);\n const derivedPathOf = sceneDerivedPathOf(scene, slot.toPose);\n return {\n ...slot,\n ...(slot.toPose ? { toPose: sceneShownToPose(scene, slot.toPose) } : {}),\n drawOne: colorOverrides ? withColorOverrides(colorOverrides, derived) : derived,\n derivedPathOf,\n alphaFor: composeAlphaFor(scene, alphaFor),\n };\n}\n"],"mappings":";;;AAuBA,SAAgBA,EACd,GACA,GACwB;CACxB,IAAMC,KAAoB,MAAeC,EAAM,UAAU,KAAKC,CAAY,CAAC,EAAE,SAAS;CACtF,OAAOC,KAAY,MAAeA,EAASD,CAAE,IAAIF,EAAiBE,CAAE,IAAIF;AAC1E;AAEA,SAAgBI,EACd,GACA,GACA,GACA,GACoD;CACpD,IAAMC,IAAUC,EAAiBL,GAAOM,EAAK,SAASA,EAAK,MAAM,GAC3DC,IAAgBC,EAAmBR,GAAOM,EAAK,MAAM;CAC3D,OAAO;EACL,GAAGA;EACH,GAAIA,EAAK,SAAS,EAAE,QAAQG,EAAiBT,GAAOM,EAAK,MAAM,EAAE,IAAI,CAAC;EACtE,SAASI,IAAiBC,EAAmBD,GAAgBN,CAAO,IAAIA;EACxE;EACA,UAAUN,EAAgBE,GAAOE,CAAQ;CAC3C;AACF"}
|
|
@@ -1,66 +1,61 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
1
|
+
import { paintedSceneLayers as e } from "./sceneLayerPaint.js";
|
|
2
|
+
import { paintCanvas as t } from "./canvasRenderer.js";
|
|
3
|
+
import { wrapNodeOutput as n } from "./wrapNodeOutput.js";
|
|
4
|
+
import { sceneDerivedPathOf as r, withDerivedPaths as i } from "./derivedPath.js";
|
|
5
|
+
import { buildSceneTree as a } from "./buildSceneTree.js";
|
|
6
|
+
import { sceneToAdapter as o } from "./sceneAdapter.js";
|
|
7
|
+
import { withColorOverrides as s } from "./colorOverrides.js";
|
|
8
|
+
import { paintMissesView as c } from "./paintCull.js";
|
|
9
|
+
import { paintBoundsFor as l } from "./defaultDrawOne.js";
|
|
10
|
+
import { cullDrawCommands as u } from "@weasel-js/renderer";
|
|
11
|
+
import { viewToMat3 as d } from "@weasel-js/geom";
|
|
12
12
|
//#region src/canvas/sceneViewRender.ts
|
|
13
|
-
function f(
|
|
13
|
+
function f(t, n = {}) {
|
|
14
|
+
let { getNode: r, getChildren: i, getPose: a, composePose: s } = o(t);
|
|
14
15
|
return {
|
|
15
|
-
getLayers: () =>
|
|
16
|
+
getLayers: () => e(t.layers, n).map((e) => ({
|
|
16
17
|
id: e.id,
|
|
17
18
|
visible: e.visible,
|
|
18
19
|
parallax: e.parallax
|
|
19
20
|
})),
|
|
20
|
-
getNode:
|
|
21
|
-
getChildren:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return n && n.kind === "container" ? n.children : [];
|
|
25
|
-
},
|
|
26
|
-
getPose: (t) => n(e, e.get(t))
|
|
21
|
+
getNode: r,
|
|
22
|
+
getChildren: i,
|
|
23
|
+
getPose: a,
|
|
24
|
+
...s ? { composePose: s } : {}
|
|
27
25
|
};
|
|
28
26
|
}
|
|
29
|
-
function p(
|
|
30
|
-
let
|
|
31
|
-
let
|
|
32
|
-
return
|
|
33
|
-
},
|
|
34
|
-
...f(n, h),
|
|
35
|
-
composePose: m.compose
|
|
36
|
-
} : f(n, h), C = _ ? {
|
|
27
|
+
function p(e, t, o, l, p, m, h, g) {
|
|
28
|
+
let _ = i(e, o), v = h ? s(h, _) : _, y = r(e), b = (t, r, i) => {
|
|
29
|
+
let a = e.overrides.read(t.id)?.alpha ?? 1;
|
|
30
|
+
return n(v(t, r, i), r, (p ? p(t.id) : 1) * a);
|
|
31
|
+
}, x = f(e, m), S = g ? {
|
|
37
32
|
x: 0,
|
|
38
33
|
y: 0,
|
|
39
|
-
width:
|
|
40
|
-
height:
|
|
41
|
-
} : void 0,
|
|
42
|
-
if (
|
|
34
|
+
width: g.width,
|
|
35
|
+
height: g.height
|
|
36
|
+
} : void 0, C = S && g?.paintBounds ? c(g.paintBounds, t, S) : void 0, w = a(x, b, t, void 0, y, C), T = S ? u(w, d(t), S) : w;
|
|
37
|
+
if (l && l.length > 0) for (let e of l) T.push(e);
|
|
43
38
|
return [{
|
|
44
39
|
kind: "group",
|
|
45
|
-
transform:
|
|
46
|
-
children:
|
|
40
|
+
transform: d(t),
|
|
41
|
+
children: T
|
|
47
42
|
}];
|
|
48
43
|
}
|
|
49
44
|
function m(e) {
|
|
50
|
-
let { scene: t, view: n, width: r, height: i, drawOne: a, extraCommands: o, alphaFor: s, layerVisibility: c, layerOrder:
|
|
51
|
-
return p(t, n, a, o, s,
|
|
45
|
+
let { scene: t, view: n, width: r, height: i, drawOne: a, extraCommands: o, alphaFor: s, layerVisibility: c, layerOrder: u, colorOverrides: d, cull: f } = e;
|
|
46
|
+
return p(t, n, a, o, s, {
|
|
52
47
|
layerVisibility: c,
|
|
53
|
-
layerOrder:
|
|
54
|
-
},
|
|
48
|
+
layerOrder: u
|
|
49
|
+
}, d, f ? {
|
|
55
50
|
width: r,
|
|
56
51
|
height: i,
|
|
57
|
-
paintBounds: e.paintBounds ??
|
|
52
|
+
paintBounds: e.paintBounds ?? l(a)
|
|
58
53
|
} : void 0);
|
|
59
54
|
}
|
|
60
55
|
function h(e) {
|
|
61
|
-
let { canvas:
|
|
62
|
-
|
|
63
|
-
width:
|
|
56
|
+
let { canvas: n, view: r, width: i, height: a, dpr: o } = e;
|
|
57
|
+
t(n, m(e), r, {
|
|
58
|
+
width: i,
|
|
64
59
|
height: a,
|
|
65
60
|
dpr: o
|
|
66
61
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sceneViewRender.js","names":["sceneAsHierarchy","paintedSceneLayers","scene","layers","l","id","parentId","node","effectivePose","buildSceneViewCommands","derivedOnly","withDerivedPaths","drawOne","poseComposition","derived","colorOverrides","withColorOverrides","derivedPathOf","sceneDerivedPathOf","wrappedDrawOne","overrideAlpha","wrapNodeOutput","pose","v","alphaFor","hierarchy","cullRect","cull","culled","paintMissesView","view","tree","buildSceneTree","children","cullDrawCommands","viewToMat3","extraCommands","cmd","sceneViewFrame","args","paintBoundsFor","renderSceneToCanvas","canvas"],"sources":["../../src/canvas/sceneViewRender.ts"],"sourcesContent":["/**\n * `renderSceneToCanvas` — substrate for detached, read-only scene views\n * (`<SceneViewCanvas>` / `<MinimapCanvas>`). Given a `<canvas>`, a `Scene`,\n * a `View`, and a per-node `drawOne`, render one frame.\n *\n * The full `<SceneCanvas>` render pipeline does much more than this (slots, layer\n * ordering, debug sinks, tool overlays). The helper deliberately re-implements\n * the small subset needed for a non-interactive scene view rather than\n * refactoring `<SceneCanvas>` to share code — the spec calls for that\n * dedupe as a follow-up.\n *\n * Note: this duplicates `<SceneCanvas>`'s GL setup + view-wrap pattern in\n * miniature. When `<SceneCanvas>` is eventually migrated onto this helper,\n * the duplication collapses; until then, keep the two render paths\n * in sync by hand where it matters (DPR handling, viewToMat3 wrap).\n */\n\nimport type { WeaselRenderer } from '../renderer/WeaselRenderer';\nimport { cachedCanvasRenderer, paintCanvas } from './canvasRenderer';\nimport type { PoseComposition } from 'features/groups/composePose';\nimport { viewToMat3 } from '../renderer/math/viewToMat3';\nimport type { DrawCommand } from '../renderer/DrawCommand';\nimport type { View } from '../core/viewport/view';\nimport type { Node, NodeId, Scene } from '../core/scene/types';\nimport { wrapNodeOutput } from './wrapNodeOutput';\nimport { buildSceneTree, type HierarchicalAdapter } from './buildSceneTree';\nimport { effectivePose } from 'core/scene/effectivePose';\nimport { withDerivedPaths, sceneDerivedPathOf } from './derivedPath';\nimport { withColorOverrides } from './colorOverrides';\nimport type { ColorOverrideRegistry } from '../animation/colorRegistry';\nimport type { SceneViewDrawOne } from './NodeShape';\nimport { paintedSceneLayers } from './sceneLayerPaint';\nimport { cullDrawCommands } from '../renderer/cullDrawCommands';\nimport { paintMissesView, type PaintBoundsFn } from './paintCull';\nimport { paintBoundsFor } from './defaultDrawOne';\n\nexport type { SceneViewDrawOne } from './NodeShape';\n\n/**\n * Which scene layers a detached view paints, on top of each layer's own\n * `visible` flag. Keyed the way `<SceneCanvas>` keys its scene layers —\n * `scene:<layerId>` — so the map a main canvas takes serves its minimap too.\n */\nexport interface SceneViewLayers {\n /** `false` hides that layer in this view. It cannot show one the scene hides. */\n layerVisibility?: Record<string, boolean>;\n /** Paint order, bottom first. A listed order is the whole list: a scene\n * layer left out of it is not painted. */\n layerOrder?: readonly string[];\n}\n\n/** The view size `buildSceneViewCommands` culls to, and how it bounds a\n * node's paint before painting it. */\nexport interface SceneViewCull<TData, TLayer extends string, TPose> {\n width: number;\n height: number;\n paintBounds?: PaintBoundsFn<Node<TData, TLayer, TPose>, TPose>;\n}\n\n/** What to draw into an existing canvas: the scene, the view, and the same\n * painting hooks `<SceneCanvas>` takes. */\nexport interface RenderSceneToCanvasArgs<TData, TLayer extends string, TPose> {\n /** The DOM canvas to paint into. The helper owns its WebGL2 context: the\n * first call on a given canvas creates a renderer and stashes it; subsequent\n * calls reuse the same renderer (and resize the drawing buffer on dim\n * changes). `releaseCanvasRenderer(canvas)` frees it. */\n canvas: HTMLCanvasElement;\n /** Scene to walk. `scene.renderOrder()` provides the per-node order. */\n scene: Scene<TData, TLayer, TPose>;\n /** Camera view applied to scene + extras (both ride the same world→screen\n * transform; extras living in screen space should be supplied via a\n * separately-prepared `extraCommands` group or rendered outside this\n * helper). */\n view: View;\n /** CSS-pixel size. The drawing buffer is set to `width × dpr` and\n * `height × dpr`; CSS size to `width` / `height`. */\n width: number;\n height: number;\n /** Per-node draw callback. */\n drawOne: SceneViewDrawOne<TData, TLayer, TPose>;\n /** Optional commands appended after the scene-node output. Used for the\n * minimap's visible-window indicator. Wrapped in the same view transform\n * as scene commands. */\n extraCommands?: 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 /** Per-view layer visibility. See {@link SceneViewLayers}. */\n layerVisibility?: SceneViewLayers['layerVisibility'];\n /** Per-view layer order. See {@link SceneViewLayers}. */\n layerOrder?: SceneViewLayers['layerOrder'];\n /** Animated vertex colors to paint, typically an animator's\n * `colorOverrides` — see `NodePaintCtx.vertexColors`. */\n colorOverrides?: ColorOverrideRegistry;\n /** Skip what cannot reach the `width × height` view: nodes `paintBounds`\n * places outside it are not painted, and scene commands that cannot reach\n * it are dropped before the renderer — the scene slot's `cull`. Off by\n * default. `extraCommands` are never culled. */\n cull?: boolean;\n /** Where `drawOne`'s output for a node can reach, as on the scene slot.\n * Defaults to `defaultPaintBounds` when `drawOne` is `defaultDrawOne`. */\n paintBounds?: PaintBoundsFn<Node<TData, TLayer, TPose>, TPose>;\n /** Optional device-pixel ratio. Defaults to `window.devicePixelRatio || 1`\n * when available, otherwise 1. Tests typically pin this to 1 or 2. */\n dpr?: number;\n}\n\n/** Test seam: the renderer `renderSceneToCanvas` created for a canvas. Not\n * re-exported from the barrel. */\nexport function __getCachedRendererForTest(\n canvas: HTMLCanvasElement,\n): WeaselRenderer | undefined {\n return cachedCanvasRenderer(canvas);\n}\n\n/**\n * Present a `Scene` as the reading surface `buildSceneTree` walks. Built\n * inline rather than via `sceneToAdapter` so this module stays free of React\n * — `renderSceneToPixels` runs headless.\n */\nfunction sceneAsHierarchy<TData, TLayer extends string, TPose>(\n scene: Scene<TData, TLayer, TPose>,\n layers: SceneViewLayers = {},\n): HierarchicalAdapter<Node<TData, TLayer, TPose>, TPose> {\n return {\n getLayers: () =>\n paintedSceneLayers(scene.layers, layers)\n .map((l) => ({ id: l.id, visible: l.visible, parallax: l.parallax })),\n getNode: (id) => scene.get(id as NodeId),\n getChildren: (parentId) => {\n if (parentId === null) return scene.roots as readonly string[];\n const node = scene.get(parentId as NodeId);\n return node && node.kind === 'container' ? (node.children as readonly string[]) : [];\n },\n getPose: (id) => effectivePose(scene, scene.get(id as NodeId)!),\n } as HierarchicalAdapter<Node<TData, TLayer, TPose>, TPose>;\n}\n\n/**\n * Build the DrawCommand list that `renderSceneToCanvas` would dispatch.\n *\n * Pure — no GL, no DOM, no side effects. Walks the scene through\n * `buildSceneTree` — the same walk `<SceneCanvas>`'s `buildSceneLayer` uses —\n * appends any `extraCommands`, and wraps the result in a single\n * `{ kind: 'group', transform: viewToMat3(view) }` so the output is in screen\n * space. Sharing the walk is what keeps hidden layers unpainted and container\n * clips applied here; a hand-rolled `renderOrder()` loop silently dropped both.\n *\n * Each node's commands additionally go through `wrapNodeOutput` — pose\n * rotation, then the `alphaFor` multiplier — exactly as `buildSceneLayer`\n * does, so a `drawOne` shared between the two paints the same thing in both.\n * A `drawOne` that rotates its own output will therefore rotate twice here;\n * emit unrotated geometry and let the pose drive it.\n *\n * Output shape follows `buildSceneTree`: one group per **visible** layer, in\n * scene-layer order (or `layers.layerOrder`), each holding one group per node\n * on that layer.\n *\n * Exported for tests and for callers that want to render into something\n * other than a real `<canvas>` (e.g. an offscreen renderer or a\n * snapshot fixture).\n */\nexport function buildSceneViewCommands<TData, TLayer extends string, TPose>(\n scene: Scene<TData, TLayer, TPose>,\n view: View,\n drawOne: SceneViewDrawOne<TData, TLayer, TPose>,\n extraCommands?: ReadonlyArray<DrawCommand>,\n alphaFor?: (id: string) => number,\n /** How a child's stored pose folds into its parent's frame. Omit for the\n * absolute-pose model. */\n poseComposition?: PoseComposition<TPose>,\n /** This view's own layer visibility and order. */\n layers?: SceneViewLayers,\n /** Animated vertex colors to paint, typically an animator's `colorOverrides`. */\n colorOverrides?: ColorOverrideRegistry,\n /** Cull the scene to this CSS-pixel view size — see\n * `RenderSceneToCanvasArgs.cull`. Omit to paint every node. */\n cull?: SceneViewCull<TData, TLayer, TPose>,\n): DrawCommand[] {\n // The scene is in scope here, so this is where the override's alpha and the\n // derived paths are applied on the headless path; `SceneCanvas` does the same\n // for the live one. `Canvas` itself never sees a scene, so it can't and doesn't.\n const derivedOnly = withDerivedPaths(scene, drawOne, undefined, poseComposition);\n const derived = colorOverrides ? withColorOverrides(colorOverrides, derivedOnly) : derivedOnly;\n const derivedPathOf = sceneDerivedPathOf(scene, undefined, poseComposition);\n const wrappedDrawOne = (\n node: Node<TData, TLayer, TPose>,\n pose: TPose,\n v: View,\n ): DrawCommand[] => {\n const overrideAlpha = scene.overrides.read(node.id as NodeId)?.alpha ?? 1;\n return wrapNodeOutput(\n derived(node, pose, v),\n pose,\n (alphaFor ? alphaFor(node.id) : 1) * overrideAlpha,\n );\n };\n\n const composes = poseComposition !== undefined && poseComposition.closure !== 'identity';\n const hierarchy = composes\n ? { ...sceneAsHierarchy(scene, layers), composePose: poseComposition!.compose }\n : sceneAsHierarchy(scene, layers);\n\n const cullRect = cull ? { x: 0, y: 0, width: cull.width, height: cull.height } : undefined;\n const culled = cullRect && cull?.paintBounds ? paintMissesView(cull.paintBounds, view, cullRect) : undefined;\n const tree: DrawCommand[] = buildSceneTree(\n hierarchy as Parameters<typeof buildSceneTree>[0],\n wrappedDrawOne as unknown as Parameters<typeof buildSceneTree>[1],\n view,\n undefined,\n derivedPathOf as unknown as Parameters<typeof buildSceneTree>[4],\n culled as Parameters<typeof buildSceneTree>[5],\n );\n const children = cullRect ? cullDrawCommands(tree, viewToMat3(view), cullRect) : tree;\n if (extraCommands && extraCommands.length > 0) {\n for (const cmd of extraCommands) children.push(cmd);\n }\n return [{\n kind: 'group',\n transform: viewToMat3(view),\n children,\n }];\n}\n\n/**\n * The commands `renderSceneToCanvas` paints for one frame — everything in\n * `args` but the canvas. `<SceneViewCanvas>` paints these through its own\n * renderer lease.\n */\nexport function sceneViewFrame<TData, TLayer extends string, TPose>(\n args: Omit<RenderSceneToCanvasArgs<TData, TLayer, TPose>, 'canvas'>,\n): DrawCommand[] {\n const {\n scene, view, width, height, drawOne, extraCommands, alphaFor, layerVisibility, layerOrder,\n colorOverrides, cull,\n } = args;\n return buildSceneViewCommands(\n scene, view, drawOne, extraCommands, alphaFor, undefined, { layerVisibility, layerOrder }, colorOverrides,\n cull ? { width, height, paintBounds: args.paintBounds ?? paintBoundsFor(drawOne) } : undefined,\n );\n}\n\n/**\n * Render one frame of `scene` at `view` into `canvas`. See module docstring\n * for the design context.\n *\n * Paints through `paintCanvas` (`./canvasRenderer`): one renderer per canvas,\n * created on the first call and resized when `width` / `height` / `dpr`\n * change. Where no WebGL2 context is available (jsdom) the call paints\n * nothing. The renderer lives until `releaseCanvasRenderer(canvas)`.\n */\nexport function renderSceneToCanvas<TData, TLayer extends string, TPose>(\n args: RenderSceneToCanvasArgs<TData, TLayer, TPose>,\n): void {\n const { canvas, view, width, height, dpr } = args;\n paintCanvas(canvas, sceneViewFrame(args), view, { width, height, dpr });\n}\n"],"mappings":";;;;;;;;;;;;AAyHA,SAASA,EACP,GACA,IAA0B,CAAC,GAC6B;CACxD,OAAO;EACL,iBACEC,EAAmBC,EAAM,QAAQC,CAAM,CAAC,CACrC,KAAK,OAAO;GAAE,IAAIC,EAAE;GAAI,SAASA,EAAE;GAAS,UAAUA,EAAE;EAAS,EAAE;EACxE,UAAU,MAAOF,EAAM,IAAIG,CAAY;EACvC,cAAc,MAAa;GACzB,IAAIC,MAAa,MAAM,OAAOJ,EAAM;GACpC,IAAMK,IAAOL,EAAM,IAAII,CAAkB;GACzC,OAAOC,KAAQA,EAAK,SAAS,cAAeA,EAAK,WAAiC,CAAC;EACrF;EACA,UAAU,MAAOC,EAAcN,GAAOA,EAAM,IAAIG,CAAY,CAAE;CAChE;AACF;AA0BA,SAAgBI,EACd,GACA,GACA,GACA,GACA,GAGA,GAEA,GAEA,GAGA,GACe;CAIf,IAAMC,IAAcC,EAAiBT,GAAOU,GAAS,KAAA,GAAWC,CAAe,GACzEC,IAAUC,IAAiBC,EAAmBD,GAAgBL,CAAW,IAAIA,GAC7EO,IAAgBC,EAAmBhB,GAAO,KAAA,GAAWW,CAAe,GACpEM,KACJ,GACA,GACA,MACkB;EAClB,IAAMC,IAAgBlB,EAAM,UAAU,KAAKK,EAAK,EAAY,CAAC,EAAE,SAAS;EACxE,OAAOc,EACLP,EAAQP,GAAMe,GAAMC,CAAC,GACrBD,IACCE,IAAWA,EAASjB,EAAK,EAAE,IAAI,KAAKa,CACvC;CACF,GAGMK,IADWZ,MAAoB,KAAA,KAAaA,EAAgB,YAAY,aAE1E;EAAE,GAAGb,EAAiBE,GAAOC,CAAM;EAAG,aAAaU,EAAiB;CAAQ,IAC5Eb,EAAiBE,GAAOC,CAAM,GAE5BuB,IAAWC,IAAO;EAAE,GAAG;EAAG,GAAG;EAAG,OAAOA,EAAK;EAAO,QAAQA,EAAK;CAAO,IAAI,KAAA,GAC3EC,IAASF,KAAYC,GAAM,cAAcE,EAAgBF,EAAK,aAAaG,GAAMJ,CAAQ,IAAI,KAAA,GAC7FK,IAAsBC,EAC1BP,GACAN,GACAW,GACA,KAAA,GACAb,GACAW,CACF,GACMK,IAAWP,IAAWQ,EAAiBH,GAAMI,EAAWL,CAAI,GAAGJ,CAAQ,IAAIK;CACjF,IAAIK,KAAiBA,EAAc,SAAS,GAC1C,KAAK,IAAMC,KAAOD,GAAe,EAAS,KAAKC,CAAG;CAEpD,OAAO,CAAC;EACN,MAAM;EACN,WAAWF,EAAWL,CAAI;EAC1B;CACF,CAAC;AACH;AAOA,SAAgBQ,EACd,GACe;CACf,IAAM,EACJ,UAAO,SAAM,UAAO,WAAQ,YAAS,kBAAe,aAAU,oBAAiB,eAC/E,mBAAgB,YACdC;CACJ,OAAO9B,EACLP,GAAO4B,GAAMlB,GAASwB,GAAeZ,GAAU,KAAA,GAAW;EAAE;EAAiB;CAAW,GAAGT,GAC3FY,IAAO;EAAE;EAAO;EAAQ,aAAaY,EAAK,eAAeC,EAAe5B,CAAO;CAAE,IAAI,KAAA,CACvF;AACF;AAWA,SAAgB6B,EACd,GACM;CACN,IAAM,EAAE,WAAQ,SAAM,UAAO,WAAQ,WAAQF;CAC7C,EAAYG,GAAQJ,EAAeC,CAAI,GAAGT,GAAM;EAAE;EAAO;EAAQ;CAAI,CAAC;AACxE"}
|
|
1
|
+
{"version":3,"file":"sceneViewRender.js","names":["viewToMat3","viewToMat3$1","sceneAsHierarchy","sceneToAdapter","scene","paintedSceneLayers","layers","l","composePose","buildSceneViewCommands","derivedOnly","withDerivedPaths","drawOne","derived","colorOverrides","withColorOverrides","derivedPathOf","sceneDerivedPathOf","wrappedDrawOne","overrideAlpha","node","wrapNodeOutput","pose","v","alphaFor","hierarchy","cullRect","cull","culled","paintMissesView","view","tree","buildSceneTree","children","cullDrawCommands","extraCommands","cmd","sceneViewFrame","args","paintBoundsFor","renderSceneToCanvas","canvas"],"sources":["../../src/canvas/sceneViewRender.ts"],"sourcesContent":["/**\n * `renderSceneToCanvas` — substrate for detached, read-only scene views\n * (`<SceneViewCanvas>` / `<MinimapCanvas>`). Given a `<canvas>`, a `Scene`,\n * a `View`, and a per-node `drawOne`, render one frame.\n */\n\nimport type { WeaselRenderer } from '@weasel-js/renderer';\nimport { cachedCanvasRenderer, paintCanvas } from './canvasRenderer';\nimport { viewToMat3 } from '@weasel-js/geom';\nimport type { DrawCommand } from '@weasel-js/renderer';\nimport type { View } from '../core/viewport/view';\nimport type { Node, NodeId, Scene } from '../core/scene/types';\nimport { wrapNodeOutput } from './wrapNodeOutput';\nimport { buildSceneTree, type HierarchicalAdapter } from './buildSceneTree';\nimport { sceneToAdapter } from './sceneAdapter';\nimport { withDerivedPaths, sceneDerivedPathOf } from './derivedPath';\nimport { withColorOverrides } from './colorOverrides';\nimport type { ColorOverrideRegistry } from '@weasel-js/animator';\nimport type { SceneViewDrawOne } from './NodeShape';\nimport { paintedSceneLayers } from './sceneLayerPaint';\nimport { cullDrawCommands } from '@weasel-js/renderer';\nimport { paintMissesView, type PaintBoundsFn } from './paintCull';\nimport { paintBoundsFor } from './defaultDrawOne';\n\nexport type { SceneViewDrawOne } from './NodeShape';\n\n/**\n * Which scene layers a detached view paints, on top of each layer's own\n * `visible` flag. Keyed the way `<SceneCanvas>` keys its scene layers —\n * `scene:<layerId>` — so the map a main canvas takes serves its minimap too.\n */\nexport interface SceneViewLayers {\n /** `false` hides that layer in this view. It cannot show one the scene hides. */\n layerVisibility?: Record<string, boolean>;\n /** Paint order, bottom first. A listed order is the whole list: a scene\n * layer left out of it is not painted. */\n layerOrder?: readonly string[];\n}\n\n/** The view size `buildSceneViewCommands` culls to, and how it bounds a\n * node's paint before painting it. */\nexport interface SceneViewCull<TData, TLayer extends string, TPose> {\n width: number;\n height: number;\n paintBounds?: PaintBoundsFn<Node<TData, TLayer, TPose>, TPose>;\n}\n\n/** What to draw into an existing canvas: the scene, the view, and the same\n * painting hooks `<SceneCanvas>` takes. */\nexport interface RenderSceneToCanvasArgs<TData, TLayer extends string, TPose> {\n /** The DOM canvas to paint into. The first call on a given canvas creates\n * its renderer and later calls reuse it;\n * `releaseCanvasRenderer(canvas)` frees it. */\n canvas: HTMLCanvasElement;\n scene: Scene<TData, TLayer, TPose>;\n /** Camera view applied to scene and `extraCommands` alike. */\n view: View;\n /** CSS-pixel size. The drawing buffer is set to `width × dpr` and\n * `height × dpr`; the element's CSS size is the caller's to set. */\n width: number;\n height: number;\n drawOne: SceneViewDrawOne<TData, TLayer, TPose>;\n /** Commands appended after the scene-node output, wrapped in the same view\n * transform as scene commands. */\n extraCommands?: DrawCommand[];\n /** Per-id alpha multiplier, mirroring `<SceneCanvas>`'s scene-slot\n * `alphaFor`. Defaults to `() => 1`. */\n alphaFor?: (id: string) => number;\n /** Per-view layer visibility. See {@link SceneViewLayers}. */\n layerVisibility?: SceneViewLayers['layerVisibility'];\n /** Per-view layer order. See {@link SceneViewLayers}. */\n layerOrder?: SceneViewLayers['layerOrder'];\n /** Animated vertex colors to paint, typically an animator's\n * `colorOverrides` — see `NodePaintCtx.vertexColors`. */\n colorOverrides?: ColorOverrideRegistry;\n /** Skip what cannot reach the `width × height` view: nodes `paintBounds`\n * places outside it are not painted, and scene commands that cannot reach\n * it are dropped before the renderer — the scene slot's `cull`. Off by\n * default. `extraCommands` are never culled. */\n cull?: boolean;\n /** Where `drawOne`'s output for a node can reach, as on the scene slot.\n * Defaults to `defaultPaintBounds` when `drawOne` is `defaultDrawOne`. */\n paintBounds?: PaintBoundsFn<Node<TData, TLayer, TPose>, TPose>;\n /** Device-pixel ratio. Defaults to `window.devicePixelRatio || 1` when\n * available, otherwise 1. */\n dpr?: number;\n}\n\n/** Test seam: the renderer `renderSceneToCanvas` created for a canvas. Not\n * re-exported from the barrel. */\nexport function __getCachedRendererForTest(\n canvas: HTMLCanvasElement,\n): WeaselRenderer | undefined {\n return cachedCanvasRenderer(canvas);\n}\n\n/**\n * Present a `Scene` as the reading surface `buildSceneTree` walks: the scene\n * adapter's own reads, under this view's layer list.\n */\nfunction sceneAsHierarchy<TData, TLayer extends string, TPose>(\n scene: Scene<TData, TLayer, TPose>,\n layers: SceneViewLayers = {},\n): HierarchicalAdapter<Node<TData, TLayer, TPose>, TPose> {\n const { getNode, getChildren, getPose, composePose } = sceneToAdapter(scene);\n return {\n getLayers: () =>\n paintedSceneLayers(scene.layers, layers)\n .map((l) => ({ id: l.id, visible: l.visible, parallax: l.parallax })),\n getNode,\n getChildren,\n getPose,\n ...(composePose ? { composePose } : {}),\n };\n}\n\n/**\n * Build the DrawCommand list that `renderSceneToCanvas` would dispatch, in\n * screen space. Pure — no GL, no DOM. Walks the scene through `buildSceneTree`,\n * the same walk `<SceneCanvas>` uses, which is what keeps hidden layers\n * unpainted and container clips applied here.\n *\n * Each node's commands go through `wrapNodeOutput` — pose rotation, then the\n * `alphaFor` multiplier — so a `drawOne` that rotates its own output rotates\n * twice; emit unrotated geometry and let the pose drive it.\n *\n * Output is one group per **visible** layer, in scene-layer order (or\n * `layers.layerOrder`), each holding one group per node on that layer.\n */\nexport function buildSceneViewCommands<TData, TLayer extends string, TPose>(\n scene: Scene<TData, TLayer, TPose>,\n view: View,\n drawOne: SceneViewDrawOne<TData, TLayer, TPose>,\n extraCommands?: ReadonlyArray<DrawCommand>,\n alphaFor?: (id: string) => number,\n /** This view's own layer visibility and order. */\n layers?: SceneViewLayers,\n /** Animated vertex colors to paint, typically an animator's `colorOverrides`. */\n colorOverrides?: ColorOverrideRegistry,\n /** Cull the scene to this CSS-pixel view size — see\n * `RenderSceneToCanvasArgs.cull`. Omit to paint every node. */\n cull?: SceneViewCull<TData, TLayer, TPose>,\n): DrawCommand[] {\n const derivedOnly = withDerivedPaths(scene, drawOne);\n const derived = colorOverrides ? withColorOverrides(colorOverrides, derivedOnly) : derivedOnly;\n const derivedPathOf = sceneDerivedPathOf(scene);\n const wrappedDrawOne = (\n node: Node<TData, TLayer, TPose>,\n pose: TPose,\n v: View,\n ): DrawCommand[] => {\n const overrideAlpha = scene.overrides.read(node.id as NodeId)?.alpha ?? 1;\n return wrapNodeOutput(\n derived(node, pose, v),\n pose,\n (alphaFor ? alphaFor(node.id) : 1) * overrideAlpha,\n );\n };\n\n const hierarchy = sceneAsHierarchy(scene, layers);\n\n const cullRect = cull ? { x: 0, y: 0, width: cull.width, height: cull.height } : undefined;\n const culled = cullRect && cull?.paintBounds ? paintMissesView(cull.paintBounds, view, cullRect) : undefined;\n const tree: DrawCommand[] = buildSceneTree(\n hierarchy as Parameters<typeof buildSceneTree>[0],\n wrappedDrawOne as unknown as Parameters<typeof buildSceneTree>[1],\n view,\n undefined,\n derivedPathOf as unknown as Parameters<typeof buildSceneTree>[4],\n culled as Parameters<typeof buildSceneTree>[5],\n );\n const children = cullRect ? cullDrawCommands(tree, viewToMat3(view), cullRect) : tree;\n if (extraCommands && extraCommands.length > 0) {\n for (const cmd of extraCommands) children.push(cmd);\n }\n return [{\n kind: 'group',\n transform: viewToMat3(view),\n children,\n }];\n}\n\n/**\n * The commands `renderSceneToCanvas` paints for one frame — everything in\n * `args` but the canvas. `<SceneViewCanvas>` paints these through its own\n * renderer lease.\n */\nexport function sceneViewFrame<TData, TLayer extends string, TPose>(\n args: Omit<RenderSceneToCanvasArgs<TData, TLayer, TPose>, 'canvas'>,\n): DrawCommand[] {\n const {\n scene, view, width, height, drawOne, extraCommands, alphaFor, layerVisibility, layerOrder,\n colorOverrides, cull,\n } = args;\n return buildSceneViewCommands(\n scene, view, drawOne, extraCommands, alphaFor, { layerVisibility, layerOrder }, colorOverrides,\n cull ? { width, height, paintBounds: args.paintBounds ?? paintBoundsFor(drawOne) } : undefined,\n );\n}\n\n/**\n * Render one frame of `scene` at `view` into `canvas`. Where no WebGL2\n * context is available (jsdom) the call paints nothing. The canvas's renderer\n * lives until `releaseCanvasRenderer(canvas)`.\n */\nexport function renderSceneToCanvas<TData, TLayer extends string, TPose>(\n args: RenderSceneToCanvasArgs<TData, TLayer, TPose>,\n): void {\n const { canvas, view, width, height, dpr } = args;\n paintCanvas(canvas, sceneViewFrame(args), view, { width, height, dpr });\n}\n"],"mappings":";;;;;;;;;;;;AAoGA,SAASE,EACP,GACA,IAA0B,CAAC,GAC6B;CACxD,IAAM,EAAE,YAAS,gBAAa,YAAS,mBAAgBC,EAAeC,CAAK;CAC3E,OAAO;EACL,iBACEC,EAAmBD,EAAM,QAAQE,CAAM,CAAC,CACrC,KAAK,OAAO;GAAE,IAAIC,EAAE;GAAI,SAASA,EAAE;GAAS,UAAUA,EAAE;EAAS,EAAE;EACxE;EACA;EACA;EACA,GAAIC,IAAc,EAAE,eAAY,IAAI,CAAC;CACvC;AACF;AAeA,SAAgBC,EACd,GACA,GACA,GACA,GACA,GAEA,GAEA,GAGA,GACe;CACf,IAAMC,IAAcC,EAAiBP,GAAOQ,CAAO,GAC7CC,IAAUC,IAAiBC,EAAmBD,GAAgBJ,CAAW,IAAIA,GAC7EM,IAAgBC,EAAmBb,CAAK,GACxCc,KACJ,GACA,GACA,MACkB;EAClB,IAAMC,IAAgBf,EAAM,UAAU,KAAKgB,EAAK,EAAY,CAAC,EAAE,SAAS;EACxE,OAAOC,EACLR,EAAQO,GAAME,GAAMC,CAAC,GACrBD,IACCE,IAAWA,EAASJ,EAAK,EAAE,IAAI,KAAKD,CACvC;CACF,GAEMM,IAAYvB,EAAiBE,GAAOE,CAAM,GAE1CoB,IAAWC,IAAO;EAAE,GAAG;EAAG,GAAG;EAAG,OAAOA,EAAK;EAAO,QAAQA,EAAK;CAAO,IAAI,KAAA,GAC3EC,IAASF,KAAYC,GAAM,cAAcE,EAAgBF,EAAK,aAAaG,GAAMJ,CAAQ,IAAI,KAAA,GAC7FK,IAAsBC,EAC1BP,GACAP,GACAY,GACA,KAAA,GACAd,GACAY,CACF,GACMK,IAAWP,IAAWQ,EAAiBH,GAAM/B,EAAW8B,CAAI,GAAGJ,CAAQ,IAAIK;CACjF,IAAII,KAAiBA,EAAc,SAAS,GAC1C,KAAK,IAAMC,KAAOD,GAAe,EAAS,KAAKC,CAAG;CAEpD,OAAO,CAAC;EACN,MAAM;EACN,WAAWpC,EAAW8B,CAAI;EAC1B;CACF,CAAC;AACH;AAOA,SAAgBO,EACd,GACe;CACf,IAAM,EACJ,UAAO,SAAM,UAAO,WAAQ,YAAS,kBAAe,aAAU,oBAAiB,eAC/E,mBAAgB,YACdC;CACJ,OAAO7B,EACLL,GAAO0B,GAAMlB,GAASuB,GAAeX,GAAU;EAAE;EAAiB;CAAW,GAAGV,GAChFa,IAAO;EAAE;EAAO;EAAQ,aAAaW,EAAK,eAAeC,EAAe3B,CAAO;CAAE,IAAI,KAAA,CACvF;AACF;AAOA,SAAgB4B,EACd,GACM;CACN,IAAM,EAAE,WAAQ,SAAM,UAAO,WAAQ,WAAQF;CAC7C,EAAYG,GAAQJ,EAAeC,CAAI,GAAGR,GAAM;EAAE;EAAO;EAAQ;CAAI,CAAC;AACxE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slopsDebugLayer.js","names":["SLOP_FILL","SLOP_STROKE","createSlopsDebugLayer","chrome","chromeStateFrom","data","isVisible","isVisibleFrom","toScreen","x","view","y","out","a","opts","region","q","pointRegionScreenQuad","transformOf","PATH_M","PATH_L","PATH_Z"],"sources":["../../src/canvas/slopsDebugLayer.ts"],"sourcesContent":["/**\n * Screen-space debug overlay rendering the kit's hit-test \"slops\" — the\n * forgiveness regions around each point affordance (corner resize handles,\n * the rotate badge, anchor / control-handle markers). Off by default; gated\n * by SceneCanvas's `debug.slops` prop.\n *\n * It walks the same affordances the hit-test does, and draws each point\n * region's square from the same frame the hit-test reads, so a halo shows\n * exactly the pixels that grab.\n */\n\nimport type { DrawCommand } from '
|
|
1
|
+
{"version":3,"file":"slopsDebugLayer.js","names":["SLOP_FILL","SLOP_STROKE","createSlopsDebugLayer","chrome","chromeStateFrom","data","isVisible","isVisibleFrom","toScreen","x","view","y","out","a","opts","region","q","pointRegionScreenQuad","transformOf","PATH_M","PATH_L","PATH_Z"],"sources":["../../src/canvas/slopsDebugLayer.ts"],"sourcesContent":["/**\n * Screen-space debug overlay rendering the kit's hit-test \"slops\" — the\n * forgiveness regions around each point affordance (corner resize handles,\n * the rotate badge, anchor / control-handle markers). Off by default; gated\n * by SceneCanvas's `debug.slops` prop.\n *\n * It walks the same affordances the hit-test does, and draws each point\n * region's square from the same frame the hit-test reads, so a halo shows\n * exactly the pixels that grab.\n */\n\nimport type { DrawCommand } from '@weasel-js/renderer';\nimport type { RenderLayer } from 'core/layers/render';\nimport type { Affordance } from 'affordances/types';\nimport { pointRegionScreenQuad, transformOf } from 'affordances/hitAffordanceRegions';\nimport { PATH_L, PATH_M, PATH_Z } from '@weasel-js/geom';\nimport { chromeStateFrom, isVisibleFrom } from './drawEnvelope';\n\nexport interface CreateSlopsDebugLayerOptions {\n /** The affordances the canvas hit-tests — `chromeAffordances`, the same\n * list handed to `buildAffordanceAt`. */\n getAffordances: () => readonly Affordance[];\n}\n\nconst SLOP_FILL = 'rgba(255, 80, 140, 0.18)';\nconst SLOP_STROKE = 'rgba(255, 80, 140, 0.55)';\n\nexport function createSlopsDebugLayer(\n opts: CreateSlopsDebugLayerOptions,\n): RenderLayer<unknown> {\n return {\n id: 'slops-debug',\n label: 'Slops (debug)',\n space: 'screen',\n draw: (data, view) => {\n // Selection, bounds and visibility come off the envelope: the halos\n // have to sit on the chrome the drawing view actually painted.\n const chrome = chromeStateFrom(data);\n if (!chrome) return [];\n const isVisible = isVisibleFrom(data);\n const toScreen = (x: number, y: number): [number, number] =>\n [(x - view.x) * view.scale.x, (y - view.y) * view.scale.y];\n const out: DrawCommand[] = [];\n for (const a of opts.getAffordances()) {\n if (isVisible && !isVisible(a.id)) continue;\n for (const region of a.regions(chrome)) {\n if (region.shape.kind !== 'point') continue;\n const q = pointRegionScreenQuad(\n region.shape, transformOf(chrome, region.targetId), view, toScreen,\n );\n out.push({\n kind: 'path',\n path: {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_L, PATH_L, PATH_L, PATH_Z]),\n coords: new Float32Array([q[0].x, q[0].y, q[1].x, q[1].y, q[2].x, q[2].y, q[3].x, q[3].y]),\n fillRule: 'nonzero',\n },\n fill: { paint: { kind: 'solid', color: SLOP_FILL } },\n stroke: { paint: { kind: 'solid', color: SLOP_STROKE }, width: 1 },\n });\n }\n }\n return out;\n },\n };\n}\n"],"mappings":";;;;AAwBA,IAAMA,IAAY,4BACZC,IAAc;AAEpB,SAAgBC,EACd,GACsB;CACtB,OAAO;EACL,IAAI;EACJ,OAAO;EACP,OAAO;EACP,OAAO,GAAM,MAAS;GAGpB,IAAMC,IAASC,EAAgBC,CAAI;GACnC,IAAI,CAACF,GAAQ,OAAO,CAAC;GACrB,IAAMG,IAAYC,EAAcF,CAAI,GAC9BG,KAAY,GAAW,MAC3B,EAAEC,IAAIC,EAAK,KAAKA,EAAK,MAAM,IAAIC,IAAID,EAAK,KAAKA,EAAK,MAAM,CAAC,GACrDE,IAAqB,CAAC;GAC5B,KAAK,IAAMC,KAAKC,EAAK,eAAe,GAClC,IAAI,MAAcR,EAAUO,EAAE,EAAE,GAChC,KAAK,IAAME,KAAUF,EAAE,QAAQV,CAAM,GAAG;IACtC,IAAIY,EAAO,MAAM,SAAS,SAAS;IACnC,IAAMC,IAAIC,EACRF,EAAO,OAAOG,EAAYf,GAAQY,EAAO,QAAQ,GAAGL,GAAMF,CAC5D;IACA,EAAI,KAAK;KACP,MAAM;KACN,MAAM;MACJ,MAAM;MACN,UAAU,IAAI,WAAW;OAACW;OAAQC;OAAQA;OAAQA;OAAQC;MAAM,CAAC;MACjE,QAAQ,IAAI,aAAa;OAACL,EAAE,EAAE,CAAC;OAAGA,EAAE,EAAE,CAAC;OAAGA,EAAE,EAAE,CAAC;OAAGA,EAAE,EAAE,CAAC;OAAGA,EAAE,EAAE,CAAC;OAAGA,EAAE,EAAE,CAAC;OAAGA,EAAE,EAAE,CAAC;OAAGA,EAAE,EAAE,CAAC;MAAC,CAAC;MACzF,UAAU;KACZ;KACA,MAAM,EAAE,OAAO;MAAE,MAAM;MAAS,OAAOhB;KAAU,EAAE;KACnD,QAAQ;MAAE,OAAO;OAAE,MAAM;OAAS,OAAOC;MAAY;MAAG,OAAO;KAAE;IACnE,CAAC;GACH;GAEF,OAAOW;EACT;CACF;AACF"}
|
|
@@ -1,19 +1,31 @@
|
|
|
1
1
|
import { watchDevicePixelRatio as e } from "../core/device/watchDevicePixelRatio.js";
|
|
2
|
-
import { leaseCanvasRenderer as t } from "./canvasRenderer.js";
|
|
3
|
-
import {
|
|
2
|
+
import { leaseCanvasRenderer as t, shaderKeyOf as n } from "./canvasRenderer.js";
|
|
3
|
+
import { getProgramSource as r, programSourceRegistry as i } from "@weasel-js/renderer";
|
|
4
|
+
import { useEffect as a, useState as o } from "react";
|
|
4
5
|
//#region src/canvas/useCanvasRenderer.ts
|
|
5
|
-
function
|
|
6
|
-
let [e] =
|
|
7
|
-
return
|
|
6
|
+
function s() {
|
|
7
|
+
let [e] = o(t);
|
|
8
|
+
return a(() => () => e.release(), [e]), e;
|
|
8
9
|
}
|
|
9
|
-
function
|
|
10
|
-
|
|
10
|
+
function c(e, t) {
|
|
11
|
+
a(() => e.subscribeRestored(t), [e, t]);
|
|
11
12
|
}
|
|
12
|
-
function
|
|
13
|
-
let
|
|
14
|
-
|
|
13
|
+
function l(t, n) {
|
|
14
|
+
let r = n === void 0;
|
|
15
|
+
a(() => r ? e(() => t()) : void 0, [r, t]);
|
|
16
|
+
}
|
|
17
|
+
function u(e, t) {
|
|
18
|
+
let o = n(e);
|
|
19
|
+
a(() => {
|
|
20
|
+
if (!o) return;
|
|
21
|
+
let e = o.split("|"), n = e.map(r);
|
|
22
|
+
return i.subscribe(() => {
|
|
23
|
+
let i = e.map(r), a = i.some((e, t) => e !== n[t]);
|
|
24
|
+
n = i, a && t();
|
|
25
|
+
});
|
|
26
|
+
}, [o, t]);
|
|
15
27
|
}
|
|
16
28
|
//#endregion
|
|
17
|
-
export {
|
|
29
|
+
export { s as useCanvasRenderer, l as useRedrawOnDensityChange, c as useRedrawOnRestore, u as useRedrawOnShaderSource };
|
|
18
30
|
|
|
19
31
|
//# sourceMappingURL=useCanvasRenderer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCanvasRenderer.js","names":["useCanvasRenderer","lease","useState","leaseCanvasRenderer","useEffect","useRedrawOnRestore","requestRedraw","useRedrawOnDensityChange","ambient","dpr","watchDevicePixelRatio"],"sources":["../../src/canvas/useCanvasRenderer.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport { watchDevicePixelRatio } from '../core/device/watchDevicePixelRatio';\nimport { leaseCanvasRenderer, type CanvasRendererLease } from './canvasRenderer';\n\n/**\n * The React lifetime of `leaseCanvasRenderer`: a stable lease for the\n * component's canvas, whose renderer and GL objects are freed on unmount.\n * Every canvas surface in core paints through this, so none can skip the\n * teardown.\n */\nexport function useCanvasRenderer(): CanvasRendererLease {\n const [lease] = useState(leaseCanvasRenderer);\n useEffect(() => () => lease.release(), [lease]);\n return lease;\n}\n\n/** Repaint a surface when its canvas gets a lost GL context back. */\nexport function useRedrawOnRestore(lease: CanvasRendererLease, requestRedraw: () => void): void {\n useEffect(() => lease.subscribeRestored(requestRedraw), [lease, requestRedraw]);\n}\n\n/**\n * Repaint a surface that follows the ambient density when `devicePixelRatio`\n * changes. The lease reads the ratio at each paint, and nothing else asks for\n * one. A surface given its own `dpr` passes it here and is left alone.\n */\nexport function useRedrawOnDensityChange(requestRedraw: () => void, dpr?: number): void {\n const ambient = dpr === undefined;\n useEffect(() => (ambient ? watchDevicePixelRatio(() => requestRedraw()) : undefined), [ambient, requestRedraw]);\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"useCanvasRenderer.js","names":["useCanvasRenderer","lease","useState","leaseCanvasRenderer","useEffect","useRedrawOnRestore","requestRedraw","useRedrawOnDensityChange","ambient","dpr","watchDevicePixelRatio","useRedrawOnShaderSource","key","shaderKeyOf","shaders","ids","seen","getProgramSource","programSourceRegistry","now","changed","src","i"],"sources":["../../src/canvas/useCanvasRenderer.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport { watchDevicePixelRatio } from '../core/device/watchDevicePixelRatio';\nimport { getProgramSource, programSourceRegistry, type ShaderProgramHandle } from '@weasel-js/renderer';\nimport { leaseCanvasRenderer, shaderKeyOf, type CanvasRendererLease } from './canvasRenderer';\n\n/**\n * The React lifetime of `leaseCanvasRenderer`: a stable lease for the\n * component's canvas, whose renderer and GL objects are freed on unmount.\n * Every canvas surface in core paints through this, so none can skip the\n * teardown.\n */\nexport function useCanvasRenderer(): CanvasRendererLease {\n const [lease] = useState(leaseCanvasRenderer);\n useEffect(() => () => lease.release(), [lease]);\n return lease;\n}\n\n/** Repaint a surface when its canvas gets a lost GL context back. */\nexport function useRedrawOnRestore(lease: CanvasRendererLease, requestRedraw: () => void): void {\n useEffect(() => lease.subscribeRestored(requestRedraw), [lease, requestRedraw]);\n}\n\n/**\n * Repaint a surface that follows the ambient density when `devicePixelRatio`\n * changes. The lease reads the ratio at each paint, and nothing else asks for\n * one. A surface given its own `dpr` passes it here and is left alone.\n */\nexport function useRedrawOnDensityChange(requestRedraw: () => void, dpr?: number): void {\n const ambient = dpr === undefined;\n useEffect(() => (ambient ? watchDevicePixelRatio(() => requestRedraw()) : undefined), [ambient, requestRedraw]);\n}\n\n/**\n * Repaint a surface when one of its custom programs is re-registered with new\n * source. The renderer recompiles on the frame that draws it, and nothing else\n * asks for that frame.\n */\nexport function useRedrawOnShaderSource(\n shaders: readonly ShaderProgramHandle[] | undefined,\n requestRedraw: () => void,\n): void {\n const key = shaderKeyOf(shaders);\n useEffect(() => {\n if (!key) return;\n const ids = key.split('|');\n let seen = ids.map(getProgramSource);\n return programSourceRegistry.subscribe(() => {\n const now = ids.map(getProgramSource);\n const changed = now.some((src, i) => src !== seen[i]);\n seen = now;\n if (changed) requestRedraw();\n });\n }, [key, requestRedraw]);\n}\n"],"mappings":";;;;;AAWA,SAAgBA,IAAyC;CACvD,IAAM,CAACC,KAASC,EAASC,CAAmB;CAE5C,OADAC,cAAsBH,EAAM,QAAQ,GAAG,CAACA,CAAK,CAAC,GACvCA;AACT;AAGA,SAAgBI,EAAmB,GAA4B,GAAiC;CAC9F,QAAgBJ,EAAM,kBAAkBK,CAAa,GAAG,CAACL,GAAOK,CAAa,CAAC;AAChF;AAOA,SAAgBC,EAAyB,GAA2B,GAAoB;CACtF,IAAMC,IAAUC,MAAQ,KAAA;CACxB,QAAiBD,IAAUE,QAA4BJ,EAAc,CAAC,IAAI,KAAA,GAAY,CAACE,GAASF,CAAa,CAAC;AAChH;AAOA,SAAgBK,EACd,GACA,GACM;CACN,IAAMC,IAAMC,EAAYC,CAAO;CAC/B,QAAgB;EACd,IAAI,CAACF,GAAK;EACV,IAAMG,IAAMH,EAAI,MAAM,GAAG,GACrBI,IAAOD,EAAI,IAAIE,CAAgB;EACnC,OAAOC,EAAsB,gBAAgB;GAC3C,IAAMC,IAAMJ,EAAI,IAAIE,CAAgB,GAC9BG,IAAUD,EAAI,MAAM,GAAK,MAAME,MAAQL,EAAKM,EAAE;GAEpD,AADA,IAAOH,GACHC,KAASd,EAAc;EAC7B,CAAC;CACH,GAAG,CAACM,GAAKN,CAAa,CAAC;AACzB"}
|