@weasel-js/core 1.9.3 → 1.9.4
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 +356 -0
- package/README.md +2 -2
- package/dist/WeaselProvider.js +5 -5
- package/dist/affordances/composeAffordanceLayer.js +10 -20
- package/dist/affordances/composeAffordanceLayer.js.map +1 -1
- package/dist/affordances/cornerResize.js +25 -17
- package/dist/affordances/cornerResize.js.map +1 -1
- package/dist/affordances/hitAffordanceRegions.js +27 -20
- package/dist/affordances/hitAffordanceRegions.js.map +1 -1
- package/dist/affordances/rotationHandle.js +18 -18
- package/dist/affordances/rotationHandle.js.map +1 -1
- package/dist/animation/behaviors/momentum.js +93 -55
- package/dist/animation/behaviors/momentum.js.map +1 -1
- package/dist/animation/loop.js +10 -12
- package/dist/animation/loop.js.map +1 -1
- package/dist/animation/reflow.js +8 -8
- package/dist/animation/reflow.js.map +1 -1
- package/dist/animation/stagger.js +64 -56
- package/dist/animation/stagger.js.map +1 -1
- package/dist/animation/timeline/booking.js +62 -54
- package/dist/animation/timeline/booking.js.map +1 -1
- package/dist/animation/timeline/createTimeline.js +85 -76
- package/dist/animation/timeline/createTimeline.js.map +1 -1
- package/dist/animation/timeline/sampleTrack.js +13 -5
- package/dist/animation/timeline/sampleTrack.js.map +1 -1
- package/dist/animation/useAnimator.js +45 -35
- package/dist/animation/useAnimator.js.map +1 -1
- package/dist/animation/wrappers/animateLifecycle.js +31 -24
- package/dist/animation/wrappers/animateLifecycle.js.map +1 -1
- package/dist/animation/wrappers/animateOnSetPose.js +28 -26
- package/dist/animation/wrappers/animateOnSetPose.js.map +1 -1
- package/dist/animation/wrappers/instantPose.js +13 -0
- package/dist/animation/wrappers/instantPose.js.map +1 -0
- package/dist/{poseDescriptor-D-OH-tu5.d.ts → autoPoseDescriptor-Ct7yqivU.d.ts} +28 -3
- package/dist/barrel/chrome.js +16 -0
- package/dist/barrel/input.js +19 -0
- package/dist/barrel/interactions.js +42 -0
- package/dist/barrel/paint.js +18 -0
- package/dist/barrel/paths.js +19 -0
- package/dist/barrel/renderer.js +20 -0
- package/dist/barrel/routing.js +51 -0
- package/dist/barrel/text.js +18 -0
- package/dist/barrel/viewport.js +52 -0
- package/dist/builtins-DPcdghtB.d.ts +1223 -0
- package/dist/canvas/Canvas.js +363 -448
- package/dist/canvas/Canvas.js.map +1 -1
- package/dist/canvas/CanvasView.js +164 -165
- package/dist/canvas/CanvasView.js.map +1 -1
- package/dist/canvas/CursorCoordsHud.js +37 -32
- package/dist/canvas/CursorCoordsHud.js.map +1 -1
- package/dist/canvas/DrawCanvas.js +49 -43
- package/dist/canvas/DrawCanvas.js.map +1 -1
- package/dist/canvas/MinimapCanvas.js +26 -25
- package/dist/canvas/MinimapCanvas.js.map +1 -1
- package/dist/canvas/NodeShape.js +59 -377
- package/dist/canvas/NodeShape.js.map +1 -1
- package/dist/canvas/PickHud.js +50 -47
- package/dist/canvas/PickHud.js.map +1 -1
- package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js +167 -0
- package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js.map +1 -0
- package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +13 -13
- package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js +67 -0
- package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js.map +1 -0
- package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js +16 -0
- package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js.map +1 -0
- package/dist/canvas/SceneCanvas/coordTrace.js +10 -0
- package/dist/canvas/SceneCanvas/coordTrace.js.map +1 -0
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js +112 -70
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -1
- package/dist/canvas/SceneCanvas/defaultNodeRouting.js +9 -8
- package/dist/canvas/SceneCanvas/defaultNodeRouting.js.map +1 -1
- package/dist/canvas/SceneCanvas/features.js +1 -0
- package/dist/canvas/SceneCanvas/features.js.map +1 -1
- package/dist/canvas/SceneCanvas/isDev.js +12 -0
- package/dist/canvas/SceneCanvas/isDev.js.map +1 -0
- package/dist/canvas/SceneCanvas/poseGeometry.js +29 -28
- package/dist/canvas/SceneCanvas/poseGeometry.js.map +1 -1
- package/dist/canvas/SceneCanvas/poseRegistrars.js +13 -0
- package/dist/canvas/SceneCanvas/poseRegistrars.js.map +1 -0
- package/dist/canvas/SceneCanvas/props.js +38 -0
- package/dist/canvas/SceneCanvas/props.js.map +1 -0
- package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js +21 -62
- package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js.map +1 -1
- package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js.map +1 -1
- package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +46 -48
- package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js +33 -33
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
- package/dist/canvas/SceneCanvas.js +534 -788
- package/dist/canvas/SceneCanvas.js.map +1 -1
- package/dist/canvas/SceneViewCanvas.js +45 -43
- package/dist/canvas/SceneViewCanvas.js.map +1 -1
- package/dist/canvas/buildSceneLayer.js +91 -0
- package/dist/canvas/buildSceneLayer.js.map +1 -0
- package/dist/canvas/buildSceneTree.js +16 -19
- package/dist/canvas/buildSceneTree.js.map +1 -1
- package/dist/canvas/canvasRenderer.js +68 -52
- package/dist/canvas/canvasRenderer.js.map +1 -1
- package/dist/canvas/deps/changes.js +13 -0
- package/dist/canvas/deps/changes.js.map +1 -0
- package/dist/canvas/deps/editAnchors.js +28 -28
- package/dist/canvas/deps/insert.js +119 -91
- package/dist/canvas/deps/insert.js.map +1 -1
- package/dist/canvas/deps/slice.js +46 -45
- package/dist/canvas/deps/slice.js.map +1 -1
- package/dist/canvas/deps/textEdit.js +10 -9
- package/dist/canvas/deps/textEdit.js.map +1 -1
- package/dist/canvas/derivedPath.js +46 -23
- package/dist/canvas/derivedPath.js.map +1 -1
- package/dist/canvas/getNodeAtPoint.js +7 -7
- package/dist/canvas/getNodeAtPoint.js.map +1 -1
- package/dist/canvas/hud.module.js +1 -1
- package/dist/canvas/hud.module.js.map +1 -1
- package/dist/canvas/kitRequirements.js +2 -2
- package/dist/canvas/kitRequirements.js.map +1 -1
- package/dist/canvas/layerOrder.js +13 -6
- package/dist/canvas/layerOrder.js.map +1 -1
- package/dist/canvas/minimapMath.js +12 -10
- package/dist/canvas/minimapMath.js.map +1 -1
- package/dist/canvas/nodeShapes/derivedPainter.js +34 -0
- package/dist/canvas/nodeShapes/derivedPainter.js.map +1 -0
- package/dist/canvas/nodeShapes/imagePainter.js +87 -0
- package/dist/canvas/nodeShapes/imagePainter.js.map +1 -0
- package/dist/canvas/nodeShapes/memo.js +9 -0
- package/dist/canvas/nodeShapes/memo.js.map +1 -0
- package/dist/canvas/nodeShapes/nodePaint.js +57 -0
- package/dist/canvas/nodeShapes/nodePaint.js.map +1 -0
- package/dist/canvas/nodeShapes/pathPainter.js +38 -0
- package/dist/canvas/nodeShapes/pathPainter.js.map +1 -0
- package/dist/canvas/nodeShapes/poseBox.js +20 -0
- package/dist/canvas/nodeShapes/poseBox.js.map +1 -0
- package/dist/canvas/nodeShapes/rectFallbackPainter.js +38 -0
- package/dist/canvas/nodeShapes/rectFallbackPainter.js.map +1 -0
- package/dist/canvas/nodeShapes/shapePainter.js +72 -0
- package/dist/canvas/nodeShapes/shapePainter.js.map +1 -0
- package/dist/canvas/nodeShapes/textPainter.js +55 -0
- package/dist/canvas/nodeShapes/textPainter.js.map +1 -0
- package/dist/canvas/overlayRoleStrokes.js.map +1 -1
- package/dist/canvas/paintCull.js +10 -11
- package/dist/canvas/paintCull.js.map +1 -1
- package/dist/canvas/pickWalk.js +52 -63
- package/dist/canvas/pickWalk.js.map +1 -1
- package/dist/canvas/poseRotation.js +11 -23
- package/dist/canvas/poseRotation.js.map +1 -1
- package/dist/canvas/renderDebugSnapshot.js +5 -5
- package/dist/canvas/renderSceneToPixels.js +3 -1
- package/dist/canvas/renderSceneToPixels.js.map +1 -1
- package/dist/canvas/sceneAdapter.js +66 -148
- package/dist/canvas/sceneAdapter.js.map +1 -1
- package/dist/canvas/sceneClipboard.js +112 -0
- package/dist/canvas/sceneClipboard.js.map +1 -0
- package/dist/canvas/sceneSlotWiring.js +4 -4
- package/dist/canvas/sceneSlotWiring.js.map +1 -1
- package/dist/canvas/sceneViewRender.js +39 -40
- package/dist/canvas/sceneViewRender.js.map +1 -1
- package/dist/canvas/useCanvasRenderer.js +14 -6
- package/dist/canvas/useCanvasRenderer.js.map +1 -1
- package/dist/canvas/useCanvasView.js +58 -0
- package/dist/canvas/useCanvasView.js.map +1 -0
- package/dist/canvas/useFrameLoop.js +35 -26
- package/dist/canvas/useFrameLoop.js.map +1 -1
- package/dist/canvas/useSceneLayerList.js +21 -0
- package/dist/canvas/useSceneLayerList.js.map +1 -0
- package/dist/clipboard.d.ts +10 -6
- package/dist/clone.d.ts +4 -3
- package/dist/core/adapters/arrayAdapter.js +48 -39
- package/dist/core/adapters/arrayAdapter.js.map +1 -1
- package/dist/core/device/index.js +5 -4
- package/dist/core/device/useDeviceProfile.js +38 -44
- package/dist/core/device/useDeviceProfile.js.map +1 -1
- package/dist/core/device/watchDevicePixelRatio.js +17 -0
- package/dist/core/device/watchDevicePixelRatio.js.map +1 -0
- package/dist/core/fillInPoseFrame.js.map +1 -1
- package/dist/core/geometry/poseDescriptor.js +21 -19
- package/dist/core/geometry/poseDescriptor.js.map +1 -1
- package/dist/core/geometry/poseFrame.js +44 -0
- package/dist/core/geometry/poseFrame.js.map +1 -0
- package/dist/core/geometry/poseRotation.js.map +1 -1
- package/dist/core/geometry/regionHit.js +9 -10
- package/dist/core/geometry/regionHit.js.map +1 -1
- package/dist/core/geometry/unionBounds.js +31 -29
- package/dist/core/geometry/unionBounds.js.map +1 -1
- package/dist/core/isPlainObject.js +2 -11
- package/dist/core/ops/arrange.js +1 -0
- package/dist/core/ops/arrange.js.map +1 -1
- package/dist/core/ops/create.js +10 -5
- package/dist/core/ops/create.js.map +1 -1
- package/dist/core/ops/delete.js +12 -24
- package/dist/core/ops/delete.js.map +1 -1
- package/dist/core/ops/reorder/index.js +43 -40
- package/dist/core/ops/reorder/index.js.map +1 -1
- package/dist/core/ops/reorder/setChildOrder.js +34 -0
- package/dist/core/ops/reorder/setChildOrder.js.map +1 -0
- package/dist/core/paintKinds.js +5 -5
- package/dist/core/paintKinds.js.map +1 -1
- package/dist/core/scene/NodeProperties.js.map +1 -1
- package/dist/core/scene/appliedLog.js +37 -0
- package/dist/core/scene/appliedLog.js.map +1 -0
- package/dist/core/scene/arrivalWindow.js +101 -0
- package/dist/core/scene/arrivalWindow.js.map +1 -0
- package/dist/core/scene/derivedPath.js.map +1 -1
- package/dist/core/scene/historyFacade.js +84 -0
- package/dist/core/scene/historyFacade.js.map +1 -0
- package/dist/core/scene/kitOps.js +173 -0
- package/dist/core/scene/kitOps.js.map +1 -0
- package/dist/core/scene/layerStack.js +38 -0
- package/dist/core/scene/layerStack.js.map +1 -0
- package/dist/core/scene/lockGuard.js +37 -0
- package/dist/core/scene/lockGuard.js.map +1 -0
- package/dist/core/scene/nodeFnFields.js +5 -6
- package/dist/core/scene/nodeFnFields.js.map +1 -1
- package/dist/core/scene/nodeMemo.js +45 -19
- package/dist/core/scene/nodeMemo.js.map +1 -1
- package/dist/core/scene/nodeStore.js +126 -0
- package/dist/core/scene/nodeStore.js.map +1 -0
- package/dist/core/scene/pickability.js +6 -0
- package/dist/core/scene/pickability.js.map +1 -0
- package/dist/core/scene/poseFeed.js +38 -38
- package/dist/core/scene/poseFeed.js.map +1 -1
- package/dist/core/scene/poseOverrides.js +34 -38
- package/dist/core/scene/poseOverrides.js.map +1 -1
- package/dist/core/scene/renderOrder.js +84 -0
- package/dist/core/scene/renderOrder.js.map +1 -0
- package/dist/core/scene/scene.js +289 -866
- package/dist/core/scene/scene.js.map +1 -1
- package/dist/core/scene/serialization.js +68 -0
- package/dist/core/scene/serialization.js.map +1 -0
- package/dist/core/scene/treeOrder.js +13 -0
- package/dist/core/scene/treeOrder.js.map +1 -0
- package/dist/core/scene/types.js.map +1 -1
- package/dist/core/viewport/meanScale.js +1 -1
- package/dist/core/viewport/meanScale.js.map +1 -1
- package/dist/core/viewport/view.js +12 -12
- package/dist/core/viewport/view.js.map +1 -1
- package/dist/core/viewport/zoomBounds.js +10 -8
- package/dist/core/viewport/zoomBounds.js.map +1 -1
- package/dist/{cornerHandles-BCrDp_mH.d.ts → cornerHandles-CtCb8a3G.d.ts} +1 -1
- package/dist/debug/createDebugOverlayLayer.js +14 -14
- package/dist/debug/createDebugOverlayLayer.js.map +1 -1
- package/dist/debug/flag.js +2 -41
- package/dist/features/chrome-caps/useHoverTracking.js +22 -17
- package/dist/features/chrome-caps/useHoverTracking.js.map +1 -1
- package/dist/features/focus/gateLayer.js +3 -4
- package/dist/features/focus/gateLayer.js.map +1 -1
- package/dist/features/images/imageCache.js +19 -9
- package/dist/features/images/imageCache.js.map +1 -1
- package/dist/features/ingestion/contentHandlers.js +14 -11
- package/dist/features/ingestion/contentHandlers.js.map +1 -1
- package/dist/features/ingestion/index.js +1 -1
- package/dist/features/ingestion/registerKitHandlers.js +7 -7
- package/dist/features/ingestion/weaselJsonHandler.js +17 -14
- package/dist/features/ingestion/weaselJsonHandler.js.map +1 -1
- package/dist/features/meshPaint/lazyKind.js +201 -35
- package/dist/features/meshPaint/lazyKind.js.map +1 -1
- package/dist/features/meshPaint/meshPaint.js +82 -79
- package/dist/features/meshPaint/meshPaint.js.map +1 -1
- package/dist/features/minimap/createMinimapContribution.js +42 -42
- package/dist/features/minimap/layers.js +44 -62
- package/dist/features/minimap/layers.js.map +1 -1
- package/dist/features/parallax/createParallaxPlane.js +10 -14
- package/dist/features/parallax/createParallaxPlane.js.map +1 -1
- package/dist/features/paths/anchorEdits.js +19 -8
- package/dist/features/paths/anchorEdits.js.map +1 -1
- package/dist/features/paths/anchors.js +31 -26
- package/dist/features/paths/anchors.js.map +1 -1
- package/dist/features/paths/booleans.js +2 -2
- package/dist/features/paths/index.js +13 -11
- package/dist/features/paths/markerCommands.js +37 -36
- package/dist/features/paths/markerCommands.js.map +1 -1
- package/dist/features/paths/pathInWorld.js +19 -19
- package/dist/features/paths/pathInWorld.js.map +1 -1
- package/dist/features/paths/pathLayer.js.map +1 -1
- package/dist/features/paths/strokeToPath.js +40 -0
- package/dist/features/paths/strokeToPath.js.map +1 -0
- package/dist/features/paths/tessellate/stroke.js.map +1 -1
- package/dist/features/patterns/commandPaint.js +18 -0
- package/dist/features/patterns/commandPaint.js.map +1 -0
- package/dist/features/patterns/index.js +5 -17
- package/dist/features/patterns/index.js.map +1 -1
- package/dist/features/patterns/rasterizeTile.js +17 -0
- package/dist/features/patterns/rasterizeTile.js.map +1 -0
- package/dist/features/patterns/resolveSpec.js +52 -44
- package/dist/features/patterns/resolveSpec.js.map +1 -1
- package/dist/features/poseRun/usePoseRun.js +8 -3
- package/dist/features/poseRun/usePoseRun.js.map +1 -1
- package/dist/features/selection/SelectionContext.js +5 -0
- package/dist/features/selection/SelectionContext.js.map +1 -1
- package/dist/features/selection/overlay.js +18 -18
- package/dist/features/selection/overlay.js.map +1 -1
- package/dist/features/text/domOffsets.js +82 -0
- package/dist/features/text/domOffsets.js.map +1 -0
- package/dist/features/text/domRuns.js +103 -131
- package/dist/features/text/domRuns.js.map +1 -1
- package/dist/features/text/hitTest.js +5 -2
- package/dist/features/text/hitTest.js.map +1 -1
- package/dist/features/text/isTextData.js +8 -0
- package/dist/features/text/isTextData.js.map +1 -0
- package/dist/features/text/overlayDirection.js +15 -0
- package/dist/features/text/overlayDirection.js.map +1 -0
- package/dist/features/text/runs/rangeStyle.js +32 -34
- package/dist/features/text/runs/rangeStyle.js.map +1 -1
- package/dist/features/text/textCommand.js +34 -33
- package/dist/features/text/textCommand.js.map +1 -1
- package/dist/features/text/textToPath.js +40 -40
- package/dist/features/text/textToPath.js.map +1 -1
- package/dist/features/text/useSceneTextEdit.js +76 -82
- package/dist/features/text/useSceneTextEdit.js.map +1 -1
- package/dist/features/text/useTextEdit.js +184 -160
- package/dist/features/text/useTextEdit.js.map +1 -1
- package/dist/features/tiling/createTiledLayer.js +24 -22
- package/dist/features/tiling/createTiledLayer.js.map +1 -1
- package/dist/index.d.ts +11033 -7749
- package/dist/index.js +316 -309
- package/dist/input/keyState.js +42 -43
- package/dist/input/keyState.js.map +1 -1
- package/dist/input/useKeyModifiers.js +11 -0
- package/dist/input/useKeyModifiers.js.map +1 -0
- package/dist/interactions/actions/align/align.js +8 -8
- package/dist/interactions/actions/clipboard/clipboardOps.js +34 -32
- package/dist/interactions/actions/clipboard/clipboardOps.js.map +1 -1
- package/dist/interactions/actions/clipboard/materializePaste.js +10 -7
- package/dist/interactions/actions/clipboard/materializePaste.js.map +1 -1
- package/dist/interactions/actions/clipboard/wireFormat.js.map +1 -1
- package/dist/interactions/actions/clone/behaviors/cloneByAltDrag.js.map +1 -1
- package/dist/interactions/actions/defaultCommitAdapter.js +20 -18
- package/dist/interactions/actions/defaultCommitAdapter.js.map +1 -1
- package/dist/interactions/actions/defaults/align.js +9 -10
- package/dist/interactions/actions/defaults/align.js.map +1 -1
- package/dist/interactions/actions/defaults/anchorEditing.js +59 -81
- package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -1
- package/dist/interactions/actions/defaults/areaSelect.js +35 -38
- package/dist/interactions/actions/defaults/areaSelect.js.map +1 -1
- package/dist/interactions/actions/defaults/clipboard.js +26 -10
- package/dist/interactions/actions/defaults/clipboard.js.map +1 -1
- package/dist/interactions/actions/defaults/clone.js +44 -60
- package/dist/interactions/actions/defaults/clone.js.map +1 -1
- package/dist/interactions/actions/defaults/copySubtree.js +40 -0
- package/dist/interactions/actions/defaults/copySubtree.js.map +1 -0
- package/dist/interactions/actions/defaults/distribute.js +14 -13
- package/dist/interactions/actions/defaults/distribute.js.map +1 -1
- package/dist/interactions/actions/defaults/duplicate.js +17 -57
- package/dist/interactions/actions/defaults/duplicate.js.map +1 -1
- package/dist/interactions/actions/defaults/editAnchors.js +18 -18
- package/dist/interactions/actions/defaults/enterTextEdit.js.map +1 -1
- package/dist/interactions/actions/defaults/flip.js +52 -46
- package/dist/interactions/actions/defaults/flip.js.map +1 -1
- package/dist/interactions/actions/defaults/group.js +43 -48
- package/dist/interactions/actions/defaults/group.js.map +1 -1
- package/dist/interactions/actions/defaults/ingest.js +35 -33
- package/dist/interactions/actions/defaults/ingest.js.map +1 -1
- package/dist/interactions/actions/defaults/insert.js +50 -51
- package/dist/interactions/actions/defaults/insert.js.map +1 -1
- package/dist/interactions/actions/defaults/insertPathAnchor.js +7 -7
- package/dist/interactions/actions/defaults/lassoSelect.js +67 -70
- package/dist/interactions/actions/defaults/lassoSelect.js.map +1 -1
- package/dist/interactions/actions/defaults/move.js +267 -249
- package/dist/interactions/actions/defaults/move.js.map +1 -1
- package/dist/interactions/actions/defaults/nudge.js +40 -68
- package/dist/interactions/actions/defaults/nudge.js.map +1 -1
- package/dist/interactions/actions/defaults/nudgeSteps.js +37 -0
- package/dist/interactions/actions/defaults/nudgeSteps.js.map +1 -0
- package/dist/interactions/actions/defaults/reorder.js +2 -0
- package/dist/interactions/actions/defaults/reorder.js.map +1 -1
- package/dist/interactions/actions/defaults/resize.js +104 -98
- package/dist/interactions/actions/defaults/resize.js.map +1 -1
- package/dist/interactions/actions/defaults/rotate.js +111 -110
- package/dist/interactions/actions/defaults/rotate.js.map +1 -1
- package/dist/interactions/actions/defaults/setFill.js +7 -7
- package/dist/interactions/actions/defaults/setFillOpacity.js +4 -4
- package/dist/interactions/actions/defaults/setStroke.js +12 -12
- package/dist/interactions/actions/defaults/setStrokeOpacity.js +6 -6
- package/dist/interactions/actions/defaults/sliceOps.js +19 -19
- package/dist/interactions/actions/defaults/viewportDragPan.js +37 -26
- package/dist/interactions/actions/defaults/viewportDragPan.js.map +1 -1
- package/dist/interactions/actions/edit-anchors/geometry.js +28 -23
- package/dist/interactions/actions/edit-anchors/geometry.js.map +1 -1
- package/dist/interactions/actions/flip/helpers.js +30 -17
- package/dist/interactions/actions/flip/helpers.js.map +1 -1
- package/dist/interactions/actions/hitSelection.js +8 -0
- package/dist/interactions/actions/hitSelection.js.map +1 -0
- package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js +14 -18
- package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js.map +1 -1
- package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js +5 -5
- package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js.map +1 -1
- package/dist/interactions/actions/move/behaviors/snapToContainer.js +32 -21
- package/dist/interactions/actions/move/behaviors/snapToContainer.js.map +1 -1
- package/dist/interactions/actions/move/gestureAdapter.js +32 -15
- package/dist/interactions/actions/move/gestureAdapter.js.map +1 -1
- package/dist/interactions/actions/move/landedDescendants.js +33 -0
- package/dist/interactions/actions/move/landedDescendants.js.map +1 -0
- package/dist/interactions/actions/outlines/createOutlines.js +18 -18
- package/dist/interactions/actions/poseDescriptorDep.js +16 -4
- package/dist/interactions/actions/poseDescriptorDep.js.map +1 -1
- package/dist/interactions/actions/poseFrame.js +11 -6
- package/dist/interactions/actions/poseFrame.js.map +1 -1
- package/dist/interactions/actions/previewOverrides.js +5 -5
- package/dist/interactions/actions/previewOverrides.js.map +1 -1
- package/dist/interactions/actions/selectionSubtree.js +69 -0
- package/dist/interactions/actions/selectionSubtree.js.map +1 -0
- package/dist/interactions/actions/useStandardActions.js +66 -62
- package/dist/interactions/actions/useStandardActions.js.map +1 -1
- package/dist/interactions/gestures/dragGesture/dragGesture.js +4 -7
- package/dist/interactions/gestures/dragGesture/dragGesture.js.map +1 -1
- package/dist/interactions/gestures/dragGesture/dragPointOf.js +23 -0
- package/dist/interactions/gestures/dragGesture/dragPointOf.js.map +1 -0
- package/dist/interactions/gestures/handleDrag/handleDrag.js +21 -26
- package/dist/interactions/gestures/handleDrag/handleDrag.js.map +1 -1
- package/dist/interactions/gestures/pointerDrag/pointerDrag.js +8 -6
- package/dist/interactions/gestures/pointerDrag/pointerDrag.js.map +1 -1
- package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js +8 -4
- package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js.map +1 -1
- package/dist/{math-Drrw4ewZ.d.ts → math-J-ACHyEg.d.ts} +1 -2
- package/dist/math.d.ts +2 -3
- package/dist/move.d.ts +12 -11
- package/dist/{originProjection-DEklpDc_.d.ts → originProjection-gHnOup4e.d.ts} +1 -1
- package/dist/{registerProgram-BMZRDgrh.d.ts → registerProgram-T9S_PfAX.d.ts} +18 -7
- package/dist/renderer/DrawCommand.js.map +1 -1
- package/dist/renderer/WeaselRenderer.js +75 -73
- package/dist/renderer/WeaselRenderer.js.map +1 -1
- package/dist/renderer/cache/GLImageCache.js +15 -5
- package/dist/renderer/cache/GLImageCache.js.map +1 -1
- package/dist/renderer/cache/GLMeshCache.js +23 -23
- package/dist/renderer/cache/GLMeshCache.js.map +1 -1
- package/dist/renderer/cache/GLTextureCache.js +18 -1
- package/dist/renderer/cache/GLTextureCache.js.map +1 -1
- package/dist/renderer/cache/cache.js.map +1 -1
- package/dist/renderer/cache/markerCommandCache.js.map +1 -1
- package/dist/renderer/cache/strokeMeshCache.js.map +1 -1
- package/dist/renderer/cullDrawCommands.js +11 -11
- package/dist/renderer/draw/batch.js +133 -0
- package/dist/renderer/draw/batch.js.map +1 -0
- package/dist/renderer/draw/clip.js +89 -0
- package/dist/renderer/draw/clip.js.map +1 -0
- package/dist/renderer/draw/customShader.js +230 -0
- package/dist/renderer/draw/customShader.js.map +1 -0
- package/dist/renderer/draw/drawTriangles.js +8 -0
- package/dist/renderer/draw/drawTriangles.js.map +1 -0
- package/dist/renderer/draw/effects.js +28 -0
- package/dist/renderer/draw/effects.js.map +1 -0
- package/dist/renderer/draw/flushBatch.js +35 -0
- package/dist/renderer/draw/flushBatch.js.map +1 -0
- package/dist/renderer/draw/gradient.js +90 -0
- package/dist/renderer/draw/gradient.js.map +1 -0
- package/dist/renderer/draw/image.js +38 -0
- package/dist/renderer/draw/image.js.map +1 -0
- package/dist/renderer/draw/mesh.js +16 -0
- package/dist/renderer/draw/mesh.js.map +1 -0
- package/dist/renderer/draw/paintBind.js +70 -0
- package/dist/renderer/draw/paintBind.js.map +1 -0
- package/dist/renderer/draw/pathPaint.js +142 -0
- package/dist/renderer/draw/pathPaint.js.map +1 -0
- package/dist/renderer/draw/scratchPass.js +83 -0
- package/dist/renderer/draw/scratchPass.js.map +1 -0
- package/dist/renderer/draw/stencil.js +28 -0
- package/dist/renderer/draw/stencil.js.map +1 -0
- package/dist/renderer/draw/text.js +167 -0
- package/dist/renderer/draw/text.js.map +1 -0
- package/dist/renderer/draw/uniforms.js +77 -0
- package/dist/renderer/draw/uniforms.js.map +1 -0
- package/dist/renderer/draw.js +60 -1116
- package/dist/renderer/draw.js.map +1 -1
- package/dist/renderer/effects/EffectTargets.js +3 -0
- package/dist/renderer/effects/EffectTargets.js.map +1 -1
- package/dist/renderer/effects/composite.js +7 -5
- package/dist/renderer/effects/composite.js.map +1 -1
- package/dist/renderer/index.js +18 -17
- package/dist/renderer/math/color.js +63 -83
- package/dist/renderer/math/color.js.map +1 -1
- package/dist/renderer/math/mat3.js +15 -11
- package/dist/renderer/math/mat3.js.map +1 -1
- package/dist/renderer/math/viewToMat3.js +1 -1
- package/dist/renderer/math/viewToMat3.js.map +1 -1
- package/dist/renderer/shaders/ShaderProgram.js +13 -13
- package/dist/renderer/shaders/ShaderProgram.js.map +1 -1
- package/dist/renderer/shaders/glyphPaint.js +3 -3
- package/dist/renderer/shaders/glyphPaint.js.map +1 -1
- package/dist/renderer/shaders/gradFill.js +2 -1
- package/dist/renderer/shaders/gradFill.js.map +1 -1
- package/dist/renderer/shaders/pathFill.js +2 -1
- package/dist/renderer/shaders/pathFill.js.map +1 -1
- package/dist/renderer/shaders/patternFill.js +2 -1
- package/dist/renderer/shaders/patternFill.js.map +1 -1
- package/dist/renderer/shaders/registerProgram.js.map +1 -1
- package/dist/renderer/strokeLengths.js.map +1 -1
- package/dist/renderer/textures/registerTexture.js +25 -5
- package/dist/renderer/textures/registerTexture.js.map +1 -1
- package/dist/renderer.d.ts +16 -15
- package/dist/renderer.js +17 -16
- package/dist/resize.d.ts +5 -6
- package/dist/resize.js +5 -5
- package/dist/style.css +1 -1
- package/dist/test-hook/install.js +12 -6
- package/dist/test-hook/install.js.map +1 -1
- package/dist/{test-seams-CuIxe0xY.d.ts → test-seams-DM2B87-g.d.ts} +4 -4
- package/dist/test-seams.d.ts +2 -2
- package/dist/tools/builtin/ellipse/useEllipseTool.js +1 -0
- package/dist/tools/builtin/ellipse/useEllipseTool.js.map +1 -1
- package/dist/tools/builtin/hand/useHandTool.js +1 -0
- package/dist/tools/builtin/hand/useHandTool.js.map +1 -1
- package/dist/tools/builtin/lasso/useLassoTool.js +11 -11
- package/dist/tools/builtin/lasso/useLassoTool.js.map +1 -1
- package/dist/tools/builtin/line/useLineTool.js +1 -0
- package/dist/tools/builtin/line/useLineTool.js.map +1 -1
- package/dist/tools/builtin/pen/usePenTool.js +153 -103
- package/dist/tools/builtin/pen/usePenTool.js.map +1 -1
- package/dist/tools/builtin/pencil/usePencilTool.js +1 -0
- package/dist/tools/builtin/pencil/usePencilTool.js.map +1 -1
- package/dist/tools/builtin/polygon/usePolygonTool.js +13 -8
- package/dist/tools/builtin/polygon/usePolygonTool.js.map +1 -1
- package/dist/tools/builtin/rect/useRectTool.js +1 -0
- package/dist/tools/builtin/rect/useRectTool.js.map +1 -1
- package/dist/tools/builtin/select/selectionContributions.js +24 -23
- package/dist/tools/builtin/select/selectionContributions.js.map +1 -1
- package/dist/tools/builtin/select/useSelectTool.js +51 -48
- package/dist/tools/builtin/select/useSelectTool.js.map +1 -1
- package/dist/tools/builtin/shared/pointerFollower.js +17 -0
- package/dist/tools/builtin/shared/pointerFollower.js.map +1 -0
- package/dist/tools/builtin/slice/useSliceTool.js +49 -54
- package/dist/tools/builtin/slice/useSliceTool.js.map +1 -1
- package/dist/tools/builtin/star/useStarTool.js +22 -16
- package/dist/tools/builtin/star/useStarTool.js.map +1 -1
- package/dist/tools/builtin/text/useTextTool.js +1 -0
- package/dist/tools/builtin/text/useTextTool.js.map +1 -1
- package/dist/tools/useKeybindings.js +14 -30
- package/dist/tools/useKeybindings.js.map +1 -1
- package/dist/{types-B_9g6hMM.d.ts → types-B4iJRHC3.d.ts} +5 -1
- package/dist/{types-A37hYkeR.d.ts → types-k-5Oqh-U.d.ts} +31 -7
- package/dist/util/color.js +3 -3
- package/dist/util/color.js.map +1 -1
- package/dist/util/paint.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +20 -18
- package/dist/autoPoseDescriptor-vCdt55xm.d.ts +0 -27
- package/dist/builtins-C-VgUlWI.d.ts +0 -4514
- package/dist/core/isPlainObject.js.map +0 -1
- package/dist/debug/flag.js.map +0 -1
- package/dist/interactions/actions/defaults/freshNodeId.js +0 -10
- package/dist/interactions/actions/defaults/freshNodeId.js.map +0 -1
- package/dist/renderer/shaders/imageFill.js +0 -14
- package/dist/renderer/shaders/imageFill.js.map +0 -1
- package/dist/tools/prefs.js +0 -62
- package/dist/tools/prefs.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { pathToAnchors as e } from "../../../features/paths/anchors.js";
|
|
2
|
+
import { worldEditToStorage as t } from "../../../features/paths/pathInWorld.js";
|
|
3
|
+
import { editingLayer as n, inPlane as r } from "../planeInput.js";
|
|
4
|
+
import { anchorAt as i, editAnchorSet as a, moveHandleTo as o, translateAnchorBy as s } from "../../../features/paths/anchorEdits.js";
|
|
5
5
|
import { isAnchorOrControl as c } from "@weasel-js/routing";
|
|
6
6
|
//#region src/interactions/actions/defaults/editAnchors.ts
|
|
7
7
|
function l(e) {
|
|
@@ -18,7 +18,7 @@ function u(e, t, n) {
|
|
|
18
18
|
}
|
|
19
19
|
return e.has(t) && e.size > 1 ? new Set(e) : /* @__PURE__ */ new Set([t]);
|
|
20
20
|
}
|
|
21
|
-
var d =
|
|
21
|
+
var d = r({
|
|
22
22
|
id: "editAnchors",
|
|
23
23
|
label: "Edit Anchors",
|
|
24
24
|
defaultBinding: {
|
|
@@ -29,10 +29,10 @@ var d = t({
|
|
|
29
29
|
requires: ["selection", "editAnchors"],
|
|
30
30
|
invoker: {
|
|
31
31
|
timing: "ongoing",
|
|
32
|
-
start(
|
|
33
|
-
let c =
|
|
32
|
+
start(n, r) {
|
|
33
|
+
let c = n.deps.editAnchors;
|
|
34
34
|
if (!c) return {};
|
|
35
|
-
let d =
|
|
35
|
+
let d = n.drag?.affordance;
|
|
36
36
|
if (!d) return {};
|
|
37
37
|
let f = l(d.kind);
|
|
38
38
|
if (!f) return {};
|
|
@@ -40,12 +40,12 @@ var d = t({
|
|
|
40
40
|
if (!m || m.kind !== "polygon") return {};
|
|
41
41
|
let h = c.getStorageKind(p);
|
|
42
42
|
if (h !== "pose" && h !== "data") return {};
|
|
43
|
-
let g =
|
|
43
|
+
let g = e(m), _ = i(g, f.anchorIndex);
|
|
44
44
|
if (!_ || f.part === "controlIn" && !_.inHandle || f.part === "controlOut" && !_.outHandle) return {};
|
|
45
45
|
let v = [f.anchorIndex];
|
|
46
46
|
if (f.part === "anchor") {
|
|
47
|
-
let
|
|
48
|
-
c.setSelectedAnchors(
|
|
47
|
+
let e = u(c.selectedAnchors, f.anchorIndex, n.modifiers.shift);
|
|
48
|
+
c.setSelectedAnchors(e), v = e.has(f.anchorIndex) ? [...e] : [];
|
|
49
49
|
}
|
|
50
50
|
let y = h === "data" ? c.getNodeShape(p) : null, b = y ? y.pose : void 0, x = y ? y.data : void 0, S = {
|
|
51
51
|
dep: c,
|
|
@@ -66,12 +66,12 @@ var d = t({
|
|
|
66
66
|
onMove(e) {
|
|
67
67
|
if (S.part === "anchor") {
|
|
68
68
|
if (S.dragging.length === 0) return;
|
|
69
|
-
let t = e.world.x - S.anchorOrigin.x, n = e.world.y - S.anchorOrigin.y, r =
|
|
70
|
-
for (let r of S.dragging)
|
|
69
|
+
let t = e.world.x - S.anchorOrigin.x, n = e.world.y - S.anchorOrigin.y, r = a(S.originPose, (e) => {
|
|
70
|
+
for (let r of S.dragging) s(e, r, t, n);
|
|
71
71
|
});
|
|
72
72
|
r && (S.currentPose = r);
|
|
73
73
|
} else {
|
|
74
|
-
let t = S.part === "controlIn" ? "in" : "out", n =
|
|
74
|
+
let t = S.part === "controlIn" ? "in" : "out", n = a(S.originPose, (n) => o(n, S.anchorIndex, t, e.world.x, e.world.y, e.modifiers.alt));
|
|
75
75
|
n && (S.currentPose = n);
|
|
76
76
|
}
|
|
77
77
|
C = !0;
|
|
@@ -80,20 +80,20 @@ var d = t({
|
|
|
80
80
|
C = !1, t !== "cancel" && S.originPose !== S.currentPose && S.dep.applyEdit(S.id, S.currentPose, "Edit anchors");
|
|
81
81
|
},
|
|
82
82
|
previewIds: () => C ? [S.id] : null,
|
|
83
|
-
previewPose: (e) => !C || e !== S.id ? null : S.storageKind === "pose" ? S.currentPose : b ?
|
|
83
|
+
previewPose: (e) => !C || e !== S.id ? null : S.storageKind === "pose" ? S.currentPose : b ? t(b, S.currentPose).pose : null,
|
|
84
84
|
previewData: (e) => {
|
|
85
85
|
if (!C || e !== S.id || S.storageKind !== "data" || !x) return null;
|
|
86
|
-
let { path:
|
|
86
|
+
let { path: n } = t(b, S.currentPose);
|
|
87
87
|
return {
|
|
88
88
|
...x,
|
|
89
|
-
path:
|
|
89
|
+
path: n
|
|
90
90
|
};
|
|
91
91
|
}
|
|
92
92
|
};
|
|
93
93
|
}
|
|
94
94
|
},
|
|
95
95
|
enabled: () => !0
|
|
96
|
-
},
|
|
96
|
+
}, n);
|
|
97
97
|
//#endregion
|
|
98
98
|
export { d as editAnchorsAction, u as selectionAfterAnchorPress };
|
|
99
99
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enterTextEdit.js","names":["enterTextEditAction","sel","deps","id","textEdit"],"sources":["../../../../src/interactions/actions/defaults/enterTextEdit.ts"],"sourcesContent":["/**\n * `enterTextEditAction` — immediate Action descriptor for entering in-place\n * text editing on a selected text node.\n *\n * ## Status: REAL\n *\n * Fires via `useTextTool.bindings` when the user clicks on a\n * selected text node. Calls `deps.textEdit.startEdit(id)` to activate the\n * contenteditable overlay managed by `useTextEdit` / `useSceneTextEdit`.\n *\n * ## No defaultBinding / defaultBinding\n *\n * This action has no ambient key or gesture binding — it fires ONLY via\n * `useTextTool`'s `Tool.bindings` entry:\n *\n * ```ts\n * bindings: [\n * { spec: { kind: 'click', target: 'selected-body' }, actionId: 'enterTextEdit' },\n * ]\n * ```\n *\n * Keeping it binding-free avoids ambient double-fire and scopes the action to\n * the text tool context where `classifyTarget` is already wired.\n *\n * ## Self-guard: only act on text nodes\n *\n * The `'selected-body'` target yields a match for any selected node kind. To\n * avoid entering text-edit mode when the text tool happens to have a non-text\n * node selected, the action self-guards via an optional `isTextNode` predicate\n * on `TextEditDep`:\n *\n * - When `isTextNode` is absent: action fires unconditionally (the binding\n * spec is the real gate — consumers should only bind this action from the\n * text tool).\n * - When `isTextNode(id)` returns `false`: action is a no-op for that node.\n *\n * ### Pre-filtering at dispatch time\n *\n * `classifyTarget` now surfaces node kind, so a binding can pre-filter instead\n * of relying on the self-guard:\n *\n * ```ts\n * { spec: { kind: 'click', target: 'kind:text:selected' }, actionId: 'enterTextEdit' }\n * ```\n *\n * That reads the *routing trait's* kind, so it matches whatever names the\n * consumer registered in `<SceneCanvas routing>` — `'text'` under the kit's\n * inferred default. `isTextNode` stays on `TextEditDep` because it also covers\n * consumers who bind the broader `'selected-body'` target, and because it is\n * the only guard for a consumer who opted out of routing entirely.\n *\n * ## Migration plan for useTextTool\n *\n * When wiring `useTextTool` to `Tool.bindings`:\n *\n * 1. Add to `useTextTool`'s `bindings`:\n * ```ts\n * { spec: { kind: 'click', target: 'selected-body' }, actionId: 'enterTextEdit' }\n * ```\n * 2. Register a `textEdit` dep sourced from the `useTextEdit` / `useSceneTextEdit`\n * return value, plus an `isTextNode` predicate
|
|
1
|
+
{"version":3,"file":"enterTextEdit.js","names":["enterTextEditAction","sel","deps","id","textEdit"],"sources":["../../../../src/interactions/actions/defaults/enterTextEdit.ts"],"sourcesContent":["/**\n * `enterTextEditAction` — immediate Action descriptor for entering in-place\n * text editing on a selected text node.\n *\n * ## Status: REAL\n *\n * Fires via `useTextTool.bindings` when the user clicks on a\n * selected text node. Calls `deps.textEdit.startEdit(id)` to activate the\n * contenteditable overlay managed by `useTextEdit` / `useSceneTextEdit`.\n *\n * ## No defaultBinding / defaultBinding\n *\n * This action has no ambient key or gesture binding — it fires ONLY via\n * `useTextTool`'s `Tool.bindings` entry:\n *\n * ```ts\n * bindings: [\n * { spec: { kind: 'click', target: 'selected-body' }, actionId: 'enterTextEdit' },\n * ]\n * ```\n *\n * Keeping it binding-free avoids ambient double-fire and scopes the action to\n * the text tool context where `classifyTarget` is already wired.\n *\n * ## Self-guard: only act on text nodes\n *\n * The `'selected-body'` target yields a match for any selected node kind. To\n * avoid entering text-edit mode when the text tool happens to have a non-text\n * node selected, the action self-guards via an optional `isTextNode` predicate\n * on `TextEditDep`:\n *\n * - When `isTextNode` is absent: action fires unconditionally (the binding\n * spec is the real gate — consumers should only bind this action from the\n * text tool).\n * - When `isTextNode(id)` returns `false`: action is a no-op for that node.\n *\n * ### Pre-filtering at dispatch time\n *\n * `classifyTarget` now surfaces node kind, so a binding can pre-filter instead\n * of relying on the self-guard:\n *\n * ```ts\n * { spec: { kind: 'click', target: 'kind:text:selected' }, actionId: 'enterTextEdit' }\n * ```\n *\n * That reads the *routing trait's* kind, so it matches whatever names the\n * consumer registered in `<SceneCanvas routing>` — `'text'` under the kit's\n * inferred default. `isTextNode` stays on `TextEditDep` because it also covers\n * consumers who bind the broader `'selected-body'` target, and because it is\n * the only guard for a consumer who opted out of routing entirely.\n *\n * ## Migration plan for useTextTool\n *\n * When wiring `useTextTool` to `Tool.bindings`:\n *\n * 1. Add to `useTextTool`'s `bindings`:\n * ```ts\n * { spec: { kind: 'click', target: 'selected-body' }, actionId: 'enterTextEdit' }\n * ```\n * 2. Register a `textEdit` dep sourced from the `useTextEdit` / `useSceneTextEdit`\n * return value, plus an `isTextNode` predicate (`isTextData`, or however the\n * consumer identifies text nodes).\n * 3. The existing `hitExisting` gate in `useTextTool`'s click route becomes\n * redundant — remove it in the same pass.\n */\n\nimport type { Action } from '@weasel-js/routing';\n\n// ---------------------------------------------------------------------------\n// TextEditDep\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// Descriptor\n// ---------------------------------------------------------------------------\n\n/**\n * @experimental\n * Static descriptor for the `enterTextEdit` Action.\n *\n * Requires dep-schema entries: `textEdit`, `selection`.\n *\n * No `defaultBinding` / `defaultBinding` — fires only via `Tool.bindings`.\n * Self-guards via `TextEditDep.isTextNode` when provided.\n */\nexport const enterTextEditAction: Action & { requires: string[] } = {\n id: 'enterTextEdit',\n label: 'Enter text edit',\n // No defaultBinding / defaultBinding — fires only via Tool.bindings.\n eligible: { mode: { in: ['normal', 'isolation'] } },\n requires: ['textEdit', 'selection'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n const sel = deps.selection?.get() ?? [];\n if (sel.length !== 1) return;\n\n const id = sel[0];\n const textEdit = deps.textEdit;\n if (!textEdit) return;\n\n // Self-guard: skip non-text nodes when the predicate is supplied.\n if (textEdit.isTextNode && !textEdit.isTextNode(id)) return;\n\n textEdit.startEdit(id);\n },\n },\n};\n"],"mappings":";AAqFA,IAAaA,IAAuD;CAClE,IAAI;CACJ,OAAO;CAEP,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,UAAU,WAAW,EAAE,EAAE;CAClD,UAAU,CAAC,YAAY,WAAW;CAClC,SAAS;EACP,QAAQ;EACR,MAAM,MAAS;GACb,IAAMC,IAAMC,EAAK,WAAW,IAAI,KAAK,CAAC;GACtC,IAAID,EAAI,WAAW,GAAG;GAEtB,IAAME,IAAKF,EAAI,IACTG,IAAWF,EAAK;GACtB,AAAKE,MAGD,GAAS,cAAeA,EAAS,WAAWD,CAAE,MAElDC,EAAS,UAAUD,CAAE;EACvB;CACF;AACF"}
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { createTransformOp as e } from "../../../core/ops/transform.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
2
|
+
import { unionAABB as t } from "../../../core/geometry/unionBounds.js";
|
|
3
|
+
import { visualBoundsViaDescriptor as n } from "../../../core/geometry/poseDescriptor.js";
|
|
4
|
+
import { shapeSources as r } from "../selectionSubtree.js";
|
|
5
|
+
import { geometryDataOp as i } from "../geometryProjection.js";
|
|
6
|
+
import { poseDescriptorOf as a } from "../poseDescriptorDep.js";
|
|
7
|
+
import { defaultCommitAdapter as o } from "../defaultCommitAdapter.js";
|
|
8
|
+
import { scenePoseFrame as s } from "../poseFrame.js";
|
|
9
|
+
import { FlipXIcon as c, FlipYIcon as l } from "./icons/editIcons.js";
|
|
10
|
+
import { requiresSelection as u } from "./requiresSelection.js";
|
|
11
|
+
import { flipPoseAboutBounds as d, flipPoseViaDescriptor as f } from "../flip/helpers.js";
|
|
12
|
+
import { actionReferenceSources as p, resolveSpatialReference as m } from "../spatialReference.js";
|
|
13
|
+
import { multiply as h, rotate as g, translate as _ } from "@weasel-js/geom";
|
|
14
|
+
import { createElement as v } from "react";
|
|
14
15
|
//#region src/interactions/actions/defaults/flip.ts
|
|
15
|
-
function
|
|
16
|
+
function y(e, t, n, r) {
|
|
16
17
|
let i = t.local(n, {
|
|
17
18
|
x: r.x + r.width / 2,
|
|
18
19
|
y: r.y + r.height / 2,
|
|
@@ -33,50 +34,55 @@ function v(e, t, n, r) {
|
|
|
33
34
|
-1,
|
|
34
35
|
0,
|
|
35
36
|
0
|
|
36
|
-
], s =
|
|
37
|
-
return
|
|
37
|
+
], s = h(h(g(a), o), g(-a));
|
|
38
|
+
return h(_(i.x, i.y), h(s, _(-i.x, -i.y)));
|
|
38
39
|
}
|
|
39
|
-
function
|
|
40
|
-
let
|
|
41
|
-
if (
|
|
42
|
-
let
|
|
43
|
-
for (let e of
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
let
|
|
48
|
-
for (let
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
40
|
+
function b(a, c, l, u, h, g, _, v, b, x) {
|
|
41
|
+
let S = a.get();
|
|
42
|
+
if (S.length === 0) return;
|
|
43
|
+
let C = s(c, v), w = [], T = /* @__PURE__ */ new Map();
|
|
44
|
+
for (let e of S) {
|
|
45
|
+
let t = r(c, [e]), i = t.length !== 1 || t[0] !== e ? n(C.world(e), _) : null;
|
|
46
|
+
for (let e of t) w.includes(e) || (w.push(e), i && T.set(e, i));
|
|
47
|
+
}
|
|
48
|
+
let E = /* @__PURE__ */ new Map();
|
|
49
|
+
for (let e of w) c.get(e) !== void 0 && E.set(e, C.world(e));
|
|
50
|
+
let D = null;
|
|
51
|
+
if (u === "union") D = t([...E.values()].map((e) => n(e, _)));
|
|
52
|
+
else if (u !== "each" && (D = m(u, p(b, x, c, C, _)), D === null)) return;
|
|
53
|
+
let O = [];
|
|
54
|
+
for (let t of w) {
|
|
55
|
+
let n = c.get(t);
|
|
56
|
+
if (!n) continue;
|
|
57
|
+
let r = E.get(t), a = D ?? T.get(t) ?? null, o = a ? d(r, l, _, a) : f(r, l, _);
|
|
58
|
+
O.push(e({
|
|
59
|
+
id: t,
|
|
60
|
+
from: n.pose,
|
|
61
|
+
to: C.local(t, o),
|
|
56
62
|
label: "Flip"
|
|
57
63
|
}));
|
|
58
|
-
let
|
|
59
|
-
id:
|
|
60
|
-
data:
|
|
61
|
-
pose:
|
|
62
|
-
},
|
|
63
|
-
|
|
64
|
+
let s = a ?? _.getBounds(r), u = i(g, {
|
|
65
|
+
id: t,
|
|
66
|
+
data: n.data,
|
|
67
|
+
pose: n.pose
|
|
68
|
+
}, y(l, C, t, s), "Flip");
|
|
69
|
+
u && O.push(u);
|
|
64
70
|
}
|
|
65
|
-
|
|
71
|
+
O.length !== 0 && (h ? h(O, "Flip") : c.applyBatch(O, "Flip", o(c, a.adapterMethods)));
|
|
66
72
|
}
|
|
67
|
-
var
|
|
73
|
+
var x = {
|
|
68
74
|
id: "flip",
|
|
69
75
|
label: "Flip",
|
|
70
76
|
group: "flip",
|
|
71
77
|
variants: [{
|
|
72
78
|
key: "x",
|
|
73
79
|
label: "Flip Horizontal",
|
|
74
|
-
icon:
|
|
80
|
+
icon: v(c),
|
|
75
81
|
params: { axis: "x" }
|
|
76
82
|
}, {
|
|
77
83
|
key: "y",
|
|
78
84
|
label: "Flip Vertical",
|
|
79
|
-
icon:
|
|
85
|
+
icon: v(l),
|
|
80
86
|
params: { axis: "y" }
|
|
81
87
|
}],
|
|
82
88
|
defaultBinding: [{
|
|
@@ -107,13 +113,13 @@ var b = {
|
|
|
107
113
|
invoker: {
|
|
108
114
|
timing: "immediate",
|
|
109
115
|
run: (e, t) => {
|
|
110
|
-
let n = t?.axis ?? "x", r = t?.pivot ?? "each",
|
|
111
|
-
|
|
116
|
+
let n = t?.axis ?? "x", r = t?.pivot ?? "each", i = e.selection, o = e.scene, s = e.applyOps, c = e.geometryProjection;
|
|
117
|
+
i && o && b(i, o, n, r, s, c, a(e.poseDescriptor), e.poseComposition, t, e.pointer);
|
|
112
118
|
}
|
|
113
119
|
},
|
|
114
|
-
enabled:
|
|
120
|
+
enabled: u
|
|
115
121
|
};
|
|
116
122
|
//#endregion
|
|
117
|
-
export {
|
|
123
|
+
export { x as flipAction };
|
|
118
124
|
|
|
119
125
|
//# sourceMappingURL=flip.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flip.js","names":["localMirror","at","frame","id","pivotWorld","theta","mirror","axis","turned","multiply","rotate","translate","flipSelection","ids","selection","scenePoseFrame","scene","poseComposition","worlds","sharedPivot","pivot","unionAABB","visualBoundsViaDescriptor","p","geom","resolveSpatialReference","actionReferenceSources","params","pointer","ops","node","world","flipped","flipPoseAboutBounds","flipPoseViaDescriptor","createTransformOp","g","dataOp","geometryDataOp","geometryProjection","applyOps","defaultCommitAdapter","flipAction","createElement","FlipXIcon","FlipYIcon","deps","poseDescriptorOf","requiresSelection"],"sources":["../../../../src/interactions/actions/defaults/flip.ts"],"sourcesContent":["import type { Scene } from 'core/scene/types';\nimport { createElement } from 'react';\nimport { FlipXIcon, FlipYIcon } from './icons/editIcons';\nimport type { Op } from 'core/ops/types';\nimport { multiply, rotate, translate, type Mat3 } from '@weasel-js/geom';\nimport { createTransformOp } from 'core/ops/transform';\nimport type { PoseDescriptor } from '../resize/geometry';\nimport { poseDescriptorOf } from '../poseDescriptorDep';\nimport {\n flipPoseAboutBounds,\n flipPoseViaDescriptor,\n type FlipAxis,\n type FlipPivot,\n} from '../flip/helpers';\nimport { unionAABB } from 'core/geometry/unionBounds';\nimport { visualBoundsViaDescriptor } from '../align/align';\nimport { scenePoseFrame, type PoseFrame } from '../poseFrame';\nimport { actionReferenceSources, resolveSpatialReference } from '../spatialReference';\nimport type { PointerContextValue } from 'features/pointer/PointerContext';\nimport type { RectPose } from 'core/scene/types';\nimport type { Action } from '@weasel-js/routing';\nimport { defaultCommitAdapter } from '../defaultCommitAdapter';\nimport { requiresSelection } from './requiresSelection';\nimport type { SelectionApi } from 'core/selection/useSelection';\nimport { geometryDataOp, type GeometryProjection } from '../geometryProjection';\n\n/**\n * The world mirror about `axis` through the center of `pivotWorld`, written in\n * the frame `id` stores its data in. `geometryProjection.transform` is given\n * the affine the node's own pose underwent, and data-held geometry is local —\n * so a world mirror has to be conjugated by the frame or an asymmetric shape\n * reflects across the wrong line while its pose lands correctly.\n *\n * The frame's turn comes back as the rotation on a rebased zero-size pose at\n * the pivot point, so no composition strategy has to expose one.\n */\nfunction localMirror(\n axis: FlipAxis,\n frame: PoseFrame<unknown>,\n id: Parameters<PoseFrame<unknown>['local']>[0],\n pivotWorld: { x: number; y: number; width: number; height: number },\n): Mat3 {\n const at = frame.local(id, {\n x: pivotWorld.x + pivotWorld.width / 2,\n y: pivotWorld.y + pivotWorld.height / 2,\n width: 0,\n height: 0,\n rotation: 0,\n }) as RectPose;\n const theta = at.rotation ?? 0;\n const mirror: Mat3 = axis === 'x' ? [-1, 0, 0, 1, 0, 0] : [1, 0, 0, -1, 0, 0];\n const turned = multiply(multiply(rotate(theta), mirror), rotate(-theta));\n return multiply(translate(at.x, at.y), multiply(turned, translate(-at.x, -at.y)));\n}\n\n/**\n * Flip the current selection in `scene` along `axis`, using the\n * `poseDescriptor` dep. Called from `flipAction.invoker.run`.\n *\n * Builds one `createTransformOp` per selected node (from = pre-flip pose,\n * to = flipped pose) and routes the batch through the consumer commit hook.\n * Mirrors `moveAction`/`nudge`'s `commitOps` helper: when `deps.applyOps` is\n * present the ops route through the consumer's history (one undo entry there);\n * otherwise they apply straight to the scene's own history via\n * `scene.applyBatch` + `defaultCommitAdapter`. Either way the whole flip is a\n * single batch → one undo entry, preserving the old `scene.batch('Flip', …)`\n * semantics exactly.\n *\n * Pivot: `'each'` (per-item own AABB) unless the caller passes `'union'`,\n * which mirrors every pose about the selection's *visual* union AABB — the\n * rotated ink extents — so items swap sides as well as reflect, or a\n * `SpatialReference`, which mirrors about the center of what it names. A rotated\n * member's own mirrored position needs no expansion: `axisAlignedBounds`\n * keeps the stored box's centre, so mirroring either box lands the same place.\n */\nfunction flipSelection(\n selection: SelectionApi,\n scene: Scene<unknown, string, unknown>,\n axis: FlipAxis,\n pivot: FlipPivot,\n applyOps: ((ops: Op[], label: string) => void) | undefined,\n geometryProjection: GeometryProjection | undefined,\n geom: PoseDescriptor<unknown>,\n poseComposition: unknown,\n params: Record<string, unknown> | undefined,\n pointer: PointerContextValue | undefined,\n): void {\n const ids = selection.get();\n if (ids.length === 0) return;\n const frame = scenePoseFrame(scene, poseComposition);\n\n const worlds = new Map<string, unknown>();\n for (const id of ids) {\n if (scene.get(id) !== undefined) worlds.set(id as string, frame.world(id));\n }\n let sharedPivot: ReturnType<typeof unionAABB> = null;\n if (pivot === 'union') {\n sharedPivot = unionAABB([...worlds.values()].map((p) => visualBoundsViaDescriptor(p, geom)));\n } else if (pivot !== 'each') {\n sharedPivot = resolveSpatialReference(pivot, actionReferenceSources(params, pointer, scene, frame, geom));\n if (sharedPivot === null) return;\n }\n\n // Read poses BEFORE building ops so each op's `from` is the pre-flip value\n // (the same value the old direct mutation captured implicitly).\n const ops: Op[] = [];\n for (const id of ids) {\n const node = scene.get(id);\n if (!node) continue;\n const world = worlds.get(id as string)!;\n const flipped = sharedPivot\n ? flipPoseAboutBounds(world, axis, geom, sharedPivot)\n : flipPoseViaDescriptor(world, axis, geom);\n ops.push(createTransformOp<unknown>({\n id: id as string,\n from: node.pose,\n to: frame.local(id, flipped),\n label: 'Flip',\n }));\n // Mirror the data-held geometry about the SAME pivot the pose flip uses,\n // so a wired geometryProjection reflects the contents in lock-step with\n // the frame. A pose-only flip of a bare-AABB pose is identity, so this\n // data op is the only way an asymmetric shape actually mirrors.\n const g = sharedPivot ?? geom.getBounds(world);\n const dataOp = geometryDataOp(\n geometryProjection,\n { id: id as string, data: node.data, pose: node.pose },\n localMirror(axis, frame, id, g),\n 'Flip',\n );\n if (dataOp) ops.push(dataOp);\n }\n if (ops.length === 0) return;\n\n if (applyOps) applyOps(ops, 'Flip');\n else scene.applyBatch(ops, 'Flip', defaultCommitAdapter(scene, selection.adapterMethods));\n}\n\n/**\n * @experimental\n * Static descriptor for the unified `flip` Action.\n *\n * Collapses the old `flip.horizontal` and `flip.vertical` pair into one action\n * with two parametric gesture bindings. The axis (`'x'` | `'y'`) is carried in\n * `opts.params.axis` and forwarded to `invoker.run` by the dispatcher, as is\n * the optional `opts.params.pivot` (a `FlipPivot`, default `'each'`).\n *\n * Requires dep-schema entries: `selection`, `scene`.\n */\nexport const flipAction: Action & { requires: string[] } = {\n id: 'flip',\n label: 'Flip',\n group: 'flip',\n variants: [\n { key: 'x', label: 'Flip Horizontal', icon: createElement(FlipXIcon), params: { axis: 'x' } },\n { key: 'y', label: 'Flip Vertical', icon: createElement(FlipYIcon), params: { axis: 'y' } },\n ],\n defaultBinding: [\n { spec: { kind: 'key', key: ['h', 'H'], mods: { shift: true } }, opts: { params: { axis: 'x' } } },\n { spec: { kind: 'key', key: ['v', 'V'], mods: { shift: true } }, opts: { params: { axis: 'y' } } },\n ],\n eligible: { capability: 'transforms-selection' },\n requires: ['selection', 'scene', 'applyOps', 'geometryProjection', 'poseDescriptor', 'poseComposition', 'pointer'],\n invoker: {\n timing: 'immediate',\n run: (deps, params) => {\n const axis = (params?.axis as FlipAxis | undefined) ?? 'x';\n const pivot = (params?.pivot as FlipPivot | undefined) ?? 'each';\n const selection = deps.selection;\n const scene = deps.scene;\n const applyOps = deps.applyOps;\n const geometryProjection = deps.geometryProjection;\n if (!selection || !scene) return;\n flipSelection(\n selection, scene, axis, pivot, applyOps, geometryProjection,\n poseDescriptorOf(deps.poseDescriptor), deps.poseComposition,\n params, deps.pointer,\n );\n },\n },\n enabled: requiresSelection,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"flip.js","names":["localMirror","at","frame","id","pivotWorld","theta","mirror","axis","turned","multiply","rotate","translate","flipSelection","selected","selection","scenePoseFrame","scene","poseComposition","ids","ownPivot","members","shapeSources","box","visualBoundsViaDescriptor","geom","member","worlds","sharedPivot","pivot","unionAABB","p","resolveSpatialReference","actionReferenceSources","params","pointer","ops","node","world","about","flipped","flipPoseAboutBounds","flipPoseViaDescriptor","createTransformOp","g","dataOp","geometryDataOp","geometryProjection","applyOps","defaultCommitAdapter","flipAction","createElement","FlipXIcon","FlipYIcon","deps","poseDescriptorOf","requiresSelection"],"sources":["../../../../src/interactions/actions/defaults/flip.ts"],"sourcesContent":["import type { NodeId, Scene } from 'core/scene/types';\nimport type { Bounds } from 'core/viewport/fitViewToBounds';\nimport { shapeSources } from '../selectionSubtree';\nimport { createElement } from 'react';\nimport { FlipXIcon, FlipYIcon } from './icons/editIcons';\nimport type { Op } from 'core/ops/types';\nimport { multiply, rotate, translate, type Mat3 } from '@weasel-js/geom';\nimport { createTransformOp } from 'core/ops/transform';\nimport type { PoseDescriptor } from '../resize/geometry';\nimport { poseDescriptorOf } from '../poseDescriptorDep';\nimport {\n flipPoseAboutBounds,\n flipPoseViaDescriptor,\n type FlipAxis,\n type FlipPivot,\n} from '../flip/helpers';\nimport { unionAABB } from 'core/geometry/unionBounds';\nimport { visualBoundsViaDescriptor } from '../align/align';\nimport { scenePoseFrame, type PoseFrame } from '../poseFrame';\nimport { actionReferenceSources, resolveSpatialReference } from '../spatialReference';\nimport type { PointerContextValue } from 'features/pointer/PointerContext';\nimport type { RectPose } from 'core/scene/types';\nimport type { Action } from '@weasel-js/routing';\nimport { defaultCommitAdapter } from '../defaultCommitAdapter';\nimport { requiresSelection } from './requiresSelection';\nimport type { SelectionApi } from 'core/selection/useSelection';\nimport { geometryDataOp, type GeometryProjection } from '../geometryProjection';\n\n/**\n * The world mirror about `axis` through the center of `pivotWorld`, written in\n * the frame `id` stores its data in. `geometryProjection.transform` is given\n * the affine the node's own pose underwent, and data-held geometry is local —\n * so a world mirror has to be conjugated by the frame or an asymmetric shape\n * reflects across the wrong line while its pose lands correctly.\n *\n * The frame's turn comes back as the rotation on a rebased zero-size pose at\n * the pivot point, so no composition strategy has to expose one.\n */\nfunction localMirror(\n axis: FlipAxis,\n frame: PoseFrame<unknown>,\n id: Parameters<PoseFrame<unknown>['local']>[0],\n pivotWorld: { x: number; y: number; width: number; height: number },\n): Mat3 {\n const at = frame.local(id, {\n x: pivotWorld.x + pivotWorld.width / 2,\n y: pivotWorld.y + pivotWorld.height / 2,\n width: 0,\n height: 0,\n rotation: 0,\n }) as RectPose;\n const theta = at.rotation ?? 0;\n const mirror: Mat3 = axis === 'x' ? [-1, 0, 0, 1, 0, 0] : [1, 0, 0, -1, 0, 0];\n const turned = multiply(multiply(rotate(theta), mirror), rotate(-theta));\n return multiply(translate(at.x, at.y), multiply(turned, translate(-at.x, -at.y)));\n}\n\n/**\n * Flip the current selection in `scene` along `axis`, using the\n * `poseDescriptor` dep. Called from `flipAction.invoker.run`.\n *\n * Builds one `createTransformOp` per selected node (from = pre-flip pose,\n * to = flipped pose) and routes the batch through the consumer commit hook.\n * Mirrors `moveAction`/`nudge`'s `commitOps` helper: when `deps.applyOps` is\n * present the ops route through the consumer's history (one undo entry there);\n * otherwise they apply straight to the scene's own history via\n * `scene.applyBatch` + `defaultCommitAdapter`. Either way the whole flip is a\n * single batch → one undo entry, preserving the old `scene.batch('Flip', …)`\n * semantics exactly.\n *\n * Pivot: `'each'` (per-item own AABB) unless the caller passes `'union'`,\n * which mirrors every pose about the selection's *visual* union AABB — the\n * rotated ink extents — so items swap sides as well as reflect, or a\n * `SpatialReference`, which mirrors about the center of what it names. A rotated\n * member's own mirrored position needs no expansion: `axisAlignedBounds`\n * keeps the stored box's centre, so mirroring either box lands the same place.\n */\nfunction flipSelection(\n selection: SelectionApi,\n scene: Scene<unknown, string, unknown>,\n axis: FlipAxis,\n pivot: FlipPivot,\n applyOps: ((ops: Op[], label: string) => void) | undefined,\n geometryProjection: GeometryProjection | undefined,\n geom: PoseDescriptor<unknown>,\n poseComposition: unknown,\n params: Record<string, unknown> | undefined,\n pointer: PointerContextValue | undefined,\n): void {\n const selected = selection.get();\n if (selected.length === 0) return;\n const frame = scenePoseFrame(scene, poseComposition);\n\n // A group whose pose derives from its children mirrors by mirroring them,\n // about the group's own box where each selected node flips in place.\n const ids: NodeId[] = [];\n const ownPivot = new Map<string, Bounds>();\n for (const id of selected) {\n const members = shapeSources(scene, [id]) as NodeId[];\n const stoodIn = members.length !== 1 || members[0] !== id;\n const box = stoodIn ? visualBoundsViaDescriptor(frame.world(id), geom) : null;\n for (const member of members) {\n if (ids.includes(member)) continue;\n ids.push(member);\n if (box) ownPivot.set(member, box);\n }\n }\n\n const worlds = new Map<string, unknown>();\n for (const id of ids) {\n if (scene.get(id) !== undefined) worlds.set(id as string, frame.world(id));\n }\n let sharedPivot: ReturnType<typeof unionAABB> = null;\n if (pivot === 'union') {\n sharedPivot = unionAABB([...worlds.values()].map((p) => visualBoundsViaDescriptor(p, geom)));\n } else if (pivot !== 'each') {\n sharedPivot = resolveSpatialReference(pivot, actionReferenceSources(params, pointer, scene, frame, geom));\n if (sharedPivot === null) return;\n }\n\n // Read poses BEFORE building ops so each op's `from` is the pre-flip value\n // (the same value the old direct mutation captured implicitly).\n const ops: Op[] = [];\n for (const id of ids) {\n const node = scene.get(id);\n if (!node) continue;\n const world = worlds.get(id as string)!;\n const about = sharedPivot ?? ownPivot.get(id as string) ?? null;\n const flipped = about\n ? flipPoseAboutBounds(world, axis, geom, about)\n : flipPoseViaDescriptor(world, axis, geom);\n ops.push(createTransformOp<unknown>({\n id: id as string,\n from: node.pose,\n to: frame.local(id, flipped),\n label: 'Flip',\n }));\n // Mirror the data-held geometry about the SAME pivot the pose flip uses,\n // so a wired geometryProjection reflects the contents in lock-step with\n // the frame. A pose-only flip of a bare-AABB pose is identity, so this\n // data op is the only way an asymmetric shape actually mirrors.\n const g = about ?? geom.getBounds(world);\n const dataOp = geometryDataOp(\n geometryProjection,\n { id: id as string, data: node.data, pose: node.pose },\n localMirror(axis, frame, id, g),\n 'Flip',\n );\n if (dataOp) ops.push(dataOp);\n }\n if (ops.length === 0) return;\n\n if (applyOps) applyOps(ops, 'Flip');\n else scene.applyBatch(ops, 'Flip', defaultCommitAdapter(scene, selection.adapterMethods));\n}\n\n/**\n * @experimental\n * Static descriptor for the unified `flip` Action.\n *\n * Collapses the old `flip.horizontal` and `flip.vertical` pair into one action\n * with two parametric gesture bindings. The axis (`'x'` | `'y'`) is carried in\n * `opts.params.axis` and forwarded to `invoker.run` by the dispatcher, as is\n * the optional `opts.params.pivot` (a `FlipPivot`, default `'each'`).\n *\n * Requires dep-schema entries: `selection`, `scene`.\n */\nexport const flipAction: Action & { requires: string[] } = {\n id: 'flip',\n label: 'Flip',\n group: 'flip',\n variants: [\n { key: 'x', label: 'Flip Horizontal', icon: createElement(FlipXIcon), params: { axis: 'x' } },\n { key: 'y', label: 'Flip Vertical', icon: createElement(FlipYIcon), params: { axis: 'y' } },\n ],\n defaultBinding: [\n { spec: { kind: 'key', key: ['h', 'H'], mods: { shift: true } }, opts: { params: { axis: 'x' } } },\n { spec: { kind: 'key', key: ['v', 'V'], mods: { shift: true } }, opts: { params: { axis: 'y' } } },\n ],\n eligible: { capability: 'transforms-selection' },\n requires: ['selection', 'scene', 'applyOps', 'geometryProjection', 'poseDescriptor', 'poseComposition', 'pointer'],\n invoker: {\n timing: 'immediate',\n run: (deps, params) => {\n const axis = (params?.axis as FlipAxis | undefined) ?? 'x';\n const pivot = (params?.pivot as FlipPivot | undefined) ?? 'each';\n const selection = deps.selection;\n const scene = deps.scene;\n const applyOps = deps.applyOps;\n const geometryProjection = deps.geometryProjection;\n if (!selection || !scene) return;\n flipSelection(\n selection, scene, axis, pivot, applyOps, geometryProjection,\n poseDescriptorOf(deps.poseDescriptor), deps.poseComposition,\n params, deps.pointer,\n );\n },\n },\n enabled: requiresSelection,\n};\n"],"mappings":"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"}
|
|
@@ -1,26 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { poseDescriptorOf as
|
|
7
|
-
import { defaultCommitAdapter as
|
|
8
|
-
import { scenePoseFrame as
|
|
9
|
-
import { createInsertOp as
|
|
10
|
-
import { GroupIcon as
|
|
11
|
-
import { requiresSelection as
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { ActionDisabledReason as h } from "@weasel-js/routing";
|
|
1
|
+
import { createTransformOp as e } from "../../../core/ops/transform.js";
|
|
2
|
+
import { unionBounds as t } from "../../../core/geometry/unionBounds.js";
|
|
3
|
+
import { visualBoundsViaDescriptor as n } from "../../../core/geometry/poseDescriptor.js";
|
|
4
|
+
import { UNION_OF_CHILDREN as r, unionOfChildren as i } from "../../../core/scene/kitRegistry.js";
|
|
5
|
+
import { createReparentOp as a } from "../../../core/ops/reparent.js";
|
|
6
|
+
import { poseDescriptorOf as o } from "../poseDescriptorDep.js";
|
|
7
|
+
import { defaultCommitAdapter as s } from "../defaultCommitAdapter.js";
|
|
8
|
+
import { scenePoseFrame as c } from "../poseFrame.js";
|
|
9
|
+
import { createInsertOp as l } from "../../../core/ops/create.js";
|
|
10
|
+
import { GroupIcon as u, UngroupIcon as d } from "./icons/editIcons.js";
|
|
11
|
+
import { requiresSelection as f } from "./requiresSelection.js";
|
|
12
|
+
import { createElement as p } from "react";
|
|
13
|
+
import { ActionDisabledReason as m } from "@weasel-js/routing";
|
|
15
14
|
//#region src/interactions/actions/defaults/group.ts
|
|
16
|
-
var
|
|
17
|
-
function _() {
|
|
18
|
-
return e(`n${(g++).toString(36)}-${Math.random().toString(36).slice(2, 8)}`);
|
|
19
|
-
}
|
|
20
|
-
var v = {
|
|
15
|
+
var h = {
|
|
21
16
|
id: "group",
|
|
22
17
|
label: "Group",
|
|
23
|
-
icon:
|
|
18
|
+
icon: p(u),
|
|
24
19
|
group: "structure",
|
|
25
20
|
defaultBinding: {
|
|
26
21
|
kind: "key",
|
|
@@ -37,49 +32,49 @@ var v = {
|
|
|
37
32
|
],
|
|
38
33
|
invoker: {
|
|
39
34
|
timing: "immediate",
|
|
40
|
-
run: (
|
|
41
|
-
let
|
|
42
|
-
if (!
|
|
43
|
-
let m =
|
|
35
|
+
run: (u) => {
|
|
36
|
+
let d = u.selection, f = u.scene, p = u.applyOps;
|
|
37
|
+
if (!d || !f) return;
|
|
38
|
+
let m = d.get();
|
|
44
39
|
if (m.length === 0) return;
|
|
45
|
-
let h = m.map((e) =>
|
|
40
|
+
let h = m.map((e) => f.get(e)).filter((e) => e !== void 0);
|
|
46
41
|
if (h.length === 0 || new Set(h.map((e) => e.layer)).size > 1) return;
|
|
47
|
-
let g = h[0].layer,
|
|
48
|
-
for (let e of h)
|
|
49
|
-
let
|
|
42
|
+
let g = h[0].layer, _ = new Set(h.map((e) => e.parent)).size === 1 ? h[0].parent : null, v = o(u.poseDescriptor), y = c(f, u.poseComposition), b = /* @__PURE__ */ new Map();
|
|
43
|
+
for (let e of h) b.set(e.id, y.world(e.id));
|
|
44
|
+
let x = t([...b.values()].map((e) => n(e, v))), S = x === null ? h[0].pose : v.fromBounds(x, h[0].pose), C = y.localUnder(_, S), w = y.pc.closure === "identity", T = f.registry.derivePose?.[r] ?? i, E = f.mintId(), D = [l({
|
|
50
45
|
node: {
|
|
51
|
-
id:
|
|
46
|
+
id: E,
|
|
52
47
|
kind: "container",
|
|
53
48
|
layer: g,
|
|
54
|
-
pose:
|
|
49
|
+
pose: C,
|
|
55
50
|
data: {},
|
|
56
|
-
parent:
|
|
57
|
-
...
|
|
51
|
+
parent: _ ?? null,
|
|
52
|
+
...w ? {
|
|
58
53
|
dependsOn: "children",
|
|
59
|
-
derivePose:
|
|
54
|
+
derivePose: T
|
|
60
55
|
} : {}
|
|
61
56
|
},
|
|
62
57
|
label: "Group"
|
|
63
58
|
})];
|
|
64
|
-
for (let
|
|
65
|
-
id:
|
|
66
|
-
fromParentId:
|
|
67
|
-
toParentId:
|
|
59
|
+
for (let t of h) D.push(a({
|
|
60
|
+
id: t.id,
|
|
61
|
+
fromParentId: t.parent ?? null,
|
|
62
|
+
toParentId: E,
|
|
68
63
|
label: "Group"
|
|
69
|
-
})), !
|
|
70
|
-
id:
|
|
71
|
-
from:
|
|
72
|
-
to:
|
|
64
|
+
})), !w && D.push(e({
|
|
65
|
+
id: t.id,
|
|
66
|
+
from: t.pose,
|
|
67
|
+
to: y.pc.decompose(S, b.get(t.id)),
|
|
73
68
|
label: "Group"
|
|
74
69
|
}));
|
|
75
|
-
|
|
70
|
+
p ? p(D, "Group") : f.applyBatch(D, "Group", s(f, d.adapterMethods)), d.set([E]);
|
|
76
71
|
}
|
|
77
72
|
},
|
|
78
|
-
enabled:
|
|
79
|
-
},
|
|
73
|
+
enabled: f
|
|
74
|
+
}, g = {
|
|
80
75
|
id: "ungroup",
|
|
81
76
|
label: "Ungroup",
|
|
82
|
-
icon:
|
|
77
|
+
icon: p(d),
|
|
83
78
|
group: "structure",
|
|
84
79
|
defaultBinding: {
|
|
85
80
|
kind: "key",
|
|
@@ -104,7 +99,7 @@ var v = {
|
|
|
104
99
|
if (r.length === 0) return;
|
|
105
100
|
let i = r.filter((e) => n.get(e)?.kind === "container");
|
|
106
101
|
if (i.length === 0) return;
|
|
107
|
-
let a =
|
|
102
|
+
let a = c(n, e.poseComposition), o = a.pc.closure === "identity";
|
|
108
103
|
n.batch("Ungroup", () => {
|
|
109
104
|
let e = [];
|
|
110
105
|
for (let t of i) {
|
|
@@ -122,10 +117,10 @@ var v = {
|
|
|
122
117
|
},
|
|
123
118
|
enabled: (e) => {
|
|
124
119
|
let t = e?.selection, n = e?.scene;
|
|
125
|
-
return t?.get().some((e) => n?.get(e)?.kind === "container") ? !0 :
|
|
120
|
+
return t?.get().some((e) => n?.get(e)?.kind === "container") ? !0 : m.NotApplicable;
|
|
126
121
|
}
|
|
127
122
|
};
|
|
128
123
|
//#endregion
|
|
129
|
-
export {
|
|
124
|
+
export { h as groupAction, g as ungroupAction };
|
|
130
125
|
|
|
131
126
|
//# sourceMappingURL=group.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group.js","names":["containerIdCounter","freshContainerId","asNodeId","groupAction","createElement","GroupIcon","selection","deps","scene","applyOps","ids","nodes","id","n","layer","parent","d","poseDescriptorOf","frame","scenePoseFrame","worlds","node","union","unionBounds","visualBoundsViaDescriptor","p","containerWorldPose","pose","absolutePoses","derive","UNION_OF_CHILDREN","unionOfChildren","containerId","ops","createInsertOp","createReparentOp","createTransformOp","defaultCommitAdapter","requiresSelection","ungroupAction","UngroupIcon","containers","freed","container","baseIndex","children","childId","i","ActionDisabledReason"],"sources":["../../../../src/interactions/actions/defaults/group.ts"],"sourcesContent":["import type { Node, NodeId } from 'core/scene/types';\nimport { createElement } from 'react';\nimport { GroupIcon, UngroupIcon } from './icons/editIcons';\nimport { asNodeId } from 'core/scene/types';\nimport type { Op } from 'core/ops/types';\nimport { createInsertOp } from 'core/ops/create';\nimport { createReparentOp } from 'core/ops/reparent';\nimport { unionBounds } from 'core/geometry/unionBounds';\nimport { unionOfChildren, UNION_OF_CHILDREN } from 'core/scene/kitRegistry';\nimport { poseDescriptorOf } from '../poseDescriptorDep';\nimport { visualBoundsViaDescriptor } from '../resize/geometry';\nimport { createTransformOp } from 'core/ops/transform';\nimport { ActionDisabledReason, type Action } from '@weasel-js/routing';\nimport { requiresSelection } from './requiresSelection';\nimport { scenePoseFrame } from '../poseFrame';\nimport { defaultCommitAdapter } from '../defaultCommitAdapter';\n\n/** Mint a fresh NodeId for a new container. The old `scene.add(spec)` path\n * (no explicit id) let the scene generate a random id, so the produced id\n * was never deterministic/observable — pre-generating one here to feed the\n * insert op preserves behavior. Mirrors the scene's default id scheme\n * (`n{counter}-{random}`), which `core/scene/scene.ts` keeps module-private.\n * Same approach as `cloneAction`. */\nlet containerIdCounter = 0;\nfunction freshContainerId(): NodeId {\n return asNodeId(`n${(containerIdCounter++).toString(36)}-${Math.random().toString(36).slice(2, 8)}`);\n}\n\n/**\n * @experimental\n * Static descriptor for the `group` Action.\n *\n * \"Group\" here means a structural `ContainerNode` — the real group that\n * round-trips to SVG `<g>` — not the legacy membership-list. `run` creates a\n * fresh container and reparents the current selection under it as a single\n * undoable batch.\n *\n * Grouping never moves a member on screen. The container takes the world\n * envelope of its members' ink; each member is then re-expressed in that\n * container's frame, which is a no-op only when the scene composes poses by\n * identity.\n *\n * Under identity the container's pose is also *derived* from its members, so\n * it tracks one that moves later instead of freezing at the moment the group\n * was made. Under any other composition that derivation is circular — the\n * members' poses are expressed in the container's own frame — so the container\n * keeps the authored envelope instead. Making it track its members again needs\n * its own decision; see the group-as-frame design doc.\n */\nexport const groupAction: Action & { requires: string[] } = {\n id: 'group',\n label: 'Group',\n icon: createElement(GroupIcon),\n group: 'structure',\n defaultBinding: { kind: 'key', key: 'g', mods: { mod: true } },\n eligible: { capability: 'edits-page' },\n requires: ['scene', 'selection', 'applyOps', 'poseDescriptor', 'poseComposition'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n const selection = deps.selection;\n const scene = deps.scene;\n const applyOps = deps.applyOps;\n if (!selection || !scene) return;\n\n const ids = selection.get();\n if (ids.length === 0) return;\n\n // Resolve nodes; drop any that have gone missing.\n const nodes = ids\n .map((id) => scene.get(id as NodeId))\n .filter((n): n is NonNullable<typeof n> => n !== undefined);\n if (nodes.length === 0) return;\n\n // Members must share a layer — containers live on a single layer.\n const layers = new Set(nodes.map((n) => n.layer));\n if (layers.size > 1) return;\n const layer = nodes[0]!.layer;\n\n // Nest under the shared parent if the members agree, else at the root.\n const parents = new Set(nodes.map((n) => n.parent));\n const parent = parents.size === 1 ? nodes[0]!.parent : null;\n\n // The container takes the world envelope of its members' ink. The\n // authored pose is only the fallback (an emptied group, a lost registry\n // key); under identity the derived union is what the scene shows.\n const d = poseDescriptorOf(deps.poseDescriptor);\n const frame = scenePoseFrame(scene, deps.poseComposition);\n const worlds = new Map<NodeId, unknown>();\n for (const node of nodes) worlds.set(node.id, frame.world(node.id));\n // Visual, not stored, bounds: a turned member's ink reaches outside its\n // own box, and the container has to cover what is drawn.\n const union = unionBounds([...worlds.values()].map((p) => visualBoundsViaDescriptor(p, d)));\n const containerWorldPose = union === null\n ? nodes[0]!.pose\n : d.fromBounds(union, nodes[0]!.pose);\n const pose = frame.localUnder(parent, containerWorldPose);\n // Under identity the container is an envelope that tracks its members;\n // under a composing strategy it is a frame they are re-expressed in.\n const absolutePoses = frame.pc.closure === 'identity';\n const derive = scene.registry.derivePose?.[UNION_OF_CHILDREN] ?? unionOfChildren;\n\n // Build ops mirroring the old direct mutations, in the same order the\n // `scene.batch('Group', …)` body produced them:\n // 1. insert the fresh container (the old `scene.add` minted a random\n // id; we pre-generate one so the insert op carries a full node —\n // the id was never observable, so behavior is preserved);\n // 2. reparent each selected id under the new container, in selection\n // order, capturing each node's PRE-mutation parent as `from`\n // (the op captures the sibling slot itself, on apply).\n // The container must exist before any child reparents into it, so the\n // insert op is emitted first. A member's pose then follows its reparent,\n // re-expressed in the container's frame so the member does not move.\n const containerId = freshContainerId();\n const ops: Op[] = [\n createInsertOp<Node<unknown, string, unknown>>({\n node: {\n id: containerId,\n kind: 'container',\n layer,\n pose: pose as unknown,\n data: {} as unknown,\n parent: parent ?? null,\n ...(absolutePoses ? { dependsOn: 'children', derivePose: derive } : {}),\n } as Node<unknown, string, unknown>,\n label: 'Group',\n }),\n ];\n for (const node of nodes) {\n ops.push(createReparentOp({\n id: node.id as string,\n fromParentId: (node.parent ?? null) as string | null,\n toParentId: containerId as string,\n label: 'Group',\n }));\n if (absolutePoses) continue;\n ops.push(createTransformOp<unknown>({\n id: node.id as string,\n from: node.pose,\n to: frame.pc.decompose(containerWorldPose, worlds.get(node.id)!),\n label: 'Group',\n }));\n }\n\n // Route the batch through the consumer `applyOps` hook when present (so\n // an app with its own history captures the group as a single undo\n // entry); otherwise commit straight to the scene's own history via\n // `scene.applyBatch`. One applyOps / applyBatch call = one undo entry,\n // matching the prior single `scene.batch('Group', …)`.\n if (applyOps) applyOps(ops, 'Group');\n else scene.applyBatch(ops, 'Group', defaultCommitAdapter(scene, selection.adapterMethods));\n\n // Selection update is selection state, not a scene op — set it after the\n // commit regardless of which path ran (the old code set it inside the\n // batch; it was never an undoable scene mutation).\n selection.set([containerId]);\n },\n },\n enabled: requiresSelection,\n};\n\n/**\n * @experimental\n * Static descriptor for the `ungroup` Action.\n *\n * \"Group\" here means a structural `ContainerNode`. `run` dissolves each\n * selected container by reparenting its children up to the container's own\n * parent (preserving z-order) and removing the now-empty container, as a single\n * undoable batch. Selected non-container nodes are ignored. The freed children\n * become the new selection.\n *\n * A child's pose is expressed in the container's frame, so each one is\n * re-expressed in the frame it lands in and nothing moves on screen.\n */\nexport const ungroupAction: Action & { requires: string[] } = {\n id: 'ungroup',\n label: 'Ungroup',\n icon: createElement(UngroupIcon),\n group: 'structure',\n defaultBinding: { kind: 'key', key: 'g', mods: { mod: true, shift: true } },\n eligible: { capability: 'edits-page' },\n requires: ['scene', 'selection', 'poseComposition'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n const selection = deps.selection;\n const scene = deps.scene;\n if (!selection || !scene) return;\n\n const ids = selection.get();\n if (ids.length === 0) return;\n\n const containers = ids.filter((id) => scene.get(id as NodeId)?.kind === 'container');\n if (containers.length === 0) return;\n\n const frame = scenePoseFrame(scene, deps.poseComposition);\n const absolutePoses = frame.pc.closure === 'identity';\n\n scene.batch('Ungroup', () => {\n const freed: NodeId[] = [];\n for (const containerId of containers) {\n const container = scene.get(containerId as NodeId);\n if (!container || container.kind !== 'container') continue;\n\n const parent = container.parent ?? null;\n const baseIndex =\n parent === null\n ? scene.roots.indexOf(containerId as NodeId)\n : scene.childrenOf(parent).indexOf(containerId as NodeId);\n\n const children = [...scene.childrenOf(containerId as NodeId)];\n // Read every world pose before the first move: the frame resolves\n // through the live scene, and the container is about to leave it.\n const worlds = new Map<NodeId, unknown>();\n if (!absolutePoses) {\n for (const childId of children) worlds.set(childId, frame.world(childId));\n }\n children.forEach((childId, i) => {\n scene.move(childId, parent, baseIndex < 0 ? undefined : baseIndex + i);\n if (!absolutePoses) {\n scene.setPose(childId, frame.localUnder(parent, worlds.get(childId)!) as never);\n }\n freed.push(childId);\n });\n\n scene.remove(containerId as NodeId);\n }\n selection.set(freed);\n });\n },\n },\n enabled: (deps) => {\n const selection = deps?.selection;\n const scene = deps?.scene;\n const any = selection?.get().some((id) => scene?.get(id as NodeId)?.kind === 'container');\n return any ? true : ActionDisabledReason.NotApplicable;\n },\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"group.js","names":["groupAction","createElement","GroupIcon","selection","deps","scene","applyOps","ids","nodes","id","n","layer","parent","d","poseDescriptorOf","frame","scenePoseFrame","worlds","node","union","unionBounds","visualBoundsViaDescriptor","p","containerWorldPose","pose","absolutePoses","derive","UNION_OF_CHILDREN","unionOfChildren","containerId","ops","createInsertOp","createReparentOp","createTransformOp","defaultCommitAdapter","requiresSelection","ungroupAction","UngroupIcon","containers","freed","container","baseIndex","children","childId","i","ActionDisabledReason"],"sources":["../../../../src/interactions/actions/defaults/group.ts"],"sourcesContent":["import type { Node, NodeId } from 'core/scene/types';\nimport { createElement } from 'react';\nimport { GroupIcon, UngroupIcon } from './icons/editIcons';\nimport type { Op } from 'core/ops/types';\nimport { createInsertOp } from 'core/ops/create';\nimport { createReparentOp } from 'core/ops/reparent';\nimport { unionBounds } from 'core/geometry/unionBounds';\nimport { unionOfChildren, UNION_OF_CHILDREN } from 'core/scene/kitRegistry';\nimport { poseDescriptorOf } from '../poseDescriptorDep';\nimport { visualBoundsViaDescriptor } from '../resize/geometry';\nimport { createTransformOp } from 'core/ops/transform';\nimport { ActionDisabledReason, type Action } from '@weasel-js/routing';\nimport { requiresSelection } from './requiresSelection';\nimport { scenePoseFrame } from '../poseFrame';\nimport { defaultCommitAdapter } from '../defaultCommitAdapter';\n\n/**\n * @experimental\n * Static descriptor for the `group` Action.\n *\n * \"Group\" here means a structural `ContainerNode` — the real group that\n * round-trips to SVG `<g>` — not the legacy membership-list. `run` creates a\n * fresh container and reparents the current selection under it as a single\n * undoable batch.\n *\n * Grouping never moves a member on screen. The container takes the world\n * envelope of its members' ink; each member is then re-expressed in that\n * container's frame, which is a no-op only when the scene composes poses by\n * identity.\n *\n * Under identity the container's pose is also *derived* from its members, so\n * it tracks one that moves later instead of freezing at the moment the group\n * was made. Under any other composition that derivation is circular — the\n * members' poses are expressed in the container's own frame — so the container\n * keeps the authored envelope instead. Making it track its members again needs\n * its own decision; see the group-as-frame design doc.\n */\nexport const groupAction: Action & { requires: string[] } = {\n id: 'group',\n label: 'Group',\n icon: createElement(GroupIcon),\n group: 'structure',\n defaultBinding: { kind: 'key', key: 'g', mods: { mod: true } },\n eligible: { capability: 'edits-page' },\n requires: ['scene', 'selection', 'applyOps', 'poseDescriptor', 'poseComposition'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n const selection = deps.selection;\n const scene = deps.scene;\n const applyOps = deps.applyOps;\n if (!selection || !scene) return;\n\n const ids = selection.get();\n if (ids.length === 0) return;\n\n // Resolve nodes; drop any that have gone missing.\n const nodes = ids\n .map((id) => scene.get(id as NodeId))\n .filter((n): n is NonNullable<typeof n> => n !== undefined);\n if (nodes.length === 0) return;\n\n // Members must share a layer — containers live on a single layer.\n const layers = new Set(nodes.map((n) => n.layer));\n if (layers.size > 1) return;\n const layer = nodes[0]!.layer;\n\n // Nest under the shared parent if the members agree, else at the root.\n const parents = new Set(nodes.map((n) => n.parent));\n const parent = parents.size === 1 ? nodes[0]!.parent : null;\n\n // The container takes the world envelope of its members' ink. The\n // authored pose is only the fallback (an emptied group, a lost registry\n // key); under identity the derived union is what the scene shows.\n const d = poseDescriptorOf(deps.poseDescriptor);\n const frame = scenePoseFrame(scene, deps.poseComposition);\n const worlds = new Map<NodeId, unknown>();\n for (const node of nodes) worlds.set(node.id, frame.world(node.id));\n // Visual, not stored, bounds: a turned member's ink reaches outside its\n // own box, and the container has to cover what is drawn.\n const union = unionBounds([...worlds.values()].map((p) => visualBoundsViaDescriptor(p, d)));\n const containerWorldPose = union === null\n ? nodes[0]!.pose\n : d.fromBounds(union, nodes[0]!.pose);\n const pose = frame.localUnder(parent, containerWorldPose);\n // Under identity the container is an envelope that tracks its members;\n // under a composing strategy it is a frame they are re-expressed in.\n const absolutePoses = frame.pc.closure === 'identity';\n const derive = scene.registry.derivePose?.[UNION_OF_CHILDREN] ?? unionOfChildren;\n\n // Build ops mirroring the old direct mutations, in the same order the\n // `scene.batch('Group', …)` body produced them:\n // 1. insert the fresh container, under an id minted first so the\n // insert op carries a whole node;\n // 2. reparent each selected id under the new container, in selection\n // order, capturing each node's PRE-mutation parent as `from`\n // (the op captures the sibling slot itself, on apply).\n // The container must exist before any child reparents into it, so the\n // insert op is emitted first. A member's pose then follows its reparent,\n // re-expressed in the container's frame so the member does not move.\n const containerId = scene.mintId();\n const ops: Op[] = [\n createInsertOp<Node<unknown, string, unknown>>({\n node: {\n id: containerId,\n kind: 'container',\n layer,\n pose: pose as unknown,\n data: {} as unknown,\n parent: parent ?? null,\n ...(absolutePoses ? { dependsOn: 'children', derivePose: derive } : {}),\n } as Node<unknown, string, unknown>,\n label: 'Group',\n }),\n ];\n for (const node of nodes) {\n ops.push(createReparentOp({\n id: node.id as string,\n fromParentId: (node.parent ?? null) as string | null,\n toParentId: containerId as string,\n label: 'Group',\n }));\n if (absolutePoses) continue;\n ops.push(createTransformOp<unknown>({\n id: node.id as string,\n from: node.pose,\n to: frame.pc.decompose(containerWorldPose, worlds.get(node.id)!),\n label: 'Group',\n }));\n }\n\n // Route the batch through the consumer `applyOps` hook when present (so\n // an app with its own history captures the group as a single undo\n // entry); otherwise commit straight to the scene's own history via\n // `scene.applyBatch`. One applyOps / applyBatch call = one undo entry,\n // matching the prior single `scene.batch('Group', …)`.\n if (applyOps) applyOps(ops, 'Group');\n else scene.applyBatch(ops, 'Group', defaultCommitAdapter(scene, selection.adapterMethods));\n\n // Selection update is selection state, not a scene op — set it after the\n // commit regardless of which path ran (the old code set it inside the\n // batch; it was never an undoable scene mutation).\n selection.set([containerId]);\n },\n },\n enabled: requiresSelection,\n};\n\n/**\n * @experimental\n * Static descriptor for the `ungroup` Action.\n *\n * \"Group\" here means a structural `ContainerNode`. `run` dissolves each\n * selected container by reparenting its children up to the container's own\n * parent (preserving z-order) and removing the now-empty container, as a single\n * undoable batch. Selected non-container nodes are ignored. The freed children\n * become the new selection.\n *\n * A child's pose is expressed in the container's frame, so each one is\n * re-expressed in the frame it lands in and nothing moves on screen.\n */\nexport const ungroupAction: Action & { requires: string[] } = {\n id: 'ungroup',\n label: 'Ungroup',\n icon: createElement(UngroupIcon),\n group: 'structure',\n defaultBinding: { kind: 'key', key: 'g', mods: { mod: true, shift: true } },\n eligible: { capability: 'edits-page' },\n requires: ['scene', 'selection', 'poseComposition'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n const selection = deps.selection;\n const scene = deps.scene;\n if (!selection || !scene) return;\n\n const ids = selection.get();\n if (ids.length === 0) return;\n\n const containers = ids.filter((id) => scene.get(id as NodeId)?.kind === 'container');\n if (containers.length === 0) return;\n\n const frame = scenePoseFrame(scene, deps.poseComposition);\n const absolutePoses = frame.pc.closure === 'identity';\n\n scene.batch('Ungroup', () => {\n const freed: NodeId[] = [];\n for (const containerId of containers) {\n const container = scene.get(containerId as NodeId);\n if (!container || container.kind !== 'container') continue;\n\n const parent = container.parent ?? null;\n const baseIndex =\n parent === null\n ? scene.roots.indexOf(containerId as NodeId)\n : scene.childrenOf(parent).indexOf(containerId as NodeId);\n\n const children = [...scene.childrenOf(containerId as NodeId)];\n // Read every world pose before the first move: the frame resolves\n // through the live scene, and the container is about to leave it.\n const worlds = new Map<NodeId, unknown>();\n if (!absolutePoses) {\n for (const childId of children) worlds.set(childId, frame.world(childId));\n }\n children.forEach((childId, i) => {\n scene.move(childId, parent, baseIndex < 0 ? undefined : baseIndex + i);\n if (!absolutePoses) {\n scene.setPose(childId, frame.localUnder(parent, worlds.get(childId)!) as never);\n }\n freed.push(childId);\n });\n\n scene.remove(containerId as NodeId);\n }\n selection.set(freed);\n });\n },\n },\n enabled: (deps) => {\n const selection = deps?.selection;\n const scene = deps?.scene;\n const any = selection?.get().some((id) => scene?.get(id as NodeId)?.kind === 'container');\n return any ? true : ActionDisabledReason.NotApplicable;\n },\n};\n"],"mappings":"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"}
|
|
@@ -6,7 +6,38 @@ var n = {
|
|
|
6
6
|
ctrl: "optional",
|
|
7
7
|
meta: "optional",
|
|
8
8
|
shift: "optional"
|
|
9
|
-
}, r =
|
|
9
|
+
}, r = [
|
|
10
|
+
"scene",
|
|
11
|
+
"selection",
|
|
12
|
+
"insert",
|
|
13
|
+
"applyOps",
|
|
14
|
+
"ingestion"
|
|
15
|
+
];
|
|
16
|
+
function i(n, r, i) {
|
|
17
|
+
let a = r?.items;
|
|
18
|
+
if (!a || a.length === 0) return;
|
|
19
|
+
let o = n.ingestion, s = n.insert, c = n.scene, l = n.selection;
|
|
20
|
+
if (!o || !s || !c || !l) return;
|
|
21
|
+
let u = n.applyOps, d = {
|
|
22
|
+
point: typeof r?.worldX == "number" && typeof r?.worldY == "number" ? {
|
|
23
|
+
x: r.worldX,
|
|
24
|
+
y: r.worldY
|
|
25
|
+
} : null,
|
|
26
|
+
viewportWorldRect: () => o.viewportWorldRect(),
|
|
27
|
+
insert: s,
|
|
28
|
+
applyOps: (t, n) => {
|
|
29
|
+
u ? u(t, n ?? "Ingest") : c.applyBatch(t, n ?? "Ingest", e(c, l.adapterMethods));
|
|
30
|
+
},
|
|
31
|
+
scene: c,
|
|
32
|
+
selection: l,
|
|
33
|
+
resolveSrc: o.resolveSrc,
|
|
34
|
+
svg: o.svg,
|
|
35
|
+
clipboard: o.clipboard,
|
|
36
|
+
deps: n
|
|
37
|
+
};
|
|
38
|
+
t(a, d, i).catch((e) => console.warn("weasel ingest:", e));
|
|
39
|
+
}
|
|
40
|
+
var a = {
|
|
10
41
|
id: "ingest",
|
|
11
42
|
label: "Insert external content",
|
|
12
43
|
defaultBinding: [{
|
|
@@ -16,43 +47,14 @@ var n = {
|
|
|
16
47
|
kind: "paste",
|
|
17
48
|
mods: n
|
|
18
49
|
}],
|
|
19
|
-
requires: [
|
|
20
|
-
"scene",
|
|
21
|
-
"selection",
|
|
22
|
-
"insert",
|
|
23
|
-
"applyOps",
|
|
24
|
-
"ingestion"
|
|
25
|
-
],
|
|
50
|
+
requires: [...r],
|
|
26
51
|
invoker: {
|
|
27
52
|
timing: "immediate",
|
|
28
|
-
run: (
|
|
29
|
-
let i = r?.items;
|
|
30
|
-
if (!i || i.length === 0) return;
|
|
31
|
-
let a = n.ingestion, o = n.insert, s = n.scene, c = n.selection;
|
|
32
|
-
if (!a || !o || !s || !c) return;
|
|
33
|
-
let l = n.applyOps, u = {
|
|
34
|
-
point: typeof r?.worldX == "number" && typeof r?.worldY == "number" ? {
|
|
35
|
-
x: r.worldX,
|
|
36
|
-
y: r.worldY
|
|
37
|
-
} : null,
|
|
38
|
-
viewportWorldRect: () => a.viewportWorldRect(),
|
|
39
|
-
insert: o,
|
|
40
|
-
applyOps: (t, n) => {
|
|
41
|
-
l ? l(t, n ?? "Ingest") : s.applyBatch(t, n ?? "Ingest", e(s, c.adapterMethods));
|
|
42
|
-
},
|
|
43
|
-
scene: s,
|
|
44
|
-
selection: c,
|
|
45
|
-
resolveSrc: a.resolveSrc,
|
|
46
|
-
svg: a.svg,
|
|
47
|
-
clipboard: a.clipboard,
|
|
48
|
-
deps: n
|
|
49
|
-
};
|
|
50
|
-
t(i, u).catch((e) => console.warn("weasel ingest:", e));
|
|
51
|
-
}
|
|
53
|
+
run: (e, t) => i(e, t)
|
|
52
54
|
},
|
|
53
55
|
enabled: () => !0
|
|
54
56
|
};
|
|
55
57
|
//#endregion
|
|
56
|
-
export { r as ingestAction };
|
|
58
|
+
export { n as ANY_INGEST_MODS, r as INGEST_REQUIRES, a as ingestAction, i as ingestFromEvent };
|
|
57
59
|
|
|
58
60
|
//# sourceMappingURL=ingest.js.map
|