@weasel-js/core 1.9.4 → 1.10.0
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 +750 -0
- package/README.md +5 -3
- package/dist/WeaselProvider.js +5 -7
- package/dist/WeaselProvider.js.map +1 -1
- package/dist/affordances/composeAffordanceLayer.js +91 -83
- package/dist/affordances/composeAffordanceLayer.js.map +1 -1
- package/dist/affordances/cornerResize.js +3 -2
- package/dist/affordances/cornerResize.js.map +1 -1
- package/dist/affordances/hitAffordanceRegions.js +54 -100
- package/dist/affordances/hitAffordanceRegions.js.map +1 -1
- package/dist/affordances/pathAnchors.js.map +1 -1
- package/dist/affordances/rotationHandle.js +5 -4
- package/dist/affordances/rotationHandle.js.map +1 -1
- package/dist/animation/behaviors/coast.js +21 -0
- package/dist/animation/behaviors/coast.js.map +1 -0
- package/dist/animation/behaviors/coastByWrite.js +107 -0
- package/dist/animation/behaviors/coastByWrite.js.map +1 -0
- package/dist/animation/behaviors/coastOnTargets.js +94 -0
- package/dist/animation/behaviors/coastOnTargets.js.map +1 -0
- package/dist/animation/behaviors/momentum.js +48 -136
- package/dist/animation/behaviors/momentum.js.map +1 -1
- package/dist/animation/clipTargets.js +12 -0
- package/dist/animation/clipTargets.js.map +1 -0
- package/dist/animation/index.js +15 -20
- package/dist/animation/poseHelpers.js +112 -33
- package/dist/animation/poseHelpers.js.map +1 -1
- package/dist/animation/poseTarget.js +115 -0
- package/dist/animation/poseTarget.js.map +1 -0
- package/dist/animation/reflow.js +113 -83
- package/dist/animation/reflow.js.map +1 -1
- package/dist/animation/rewind.js +66 -0
- package/dist/animation/rewind.js.map +1 -0
- package/dist/animation/rig/bindRig.js +85 -53
- package/dist/animation/rig/bindRig.js.map +1 -1
- package/dist/animation/rig/rigNode.js +93 -0
- package/dist/animation/rig/rigNode.js.map +1 -0
- package/dist/animation/rig/rigSeat.js +26 -0
- package/dist/animation/rig/rigSeat.js.map +1 -0
- package/dist/animation/rig/skinBinding.js +56 -0
- package/dist/animation/rig/skinBinding.js.map +1 -0
- package/dist/animation/rig/useRig.js +31 -16
- package/dist/animation/rig/useRig.js.map +1 -1
- package/dist/animation/wrappers/animateLifecycle.js +8 -7
- package/dist/animation/wrappers/animateLifecycle.js.map +1 -1
- package/dist/animation/wrappers/animateOnSetPose.js +31 -31
- package/dist/animation/wrappers/animateOnSetPose.js.map +1 -1
- package/dist/animation/wrappers/instantPose.js.map +1 -1
- package/dist/animation/writtenPoseTarget.js +33 -0
- package/dist/animation/writtenPoseTarget.js.map +1 -0
- package/dist/autoPoseDescriptor-DHg5KqaJ.d.ts +27 -0
- package/dist/barrel/canvas.js +31 -0
- package/dist/barrel/chrome.js +10 -10
- package/dist/barrel/input.js +16 -17
- package/dist/barrel/interactions.js +35 -39
- package/dist/barrel/paint.js +11 -18
- package/dist/barrel/paths.js +12 -19
- package/dist/barrel/renderer.js +14 -20
- package/dist/barrel/routing.js +42 -36
- package/dist/barrel/scene.js +37 -0
- package/dist/barrel/text.js +9 -18
- package/dist/barrel/viewport.js +41 -51
- package/dist/canvas/Canvas.js +281 -475
- package/dist/canvas/Canvas.js.map +1 -1
- package/dist/canvas/CanvasView.js +169 -188
- package/dist/canvas/CanvasView.js.map +1 -1
- package/dist/canvas/CursorCoordsHud.js +22 -23
- package/dist/canvas/CursorCoordsHud.js.map +1 -1
- package/dist/canvas/DrawCanvas.js +39 -56
- package/dist/canvas/DrawCanvas.js.map +1 -1
- package/dist/canvas/ModalityHud.js.map +1 -1
- package/dist/canvas/NodeShape.js +28 -29
- package/dist/canvas/NodeShape.js.map +1 -1
- package/dist/canvas/PickHud.js.map +1 -1
- package/dist/canvas/SceneCanvas/DevHuds.js +40 -0
- package/dist/canvas/SceneCanvas/DevHuds.js.map +1 -0
- package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js +66 -107
- package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js.map +1 -1
- package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +27 -31
- package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js.map +1 -1
- package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js +51 -54
- package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js.map +1 -1
- package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js +3 -3
- package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js.map +1 -1
- package/dist/canvas/SceneCanvas/coordTrace.js +37 -1
- package/dist/canvas/SceneCanvas/coordTrace.js.map +1 -1
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js +40 -29
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -1
- package/dist/canvas/SceneCanvas/defaultNodeRouting.js +1 -1
- package/dist/canvas/SceneCanvas/defaultNodeRouting.js.map +1 -1
- package/dist/canvas/SceneCanvas/dispatcherGestureBounds.js.map +1 -1
- package/dist/canvas/SceneCanvas/features.js +73 -43
- package/dist/canvas/SceneCanvas/features.js.map +1 -1
- package/dist/canvas/SceneCanvas/isDev.js.map +1 -1
- package/dist/canvas/SceneCanvas/poseGeometry.js +33 -37
- package/dist/canvas/SceneCanvas/poseGeometry.js.map +1 -1
- package/dist/canvas/SceneCanvas/props.js +15 -14
- package/dist/canvas/SceneCanvas/props.js.map +1 -1
- package/dist/canvas/SceneCanvas/toolRegistry.js +23 -0
- package/dist/canvas/SceneCanvas/toolRegistry.js.map +1 -0
- package/dist/canvas/SceneCanvas/useActionsPropResolver.js +6 -1
- package/dist/canvas/SceneCanvas/useActionsPropResolver.js.map +1 -1
- package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js.map +1 -1
- package/dist/canvas/SceneCanvas/useBuiltinTools.js +21 -0
- package/dist/canvas/SceneCanvas/useBuiltinTools.js.map +1 -0
- package/dist/canvas/SceneCanvas/useCanvasCamera.js +38 -0
- package/dist/canvas/SceneCanvas/useCanvasCamera.js.map +1 -0
- package/dist/canvas/SceneCanvas/useCanvasDispatcher.js +20 -0
- package/dist/canvas/SceneCanvas/useCanvasDispatcher.js.map +1 -0
- package/dist/canvas/SceneCanvas/useCanvasSelection.js +16 -0
- package/dist/canvas/SceneCanvas/useCanvasSelection.js.map +1 -0
- package/dist/canvas/SceneCanvas/useCanvasTools.js +67 -0
- package/dist/canvas/SceneCanvas/useCanvasTools.js.map +1 -0
- package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js +29 -29
- package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js.map +1 -1
- package/dist/canvas/SceneCanvas/useHeldModifiers.js +20 -0
- package/dist/canvas/SceneCanvas/useHeldModifiers.js.map +1 -0
- package/dist/canvas/SceneCanvas/useNodeAtPoint.js +26 -0
- package/dist/canvas/SceneCanvas/useNodeAtPoint.js.map +1 -0
- package/dist/canvas/SceneCanvas/useNodeKinds.js +26 -0
- package/dist/canvas/SceneCanvas/useNodeKinds.js.map +1 -0
- package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +39 -37
- package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneCanvasHandle.js +47 -0
- package/dist/canvas/SceneCanvas/useSceneCanvasHandle.js.map +1 -0
- package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js +66 -0
- package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js.map +1 -0
- package/dist/canvas/SceneCanvas/useSceneChrome.js +59 -0
- package/dist/canvas/SceneCanvas/useSceneChrome.js.map +1 -0
- package/dist/canvas/SceneCanvas/useSceneRedrawSources.js +23 -0
- package/dist/canvas/SceneCanvas/useSceneRedrawSources.js.map +1 -0
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js +76 -80
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneSlotLayers.js +37 -0
- package/dist/canvas/SceneCanvas/useSceneSlotLayers.js.map +1 -0
- package/dist/canvas/SceneCanvas/useSelectionOverlayLayer.js +38 -0
- package/dist/canvas/SceneCanvas/useSelectionOverlayLayer.js.map +1 -0
- package/dist/canvas/SceneCanvas/useViewLayerGate.js +20 -0
- package/dist/canvas/SceneCanvas/useViewLayerGate.js.map +1 -0
- package/dist/canvas/SceneCanvas/useViewportActions.js +9 -1
- package/dist/canvas/SceneCanvas/useViewportActions.js.map +1 -1
- package/dist/canvas/SceneCanvas/worldPointAt.js +9 -0
- package/dist/canvas/SceneCanvas/worldPointAt.js.map +1 -0
- package/dist/canvas/SceneCanvas.js +303 -707
- package/dist/canvas/SceneCanvas.js.map +1 -1
- package/dist/canvas/SceneViewCanvas.js +41 -47
- package/dist/canvas/SceneViewCanvas.js.map +1 -1
- package/dist/canvas/adapterDerivedPath.js +26 -0
- package/dist/canvas/adapterDerivedPath.js.map +1 -0
- package/dist/canvas/affordanceAt.js +11 -1
- package/dist/canvas/affordanceAt.js.map +1 -1
- package/dist/canvas/buildSceneLayer.js +81 -61
- package/dist/canvas/buildSceneLayer.js.map +1 -1
- package/dist/canvas/buildSceneTree.js.map +1 -1
- package/dist/canvas/canvasRenderer.js +40 -44
- package/dist/canvas/canvasRenderer.js.map +1 -1
- package/dist/canvas/colorOverrides.js.map +1 -1
- package/dist/canvas/defaultDrawOne.js +12 -12
- package/dist/canvas/defaultDrawOne.js.map +1 -1
- package/dist/canvas/deps/areaSelect.js +4 -4
- package/dist/canvas/deps/areaSelect.js.map +1 -1
- package/dist/canvas/deps/debug.js.map +1 -1
- package/dist/canvas/deps/editAnchors.js +49 -68
- package/dist/canvas/deps/editAnchors.js.map +1 -1
- package/dist/canvas/deps/geometryProjection.js.map +1 -1
- package/dist/canvas/deps/hitTestArea.js +31 -26
- package/dist/canvas/deps/hitTestArea.js.map +1 -1
- package/dist/canvas/deps/insert.js +65 -54
- package/dist/canvas/deps/insert.js.map +1 -1
- package/dist/canvas/deps/lassoSelect.js +5 -5
- package/dist/canvas/deps/lassoSelect.js.map +1 -1
- package/dist/canvas/deps/poseDescriptor.js +1 -1
- package/dist/canvas/deps/poseDescriptor.js.map +1 -1
- package/dist/canvas/deps/resizePolicy.js.map +1 -1
- package/dist/canvas/deps/slice.js +44 -45
- package/dist/canvas/deps/slice.js.map +1 -1
- package/dist/canvas/deps/textEdit.js +8 -8
- package/dist/canvas/deps/textEdit.js.map +1 -1
- package/dist/canvas/deps/view.js.map +1 -1
- package/dist/canvas/derivedPath.js +43 -41
- package/dist/canvas/derivedPath.js.map +1 -1
- package/dist/canvas/drawEnvelope.js +8 -4
- package/dist/canvas/drawEnvelope.js.map +1 -1
- package/dist/canvas/getNodeAtPoint.js +2 -6
- package/dist/canvas/getNodeAtPoint.js.map +1 -1
- package/dist/canvas/hud.module.js.map +1 -1
- package/dist/canvas/insertPreviewExtent.js.map +1 -1
- package/dist/canvas/layerOrder.js.map +1 -1
- package/dist/canvas/layerSlots.js +6 -1
- package/dist/canvas/layerSlots.js.map +1 -1
- package/dist/canvas/nodeShapes/derivedPainter.js +12 -12
- package/dist/canvas/nodeShapes/derivedPainter.js.map +1 -1
- package/dist/canvas/nodeShapes/imagePainter.js +10 -10
- package/dist/canvas/nodeShapes/imagePainter.js.map +1 -1
- package/dist/canvas/nodeShapes/memo.js.map +1 -1
- package/dist/canvas/nodeShapes/nodePaint.js +34 -23
- package/dist/canvas/nodeShapes/nodePaint.js.map +1 -1
- package/dist/canvas/nodeShapes/pathPainter.js +23 -22
- package/dist/canvas/nodeShapes/pathPainter.js.map +1 -1
- package/dist/canvas/nodeShapes/poseBox.js +6 -6
- package/dist/canvas/nodeShapes/poseBox.js.map +1 -1
- package/dist/canvas/nodeShapes/rectFallbackPainter.js +8 -8
- package/dist/canvas/nodeShapes/rectFallbackPainter.js.map +1 -1
- package/dist/canvas/nodeShapes/shapePainter.js +16 -16
- package/dist/canvas/nodeShapes/shapePainter.js.map +1 -1
- package/dist/canvas/nodeShapes/textPainter.js +1 -1
- package/dist/canvas/nodeShapes/textPainter.js.map +1 -1
- package/dist/canvas/overlayRoleStrokes.js.map +1 -1
- package/dist/canvas/paintCull.js +6 -8
- package/dist/canvas/paintCull.js.map +1 -1
- package/dist/{features/cursor → canvas}/paintedCursorLayer.js +2 -2
- package/dist/canvas/paintedCursorLayer.js.map +1 -0
- package/dist/canvas/pickWalk.js +52 -50
- package/dist/canvas/pickWalk.js.map +1 -1
- package/dist/canvas/planeClips.js +18 -19
- package/dist/canvas/planeClips.js.map +1 -1
- package/dist/canvas/poseCascade.js +41 -0
- package/dist/canvas/poseCascade.js.map +1 -0
- package/dist/canvas/poseRotation.js +1 -3
- package/dist/canvas/poseRotation.js.map +1 -1
- package/dist/canvas/rasterReadback.js +22 -0
- package/dist/canvas/rasterReadback.js.map +1 -0
- package/dist/canvas/renderDebugSnapshot.js +12 -12
- package/dist/canvas/renderDebugSnapshot.js.map +1 -1
- package/dist/canvas/renderNeeds.js +3 -3
- package/dist/canvas/renderNeeds.js.map +1 -1
- package/dist/canvas/renderSceneToPixels.js +64 -83
- package/dist/canvas/renderSceneToPixels.js.map +1 -1
- package/dist/canvas/sceneAdapter.js +68 -132
- package/dist/canvas/sceneAdapter.js.map +1 -1
- package/dist/canvas/sceneClipboard.js +1 -1
- package/dist/canvas/sceneClipboard.js.map +1 -1
- package/dist/canvas/sceneLayerPaint.js +4 -4
- package/dist/canvas/sceneLayerPaint.js.map +1 -1
- package/dist/canvas/sceneSlotWiring.js +4 -4
- package/dist/canvas/sceneSlotWiring.js.map +1 -1
- package/dist/canvas/sceneViewRender.js +36 -35
- package/dist/canvas/sceneViewRender.js.map +1 -1
- package/dist/canvas/slopsDebugLayer.js +4 -4
- package/dist/canvas/slopsDebugLayer.js.map +1 -1
- package/dist/canvas/surface.module.js +6 -0
- package/dist/canvas/surface.module.js.map +1 -0
- package/dist/canvas/surfaceBox.js +16 -0
- package/dist/canvas/surfaceBox.js.map +1 -0
- package/dist/canvas/useCanvasRenderer.js +23 -11
- package/dist/canvas/useCanvasRenderer.js.map +1 -1
- package/dist/canvas/useCanvasSurface.js +31 -0
- package/dist/canvas/useCanvasSurface.js.map +1 -0
- package/dist/canvas/useCanvasView.js +46 -37
- package/dist/canvas/useCanvasView.js.map +1 -1
- package/dist/canvas/useFrameLoop.js +11 -12
- package/dist/canvas/useFrameLoop.js.map +1 -1
- package/dist/canvas/useHostAnchor.js +35 -33
- package/dist/canvas/useHostAnchor.js.map +1 -1
- package/dist/canvas/useLateContentRedraw.js +8 -8
- package/dist/canvas/useLateContentRedraw.js.map +1 -1
- package/dist/canvas/useSceneLayerList.js +4 -14
- package/dist/canvas/useSceneLayerList.js.map +1 -1
- package/dist/canvas/useSurfaceInput.js +42 -0
- package/dist/canvas/useSurfaceInput.js.map +1 -0
- package/dist/canvas/useToolCursor.js +29 -0
- package/dist/canvas/useToolCursor.js.map +1 -0
- package/dist/canvas/useViewHelpers.js +46 -85
- package/dist/canvas/useViewHelpers.js.map +1 -1
- package/dist/canvas/viewInputs.js.map +1 -1
- package/dist/canvas/viewRegistry.js +25 -27
- package/dist/canvas/viewRegistry.js.map +1 -1
- package/dist/canvas/watchElementMove.js +43 -0
- package/dist/canvas/watchElementMove.js.map +1 -0
- package/dist/canvas/wrapNodeOutput.js.map +1 -1
- package/dist/clipboard.d.ts +7 -14
- package/dist/{types-B4iJRHC3.d.ts → clone-2a5hVbBd.d.ts} +122 -77
- package/dist/clone.d.ts +4 -8
- package/dist/clone.js +0 -2
- package/dist/core/device/targets.js.map +1 -1
- package/dist/core/device/useDeviceProfile.js +13 -13
- package/dist/core/device/useDeviceProfile.js.map +1 -1
- package/dist/{interactions/actions/resize → core/geometry}/autoPoseDescriptor.js +8 -7
- package/dist/core/geometry/autoPoseDescriptor.js.map +1 -0
- package/dist/core/geometry/pathPoseDescriptor.js +88 -0
- package/dist/core/geometry/pathPoseDescriptor.js.map +1 -0
- package/dist/core/geometry/poseDescriptor.js +61 -14
- package/dist/core/geometry/poseDescriptor.js.map +1 -1
- package/dist/core/geometry/regionHit.js +35 -37
- package/dist/core/geometry/regionHit.js.map +1 -1
- package/dist/core/geometry/targetFrame.js +94 -0
- package/dist/core/geometry/targetFrame.js.map +1 -0
- package/dist/core/geometry/unionBounds.js +4 -5
- package/dist/core/geometry/unionBounds.js.map +1 -1
- package/dist/core/layers/backgroundFill.js +31 -0
- package/dist/core/layers/backgroundFill.js.map +1 -0
- package/dist/{features/groups → core/layers}/children.js +1 -1
- package/dist/core/layers/children.js.map +1 -0
- package/dist/{features/focus → core/layers}/gateLayer.js +2 -2
- package/dist/core/layers/gateLayer.js.map +1 -0
- package/dist/core/layers/layerGroup.js +40 -0
- package/dist/core/layers/layerGroup.js.map +1 -0
- package/dist/core/layers/render.js +50 -76
- package/dist/core/layers/render.js.map +1 -1
- package/dist/core/ops/createHistory.js +9 -9
- package/dist/core/ops/createHistory.js.map +1 -1
- package/dist/core/ops/delete.js.map +1 -1
- package/dist/core/paint/meshKind.js +16 -0
- package/dist/core/paint/meshKind.js.map +1 -0
- package/dist/{features/meshPaint/lazyKind.js → core/paint/meshKindLazy.js} +103 -92
- package/dist/core/paint/meshKindLazy.js.map +1 -0
- package/dist/core/paint/paintKindEntry.js +8 -0
- package/dist/core/paint/paintKindEntry.js.map +1 -0
- package/dist/core/paint/paintKinds.js +144 -0
- package/dist/core/paint/paintKinds.js.map +1 -0
- package/dist/core/paint/registerMesh.js +7 -0
- package/dist/core/paint/registerMesh.js.map +1 -0
- package/dist/core/scene/NodeProperties.js.map +1 -1
- package/dist/core/scene/NodeRouting.js.map +1 -1
- package/dist/core/scene/arrivalWindow.js +65 -64
- package/dist/core/scene/arrivalWindow.js.map +1 -1
- package/dist/core/scene/boundOps.js +40 -0
- package/dist/core/scene/boundOps.js.map +1 -0
- package/dist/core/scene/composeFrame.js +9 -6
- package/dist/core/scene/composeFrame.js.map +1 -1
- package/dist/{features/groups → core/scene}/composePose.js +18 -18
- package/dist/core/scene/composePose.js.map +1 -0
- package/dist/core/scene/depMemo.js +31 -6
- package/dist/core/scene/depMemo.js.map +1 -1
- package/dist/core/scene/derivedPath.js +19 -20
- package/dist/core/scene/derivedPath.js.map +1 -1
- package/dist/core/scene/editMode.js +26 -0
- package/dist/core/scene/editMode.js.map +1 -0
- package/dist/core/scene/effectivePose.js +38 -39
- package/dist/core/scene/effectivePose.js.map +1 -1
- package/dist/core/scene/fieldEdits.js +98 -0
- package/dist/core/scene/fieldEdits.js.map +1 -0
- package/dist/core/scene/historyFacade.js +116 -70
- package/dist/core/scene/historyFacade.js.map +1 -1
- package/dist/core/scene/historyForm.js +6 -0
- package/dist/core/scene/historyForm.js.map +1 -0
- package/dist/core/scene/kitOps.js +83 -71
- package/dist/core/scene/kitOps.js.map +1 -1
- package/dist/core/scene/kitRegistry.js.map +1 -1
- package/dist/core/scene/layerStack.js +105 -12
- package/dist/core/scene/layerStack.js.map +1 -1
- package/dist/core/scene/layoutPass.js +58 -59
- package/dist/core/scene/layoutPass.js.map +1 -1
- package/dist/{features/groups → core/scene}/nestedHit.js +3 -3
- package/dist/core/scene/nestedHit.js.map +1 -0
- package/dist/core/scene/nodeFnFields.js +9 -9
- package/dist/core/scene/nodeFnFields.js.map +1 -1
- package/dist/core/scene/nodeMemo.js.map +1 -1
- package/dist/core/scene/nodeStore.js +72 -71
- package/dist/core/scene/nodeStore.js.map +1 -1
- package/dist/core/scene/notifier.js +37 -0
- package/dist/core/scene/notifier.js.map +1 -0
- package/dist/core/scene/opTable.js +50 -0
- package/dist/core/scene/opTable.js.map +1 -0
- package/dist/core/scene/outerOps.js +66 -0
- package/dist/core/scene/outerOps.js.map +1 -0
- package/dist/core/scene/poseHold.js +39 -0
- package/dist/core/scene/poseHold.js.map +1 -0
- package/dist/core/scene/poseOverrides.js +44 -36
- package/dist/core/scene/poseOverrides.js.map +1 -1
- package/dist/core/scene/poseSnapshot.js.map +1 -1
- package/dist/core/scene/reconcileSpecs.js +3 -2
- package/dist/core/scene/reconcileSpecs.js.map +1 -1
- package/dist/core/scene/recorder.js +86 -0
- package/dist/core/scene/recorder.js.map +1 -0
- package/dist/core/scene/renderOrder.js.map +1 -1
- package/dist/core/scene/scene.js +81 -690
- package/dist/core/scene/scene.js.map +1 -1
- package/dist/core/scene/sceneEdits.js +58 -0
- package/dist/core/scene/sceneEdits.js.map +1 -0
- package/dist/core/scene/sceneMutators.js +49 -0
- package/dist/core/scene/sceneMutators.js.map +1 -0
- package/dist/core/scene/scenePoseAdapter.js +16 -0
- package/dist/core/scene/scenePoseAdapter.js.map +1 -0
- package/dist/core/scene/sceneRecording.js +90 -0
- package/dist/core/scene/sceneRecording.js.map +1 -0
- package/dist/core/scene/sceneSelection.js +28 -0
- package/dist/core/scene/sceneSelection.js.map +1 -0
- package/dist/core/scene/sceneState.js +49 -0
- package/dist/core/scene/sceneState.js.map +1 -0
- package/dist/core/scene/serialization.js +8 -5
- package/dist/core/scene/serialization.js.map +1 -1
- package/dist/core/scene/staleReplay.js +51 -0
- package/dist/core/scene/staleReplay.js.map +1 -0
- package/dist/core/scene/statedFields.js +9 -0
- package/dist/core/scene/statedFields.js.map +1 -0
- package/dist/core/scene/treeEdits.js +127 -0
- package/dist/core/scene/treeEdits.js.map +1 -0
- package/dist/core/scene/treeReads.js +26 -0
- package/dist/core/scene/treeReads.js.map +1 -0
- package/dist/core/scene/types.js.map +1 -1
- package/dist/{features/groups → core/scene}/unionOfChildren.js +3 -3
- package/dist/core/scene/unionOfChildren.js.map +1 -0
- package/dist/core/scene/unitScopes.js +13 -0
- package/dist/core/scene/unitScopes.js.map +1 -0
- package/dist/core/scene/useScene.js.map +1 -1
- package/dist/core/selection/readOnlySelection.js +32 -0
- package/dist/core/selection/readOnlySelection.js.map +1 -0
- package/dist/core/selection/usePublishSceneSelection.js +26 -0
- package/dist/core/selection/usePublishSceneSelection.js.map +1 -0
- package/dist/core/selection/useSelection.js +34 -25
- package/dist/core/selection/useSelection.js.map +1 -1
- package/dist/core/shapeKinds.js.map +1 -1
- package/dist/core/stylus/stylus.js.map +1 -1
- package/dist/core/stylus/usePointerStylus.js.map +1 -1
- package/dist/core/usePaintKinds.js +1 -1
- package/dist/core/usePaintKinds.js.map +1 -1
- package/dist/core/viewport/clientToWorld.js.map +1 -1
- package/dist/core/viewport/fitViewToBounds.js.map +1 -1
- package/dist/core/viewport/parallax.js.map +1 -1
- package/dist/core/viewport/screenSlop.js +11 -11
- package/dist/core/viewport/screenSlop.js.map +1 -1
- package/dist/core/viewport/useCanvasSize.js.map +1 -1
- package/dist/core/viewport/useDecayLoop.js +8 -8
- package/dist/core/viewport/useDecayLoop.js.map +1 -1
- package/dist/core/viewport/useNodeOverlayFrame.js +84 -0
- package/dist/core/viewport/useNodeOverlayFrame.js.map +1 -0
- package/dist/core/viewport/useViewAnimation.js +102 -43
- package/dist/core/viewport/useViewAnimation.js.map +1 -1
- package/dist/core/viewport/view.js +7 -7
- package/dist/core/viewport/view.js.map +1 -1
- package/dist/core/viewport/wheelHandler.js.map +1 -1
- package/dist/{cornerHandles-CtCb8a3G.d.ts → cornerHandles-BEshc4z3.d.ts} +11 -24
- package/dist/debug/createDebugOverlayLayer.js +100 -100
- package/dist/debug/createDebugOverlayLayer.js.map +1 -1
- package/dist/debug/createDebugSink.js.map +1 -1
- package/dist/debug/frameStats.js.map +1 -1
- package/dist/debug/useDebugSink.js +52 -0
- package/dist/debug/useDebugSink.js.map +1 -0
- package/dist/features/chrome-caps/buildChromeCtx.js.map +1 -1
- package/dist/features/chrome-caps/conditions.js.map +1 -1
- package/dist/features/chrome-caps/defaults.js.map +1 -1
- package/dist/features/chrome-caps/resolve.js.map +1 -1
- package/dist/features/chrome-caps/useChromeCaps.js +54 -0
- package/dist/features/chrome-caps/useChromeCaps.js.map +1 -0
- package/dist/features/chrome-caps/useHoverTracking.js.map +1 -1
- package/dist/features/ingestion/contentHandlers.js +25 -19
- package/dist/features/ingestion/contentHandlers.js.map +1 -1
- package/dist/features/ingestion/imageHandler.js +21 -24
- package/dist/features/ingestion/imageHandler.js.map +1 -1
- package/dist/features/ingestion/openFilePicker.js.map +1 -1
- package/dist/features/ingestion/placement.js +16 -0
- package/dist/features/ingestion/placement.js.map +1 -0
- package/dist/features/ingestion/svgHandler.js +5 -0
- package/dist/features/ingestion/svgHandler.js.map +1 -1
- package/dist/features/ingestion/textHandler.js +28 -0
- package/dist/features/ingestion/textHandler.js.map +1 -0
- package/dist/features/ingestion/useCanvasIngestion.js +48 -0
- package/dist/features/ingestion/useCanvasIngestion.js.map +1 -0
- package/dist/features/ingestion/weaselJsonHandler.js +5 -0
- package/dist/features/ingestion/weaselJsonHandler.js.map +1 -1
- package/dist/features/longPress/longPressFeedback.js.map +1 -1
- package/dist/features/modes/modeLayers.js +7 -7
- package/dist/features/modes/modeLayers.js.map +1 -1
- package/dist/features/paths/editablePath.js +47 -0
- package/dist/features/paths/editablePath.js.map +1 -0
- package/dist/features/paths/index.js +9 -16
- package/dist/features/paths/pathEditState.js +41 -0
- package/dist/features/paths/pathEditState.js.map +1 -0
- package/dist/features/paths/pathEditingOverlayLayer.js +36 -38
- package/dist/features/paths/pathEditingOverlayLayer.js.map +1 -1
- package/dist/features/paths/pathLayer.js +3 -2
- package/dist/features/paths/pathLayer.js.map +1 -1
- package/dist/features/paths/penPreviewLayer.js +86 -88
- package/dist/features/paths/penPreviewLayer.js.map +1 -1
- package/dist/features/paths/usePathEdit.js +34 -0
- package/dist/features/paths/usePathEdit.js.map +1 -0
- package/dist/features/poseRun/usePoseRun.js +42 -55
- package/dist/features/poseRun/usePoseRun.js.map +1 -1
- package/dist/features/selection/overlay.js +170 -178
- package/dist/features/selection/overlay.js.map +1 -1
- package/dist/features/text/index.js +6 -0
- package/dist/features/text/textLayer.js +1 -1
- package/dist/features/text/textLayer.js.map +1 -1
- package/dist/features/text/useSceneTextEdit.js +95 -82
- package/dist/features/text/useSceneTextEdit.js.map +1 -1
- package/dist/features/viewports/viewportLayer.js +25 -36
- package/dist/features/viewports/viewportLayer.js.map +1 -1
- package/dist/index.d.ts +4507 -8459
- package/dist/index.js +275 -320
- package/dist/input/keyState.js +14 -14
- package/dist/interactions/actions/actionShortcuts.js.map +1 -1
- package/dist/interactions/actions/{defaults/align.js → align/action.js} +15 -16
- package/dist/interactions/actions/align/action.js.map +1 -0
- package/dist/interactions/actions/align/align.js +23 -23
- package/dist/interactions/actions/align/align.js.map +1 -1
- package/dist/interactions/actions/booleans/action.js +65 -0
- package/dist/interactions/actions/booleans/action.js.map +1 -0
- package/dist/interactions/actions/booleans/booleans.js +69 -78
- package/dist/interactions/actions/booleans/booleans.js.map +1 -1
- package/dist/interactions/actions/booleans/operands.js +40 -0
- package/dist/interactions/actions/booleans/operands.js.map +1 -0
- package/dist/interactions/actions/booleans/pieces.js +45 -0
- package/dist/interactions/actions/booleans/pieces.js.map +1 -0
- package/dist/interactions/actions/booleans/placement.js +24 -0
- package/dist/interactions/actions/booleans/placement.js.map +1 -0
- package/dist/interactions/actions/booleans/useBooleans.js +11 -9
- package/dist/interactions/actions/booleans/useBooleans.js.map +1 -1
- package/dist/interactions/actions/booleans/useBooleansAdapter.js.map +1 -1
- package/dist/interactions/actions/{defaults/clipboard.js → clipboard/action.js} +19 -19
- package/dist/interactions/actions/clipboard/action.js.map +1 -0
- package/dist/interactions/actions/clipboard/clipboardOps.js +15 -15
- package/dist/interactions/actions/clipboard/clipboardOps.js.map +1 -1
- package/dist/interactions/actions/clipboard/wireFormat.js.map +1 -1
- package/dist/interactions/actions/clone/action.js +98 -0
- package/dist/interactions/actions/clone/action.js.map +1 -0
- package/dist/interactions/actions/clone/behaviors.js +52 -0
- package/dist/interactions/actions/clone/behaviors.js.map +1 -0
- package/dist/interactions/actions/defaultCommitAdapter.js +10 -37
- package/dist/interactions/actions/defaultCommitAdapter.js.map +1 -1
- package/dist/interactions/actions/defaults/anchorEditing.js +41 -43
- package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -1
- package/dist/interactions/actions/defaults/areaSelect.js.map +1 -1
- package/dist/interactions/actions/defaults/cancelGesture.js.map +1 -1
- package/dist/interactions/actions/defaults/clearSelection.js.map +1 -1
- package/dist/interactions/actions/defaults/createPaintAction.js.map +1 -1
- package/dist/interactions/actions/defaults/delete.js.map +1 -1
- package/dist/interactions/actions/defaults/duplicate.js +19 -19
- package/dist/interactions/actions/defaults/duplicate.js.map +1 -1
- package/dist/interactions/actions/defaults/enterTextEdit.js.map +1 -1
- package/dist/interactions/actions/defaults/group.js +35 -40
- package/dist/interactions/actions/defaults/group.js.map +1 -1
- package/dist/interactions/actions/defaults/icons/booleanIcons.js +24 -1
- package/dist/interactions/actions/defaults/icons/booleanIcons.js.map +1 -1
- package/dist/interactions/actions/defaults/icons/outlineIcons.js +39 -1
- package/dist/interactions/actions/defaults/icons/outlineIcons.js.map +1 -1
- package/dist/interactions/actions/defaults/ingest.js +19 -15
- package/dist/interactions/actions/defaults/ingest.js.map +1 -1
- package/dist/interactions/actions/defaults/insertPathAnchor.js +14 -15
- package/dist/interactions/actions/defaults/insertPathAnchor.js.map +1 -1
- package/dist/interactions/actions/defaults/nudge.js +30 -31
- package/dist/interactions/actions/defaults/nudge.js.map +1 -1
- package/dist/interactions/actions/defaults/pinchZoom.js.map +1 -1
- package/dist/interactions/actions/defaults/requiresSelection.js.map +1 -1
- package/dist/interactions/actions/defaults/setFill.js +9 -3
- package/dist/interactions/actions/defaults/setFill.js.map +1 -1
- package/dist/interactions/actions/defaults/setFillOpacity.js +4 -1
- package/dist/interactions/actions/defaults/setFillOpacity.js.map +1 -1
- package/dist/interactions/actions/defaults/setStroke.js.map +1 -1
- package/dist/interactions/actions/defaults/sliceOps.js +20 -22
- package/dist/interactions/actions/defaults/sliceOps.js.map +1 -1
- package/dist/interactions/actions/defaults/toolActivate.js.map +1 -1
- package/dist/interactions/actions/defaults/toolResetToDefault.js.map +1 -1
- package/dist/interactions/actions/defaults/viewportDragPan.js +1 -1
- package/dist/interactions/actions/defaults/viewportDragPan.js.map +1 -1
- package/dist/interactions/actions/defaults/viewportWheelPan.js.map +1 -1
- package/dist/interactions/actions/defaults/viewportZoom.js.map +1 -1
- package/dist/interactions/actions/{defaults/distribute.js → distribute/action.js} +18 -19
- package/dist/interactions/actions/distribute/action.js.map +1 -0
- package/dist/interactions/actions/distribute/distribute.js +11 -11
- package/dist/interactions/actions/distribute/distribute.js.map +1 -1
- package/dist/interactions/actions/{defaults/editAnchors.js → edit-anchors/action.js} +19 -21
- package/dist/interactions/actions/edit-anchors/action.js.map +1 -0
- package/dist/interactions/actions/edit-anchors/geometry.js +2 -4
- package/dist/interactions/actions/edit-anchors/geometry.js.map +1 -1
- package/dist/interactions/actions/flip/action.js +124 -0
- package/dist/interactions/actions/flip/action.js.map +1 -0
- package/dist/interactions/actions/flip/helpers.js +1 -1
- package/dist/interactions/actions/flip/helpers.js.map +1 -1
- package/dist/interactions/actions/gestureFrames.js +18 -0
- package/dist/interactions/actions/gestureFrames.js.map +1 -0
- package/dist/interactions/actions/gestureLifecycle.js +47 -20
- package/dist/interactions/actions/gestureLifecycle.js.map +1 -1
- package/dist/interactions/actions/insert/action.js +72 -0
- package/dist/interactions/actions/insert/action.js.map +1 -0
- package/dist/interactions/actions/insert/commit.js +28 -0
- package/dist/interactions/actions/insert/commit.js.map +1 -0
- package/dist/interactions/actions/insert/extras.js +65 -0
- package/dist/interactions/actions/insert/extras.js.map +1 -0
- package/dist/interactions/actions/insert/frame.js +48 -0
- package/dist/interactions/actions/insert/frame.js.map +1 -0
- package/dist/interactions/actions/insert/geometry.js +35 -0
- package/dist/interactions/actions/insert/geometry.js.map +1 -0
- package/dist/interactions/actions/insert/rotateAction.js +21 -0
- package/dist/interactions/actions/insert/rotateAction.js.map +1 -0
- package/dist/interactions/actions/insert/session.js +59 -0
- package/dist/interactions/actions/insert/session.js.map +1 -0
- package/dist/interactions/actions/insert/shape.js +34 -0
- package/dist/interactions/actions/insert/shape.js.map +1 -0
- package/dist/interactions/actions/lasso-select/action.js +143 -0
- package/dist/interactions/actions/lasso-select/action.js.map +1 -0
- package/dist/interactions/actions/move/action.js +87 -0
- package/dist/interactions/actions/move/action.js.map +1 -0
- package/dist/interactions/actions/move/behaviors/layoutDrop.js +51 -0
- package/dist/interactions/actions/move/behaviors/layoutDrop.js.map +1 -0
- package/dist/interactions/actions/move/behaviors/reparentOnDrop.js +15 -0
- package/dist/interactions/actions/move/behaviors/reparentOnDrop.js.map +1 -0
- package/dist/interactions/actions/move/behaviors/snapToContainer.js +24 -23
- package/dist/interactions/actions/move/behaviors/snapToContainer.js.map +1 -1
- package/dist/interactions/actions/move/capture.js +99 -0
- package/dist/interactions/actions/move/capture.js.map +1 -0
- package/dist/interactions/actions/move/commit/index.js +41 -0
- package/dist/interactions/actions/move/commit/index.js.map +1 -0
- package/dist/interactions/actions/move/commit/layoutDrop.js +44 -0
- package/dist/interactions/actions/move/commit/layoutDrop.js.map +1 -0
- package/dist/interactions/actions/move/commit/layoutRelease.js +100 -0
- package/dist/interactions/actions/move/commit/layoutRelease.js.map +1 -0
- package/dist/interactions/actions/move/commit/rebase.js +18 -0
- package/dist/interactions/actions/move/commit/rebase.js.map +1 -0
- package/dist/interactions/actions/move/commit/reparent.js +65 -0
- package/dist/interactions/actions/move/commit/reparent.js.map +1 -0
- package/dist/interactions/actions/move/delta.js +51 -0
- package/dist/interactions/actions/move/delta.js.map +1 -0
- package/dist/interactions/actions/move/frame.js +59 -0
- package/dist/interactions/actions/move/frame.js.map +1 -0
- package/dist/interactions/actions/move/gestureAdapter.js +15 -40
- package/dist/interactions/actions/move/gestureAdapter.js.map +1 -1
- package/dist/interactions/actions/move/landedDescendants.js +8 -8
- package/dist/interactions/actions/move/layout/container.js +94 -0
- package/dist/interactions/actions/move/layout/container.js.map +1 -0
- package/dist/interactions/actions/move/layout/dragged.js +58 -0
- package/dist/interactions/actions/move/layout/dragged.js.map +1 -0
- package/dist/interactions/actions/move/layout/dropPass.js +122 -0
- package/dist/interactions/actions/move/layout/dropPass.js.map +1 -0
- package/dist/interactions/actions/move/layout/exits.js +38 -0
- package/dist/interactions/actions/move/layout/exits.js.map +1 -0
- package/dist/interactions/actions/move/layout/glide.js +48 -0
- package/dist/interactions/actions/move/layout/glide.js.map +1 -0
- package/dist/interactions/actions/move/session.js +63 -0
- package/dist/interactions/actions/move/session.js.map +1 -0
- package/dist/interactions/actions/move/translate.js +61 -0
- package/dist/interactions/actions/move/translate.js.map +1 -0
- package/dist/interactions/actions/outlines/createOutlines.js +17 -64
- package/dist/interactions/actions/outlines/createOutlines.js.map +1 -1
- package/dist/interactions/actions/outlines/createOutlinesAction.js +51 -0
- package/dist/interactions/actions/outlines/createOutlinesAction.js.map +1 -0
- package/dist/interactions/actions/outlines/outlineStroke.js +72 -0
- package/dist/interactions/actions/outlines/outlineStroke.js.map +1 -0
- package/dist/interactions/actions/outlines/outlineStrokeAction.js +37 -0
- package/dist/interactions/actions/outlines/outlineStrokeAction.js.map +1 -0
- package/dist/interactions/actions/outlines/replaceWithPaths.js +54 -0
- package/dist/interactions/actions/outlines/replaceWithPaths.js.map +1 -0
- package/dist/interactions/actions/outlines/strokeRegion.js +27 -0
- package/dist/interactions/actions/outlines/strokeRegion.js.map +1 -0
- package/dist/interactions/actions/planeInput.js.map +1 -1
- package/dist/interactions/actions/pointerState.js +12 -0
- package/dist/interactions/actions/pointerState.js.map +1 -0
- package/dist/interactions/actions/poseDescriptorDep.js +1 -1
- package/dist/interactions/actions/poseDescriptorDep.js.map +1 -1
- package/dist/interactions/actions/poseFrame.js +26 -26
- package/dist/interactions/actions/poseFrame.js.map +1 -1
- package/dist/interactions/actions/resize/action.js +55 -0
- package/dist/interactions/actions/resize/action.js.map +1 -0
- package/dist/interactions/actions/resize/behaviors/lockAspect.js.map +1 -1
- package/dist/interactions/actions/resize/boxFrame.js +16 -0
- package/dist/interactions/actions/resize/boxFrame.js.map +1 -0
- package/dist/interactions/actions/resize/capture.js +85 -0
- package/dist/interactions/actions/resize/capture.js.map +1 -0
- package/dist/interactions/actions/resize/commit.js +69 -0
- package/dist/interactions/actions/resize/commit.js.map +1 -0
- package/dist/interactions/actions/resize/frame.js +74 -0
- package/dist/interactions/actions/resize/frame.js.map +1 -0
- package/dist/interactions/actions/resize/pointSnap.js +111 -0
- package/dist/interactions/actions/resize/pointSnap.js.map +1 -0
- package/dist/interactions/actions/resize/ruleBounds.js +9 -0
- package/dist/interactions/actions/resize/ruleBounds.js.map +1 -0
- package/dist/interactions/actions/resize/session.js +49 -0
- package/dist/interactions/actions/resize/session.js.map +1 -0
- package/dist/interactions/actions/resolveOverlays.js.map +1 -1
- package/dist/interactions/actions/resolvePreviews.js.map +1 -1
- package/dist/interactions/actions/rotate/action.js +56 -0
- package/dist/interactions/actions/rotate/action.js.map +1 -0
- package/dist/interactions/actions/rotate/behaviors/index.js +7 -0
- package/dist/interactions/actions/rotate/behaviors/index.js.map +1 -0
- package/dist/interactions/actions/rotate/behaviors/snapRotation.js +12 -0
- package/dist/interactions/actions/rotate/behaviors/snapRotation.js.map +1 -0
- package/dist/interactions/actions/rotate/commit.js +40 -0
- package/dist/interactions/actions/rotate/commit.js.map +1 -0
- package/dist/interactions/actions/rotate/frame.js +65 -0
- package/dist/interactions/actions/rotate/frame.js.map +1 -0
- package/dist/interactions/actions/rotate/handle.js +12 -12
- package/dist/interactions/actions/rotate/handle.js.map +1 -1
- package/dist/interactions/actions/rotate/session.js +92 -0
- package/dist/interactions/actions/rotate/session.js.map +1 -0
- package/dist/interactions/actions/spatialReference.js.map +1 -1
- package/dist/interactions/actions/useStandardActions.js +77 -72
- package/dist/interactions/actions/useStandardActions.js.map +1 -1
- package/dist/interactions/gestures/pointerDrag/pointerDrag.js +61 -42
- package/dist/interactions/gestures/pointerDrag/pointerDrag.js.map +1 -1
- package/dist/interactions/gestures/shared/originProjection.js +1 -1
- package/dist/interactions/gestures/shared/originProjection.js.map +1 -1
- package/dist/interactions/gestures/shared/screenTolerance.js +8 -2
- package/dist/interactions/gestures/shared/screenTolerance.js.map +1 -1
- package/dist/interactions/gestures/shared/snap.js.map +1 -1
- package/dist/layout/arrivals.js +20 -23
- package/dist/layout/arrivals.js.map +1 -1
- package/dist/math-CYUjoyyU.d.ts +33 -0
- package/dist/math.d.ts +5 -2
- package/dist/math.js +6 -6
- package/dist/mesh.d.ts +4 -268
- package/dist/mesh.js +3 -7
- package/dist/move.d.ts +6 -4
- package/dist/{originProjection-gHnOup4e.d.ts → originProjection-PPT88jZv.d.ts} +1 -1
- package/dist/patterns-builtin.d.ts +1 -118
- package/dist/patterns-builtin.js +2 -3
- package/dist/poseDescriptor-Bqk-11Rl.d.ts +73 -0
- package/dist/renderer.d.ts +1 -92
- package/dist/renderer.js +2 -19
- package/dist/resize.d.ts +11 -22
- package/dist/resize.js +1 -1
- package/dist/style.css +1 -1
- package/dist/test-hook/install.js.map +1 -1
- package/dist/test-hook/useTestHook.js +22 -0
- package/dist/test-hook/useTestHook.js.map +1 -0
- package/dist/test-seams-D0pyV3pR.d.ts +149 -0
- package/dist/test-seams.d.ts +4 -4
- package/dist/test-seams.js +2 -2
- package/dist/tools/builtin/bone/boneActions.js +130 -0
- package/dist/tools/builtin/bone/boneActions.js.map +1 -0
- package/dist/tools/builtin/bone/boneOverlay.js +58 -0
- package/dist/tools/builtin/bone/boneOverlay.js.map +1 -0
- package/dist/tools/builtin/bone/placedRig.js +24 -0
- package/dist/tools/builtin/bone/placedRig.js.map +1 -0
- package/dist/tools/builtin/bone/rigEditState.js +21 -0
- package/dist/tools/builtin/bone/rigEditState.js.map +1 -0
- package/dist/tools/builtin/bone/useBoneTool.js +98 -0
- package/dist/tools/builtin/bone/useBoneTool.js.map +1 -0
- package/dist/tools/builtin/ellipse/useEllipseTool.js.map +1 -1
- package/dist/tools/builtin/eyedropper/useEyedropperTool.js.map +1 -1
- package/dist/tools/builtin/hand/useHandTool.js.map +1 -1
- package/dist/tools/builtin/image/useImageTool.js.map +1 -1
- package/dist/tools/builtin/lasso/useLassoTool.js.map +1 -1
- package/dist/tools/builtin/line/useLineTool.js.map +1 -1
- package/dist/tools/builtin/pen/usePenTool.js +161 -163
- package/dist/tools/builtin/pen/usePenTool.js.map +1 -1
- package/dist/tools/builtin/pencil/usePencilTool.js.map +1 -1
- package/dist/tools/builtin/pickTopMostHit.js.map +1 -1
- package/dist/tools/builtin/polygon/usePolygonTool.js.map +1 -1
- package/dist/tools/builtin/rect/useRectTool.js.map +1 -1
- package/dist/tools/builtin/select/adapterPointQuery.js +36 -0
- package/dist/tools/builtin/select/adapterPointQuery.js.map +1 -0
- package/dist/tools/builtin/select/selectionContributions.js +4 -4
- package/dist/tools/builtin/select/selectionContributions.js.map +1 -1
- package/dist/tools/builtin/select/useSelectTool.js +43 -71
- package/dist/tools/builtin/select/useSelectTool.js.map +1 -1
- package/dist/tools/builtin/shared/pointerFollower.js.map +1 -1
- package/dist/tools/builtin/slice/useSliceTool.js +67 -72
- package/dist/tools/builtin/slice/useSliceTool.js.map +1 -1
- package/dist/tools/builtin/star/useStarTool.js.map +1 -1
- package/dist/tools/builtin/text/useTextTool.js +8 -0
- package/dist/tools/builtin/text/useTextTool.js.map +1 -1
- package/dist/tools/builtin/weight/useWeightTool.js +77 -0
- package/dist/tools/builtin/weight/useWeightTool.js.map +1 -0
- package/dist/tools/builtin/weight/weightActions.js +112 -0
- package/dist/tools/builtin/weight/weightActions.js.map +1 -0
- package/dist/tools/builtin/weight/weightOverlay.js +61 -0
- package/dist/tools/builtin/weight/weightOverlay.js.map +1 -0
- package/dist/tools/overlayBinding.js.map +1 -1
- package/dist/tools/useKeybindings.js +20 -14
- package/dist/tools/useKeybindings.js.map +1 -1
- package/dist/{types-k-5Oqh-U.d.ts → types-CIKDwlsP.d.ts} +84 -164
- package/dist/util/paint.js +1 -1
- package/dist/util/paint.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +26 -21
- package/dist/animation/colorHelpers.js +0 -135
- package/dist/animation/colorHelpers.js.map +0 -1
- package/dist/animation/colorRegistry.js +0 -37
- package/dist/animation/colorRegistry.js.map +0 -1
- package/dist/animation/engine/axes.js +0 -36
- package/dist/animation/engine/axes.js.map +0 -1
- package/dist/animation/engine/codec.js +0 -170
- package/dist/animation/engine/codec.js.map +0 -1
- package/dist/animation/engine/integrator.js +0 -12
- package/dist/animation/engine/integrator.js.map +0 -1
- package/dist/animation/loop.js +0 -60
- package/dist/animation/loop.js.map +0 -1
- package/dist/animation/observe.js +0 -23
- package/dist/animation/observe.js.map +0 -1
- package/dist/animation/rig/blendPoses.js +0 -43
- package/dist/animation/rig/blendPoses.js.map +0 -1
- package/dist/animation/rig/mirrorPose.js +0 -19
- package/dist/animation/rig/mirrorPose.js.map +0 -1
- package/dist/animation/rig/resolveSkeleton.js +0 -33
- package/dist/animation/rig/resolveSkeleton.js.map +0 -1
- package/dist/animation/rig/solveIk.js +0 -103
- package/dist/animation/rig/solveIk.js.map +0 -1
- package/dist/animation/rig/types.js +0 -12
- package/dist/animation/rig/types.js.map +0 -1
- package/dist/animation/slew.js +0 -27
- package/dist/animation/slew.js.map +0 -1
- package/dist/animation/stagger.js +0 -146
- package/dist/animation/stagger.js.map +0 -1
- package/dist/animation/timeline/booking.js +0 -114
- package/dist/animation/timeline/booking.js.map +0 -1
- package/dist/animation/timeline/createTimeline.js +0 -125
- package/dist/animation/timeline/createTimeline.js.map +0 -1
- package/dist/animation/timeline/sampleTrack.js +0 -79
- package/dist/animation/timeline/sampleTrack.js.map +0 -1
- package/dist/animation/useAnimator.js +0 -388
- package/dist/animation/useAnimator.js.map +0 -1
- package/dist/autoPoseDescriptor-Ct7yqivU.d.ts +0 -108
- package/dist/builtins-DPcdghtB.d.ts +0 -1223
- package/dist/canvas/MinimapCanvas.js +0 -140
- package/dist/canvas/MinimapCanvas.js.map +0 -1
- package/dist/canvas/deps/poseComposition.js +0 -11
- package/dist/canvas/deps/poseComposition.js.map +0 -1
- package/dist/canvas/minimapMath.js +0 -82
- package/dist/canvas/minimapMath.js.map +0 -1
- package/dist/canvas/toolPreview.js +0 -39
- package/dist/canvas/toolPreview.js.map +0 -1
- package/dist/core/adapters/arrayAdapter.js +0 -94
- package/dist/core/adapters/arrayAdapter.js.map +0 -1
- package/dist/core/adapters/useArrayAdapter.js +0 -13
- package/dist/core/adapters/useArrayAdapter.js.map +0 -1
- package/dist/core/fillInPoseFrame.js +0 -102
- package/dist/core/fillInPoseFrame.js.map +0 -1
- package/dist/core/geometry/poseFrame.js +0 -44
- package/dist/core/geometry/poseFrame.js.map +0 -1
- package/dist/core/geometry/poseRotation.js +0 -58
- package/dist/core/geometry/poseRotation.js.map +0 -1
- package/dist/core/gradient.js +0 -136
- package/dist/core/gradient.js.map +0 -1
- package/dist/core/markerInset.js +0 -24
- package/dist/core/markerInset.js.map +0 -1
- package/dist/core/mixed.js +0 -6
- package/dist/core/mixed.js.map +0 -1
- package/dist/core/paintKinds.js +0 -156
- package/dist/core/paintKinds.js.map +0 -1
- package/dist/core/scene/pickability.js +0 -6
- package/dist/core/scene/pickability.js.map +0 -1
- package/dist/core/strokeMarkerShapes.js +0 -139
- package/dist/core/strokeMarkerShapes.js.map +0 -1
- package/dist/core/strokeMarkers.js +0 -28
- package/dist/core/strokeMarkers.js.map +0 -1
- package/dist/core/viewport/meanScale.js +0 -8
- package/dist/core/viewport/meanScale.js.map +0 -1
- package/dist/core/viewport/pxExtent.js +0 -42
- package/dist/core/viewport/pxExtent.js.map +0 -1
- package/dist/features/cursor/paintedCursorLayer.js.map +0 -1
- package/dist/features/focus/gateLayer.js.map +0 -1
- package/dist/features/focus/useCanvasFocus.js +0 -29
- package/dist/features/focus/useCanvasFocus.js.map +0 -1
- package/dist/features/groups/children.js.map +0 -1
- package/dist/features/groups/composePose.js.map +0 -1
- package/dist/features/groups/nestedHit.js.map +0 -1
- package/dist/features/groups/unionOfChildren.js.map +0 -1
- package/dist/features/images/imageCache.js +0 -104
- package/dist/features/images/imageCache.js.map +0 -1
- package/dist/features/ingestion/index.js +0 -8
- package/dist/features/meshPaint/bake.js +0 -79
- package/dist/features/meshPaint/bake.js.map +0 -1
- package/dist/features/meshPaint/bakeCache.js +0 -59
- package/dist/features/meshPaint/bakeCache.js.map +0 -1
- package/dist/features/meshPaint/handles.js +0 -86
- package/dist/features/meshPaint/handles.js.map +0 -1
- package/dist/features/meshPaint/lazyKind.js.map +0 -1
- package/dist/features/meshPaint/meshPaint.js +0 -239
- package/dist/features/meshPaint/meshPaint.js.map +0 -1
- package/dist/features/meshPaint/meshShader.js +0 -6
- package/dist/features/meshPaint/meshShader.js.map +0 -1
- package/dist/features/meshPaint/register.js +0 -7
- package/dist/features/meshPaint/register.js.map +0 -1
- package/dist/features/meshPaint/surface.js +0 -110
- package/dist/features/meshPaint/surface.js.map +0 -1
- package/dist/features/minimap/actions.js +0 -53
- package/dist/features/minimap/actions.js.map +0 -1
- package/dist/features/minimap/createMinimapContribution.js +0 -96
- package/dist/features/minimap/createMinimapContribution.js.map +0 -1
- package/dist/features/minimap/layers.js +0 -85
- package/dist/features/minimap/layers.js.map +0 -1
- package/dist/features/overlays/useNodeOverlayFrame.js +0 -103
- package/dist/features/overlays/useNodeOverlayFrame.js.map +0 -1
- package/dist/features/parallax/createParallaxLayer.js +0 -26
- package/dist/features/parallax/createParallaxLayer.js.map +0 -1
- package/dist/features/parallax/createParallaxPlane.js +0 -22
- package/dist/features/parallax/createParallaxPlane.js.map +0 -1
- package/dist/features/paths/anchorEdits.js +0 -167
- package/dist/features/paths/anchorEdits.js.map +0 -1
- package/dist/features/paths/anchors.js +0 -159
- package/dist/features/paths/anchors.js.map +0 -1
- package/dist/features/paths/booleans.js +0 -2
- package/dist/features/paths/markerCommands.js +0 -149
- package/dist/features/paths/markerCommands.js.map +0 -1
- package/dist/features/paths/markerSites.js +0 -59
- package/dist/features/paths/markerSites.js.map +0 -1
- package/dist/features/paths/markers.js +0 -95
- package/dist/features/paths/markers.js.map +0 -1
- package/dist/features/paths/nearestAnchor.js +0 -36
- package/dist/features/paths/nearestAnchor.js.map +0 -1
- package/dist/features/paths/pathInWorld.js +0 -41
- package/dist/features/paths/pathInWorld.js.map +0 -1
- package/dist/features/paths/poseDescriptor.js +0 -39
- package/dist/features/paths/poseDescriptor.js.map +0 -1
- package/dist/features/paths/strokeToPath.js +0 -40
- package/dist/features/paths/strokeToPath.js.map +0 -1
- package/dist/features/paths/tessellate/dash.js +0 -52
- package/dist/features/paths/tessellate/dash.js.map +0 -1
- package/dist/features/paths/tessellate/insets.js +0 -32
- package/dist/features/paths/tessellate/insets.js.map +0 -1
- package/dist/features/paths/tessellate/metric.js +0 -72
- package/dist/features/paths/tessellate/metric.js.map +0 -1
- package/dist/features/paths/tessellate/stroke.js +0 -170
- package/dist/features/paths/tessellate/stroke.js.map +0 -1
- package/dist/features/paths/tessellate/vertexWidths.js +0 -32
- package/dist/features/paths/tessellate/vertexWidths.js.map +0 -1
- package/dist/features/patterns/commandPaint.js +0 -18
- package/dist/features/patterns/commandPaint.js.map +0 -1
- package/dist/features/patterns/index.js +0 -11
- package/dist/features/patterns/index.js.map +0 -1
- package/dist/features/patterns/patterns-builtin.js +0 -38
- package/dist/features/patterns/patterns-builtin.js.map +0 -1
- package/dist/features/patterns/rasterizeTile.js +0 -17
- package/dist/features/patterns/rasterizeTile.js.map +0 -1
- package/dist/features/patterns/resolveSpec.js +0 -65
- package/dist/features/patterns/resolveSpec.js.map +0 -1
- package/dist/features/patterns/tileGeometry.js +0 -158
- package/dist/features/patterns/tileGeometry.js.map +0 -1
- package/dist/features/pointer/PointerContext.js +0 -45
- package/dist/features/pointer/PointerContext.js.map +0 -1
- package/dist/features/selection/SelectionContext.js +0 -51
- package/dist/features/selection/SelectionContext.js.map +0 -1
- package/dist/features/simulation/createSimulation.js +0 -61
- package/dist/features/simulation/createSimulation.js.map +0 -1
- package/dist/features/simulation/types.js +0 -6
- package/dist/features/simulation/types.js.map +0 -1
- package/dist/features/simulation/useSimulation.js +0 -74
- package/dist/features/simulation/useSimulation.js.map +0 -1
- package/dist/features/text/domOffsets.js +0 -82
- package/dist/features/text/domOffsets.js.map +0 -1
- package/dist/features/text/domRuns.js +0 -230
- package/dist/features/text/domRuns.js.map +0 -1
- package/dist/features/text/fitTextPose.js +0 -38
- package/dist/features/text/fitTextPose.js.map +0 -1
- package/dist/features/text/hitTest.js +0 -48
- package/dist/features/text/hitTest.js.map +0 -1
- package/dist/features/text/isTextData.js +0 -8
- package/dist/features/text/isTextData.js.map +0 -1
- package/dist/features/text/overlayDirection.js +0 -15
- package/dist/features/text/overlayDirection.js.map +0 -1
- package/dist/features/text/renderLabel.js +0 -14
- package/dist/features/text/renderLabel.js.map +0 -1
- package/dist/features/text/runs/effectiveRangeStyle.js +0 -66
- package/dist/features/text/runs/effectiveRangeStyle.js.map +0 -1
- package/dist/features/text/runs/flagRange.js +0 -53
- package/dist/features/text/runs/flagRange.js.map +0 -1
- package/dist/features/text/runs/rangeStyle.js +0 -133
- package/dist/features/text/runs/rangeStyle.js.map +0 -1
- package/dist/features/text/textCommand.js +0 -60
- package/dist/features/text/textCommand.js.map +0 -1
- package/dist/features/text/textToPath.js +0 -181
- package/dist/features/text/textToPath.js.map +0 -1
- package/dist/features/text/useTextEdit.js +0 -491
- package/dist/features/text/useTextEdit.js.map +0 -1
- package/dist/features/tiling/createTiledLayer.js +0 -65
- package/dist/features/tiling/createTiledLayer.js.map +0 -1
- package/dist/features/tiling/tiledProject.js +0 -14
- package/dist/features/tiling/tiledProject.js.map +0 -1
- package/dist/interactions/actions/clone/behaviors/cloneByAltDrag.js +0 -26
- package/dist/interactions/actions/clone/behaviors/cloneByAltDrag.js.map +0 -1
- package/dist/interactions/actions/defaults/align.js.map +0 -1
- package/dist/interactions/actions/defaults/booleans.js +0 -52
- package/dist/interactions/actions/defaults/booleans.js.map +0 -1
- package/dist/interactions/actions/defaults/clipboard.js.map +0 -1
- package/dist/interactions/actions/defaults/clone.js +0 -91
- package/dist/interactions/actions/defaults/clone.js.map +0 -1
- package/dist/interactions/actions/defaults/createOutlines.js +0 -47
- package/dist/interactions/actions/defaults/createOutlines.js.map +0 -1
- package/dist/interactions/actions/defaults/distribute.js.map +0 -1
- package/dist/interactions/actions/defaults/editAnchors.js.map +0 -1
- package/dist/interactions/actions/defaults/flip.js +0 -125
- package/dist/interactions/actions/defaults/flip.js.map +0 -1
- package/dist/interactions/actions/defaults/insert.js +0 -287
- package/dist/interactions/actions/defaults/insert.js.map +0 -1
- package/dist/interactions/actions/defaults/lassoSelect.js +0 -153
- package/dist/interactions/actions/defaults/lassoSelect.js.map +0 -1
- package/dist/interactions/actions/defaults/move.js +0 -778
- package/dist/interactions/actions/defaults/move.js.map +0 -1
- package/dist/interactions/actions/defaults/resize.js +0 -341
- package/dist/interactions/actions/defaults/resize.js.map +0 -1
- package/dist/interactions/actions/defaults/rotate.js +0 -185
- package/dist/interactions/actions/defaults/rotate.js.map +0 -1
- package/dist/interactions/actions/previewOverrides.js +0 -25
- package/dist/interactions/actions/previewOverrides.js.map +0 -1
- package/dist/interactions/actions/resize/autoPoseDescriptor.js.map +0 -1
- package/dist/math-J-ACHyEg.d.ts +0 -159
- package/dist/registerProgram-T9S_PfAX.d.ts +0 -208
- package/dist/renderer/DrawCommand.js +0 -6
- package/dist/renderer/DrawCommand.js.map +0 -1
- package/dist/renderer/WeaselRenderer.js +0 -333
- package/dist/renderer/WeaselRenderer.js.map +0 -1
- package/dist/renderer/batchClip.js +0 -46
- package/dist/renderer/batchClip.js.map +0 -1
- package/dist/renderer/cache/GLImageCache.js +0 -74
- package/dist/renderer/cache/GLImageCache.js.map +0 -1
- package/dist/renderer/cache/GLMeshCache.js +0 -102
- package/dist/renderer/cache/GLMeshCache.js.map +0 -1
- package/dist/renderer/cache/GLTextureCache.js +0 -68
- package/dist/renderer/cache/GLTextureCache.js.map +0 -1
- package/dist/renderer/cache/GradientRampAtlas.js +0 -82
- package/dist/renderer/cache/GradientRampAtlas.js.map +0 -1
- package/dist/renderer/cache/cache.js +0 -13
- package/dist/renderer/cache/cache.js.map +0 -1
- package/dist/renderer/cache/markerCommandCache.js +0 -63
- package/dist/renderer/cache/markerCommandCache.js.map +0 -1
- package/dist/renderer/cache/outlineMeshCache.js +0 -15
- package/dist/renderer/cache/outlineMeshCache.js.map +0 -1
- package/dist/renderer/cache/outlineStrokeMeshCache.js +0 -36
- package/dist/renderer/cache/outlineStrokeMeshCache.js.map +0 -1
- package/dist/renderer/cache/strokeMeshCache.js +0 -55
- package/dist/renderer/cache/strokeMeshCache.js.map +0 -1
- package/dist/renderer/cullDrawCommands.js +0 -90
- package/dist/renderer/cullDrawCommands.js.map +0 -1
- package/dist/renderer/draw/batch.js +0 -133
- package/dist/renderer/draw/batch.js.map +0 -1
- package/dist/renderer/draw/clip.js +0 -89
- package/dist/renderer/draw/clip.js.map +0 -1
- package/dist/renderer/draw/customShader.js +0 -230
- package/dist/renderer/draw/customShader.js.map +0 -1
- package/dist/renderer/draw/drawTriangles.js +0 -8
- package/dist/renderer/draw/drawTriangles.js.map +0 -1
- package/dist/renderer/draw/effects.js +0 -28
- package/dist/renderer/draw/effects.js.map +0 -1
- package/dist/renderer/draw/flushBatch.js +0 -35
- package/dist/renderer/draw/flushBatch.js.map +0 -1
- package/dist/renderer/draw/gradient.js +0 -90
- package/dist/renderer/draw/gradient.js.map +0 -1
- package/dist/renderer/draw/image.js +0 -38
- package/dist/renderer/draw/image.js.map +0 -1
- package/dist/renderer/draw/mesh.js +0 -16
- package/dist/renderer/draw/mesh.js.map +0 -1
- package/dist/renderer/draw/paintBind.js +0 -70
- package/dist/renderer/draw/paintBind.js.map +0 -1
- package/dist/renderer/draw/pathPaint.js +0 -142
- package/dist/renderer/draw/pathPaint.js.map +0 -1
- package/dist/renderer/draw/scratchPass.js +0 -83
- package/dist/renderer/draw/scratchPass.js.map +0 -1
- package/dist/renderer/draw/stencil.js +0 -28
- package/dist/renderer/draw/stencil.js.map +0 -1
- package/dist/renderer/draw/text.js +0 -167
- package/dist/renderer/draw/text.js.map +0 -1
- package/dist/renderer/draw/uniforms.js +0 -77
- package/dist/renderer/draw/uniforms.js.map +0 -1
- package/dist/renderer/draw.js +0 -79
- package/dist/renderer/draw.js.map +0 -1
- package/dist/renderer/drawBatch.js +0 -198
- package/dist/renderer/drawBatch.js.map +0 -1
- package/dist/renderer/effects/EffectTargets.js +0 -48
- package/dist/renderer/effects/EffectTargets.js.map +0 -1
- package/dist/renderer/effects/builtins.js +0 -31
- package/dist/renderer/effects/builtins.js.map +0 -1
- package/dist/renderer/effects/composite.js +0 -11
- package/dist/renderer/effects/composite.js.map +0 -1
- package/dist/renderer/effects/effectPrelude.js +0 -10
- package/dist/renderer/effects/effectPrelude.js.map +0 -1
- package/dist/renderer/effects/types.js +0 -10
- package/dist/renderer/effects/types.js.map +0 -1
- package/dist/renderer/glyphOutlineMesh.js +0 -67
- package/dist/renderer/glyphOutlineMesh.js.map +0 -1
- package/dist/renderer/index.js +0 -20
- package/dist/renderer/math/color.js +0 -321
- package/dist/renderer/math/color.js.map +0 -1
- package/dist/renderer/math/mat3.js +0 -80
- package/dist/renderer/math/mat3.js.map +0 -1
- package/dist/renderer/math/patternSpace.js +0 -22
- package/dist/renderer/math/patternSpace.js.map +0 -1
- package/dist/renderer/math/viewToMat3.js +0 -19
- package/dist/renderer/math/viewToMat3.js.map +0 -1
- package/dist/renderer/paintResources.js +0 -18
- package/dist/renderer/paintResources.js.map +0 -1
- package/dist/renderer/paintScratch.js +0 -37
- package/dist/renderer/paintScratch.js.map +0 -1
- package/dist/renderer/shaders/ShaderProgram.js +0 -74
- package/dist/renderer/shaders/ShaderProgram.js.map +0 -1
- package/dist/renderer/shaders/batchFill.js +0 -119
- package/dist/renderer/shaders/batchFill.js.map +0 -1
- package/dist/renderer/shaders/customPrelude.js +0 -34
- package/dist/renderer/shaders/customPrelude.js.map +0 -1
- package/dist/renderer/shaders/extractUniformNames.js +0 -184
- package/dist/renderer/shaders/extractUniformNames.js.map +0 -1
- package/dist/renderer/shaders/glyphPaint.js +0 -61
- package/dist/renderer/shaders/glyphPaint.js.map +0 -1
- package/dist/renderer/shaders/gradFill.js +0 -31
- package/dist/renderer/shaders/gradFill.js.map +0 -1
- package/dist/renderer/shaders/pathFill.js +0 -14
- package/dist/renderer/shaders/pathFill.js.map +0 -1
- package/dist/renderer/shaders/patternFill.js +0 -25
- package/dist/renderer/shaders/patternFill.js.map +0 -1
- package/dist/renderer/shaders/registerProgram.js +0 -18
- package/dist/renderer/shaders/registerProgram.js.map +0 -1
- package/dist/renderer/spriteSheet.js +0 -14
- package/dist/renderer/spriteSheet.js.map +0 -1
- package/dist/renderer/state/GroupState.js +0 -77
- package/dist/renderer/state/GroupState.js.map +0 -1
- package/dist/renderer/strokeLengths.js +0 -50
- package/dist/renderer/strokeLengths.js.map +0 -1
- package/dist/renderer/syntheticItalic.js +0 -6
- package/dist/renderer/syntheticItalic.js.map +0 -1
- package/dist/renderer/textures/registerTexture.js +0 -34
- package/dist/renderer/textures/registerTexture.js.map +0 -1
- package/dist/scheduling/useVisibleRaf.js +0 -69
- package/dist/scheduling/useVisibleRaf.js.map +0 -1
- package/dist/test-seams-DM2B87-g.d.ts +0 -356
|
@@ -1,96 +1,54 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { IDENTITY_TARGET as e, angleOf as t, localToWorld as n, normalToWorld as r, pxExtentIn as i, targetTransformOf as a, worldToLocal as o } from "../core/geometry/targetFrame.js";
|
|
2
|
+
import { scaleDelta as s, screenAngleOf as c, standoff as l } from "@weasel-js/geom";
|
|
3
3
|
//#region src/affordances/hitAffordanceRegions.ts
|
|
4
|
-
function
|
|
5
|
-
for (let
|
|
6
|
-
let
|
|
7
|
-
if (a && !a(
|
|
8
|
-
let
|
|
9
|
-
for (let e = 0; e <
|
|
10
|
-
let a =
|
|
11
|
-
if (!
|
|
12
|
-
let
|
|
13
|
-
(
|
|
4
|
+
function u(e, t, n, r, i, a) {
|
|
5
|
+
for (let o = e.length - 1; o >= 0; o--) {
|
|
6
|
+
let s = e[o];
|
|
7
|
+
if (a && !a(s.id)) continue;
|
|
8
|
+
let c = s.regions(r), l = null;
|
|
9
|
+
for (let e = 0; e < c.length; e++) {
|
|
10
|
+
let a = c[e], o = f(r, a.targetId);
|
|
11
|
+
if (!v(a, t, n, o, i)) continue;
|
|
12
|
+
let s = d(a, t, n, o, i);
|
|
13
|
+
(l === null || s <= l.d2) && (l = {
|
|
14
14
|
region: a,
|
|
15
|
-
d2:
|
|
15
|
+
d2: s
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
|
-
if (
|
|
19
|
-
affordanceId:
|
|
20
|
-
regionId:
|
|
21
|
-
region:
|
|
22
|
-
binding:
|
|
18
|
+
if (l) return {
|
|
19
|
+
affordanceId: s.id,
|
|
20
|
+
regionId: l.region.id,
|
|
21
|
+
region: l.region,
|
|
22
|
+
binding: l.region.bind()
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
25
|
return null;
|
|
26
26
|
}
|
|
27
|
-
function
|
|
28
|
-
let
|
|
29
|
-
return
|
|
27
|
+
function d(e, t, r, i, a) {
|
|
28
|
+
let o = e.shape, s = o.kind === "point" ? g(o, i, a) : o.kind === "annulus" ? n(i, o.cx, o.cy) : n(i, o.x + o.width / 2, o.y + o.height / 2), c = s.x - t, l = s.y - r;
|
|
29
|
+
return c * c + l * l;
|
|
30
30
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
cy: 0,
|
|
34
|
-
cos: 1,
|
|
35
|
-
sin: 0,
|
|
36
|
-
identity: !0
|
|
37
|
-
};
|
|
38
|
-
function c(t, n) {
|
|
39
|
-
if (n === null) return s;
|
|
40
|
-
let r = t.boundsOf(n);
|
|
41
|
-
if (!r) return s;
|
|
42
|
-
let i = e(r);
|
|
43
|
-
return i ? {
|
|
44
|
-
cx: i.cx,
|
|
45
|
-
cy: i.cy,
|
|
46
|
-
cos: Math.cos(i.rotation),
|
|
47
|
-
sin: Math.sin(i.rotation),
|
|
48
|
-
identity: !1
|
|
49
|
-
} : s;
|
|
31
|
+
function f(t, n) {
|
|
32
|
+
return n === null ? e : a(t.boundsOf(n));
|
|
50
33
|
}
|
|
51
|
-
function
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
function u(e, t, n) {
|
|
55
|
-
if (e.identity) return {
|
|
56
|
-
x: t,
|
|
57
|
-
y: n
|
|
58
|
-
};
|
|
59
|
-
let r = t - e.cx, i = n - e.cy;
|
|
60
|
-
return {
|
|
61
|
-
x: e.cx + e.cos * r - e.sin * i,
|
|
62
|
-
y: e.cy + e.sin * r + e.cos * i
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
function d(e, t, n) {
|
|
66
|
-
if (e.identity) return {
|
|
67
|
-
x: t,
|
|
68
|
-
y: n
|
|
69
|
-
};
|
|
70
|
-
let r = t - e.cx, i = n - e.cy;
|
|
71
|
-
return {
|
|
72
|
-
x: e.cx + e.cos * r + e.sin * i,
|
|
73
|
-
y: e.cy - e.sin * r + e.cos * i
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
function f(e, n, i) {
|
|
77
|
-
let a = h(e, n, i), o = e.turned ? r(l(n), i.scale) : 0, s = e.hitRadiusPx, c = [-s, s], u = [-s, s], d = e.cornerOf;
|
|
34
|
+
function p(e, n, r) {
|
|
35
|
+
let a = g(e, n, r), o = e.turned ? c(t(n), r.scale) : 0, s = e.hitRadiusPx, l = [-s, s], u = [-s, s], d = e.cornerOf;
|
|
78
36
|
if (d) {
|
|
79
|
-
let e =
|
|
80
|
-
d.width < e.x && (
|
|
37
|
+
let e = i(m * s, r.scale, n), [t, a, o, c] = n.toWorld, f = d.outward.y * Math.sign(r.scale.x * r.scale.y * (t * c - a * o));
|
|
38
|
+
d.width < e.x && (l[d.outward.x > 0 ? 0 : 1] = 0), d.height < e.y && (u[f > 0 ? 0 : 1] = 0);
|
|
81
39
|
}
|
|
82
40
|
return {
|
|
83
41
|
x: a.x,
|
|
84
42
|
y: a.y,
|
|
85
43
|
angle: o,
|
|
86
44
|
half: s,
|
|
87
|
-
u:
|
|
45
|
+
u: l,
|
|
88
46
|
v: u
|
|
89
47
|
};
|
|
90
48
|
}
|
|
91
|
-
var
|
|
92
|
-
function
|
|
93
|
-
let i =
|
|
49
|
+
var m = 4;
|
|
50
|
+
function h(e, t, n, r) {
|
|
51
|
+
let i = p(e, t, n), [a, o] = r(i.x, i.y), s = Math.cos(i.angle), c = Math.sin(i.angle);
|
|
94
52
|
return [
|
|
95
53
|
[i.u[0], i.v[0]],
|
|
96
54
|
[i.u[1], i.v[0]],
|
|
@@ -101,45 +59,41 @@ function m(e, t, n, r) {
|
|
|
101
59
|
y: o + c * e + s * t
|
|
102
60
|
}));
|
|
103
61
|
}
|
|
104
|
-
function
|
|
105
|
-
let
|
|
106
|
-
|
|
107
|
-
let a = e.standoff.normal, o = t.identity ? a : {
|
|
108
|
-
x: t.cos * a.x - t.sin * a.y,
|
|
109
|
-
y: t.sin * a.x + t.cos * a.y
|
|
110
|
-
};
|
|
111
|
-
return i(r, o, e.standoff.px, n.scale);
|
|
62
|
+
function g(e, t, i) {
|
|
63
|
+
let a = n(t, e.x, e.y);
|
|
64
|
+
return e.standoff ? l(a, r(t, e.standoff.normal), e.standoff.px, i.scale) : a;
|
|
112
65
|
}
|
|
113
|
-
function
|
|
114
|
-
let
|
|
115
|
-
if (
|
|
116
|
-
rx:
|
|
117
|
-
ry:
|
|
66
|
+
function _(t, n, r = e) {
|
|
67
|
+
let a = t.minBandPx ?? 0;
|
|
68
|
+
if (a === 0) return {
|
|
69
|
+
rx: t.rx,
|
|
70
|
+
ry: t.ry
|
|
118
71
|
};
|
|
119
|
-
let
|
|
72
|
+
let o = i(a, n.scale, r);
|
|
120
73
|
return {
|
|
121
|
-
rx: Math.max(
|
|
122
|
-
ry: Math.max(
|
|
74
|
+
rx: Math.max(t.rx, t.innerWidth / 2 + o.x),
|
|
75
|
+
ry: Math.max(t.ry, t.innerHeight / 2 + o.y)
|
|
123
76
|
};
|
|
124
77
|
}
|
|
125
|
-
function
|
|
126
|
-
let o = d(i, t, r);
|
|
78
|
+
function v(e, t, n, r, i) {
|
|
127
79
|
if (e.shape.kind === "point") {
|
|
128
|
-
let
|
|
129
|
-
return u >=
|
|
80
|
+
let a = p(e.shape, r, i), o = s(t - a.x, n - a.y, i.scale), c = Math.cos(a.angle), l = Math.sin(a.angle), u = c * o.x + l * o.y, d = -l * o.x + c * o.y;
|
|
81
|
+
return u >= a.u[0] && u <= a.u[1] && d >= a.v[0] && d <= a.v[1];
|
|
130
82
|
}
|
|
83
|
+
let a = o(r, t, n);
|
|
84
|
+
if (!a) return !1;
|
|
131
85
|
if (e.shape.kind === "annulus") {
|
|
132
86
|
let t = e.shape;
|
|
133
|
-
if (
|
|
134
|
-
let { rx: n, ry:
|
|
135
|
-
if (n <= 0 ||
|
|
136
|
-
let s = (
|
|
87
|
+
if (a.x >= t.innerX && a.x <= t.innerX + t.innerWidth && a.y >= t.innerY && a.y <= t.innerY + t.innerHeight) return !1;
|
|
88
|
+
let { rx: n, ry: o } = _(t, i, r);
|
|
89
|
+
if (n <= 0 || o <= 0) return !1;
|
|
90
|
+
let s = (a.x - t.cx) / n, c = (a.y - t.cy) / o;
|
|
137
91
|
return s * s + c * c <= 1;
|
|
138
92
|
}
|
|
139
|
-
let
|
|
140
|
-
return
|
|
93
|
+
let c = e.shape;
|
|
94
|
+
return a.x >= c.x && a.x <= c.x + c.width && a.y >= c.y && a.y <= c.y + c.height;
|
|
141
95
|
}
|
|
142
96
|
//#endregion
|
|
143
|
-
export {
|
|
97
|
+
export { t as angleOf, _ as annulusSemiAxes, u as hitAffordanceRegions, n as localToWorld, g as pointRegionAnchor, p as pointRegionFrame, h as pointRegionScreenQuad, f as transformOf };
|
|
144
98
|
|
|
145
99
|
//# sourceMappingURL=hitAffordanceRegions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hitAffordanceRegions.js","names":["hitAffordanceRegions","i","affordances","a","isVisible","regions","state","best","j","region","xf","transformOf","hitRegion","wx","wy","view","d2","regionDistance2","s","w","pointRegionAnchor","localToWorld","dx","dy","IDENTITY_XF","targetId","b","r","poseRotationOf","angleOf","lx","ly","worldToLocal","pointRegionFrame","shape","angle","screenAngleOf","half","u","v","body","floor","pxExtent","SMALL_BODY_RADII","vOut","pointRegionScreenQuad","f","cx","cy","toScreen","c","sn","n","wn","standoff","annulusSemiAxes","bandPx","band","rotation","local","d","scaleDelta","rx","ry","ex","ey"],"sources":["../../src/affordances/hitAffordanceRegions.ts"],"sourcesContent":["/**\n * The one affordance hit-test walk.\n *\n * The kit used to hit-test selection chrome two ways: this region walk\n * (reached through `composeAffordanceLayer`'s `RenderLayer.hitTest`) and a\n * hand-written classifier in `canvas/affordanceAt.ts` that re-derived corner\n * positions, the rotate ring, and anchor points from `ChromeState` itself.\n * Both read the same state and answered the same question, so the geometry\n * lived twice and could disagree — and only the hand-written side ran for the\n * kit's own chrome, which is why `AffordanceRegion.cursor` was declared, set,\n * and never consumed.\n *\n * Now there is one walk. `composeAffordanceLayer.hitTest` delegates here, and\n * so does `buildAffordanceAt`, so an affordance's `regions()` is the single\n * source of truth for where its chrome is and what a press on it means.\n */\n\nimport type { View } from 'core/viewport/view';\nimport { pxExtent, scaleDelta, screenAngleOf, standoff } from 'core/viewport/pxExtent';\nimport type { ChromeState, Bounds } from 'core/selection/chromeState';\nimport { poseRotationOf } from 'core/geometry/poseRotation';\nimport type { Affordance, AffordanceBinding, AffordanceRegion } from './types';\n\n/** What the walk found: the region, plus the ids needed to describe it. */\nexport interface AffordanceRegionHit {\n /** `Affordance.id` — also the chrome-caps visibility id. */\n affordanceId: string;\n /** `AffordanceRegion.id`. */\n regionId: string;\n /** The region itself, so callers can read `hitKind` / `cursor`. */\n region: AffordanceRegion;\n /** Result of the region's `bind()`, called exactly once. */\n binding: AffordanceBinding;\n}\n\n/**\n * Walk affordances for a world-space hit, topmost first.\n *\n * **Across affordances**: order mirrors paint. Affordances are drawn first →\n * last (bottom → top), so the walk runs last → first and stops at the first\n * one that claims the point. Layering wins outright — a nearer region on a\n * lower affordance does not beat a farther one on top of it.\n *\n * **Within an affordance**: the *nearest* hit region wins, ties going to the\n * later-declared one. Both hit-testers this replaced took the first region\n * they found instead, in opposite orders, which is only invisible while\n * regions don't overlap. They do: the four corner handles of a selection\n * smaller than the hit radius all contain the same click, and \"first in the\n * table\" silently answered top-left (or bottom-right) no matter which handle\n * the pointer was actually on.\n *\n * `isVisible` (when supplied) gates by the same chrome id used at paint time,\n * so chrome that isn't drawn can't be hit either.\n */\nexport function hitAffordanceRegions(\n affordances: readonly Affordance[],\n wx: number,\n wy: number,\n state: ChromeState,\n view: View,\n isVisible?: (id: string) => boolean,\n): AffordanceRegionHit | null {\n for (let i = affordances.length - 1; i >= 0; i--) {\n const a = affordances[i];\n if (isVisible && !isVisible(a.id)) continue;\n const regions = a.regions(state);\n let best: { region: AffordanceRegion; d2: number } | null = null;\n for (let j = 0; j < regions.length; j++) {\n const region = regions[j];\n const xf = transformOf(state, region.targetId);\n if (!hitRegion(region, wx, wy, xf, view)) continue;\n const d2 = regionDistance2(region, wx, wy, xf, view);\n // `<=` so a later-declared region wins an exact tie, preserving the\n // \"later is on top\" reading of declaration order.\n if (best === null || d2 <= best.d2) best = { region, d2 };\n }\n if (best) {\n return {\n affordanceId: a.id,\n regionId: best.region.id,\n region: best.region,\n binding: best.region.bind(),\n };\n }\n }\n return null;\n}\n\n/** Squared world distance from the point to a region's representative center,\n * used only to rank regions that all already contain the point. */\nfunction regionDistance2(\n region: AffordanceRegion,\n wx: number,\n wy: number,\n xf: TargetTransform,\n view: View,\n): number {\n const s = region.shape;\n const w = s.kind === 'point'\n ? pointRegionAnchor(s, xf, view)\n : s.kind === 'annulus'\n ? localToWorld(xf, s.cx, s.cy)\n : localToWorld(xf, s.x + s.width / 2, s.y + s.height / 2);\n const dx = w.x - wx;\n const dy = w.y - wy;\n return dx * dx + dy * dy;\n}\n\n// ─── Transform helpers ──────────────────────────────────────────────────────\n\n/** Local↔world transform for an affordance target. Translation is the AABB\n * origin; rotation is around the AABB center. `identity` short-circuits the\n * math when the target isn't rotated. */\nexport interface TargetTransform {\n /** Rotation pivot (AABB center) in world coords. */\n cx: number;\n cy: number;\n /** cos(rotation) — 1 when identity. */\n cos: number;\n /** sin(rotation) — 0 when identity. */\n sin: number;\n identity: boolean;\n}\n\nconst IDENTITY_XF: TargetTransform = { cx: 0, cy: 0, cos: 1, sin: 0, identity: true };\n\nexport function transformOf(state: ChromeState, targetId: string | null): TargetTransform {\n if (targetId === null) return IDENTITY_XF;\n const b: Bounds | null = state.boundsOf(targetId);\n if (!b) return IDENTITY_XF;\n // Pivot + angle come from the kit's one rotation convention.\n const r = poseRotationOf(b);\n if (!r) return IDENTITY_XF;\n return {\n cx: r.cx,\n cy: r.cy,\n cos: Math.cos(r.rotation),\n sin: Math.sin(r.rotation),\n identity: false,\n };\n}\n\n/** A target transform's rotation in radians, for cursors baked at an angle. */\nexport function angleOf(xf: TargetTransform): number {\n return xf.identity ? 0 : Math.atan2(xf.sin, xf.cos);\n}\n\n/** local point → world point. */\nexport function localToWorld(xf: TargetTransform, lx: number, ly: number): { x: number; y: number } {\n if (xf.identity) return { x: lx, y: ly };\n const dx = lx - xf.cx;\n const dy = ly - xf.cy;\n return {\n x: xf.cx + xf.cos * dx - xf.sin * dy,\n y: xf.cy + xf.sin * dx + xf.cos * dy,\n };\n}\n\n/** world point → local point. */\nfunction worldToLocal(xf: TargetTransform, wx: number, wy: number): { x: number; y: number } {\n if (xf.identity) return { x: wx, y: wy };\n const dx = wx - xf.cx;\n const dy = wy - xf.cy;\n // Inverse rotation: cos stays, sin negates.\n return {\n x: xf.cx + xf.cos * dx + xf.sin * dy,\n y: xf.cy - xf.sin * dx + xf.cos * dy,\n };\n}\n\n// ─── Shape resolution ───────────────────────────────────────────────────────\n\ntype PointShape = Extract<AffordanceRegion['shape'], { kind: 'point' }>;\n\n/** Where a point region's hit square sits: its center in world coords, its\n * turn on screen, its screen half-extent, and the span of the square that\n * takes a press along each of its own axes (`[-half, half]` unless\n * `cornerOf` cuts it). Hit-test, paint, the debug hitbox and the slops\n * overlay all read it from here. */\nexport function pointRegionFrame(\n shape: PointShape,\n xf: TargetTransform,\n view: View,\n): { x: number; y: number; angle: number; half: number; u: [number, number]; v: [number, number] } {\n const a = pointRegionAnchor(shape, xf, view);\n const angle = shape.turned ? screenAngleOf(angleOf(xf), view.scale) : 0;\n const half = shape.hitRadiusPx;\n const u: [number, number] = [-half, half];\n const v: [number, number] = [-half, half];\n const body = shape.cornerOf;\n if (body) {\n // The body in world units that spans four hit radii on screen, per axis.\n const floor = pxExtent(SMALL_BODY_RADII * half, view.scale, angleOf(xf));\n // `v` runs a quarter turn on from `u` on screen, which is the target's +y\n // only while the view keeps its handedness.\n const vOut = body.outward.y * Math.sign(view.scale.x * view.scale.y);\n if (body.width < floor.x) u[body.outward.x > 0 ? 0 : 1] = 0;\n if (body.height < floor.y) v[vOut > 0 ? 0 : 1] = 0;\n }\n return { x: a.x, y: a.y, angle, half, u, v };\n}\n\n/** A body under this many hit radii across gives up the inward half of each\n * corner's hit square, so there is somewhere on it that is not a handle. */\nconst SMALL_BODY_RADII = 4;\n\n/** A point region's hit square as four screen-space corners, relative to its\n * world center carried to the screen by `toScreen`. */\nexport function pointRegionScreenQuad(\n shape: PointShape,\n xf: TargetTransform,\n view: View,\n toScreen: (x: number, y: number) => [number, number],\n): { x: number; y: number }[] {\n const f = pointRegionFrame(shape, xf, view);\n const [cx, cy] = toScreen(f.x, f.y);\n const c = Math.cos(f.angle), sn = Math.sin(f.angle);\n return [[f.u[0], f.v[0]], [f.u[1], f.v[0]], [f.u[1], f.v[1]], [f.u[0], f.v[1]]].map(([u, v]) => ({\n x: cx + c * u - sn * v,\n y: cy + sn * u + c * v,\n }));\n}\n\n/** A point region's anchor in world coords, its `standoff` applied. */\nexport function pointRegionAnchor(\n shape: PointShape,\n xf: TargetTransform,\n view: View,\n): { x: number; y: number } {\n const a = localToWorld(xf, shape.x, shape.y);\n if (!shape.standoff) return a;\n const n = shape.standoff.normal;\n const wn = xf.identity\n ? n\n : { x: xf.cos * n.x - xf.sin * n.y, y: xf.sin * n.x + xf.cos * n.y };\n return standoff(a, wn, shape.standoff.px, view.scale);\n}\n\n/**\n * An annulus region's effective outer semi-axes, with `minBandPx` applied.\n *\n * The affordance declares the natural ellipse (typically the smallest one\n * containing the inner rect) plus a screen-space floor on band thickness;\n * this is where the floor becomes world units, because this is where the view\n * is known. Paint calls it too, so the visible ring and the hoverable ring\n * are the same ring.\n */\nexport function annulusSemiAxes(\n shape: Extract<AffordanceRegion['shape'], { kind: 'annulus' }>,\n view: View,\n /** The target's rotation, which decides what a screen pixel is along each\n * of its axes. */\n rotation = 0,\n): { rx: number; ry: number } {\n const bandPx = shape.minBandPx ?? 0;\n if (bandPx === 0) return { rx: shape.rx, ry: shape.ry };\n const band = pxExtent(bandPx, view.scale, rotation);\n return {\n rx: Math.max(shape.rx, shape.innerWidth / 2 + band.x),\n ry: Math.max(shape.ry, shape.innerHeight / 2 + band.y),\n };\n}\n\n// ─── Per-shape hit-test ─────────────────────────────────────────────────────\n\nfunction hitRegion(\n region: AffordanceRegion,\n wx: number,\n wy: number,\n xf: TargetTransform,\n view: View,\n): boolean {\n const local = worldToLocal(xf, wx, wy);\n if (region.shape.kind === 'point') {\n // Square hit, not circular: the handle a `point` region paints is a\n // square, and the hit zone should match what the user sees. (The old\n // hand-written classifier used a circle here, which made the corners of\n // an 8px handle unclickable.)\n //\n // Compared in screen space, where that square is axis-aligned. Testing it\n // in the target's local frame instead would tilt it under a rotated\n // target and stretch it under non-uniform zoom.\n const f = pointRegionFrame(region.shape, xf, view);\n const d = scaleDelta(wx - f.x, wy - f.y, view.scale);\n const c = Math.cos(f.angle), sn = Math.sin(f.angle);\n const u = c * d.x + sn * d.y, v = -sn * d.x + c * d.y;\n return u >= f.u[0] && u <= f.u[1] && v >= f.v[0] && v <= f.v[1];\n }\n if (region.shape.kind === 'annulus') {\n const s = region.shape;\n // Outside the inner-rect cutout?\n const insideInner =\n local.x >= s.innerX && local.x <= s.innerX + s.innerWidth &&\n local.y >= s.innerY && local.y <= s.innerY + s.innerHeight;\n if (insideInner) return false;\n // Inside the outer ellipse? `((x-cx)/rx)² + ((y-cy)/ry)² ≤ 1`.\n const { rx, ry } = annulusSemiAxes(s, view, angleOf(xf));\n if (rx <= 0 || ry <= 0) return false;\n const ex = (local.x - s.cx) / rx;\n const ey = (local.y - s.cy) / ry;\n return ex * ex + ey * ey <= 1;\n }\n // rect: axis-aligned in local frame.\n const r = region.shape;\n return local.x >= r.x && local.x <= r.x + r.width\n && local.y >= r.y && local.y <= r.y + r.height;\n}\n"],"mappings":";;;AAsDA,SAAgBA,EACd,GACA,GACA,GACA,GACA,GACA,GAC4B;CAC5B,KAAK,IAAIC,IAAIC,EAAY,SAAS,GAAGD,KAAK,GAAG,KAAK;EAChD,IAAME,IAAID,EAAYD;EACtB,IAAIG,KAAa,CAACA,EAAUD,EAAE,EAAE,GAAG;EACnC,IAAME,IAAUF,EAAE,QAAQG,CAAK,GAC3BC,IAAwD;EAC5D,KAAK,IAAIC,IAAI,GAAGA,IAAIH,EAAQ,QAAQ,KAAK;GACvC,IAAMI,IAASJ,EAAQG,IACjBE,IAAKC,EAAYL,GAAOG,EAAO,QAAQ;GAC7C,IAAI,CAACG,EAAUH,GAAQI,GAAIC,GAAIJ,GAAIK,CAAI,GAAG;GAC1C,IAAMC,IAAKC,EAAgBR,GAAQI,GAAIC,GAAIJ,GAAIK,CAAI;GAGnD,CAAIR,MAAS,QAAQS,KAAMT,EAAK,QAAI,IAAO;IAAE;IAAQ;GAAG;EAC1D;EACA,IAAIA,GACF,OAAO;GACL,cAAcJ,EAAE;GAChB,UAAUI,EAAK,OAAO;GACtB,QAAQA,EAAK;GACb,SAASA,EAAK,OAAO,KAAK;EAC5B;CAEJ;CACA,OAAO;AACT;AAIA,SAASU,EACP,GACA,GACA,GACA,GACA,GACQ;CACR,IAAMC,IAAIT,EAAO,OACXU,IAAID,EAAE,SAAS,UACjBE,EAAkBF,GAAGR,GAAIK,CAAI,IAC7BG,EAAE,SAAS,YACTG,EAAaX,GAAIQ,EAAE,IAAIA,EAAE,EAAE,IAC3BG,EAAaX,GAAIQ,EAAE,IAAIA,EAAE,QAAQ,GAAGA,EAAE,IAAIA,EAAE,SAAS,CAAC,GACtDI,IAAKH,EAAE,IAAIN,GACXU,IAAKJ,EAAE,IAAIL;CACjB,OAAOQ,IAAKA,IAAKC,IAAKA;AACxB;AAkBA,IAAMC,IAA+B;CAAE,IAAI;CAAG,IAAI;CAAG,KAAK;CAAG,KAAK;CAAG,UAAU;AAAK;AAEpF,SAAgBb,EAAY,GAAoB,GAA0C;CACxF,IAAIc,MAAa,MAAM,OAAOD;CAC9B,IAAME,IAAmBpB,EAAM,SAASmB,CAAQ;CAChD,IAAI,CAACC,GAAG,OAAOF;CAEf,IAAMG,IAAIC,EAAeF,CAAC;CAE1B,OADKC,IACE;EACL,IAAIA,EAAE;EACN,IAAIA,EAAE;EACN,KAAK,KAAK,IAAIA,EAAE,QAAQ;EACxB,KAAK,KAAK,IAAIA,EAAE,QAAQ;EACxB,UAAU;CACZ,IAPeH;AAQjB;AAGA,SAAgBK,EAAQ,GAA6B;CACnD,OAAOnB,EAAG,WAAW,IAAI,KAAK,MAAMA,EAAG,KAAKA,EAAG,GAAG;AACpD;AAGA,SAAgBW,EAAa,GAAqB,GAAY,GAAsC;CAClG,IAAIX,EAAG,UAAU,OAAO;EAAE,GAAGoB;EAAI,GAAGC;CAAG;CACvC,IAAMT,IAAKQ,IAAKpB,EAAG,IACba,IAAKQ,IAAKrB,EAAG;CACnB,OAAO;EACL,GAAGA,EAAG,KAAKA,EAAG,MAAMY,IAAKZ,EAAG,MAAMa;EAClC,GAAGb,EAAG,KAAKA,EAAG,MAAMY,IAAKZ,EAAG,MAAMa;CACpC;AACF;AAGA,SAASS,EAAa,GAAqB,GAAY,GAAsC;CAC3F,IAAItB,EAAG,UAAU,OAAO;EAAE,GAAGG;EAAI,GAAGC;CAAG;CACvC,IAAMQ,IAAKT,IAAKH,EAAG,IACba,IAAKT,IAAKJ,EAAG;CAEnB,OAAO;EACL,GAAGA,EAAG,KAAKA,EAAG,MAAMY,IAAKZ,EAAG,MAAMa;EAClC,GAAGb,EAAG,KAAKA,EAAG,MAAMY,IAAKZ,EAAG,MAAMa;CACpC;AACF;AAWA,SAAgBU,EACd,GACA,GACA,GACiG;CACjG,IAAM,IAAIb,EAAkBc,GAAOxB,GAAIK,CAAI,GACrCoB,IAAQD,EAAM,SAASE,EAAcP,EAAQnB,CAAE,GAAGK,EAAK,KAAK,IAAI,GAChEsB,IAAOH,EAAM,aACbI,IAAsB,CAAC,CAACD,GAAMA,CAAI,GAClCE,IAAsB,CAAC,CAACF,GAAMA,CAAI,GAClCG,IAAON,EAAM;CACnB,IAAIM,GAAM;EAER,IAAMC,IAAQC,EAASC,IAAmBN,GAAMtB,EAAK,OAAOc,EAAQnB,CAAE,CAAC,GAGjEkC,IAAOJ,EAAK,QAAQ,IAAI,KAAK,KAAKzB,EAAK,MAAM,IAAIA,EAAK,MAAM,CAAC;EAEnE,AADIyB,EAAK,QAAQC,EAAM,MAAG,EAAED,EAAK,QAAQ,IAAI,IAAI,IAAI,KAAK,IACtDA,EAAK,SAASC,EAAM,MAAG,EAAEG,IAAO,IAAI,IAAI,KAAK;CACnD;CACA,OAAO;EAAE,GAAG,EAAE;EAAG,GAAG,EAAE;EAAG;EAAO;EAAM;EAAG;CAAE;AAC7C;AAIA,IAAMD,IAAmB;AAIzB,SAAgBE,EACd,GACA,GACA,GACA,GAC4B;CAC5B,IAAMC,IAAIb,EAAiBC,GAAOxB,GAAIK,CAAI,GACpC,CAACgC,GAAIC,KAAMC,EAASH,EAAE,GAAGA,EAAE,CAAC,GAC5BI,IAAI,KAAK,IAAIJ,EAAE,KAAK,GAAGK,IAAK,KAAK,IAAIL,EAAE,KAAK;CAClD,OAAO;EAAC,CAACA,EAAE,EAAE,IAAIA,EAAE,EAAE,EAAE;EAAG,CAACA,EAAE,EAAE,IAAIA,EAAE,EAAE,EAAE;EAAG,CAACA,EAAE,EAAE,IAAIA,EAAE,EAAE,EAAE;EAAG,CAACA,EAAE,EAAE,IAAIA,EAAE,EAAE,EAAE;CAAC,CAAC,CAAC,KAAK,CAACR,GAAGC,QAAQ;EAC/F,GAAGQ,IAAKG,IAAIZ,IAAIa,IAAKZ;EACrB,GAAGS,IAAKG,IAAKb,IAAIY,IAAIX;CACvB,EAAE;AACJ;AAGA,SAAgBnB,EACd,GACA,GACA,GAC0B;CAC1B,IAAMjB,IAAIkB,EAAaX,GAAIwB,EAAM,GAAGA,EAAM,CAAC;CAC3C,IAAI,CAACA,EAAM,UAAU,OAAO/B;CAC5B,IAAMiD,IAAIlB,EAAM,SAAS,QACnBmB,IAAK3C,EAAG,WACV0C,IACA;EAAE,GAAG1C,EAAG,MAAM0C,EAAE,IAAI1C,EAAG,MAAM0C,EAAE;EAAG,GAAG1C,EAAG,MAAM0C,EAAE,IAAI1C,EAAG,MAAM0C,EAAE;CAAE;CACrE,OAAOE,EAASnD,GAAGkD,GAAInB,EAAM,SAAS,IAAInB,EAAK,KAAK;AACtD;AAWA,SAAgBwC,EACd,GACA,GAGA,IAAW,GACiB;CAC5B,IAAMC,IAAStB,EAAM,aAAa;CAClC,IAAIsB,MAAW,GAAG,OAAO;EAAE,IAAItB,EAAM;EAAI,IAAIA,EAAM;CAAG;CACtD,IAAMuB,IAAOf,EAASc,GAAQzC,EAAK,OAAO2C,CAAQ;CAClD,OAAO;EACL,IAAI,KAAK,IAAIxB,EAAM,IAAIA,EAAM,aAAa,IAAIuB,EAAK,CAAC;EACpD,IAAI,KAAK,IAAIvB,EAAM,IAAIA,EAAM,cAAc,IAAIuB,EAAK,CAAC;CACvD;AACF;AAIA,SAAS7C,EACP,GACA,GACA,GACA,GACA,GACS;CACT,IAAM+C,IAAQ3B,EAAatB,GAAIG,GAAIC,CAAE;CACrC,IAAIL,EAAO,MAAM,SAAS,SAAS;EASjC,IAAMqC,IAAIb,EAAiBxB,EAAO,OAAOC,GAAIK,CAAI,GAC3C6C,IAAIC,EAAWhD,IAAKiC,EAAE,GAAGhC,IAAKgC,EAAE,GAAG/B,EAAK,KAAK,GAC7C,IAAI,KAAK,IAAI+B,EAAE,KAAK,GAAGK,IAAK,KAAK,IAAIL,EAAE,KAAK,GAC5C,IAAI,IAAIc,EAAE,IAAIT,IAAKS,EAAE,GAAGrB,IAAI,CAACY,IAAKS,EAAE,IAAI,IAAIA,EAAE;EACpD,OAAO,KAAKd,EAAE,EAAE,MAAM,KAAKA,EAAE,EAAE,MAAMP,KAAKO,EAAE,EAAE,MAAMP,KAAKO,EAAE,EAAE;CAC/D;CACA,IAAIrC,EAAO,MAAM,SAAS,WAAW;EACnC,IAAMS,IAAIT,EAAO;EAKjB,IAFEkD,EAAM,KAAKzC,EAAE,UAAUyC,EAAM,KAAKzC,EAAE,SAASA,EAAE,cAC/CyC,EAAM,KAAKzC,EAAE,UAAUyC,EAAM,KAAKzC,EAAE,SAASA,EAAE,aAChC,OAAO;EAExB,IAAM,EAAE,OAAI,UAAOqC,EAAgBrC,GAAGH,GAAMc,EAAQnB,CAAE,CAAC;EACvD,IAAIoD,KAAM,KAAKC,KAAM,GAAG,OAAO;EAC/B,IAAMC,KAAML,EAAM,IAAIzC,EAAE,MAAM4C,GACxBG,KAAMN,EAAM,IAAIzC,EAAE,MAAM6C;EAC9B,OAAOC,IAAKA,IAAKC,IAAKA,KAAM;CAC9B;CAEA,IAAMtC,IAAIlB,EAAO;CACjB,OAAOkD,EAAM,KAAKhC,EAAE,KAAKgC,EAAM,KAAKhC,EAAE,IAAIA,EAAE,SACrCgC,EAAM,KAAKhC,EAAE,KAAKgC,EAAM,KAAKhC,EAAE,IAAIA,EAAE;AAC9C"}
|
|
1
|
+
{"version":3,"file":"hitAffordanceRegions.js","names":["hitAffordanceRegions","i","affordances","a","isVisible","regions","state","best","j","region","xf","transformOf","hitRegion","wx","wy","view","d2","regionDistance2","s","w","pointRegionAnchor","localToWorld","dx","dy","targetId","IDENTITY_TARGET","targetTransformOf","pointRegionFrame","shape","angle","screenAngleOf","angleOf","half","u","v","body","floor","pxExtentIn","SMALL_BODY_RADII","b","c","d","vOut","pointRegionScreenQuad","f","cx","cy","toScreen","sn","standoff","normalToWorld","annulusSemiAxes","bandPx","band","scaleDelta","local","worldToLocal","rx","ry","ex","ey","r"],"sources":["../../src/affordances/hitAffordanceRegions.ts"],"sourcesContent":["/**\n * The one affordance hit-test walk: an affordance's `regions()` is the single\n * source of truth for where its chrome is and what a press on it means.\n */\n\nimport type { View } from 'core/viewport/view';\nimport { scaleDelta, screenAngleOf, standoff } from '@weasel-js/geom';\nimport type { ChromeState } from 'core/selection/chromeState';\nimport {\n angleOf, IDENTITY_TARGET, localToWorld, normalToWorld, pxExtentIn, targetTransformOf, worldToLocal,\n type TargetTransform,\n} from 'core/geometry/targetFrame';\nimport type { Affordance, AffordanceBinding, AffordanceRegion } from './types';\n\n/** What the walk found: the region, plus the ids needed to describe it. */\nexport interface AffordanceRegionHit {\n /** `Affordance.id` — also the chrome-caps visibility id. */\n affordanceId: string;\n /** `AffordanceRegion.id`. */\n regionId: string;\n /** The region itself, so callers can read `hitKind` / `cursor`. */\n region: AffordanceRegion;\n /** Result of the region's `bind()`, called exactly once. */\n binding: AffordanceBinding;\n}\n\n/**\n * Walk affordances for a world-space hit, topmost first.\n *\n * **Across affordances**: order mirrors paint. Affordances are drawn first →\n * last (bottom → top), so the walk runs last → first and stops at the first\n * one that claims the point. Layering wins outright — a nearer region on a\n * lower affordance does not beat a farther one on top of it.\n *\n * **Within an affordance**: the *nearest* hit region wins, ties going to the\n * later-declared one. Regions overlap: the four corner handles of a selection\n * smaller than the hit radius all contain the same click.\n *\n * `isVisible` (when supplied) gates by the same chrome id used at paint time,\n * so chrome that isn't drawn can't be hit either.\n */\nexport function hitAffordanceRegions(\n affordances: readonly Affordance[],\n wx: number,\n wy: number,\n state: ChromeState,\n view: View,\n isVisible?: (id: string) => boolean,\n): AffordanceRegionHit | null {\n for (let i = affordances.length - 1; i >= 0; i--) {\n const a = affordances[i];\n if (isVisible && !isVisible(a.id)) continue;\n const regions = a.regions(state);\n let best: { region: AffordanceRegion; d2: number } | null = null;\n for (let j = 0; j < regions.length; j++) {\n const region = regions[j];\n const xf = transformOf(state, region.targetId);\n if (!hitRegion(region, wx, wy, xf, view)) continue;\n const d2 = regionDistance2(region, wx, wy, xf, view);\n // `<=` so a later-declared region wins an exact tie, preserving the\n // \"later is on top\" reading of declaration order.\n if (best === null || d2 <= best.d2) best = { region, d2 };\n }\n if (best) {\n return {\n affordanceId: a.id,\n regionId: best.region.id,\n region: best.region,\n binding: best.region.bind(),\n };\n }\n }\n return null;\n}\n\n/** Squared world distance from the point to a region's representative center,\n * used only to rank regions that all already contain the point. */\nfunction regionDistance2(\n region: AffordanceRegion,\n wx: number,\n wy: number,\n xf: TargetTransform,\n view: View,\n): number {\n const s = region.shape;\n const w = s.kind === 'point'\n ? pointRegionAnchor(s, xf, view)\n : s.kind === 'annulus'\n ? localToWorld(xf, s.cx, s.cy)\n : localToWorld(xf, s.x + s.width / 2, s.y + s.height / 2);\n const dx = w.x - wx;\n const dy = w.y - wy;\n return dx * dx + dy * dy;\n}\n\n// ─── Transform helpers ──────────────────────────────────────────────────────\n\nexport { angleOf, localToWorld, type TargetTransform };\n\n/** The frame `targetId`'s bounds are drawn in; identity for no target. */\nexport function transformOf(state: ChromeState, targetId: string | null): TargetTransform {\n if (targetId === null) return IDENTITY_TARGET;\n return targetTransformOf(state.boundsOf(targetId));\n}\n\n// ─── Shape resolution ───────────────────────────────────────────────────────\n\ntype PointShape = Extract<AffordanceRegion['shape'], { kind: 'point' }>;\n\n/** Where a point region's hit square sits: its center in world coords, its\n * turn on screen, its screen half-extent, and the span of the square that\n * takes a press along each of its own axes (`[-half, half]` unless\n * `cornerOf` cuts it). */\nexport function pointRegionFrame(\n shape: PointShape,\n xf: TargetTransform,\n view: View,\n): { x: number; y: number; angle: number; half: number; u: [number, number]; v: [number, number] } {\n const a = pointRegionAnchor(shape, xf, view);\n const angle = shape.turned ? screenAngleOf(angleOf(xf), view.scale) : 0;\n const half = shape.hitRadiusPx;\n const u: [number, number] = [-half, half];\n const v: [number, number] = [-half, half];\n const body = shape.cornerOf;\n if (body) {\n // The body in world units that spans four hit radii on screen, per axis.\n const floor = pxExtentIn(SMALL_BODY_RADII * half, view.scale, xf);\n // `v` runs a quarter turn on from `u` on screen, which is the target's +y\n // only while the view and the target's frame keep their handedness.\n const [a, b, c, d] = xf.toWorld;\n const vOut = body.outward.y * Math.sign(view.scale.x * view.scale.y * (a * d - b * c));\n if (body.width < floor.x) u[body.outward.x > 0 ? 0 : 1] = 0;\n if (body.height < floor.y) v[vOut > 0 ? 0 : 1] = 0;\n }\n return { x: a.x, y: a.y, angle, half, u, v };\n}\n\n/** A body under this many hit radii across gives up the inward half of each\n * corner's hit square, so there is somewhere on it that is not a handle. */\nconst SMALL_BODY_RADII = 4;\n\n/** A point region's hit square as four screen-space corners, relative to its\n * world center carried to the screen by `toScreen`. */\nexport function pointRegionScreenQuad(\n shape: PointShape,\n xf: TargetTransform,\n view: View,\n toScreen: (x: number, y: number) => [number, number],\n): { x: number; y: number }[] {\n const f = pointRegionFrame(shape, xf, view);\n const [cx, cy] = toScreen(f.x, f.y);\n const c = Math.cos(f.angle), sn = Math.sin(f.angle);\n return [[f.u[0], f.v[0]], [f.u[1], f.v[0]], [f.u[1], f.v[1]], [f.u[0], f.v[1]]].map(([u, v]) => ({\n x: cx + c * u - sn * v,\n y: cy + sn * u + c * v,\n }));\n}\n\n/** A point region's anchor in world coords, its `standoff` applied. */\nexport function pointRegionAnchor(\n shape: PointShape,\n xf: TargetTransform,\n view: View,\n): { x: number; y: number } {\n const a = localToWorld(xf, shape.x, shape.y);\n if (!shape.standoff) return a;\n return standoff(a, normalToWorld(xf, shape.standoff.normal), shape.standoff.px, view.scale);\n}\n\n/**\n * An annulus region's effective outer semi-axes, in world units, with the\n * screen-space `minBandPx` floor on band thickness applied. Paint calls it\n * too, so the visible ring and the hoverable ring are the same ring.\n */\nexport function annulusSemiAxes(\n shape: Extract<AffordanceRegion['shape'], { kind: 'annulus' }>,\n view: View,\n /** The target's frame, which decides what a screen pixel is along each of\n * its axes. */\n xf: TargetTransform = IDENTITY_TARGET,\n): { rx: number; ry: number } {\n const bandPx = shape.minBandPx ?? 0;\n if (bandPx === 0) return { rx: shape.rx, ry: shape.ry };\n const band = pxExtentIn(bandPx, view.scale, xf);\n return {\n rx: Math.max(shape.rx, shape.innerWidth / 2 + band.x),\n ry: Math.max(shape.ry, shape.innerHeight / 2 + band.y),\n };\n}\n\n// ─── Per-shape hit-test ─────────────────────────────────────────────────────\n\nfunction hitRegion(\n region: AffordanceRegion,\n wx: number,\n wy: number,\n xf: TargetTransform,\n view: View,\n): boolean {\n if (region.shape.kind === 'point') {\n // Square hit, not circular: the handle a `point` region paints is a\n // square, and a circle leaves its corners unclickable.\n //\n // Compared in screen space: testing it in the target's local frame would\n // stretch it under non-uniform zoom.\n const f = pointRegionFrame(region.shape, xf, view);\n const d = scaleDelta(wx - f.x, wy - f.y, view.scale);\n const c = Math.cos(f.angle), sn = Math.sin(f.angle);\n const u = c * d.x + sn * d.y, v = -sn * d.x + c * d.y;\n return u >= f.u[0] && u <= f.u[1] && v >= f.v[0] && v <= f.v[1];\n }\n const local = worldToLocal(xf, wx, wy);\n if (!local) return false;\n if (region.shape.kind === 'annulus') {\n const s = region.shape;\n // Outside the inner-rect cutout?\n const insideInner =\n local.x >= s.innerX && local.x <= s.innerX + s.innerWidth &&\n local.y >= s.innerY && local.y <= s.innerY + s.innerHeight;\n if (insideInner) return false;\n // Inside the outer ellipse? `((x-cx)/rx)² + ((y-cy)/ry)² ≤ 1`.\n const { rx, ry } = annulusSemiAxes(s, view, xf);\n if (rx <= 0 || ry <= 0) return false;\n const ex = (local.x - s.cx) / rx;\n const ey = (local.y - s.cy) / ry;\n return ex * ex + ey * ey <= 1;\n }\n // rect: axis-aligned in local frame.\n const r = region.shape;\n return local.x >= r.x && local.x <= r.x + r.width\n && local.y >= r.y && local.y <= r.y + r.height;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pathAnchors.js","names":["PATH_ANCHOR_CHROME_ID","createPathAnchorAffordances","opts","editablePaths","anchorState","getAnchorState","out","id","state","pose","point","hitRadius","scratch","editingId","a","enumerateAnchors","path"],"sources":["../../src/affordances/pathAnchors.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"pathAnchors.js","names":["PATH_ANCHOR_CHROME_ID","createPathAnchorAffordances","opts","editablePaths","anchorState","getAnchorState","out","id","state","pose","point","hitRadius","scratch","editingId","a","enumerateAnchors","path"],"sources":["../../src/affordances/pathAnchors.ts"],"sourcesContent":["/** Path anchor + control-handle affordances. */\n\nimport type { CursorSpec } from '@weasel-js/cursor';\nimport type { Affordance, AffordanceBinding, AffordanceRegion, CommonAffordanceScratch } from './types';\nimport type { ChromeState } from 'core/selection/chromeState';\nimport type { PolygonPath } from '@weasel-js/geom';\nimport { enumerateAnchors } from 'interactions/actions/edit-anchors/geometry';\n\n/**\n * Live anchor-editing state. The thunk that returns it is called on every\n * pointer event, so it must be cheap (O(1) field reads).\n */\nexport interface AnchorState {\n /** Id of the path currently in anchor-edit mode, or `null`. Control handles\n * are only hittable on the path that is being edited. */\n editingId: string | null;\n /** Current editable path for a node id. Non-polygon values are ignored. */\n getPose(id: string): unknown;\n}\n\n/** Options for the path-anchor affordances. */\nexport interface PathAnchorAffordanceOptions {\n /** Hit radius (screen-px) for anchor and control points. Default 8. */\n hitRadius?: number;\n /** Cursor while hovering an anchor or control. Defaults to `'pointer'`. */\n cursor?: CursorSpec;\n}\n\n/** What an anchor hit hands to the action that follows. */\nexport interface AnchorScratch extends CommonAffordanceScratch {\n /** Node id of the path the anchor belongs to. */\n targetId: string;\n /** Sequential anchor index in path walk order. */\n anchorIndex: number;\n /** Which of the anchor's three grabbable points this is. */\n part: 'anchor' | 'controlIn' | 'controlOut';\n}\n\n/** Chrome-caps id gating both returned affordances. */\nexport const PATH_ANCHOR_CHROME_ID = 'path-edit.anchors';\n\n/**\n * Anchor + control affordances for the selected paths, bottom → top.\n *\n * Returns **two** affordances rather than one so that a control handle beats\n * an anchor regardless of which is nearer, the way controls draw on top.\n * Within each of the two, nearest wins. They deliberately share one id:\n * chrome-caps gates anchor editing as a single piece of chrome.\n *\n * Order matters — spread this into an affordance list in the returned order.\n */\nexport function createPathAnchorAffordances(\n getAnchorState: () => AnchorState | null,\n opts: PathAnchorAffordanceOptions = {},\n): Affordance[] {\n const { hitRadius = 8, cursor = 'pointer' } = opts;\n\n /** Selected polygon paths, paired with their node id. */\n const editablePaths = (state: ChromeState): Array<{ id: string; path: PolygonPath }> => {\n const anchorState = getAnchorState();\n if (!anchorState) return [];\n const out: Array<{ id: string; path: PolygonPath }> = [];\n for (const id of state.selection) {\n const pose = anchorState.getPose(id);\n if (!pose || (pose as { kind?: string }).kind !== 'polygon') continue;\n out.push({ id, path: pose as PolygonPath });\n }\n return out;\n };\n\n const point = (\n id: string,\n targetId: string,\n x: number,\n y: number,\n scratch: AnchorScratch,\n hitKind: string,\n ): AffordanceRegion => ({\n id,\n // Anchor coordinates are already world space, pose rotation baked in.\n // Anchoring to `null` keeps the framework from applying it twice.\n targetId: null,\n shape: { kind: 'point', x, y, hitRadiusPx: hitRadius },\n hitKind,\n cursor,\n bind: (): AffordanceBinding => ({ initialScratch: { ...scratch, targetId } }),\n });\n\n const anchors: Affordance = {\n id: PATH_ANCHOR_CHROME_ID,\n regions(state) {\n const editingId = getAnchorState()?.editingId ?? null;\n const out: AffordanceRegion[] = [];\n for (const { id, path } of editablePaths(state)) {\n // `editAnchorsAction` edits whatever path the dep says is in edit\n // mode, ignoring which one was hit — so once a path IS being edited,\n // only its own anchors may claim the press.\n if (editingId !== null && id !== editingId) continue;\n for (const a of enumerateAnchors(path)) {\n out.push(point(\n `${id}:anchor:${a.anchorIndex}`,\n id, a.x, a.y,\n { targetId: id, anchorIndex: a.anchorIndex, part: 'anchor' },\n `anchor:${a.anchorIndex}`,\n ));\n }\n }\n return out;\n },\n };\n\n const controls: Affordance = {\n id: PATH_ANCHOR_CHROME_ID,\n regions(state) {\n const anchorState = getAnchorState();\n const editingId = anchorState?.editingId ?? null;\n if (editingId === null) return [];\n const out: AffordanceRegion[] = [];\n for (const { id, path } of editablePaths(state)) {\n // Controls are grabbable only on the path actually in edit mode.\n if (id !== editingId) continue;\n for (const a of enumerateAnchors(path)) {\n if (a.controlIn) {\n out.push(point(\n `${id}:controlIn:${a.anchorIndex}`,\n id, a.controlIn.x, a.controlIn.y,\n { targetId: id, anchorIndex: a.anchorIndex, part: 'controlIn' },\n `controlIn:${a.anchorIndex}`,\n ));\n }\n if (a.controlOut) {\n out.push(point(\n `${id}:controlOut:${a.anchorIndex}`,\n id, a.controlOut.x, a.controlOut.y,\n { targetId: id, anchorIndex: a.anchorIndex, part: 'controlOut' },\n `controlOut:${a.anchorIndex}`,\n ));\n }\n }\n }\n return out;\n },\n };\n\n return [anchors, controls];\n}\n"],"mappings":";;AAuCA,IAAaA,IAAwB;AAYrC,SAAgBC,EACd,GACA,IAAoC,CAAC,GACvB;CACd,IAAM,EAAE,eAAY,GAAG,YAAS,cAAcC,GAGxCC,KAAiB,MAAiE;EACtF,IAAMC,IAAcC,EAAe;EACnC,IAAI,CAACD,GAAa,OAAO,CAAC;EAC1B,IAAME,IAAgD,CAAC;EACvD,KAAK,IAAMC,KAAMC,EAAM,WAAW;GAChC,IAAMC,IAAOL,EAAY,QAAQG,CAAE;GACnC,AAAKE,KAASA,EAA2B,SAAS,aAClDH,EAAI,KAAK;IAAE;IAAI,MAAMG;GAAoB,CAAC;EAC5C;EACA,OAAOH;CACT,GAEMI,KACJ,GACA,GACA,GACA,GACA,GACA,OACsB;EACtB;EAGA,UAAU;EACV,OAAO;GAAE,MAAM;GAAS;GAAG;GAAG,aAAaC;EAAU;EACrD;EACA;EACA,aAAgC,EAAE,gBAAgB;GAAE,GAAGC;GAAS;EAAS,EAAE;CAC7E;CA0DA,OAAO,CAAC;EAvDN,IAAIZ;EACJ,QAAQ,GAAO;GACb,IAAMa,IAAYR,EAAe,CAAC,EAAE,aAAa,MAC3CC,IAA0B,CAAC;GACjC,KAAK,IAAM,EAAE,OAAI,aAAUH,EAAcK,CAAK,GAI5C,IAAIK,MAAc,QAAQN,MAAOM,GACjC,KAAK,IAAMC,KAAKC,EAAiBC,CAAI,GACnC,EAAI,KAAKN,EACP,GAAGH,EAAG,UAAUO,EAAE,eAClBP,GAAIO,EAAE,GAAGA,EAAE,GACX;IAAE,UAAUP;IAAI,aAAaO,EAAE;IAAa,MAAM;GAAS,GAC3D,UAAUA,EAAE,aACd,CAAC;GAGL,OAAOR;EACT;CAoCM,GAAS;EAhCf,IAAIN;EACJ,QAAQ,GAAO;GAEb,IAAMa,IADcR,EACF,CAAA,EAAa,aAAa;GAC5C,IAAIQ,MAAc,MAAM,OAAO,CAAC;GAChC,IAAMP,IAA0B,CAAC;GACjC,KAAK,IAAM,EAAE,OAAI,aAAUH,EAAcK,CAAK,GAE5C,IAAID,MAAOM,GACX,KAAK,IAAMC,KAAKC,EAAiBC,CAAI,GASnC,AARIF,EAAE,aACJR,EAAI,KAAKI,EACP,GAAGH,EAAG,aAAaO,EAAE,eACrBP,GAAIO,EAAE,UAAU,GAAGA,EAAE,UAAU,GAC/B;IAAE,UAAUP;IAAI,aAAaO,EAAE;IAAa,MAAM;GAAY,GAC9D,aAAaA,EAAE,aACjB,CAAC,GAECA,EAAE,cACJR,EAAI,KAAKI,EACP,GAAGH,EAAG,cAAcO,EAAE,eACtBP,GAAIO,EAAE,WAAW,GAAGA,EAAE,WAAW,GACjC;IAAE,UAAUP;IAAI,aAAaO,EAAE;IAAa,MAAM;GAAa,GAC/D,cAAcA,EAAE,aAClB,CAAC;GAIP,OAAOR;EACT;CAGe,CAAQ;AAC3B"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { angleOf as e
|
|
1
|
+
import { angleOf as e } from "../core/geometry/targetFrame.js";
|
|
2
|
+
import { transformOf as t } from "./hitAffordanceRegions.js";
|
|
2
3
|
import { MULTI_RESIZE_TARGET_ID as n } from "../core/selection/selectionTarget.js";
|
|
3
4
|
//#region src/affordances/rotationHandle.ts
|
|
4
5
|
var r = (e) => "fill" in e || "stroke" in e || "insetPx" in e, i = {
|
|
5
|
-
fill: {
|
|
6
|
-
|
|
6
|
+
fill: { paint: {
|
|
7
|
+
kind: "solid",
|
|
7
8
|
color: "rgba(26, 19, 13, 0.12)"
|
|
8
|
-
},
|
|
9
|
+
} },
|
|
9
10
|
insetPx: 10
|
|
10
11
|
};
|
|
11
12
|
function a(n = {}) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rotationHandle.js","names":["isAnnulusForm","paint","DEFAULT_PAINT","createRotationAffordance","opts","annulusPaint","target","pickTarget","state","b","halfW","halfH","regionCursor","cursor","angleOf","transformOf","bind","region","bandPx","handle","id","MULTI_RESIZE_TARGET_ID"],"sources":["../../src/affordances/rotationHandle.ts"],"sourcesContent":["import type { Affordance, AffordanceBinding, AffordanceRegion, CommonAffordanceScratch } from './types';\nimport type { ChromeState, Bounds } from 'core/selection/chromeState';\nimport type { CommandFill, CommandStroke } from '@weasel-js/paint';\nimport { MULTI_RESIZE_TARGET_ID } from 'core/selection/selectionTarget';\nimport { angleOf, transformOf } from './hitAffordanceRegions';\nimport type { CursorSpec } from '@weasel-js/cursor';\n\n/** Options for `createRotationAffordance` — how thick the rotate band is\n * outside the selection, and how (or whether) it is painted. */\nexport interface RotationAffordanceOptions {\n /** Minimum screen-space thickness of the rotate-zone band outside the\n * selection AABB. The outer ellipse semi-axes are clamped to\n * `max(w/√2, w/2 + bandPx/scale)` so the zone stays hoverable at any\n * zoom and any selection size. Default 24. */\n bandPx?: number;\n /** Paint for the ring. `null` / `false` = invisible. Default is a\n * semi-transparent fill of the band, contracted by `insetPx` screen\n * pixels on the outer edge so the visible band sits inside the\n * hoverable zone with a clear margin. Pass a `Stroke` (or\n * `{ fill, stroke, insetPx }`) to override. */\n paint?:\n | CommandStroke\n | { fill?: CommandFill; stroke?: CommandStroke; insetPx?: number }\n | null\n | false;\n /** Cursor while hovering the ring. Defaults to the `rotate` glyph turned\n * with the target, falling back to `'grab'` if the browser rejects the\n * image. */\n cursor?: CursorSpec;\n /** A grab region for a rotate badge painted off the top edge — the one\n * the selection overlay's `rotationHandle` draws. `distancePx` is how far\n * off the edge it sits and `hitRadiusPx` the half-extent of its square,\n * both in screen pixels. Placed by the same `standoff` the painted badge\n * is, so the two cannot drift apart. Omitted, only the ring rotates. */\n handle?: { distancePx: number; hitRadiusPx: number };\n}\n\n/** What a rotation-handle hit hands to the rotate action: what is being\n * rotated, and the world-space pivot it turns around. */\nexport interface RotationScratch extends CommonAffordanceScratch {\n /** Id of the rotation target — single selection id, or\n * `MULTI_RESIZE_TARGET_ID` for multi-selection. */\n targetId: string;\n /** Rotation pivot in world coords — the AABB (or union AABB) center. */\n fixedPoint: { x: number; y: number };\n}\n\ntype AnnulusPaintForm = { fill?: CommandFill; stroke?: CommandStroke; insetPx?: number };\n\nconst isAnnulusForm = (paint: CommandStroke | AnnulusPaintForm): paint is AnnulusPaintForm =>\n 'fill' in paint || 'stroke' in paint || 'insetPx' in paint;\n\nconst DEFAULT_PAINT: AnnulusPaintForm = {\n fill: { fill: 'solid', color: 'rgba(26, 19, 13, 0.12)' },\n insetPx: 10,\n};\n\n/**\n * @experimental\n * Rotation affordance for the active selection. Replaces the legacy\n * \"small dot above the AABB\" handle with an elliptical ring that wraps\n * the selection: the smallest ellipse containing the AABB, minus the AABB\n * itself. Hovering the ring sets the cursor (default the `rotate` glyph)\n * and drag-from-ring triggers `rotateAction` via the same\n * binding path the old point-handle used (id stays\n * `'selection.rotation-handle'`).\n *\n * The ring is target-local — under target rotation the ellipse rotates\n * with the AABB so the hoverable band always wraps the rendered shape.\n *\n * Visibility: gated by chrome-caps' `'selection.rotation-handle'` rule.\n * The ring paints as a faint band by default; `paint: null` leaves the\n * cursor change as the only cue.\n */\nexport function createRotationAffordance(\n opts: RotationAffordanceOptions = {},\n): Affordance {\n const { bandPx = 24, paint = DEFAULT_PAINT, cursor, handle } = opts;\n\n // Normalize `paint` into the AnnulusPaint shape understood by\n // `composeAffordanceLayer`. Three input forms are accepted: a bare\n // `Stroke` (legacy outline form), the `{ fill, stroke, insetPx }`\n // object form, or `null`/`false` for invisible. The object form is what\n // carries these three keys; `Stroke` carries none of them, and cannot be\n // told apart by its own `paint` since that is optional.\n const annulusPaint:\n | { kind: 'annulus'; fill?: CommandFill; stroke?: CommandStroke; insetPx?: number }\n | null = (() => {\n if (!paint) return null;\n if (!isAnnulusForm(paint)) {\n return { kind: 'annulus' as const, stroke: paint };\n }\n return {\n kind: 'annulus' as const,\n ...(paint.fill ? { fill: paint.fill } : {}),\n ...(paint.stroke ? { stroke: paint.stroke } : {}),\n ...(paint.insetPx !== undefined ? { insetPx: paint.insetPx } : {}),\n };\n })();\n\n return {\n id: 'selection.rotation-handle',\n regions(state: ChromeState): readonly AffordanceRegion[] {\n const target = pickTarget(state);\n if (!target) return [];\n const b = target.bounds;\n\n // The natural ring: the smallest ellipse containing the AABB. For a\n // small or thin selection that band is too tight to hover, so\n // `minBandPx` asks the framework to widen it to at least `bandPx`\n // screen pixels outside the rect. The floor is declared in screen units\n // rather than applied here because `ChromeState` carries no view scale\n // — the framework applies it at paint and hit time, where the view is\n // known, so the ring holds its apparent thickness at any zoom.\n const halfW = b.width / 2;\n const halfH = b.height / 2;\n\n // Turned with the target, so the arc follows the selection it rotates.\n // Resolved per region rather than defaulted in the option list because\n // the angle is only known once a target is picked.\n const regionCursor: CursorSpec = cursor ?? {\n glyph: 'rotate',\n angle: angleOf(transformOf(state, target.id)),\n fallback: 'grab',\n };\n const bind = (): AffordanceBinding => ({\n initialScratch: {\n targetId: target.id,\n // Pivot. `rotateAction` recomputes its own union pivot for\n // multi-selection, but the single-target case reads this.\n fixedPoint: { x: b.x + halfW, y: b.y + halfH },\n } satisfies RotationScratch,\n });\n\n const region: AffordanceRegion = {\n id: 'selection.rotation-handle',\n targetId: target.id,\n shape: {\n kind: 'annulus',\n cx: b.x + halfW,\n cy: b.y + halfH,\n rx: halfW * Math.SQRT2,\n ry: halfH * Math.SQRT2,\n innerX: b.x,\n innerY: b.y,\n innerWidth: b.width,\n innerHeight: b.height,\n minBandPx: bandPx,\n },\n ...(annulusPaint ? { paint: annulusPaint } : {}),\n hitKind: 'rotate-handle',\n cursor: regionCursor,\n bind,\n };\n if (!handle) return [region];\n const badge: AffordanceRegion = {\n id: 'rotation-badge',\n targetId: target.id,\n shape: {\n kind: 'point',\n x: b.x + halfW,\n y: b.y,\n hitRadiusPx: handle.hitRadiusPx,\n standoff: { px: handle.distancePx, normal: { x: 0, y: -1 } },\n },\n hitKind: 'rotate-handle',\n cursor: regionCursor,\n bind,\n };\n return [region, badge];\n },\n };\n}\n\nfunction pickTarget(state: ChromeState): { id: string; bounds: Bounds } | null {\n if (state.selection.length === 1) {\n const id = state.selection[0];\n // Skip when the selected node's pose-descriptor declares it can't\n // carry a rotation. Without this the rotation affordance would expose\n // a rotate cursor over (e.g.) polygon-Path selections whose\n // `rotateAction` write is silently dropped at paint time.\n if (state.canRotate && !state.canRotate(id)) return null;\n const b = state.boundsOf(id);\n return b ? { id, bounds: b } : null;\n }\n // Multi-selection: anchor the ring to the union AABB. `rotateAction`\n // ignores the synthetic id and pivots at its own union center\n // (`useUnionPivot: ids.length > 1` branch in `defaults/rotate.ts`).\n // Require every selected id to support rotation — a partial multi-rotate\n // (some ids rotate, others silently no-op) would feel broken.\n if (state.multiActive && state.unionBounds) {\n if (state.canRotate) {\n for (const id of state.selection) {\n if (!state.canRotate(id)) return null;\n }\n }\n return { id: MULTI_RESIZE_TARGET_ID, bounds: state.unionBounds };\n }\n return null;\n}\n"],"mappings":";;;AAiDA,IAAMA,KAAiB,MACrB,UAAUC,KAAS,YAAYA,KAAS,aAAaA,GAEjDC,IAAkC;CACtC,MAAM;EAAE,MAAM;EAAS,OAAO;CAAyB;CACvD,SAAS;AACX;AAmBA,SAAgBC,EACd,IAAkC,CAAC,GACvB;CACZ,IAAM,EAAE,YAAS,IAAI,WAAQD,GAAe,WAAQ,cAAWE,GAQzDC,IAGGJ,IACAD,EAAcC,CAAK,IAGjB;EACL,MAAM;EACN,GAAIA,EAAM,OAAO,EAAE,MAAMA,EAAM,KAAK,IAAI,CAAC;EACzC,GAAIA,EAAM,SAAS,EAAE,QAAQA,EAAM,OAAO,IAAI,CAAC;EAC/C,GAAIA,EAAM,YAAY,KAAA,IAAyC,CAAC,IAA9B,EAAE,SAASA,EAAM,QAAQ;CAC7D,IAPS;EAAE,MAAM;EAAoB,QAAQA;CAAM,IAFhC;CAYvB,OAAO;EACL,IAAI;EACJ,QAAQ,GAAiD;GACvD,IAAMK,IAASC,EAAWC,CAAK;GAC/B,IAAI,CAACF,GAAQ,OAAO,CAAC;GACrB,IAAMG,IAAIH,EAAO,QASXI,IAAQD,EAAE,QAAQ,GAClBE,IAAQF,EAAE,SAAS,GAKnBG,IAA2BC,KAAU;IACzC,OAAO;IACP,OAAOC,EAAQC,EAAYP,GAAOF,EAAO,EAAE,CAAC;IAC5C,UAAU;GACZ,GACMU,WAAiC,EACrC,gBAAgB;IACd,UAAUV,EAAO;IAGjB,YAAY;KAAE,GAAGG,EAAE,IAAIC;KAAO,GAAGD,EAAE,IAAIE;IAAM;GAC/C,EACF,IAEMM,IAA2B;IAC/B,IAAI;IACJ,UAAUX,EAAO;IACjB,OAAO;KACL,MAAM;KACN,IAAIG,EAAE,IAAIC;KACV,IAAID,EAAE,IAAIE;KACV,IAAID,IAAQ,KAAK;KACjB,IAAIC,IAAQ,KAAK;KACjB,QAAQF,EAAE;KACV,QAAQA,EAAE;KACV,YAAYA,EAAE;KACd,aAAaA,EAAE;KACf,WAAWS;IACb;IACA,GAAIb,IAAe,EAAE,OAAOA,EAAa,IAAI,CAAC;IAC9C,SAAS;IACT,QAAQO;IACR;GACF;GAgBA,OAfKO,IAeE,CAACF,GAAQ;IAbd,IAAI;IACJ,UAAUX,EAAO;IACjB,OAAO;KACL,MAAM;KACN,GAAGG,EAAE,IAAIC;KACT,GAAGD,EAAE;KACL,aAAaU,EAAO;KACpB,UAAU;MAAE,IAAIA,EAAO;MAAY,QAAQ;OAAE,GAAG;OAAG,GAAG;MAAG;KAAE;IAC7D;IACA,SAAS;IACT,QAAQP;IACR;GAEc,CAAK,IAfD,CAACK,CAAM;EAgB7B;CACF;AACF;AAEA,SAASV,EAAW,GAA2D;CAC7E,IAAIC,EAAM,UAAU,WAAW,GAAG;EAChC,IAAMY,IAAKZ,EAAM,UAAU;EAK3B,IAAIA,EAAM,aAAa,CAACA,EAAM,UAAUY,CAAE,GAAG,OAAO;EACpD,IAAMX,IAAID,EAAM,SAASY,CAAE;EAC3B,OAAOX,IAAI;GAAE;GAAI,QAAQA;EAAE,IAAI;CACjC;CAMA,IAAID,EAAM,eAAeA,EAAM,aAAa;EAC1C,IAAIA,EAAM,WACH;QAAA,IAAMY,KAAMZ,EAAM,WACrB,IAAI,CAACA,EAAM,UAAUY,CAAE,GAAG,OAAO;EAAA;EAGrC,OAAO;GAAE,IAAIC;GAAwB,QAAQb,EAAM;EAAY;CACjE;CACA,OAAO;AACT"}
|
|
1
|
+
{"version":3,"file":"rotationHandle.js","names":["isAnnulusForm","paint","DEFAULT_PAINT","createRotationAffordance","opts","annulusPaint","target","pickTarget","state","b","halfW","halfH","regionCursor","cursor","angleOf","transformOf","bind","region","bandPx","handle","id","MULTI_RESIZE_TARGET_ID"],"sources":["../../src/affordances/rotationHandle.ts"],"sourcesContent":["import type { Affordance, AffordanceBinding, AffordanceRegion, CommonAffordanceScratch } from './types';\nimport type { ChromeState, Bounds } from 'core/selection/chromeState';\nimport type { CommandStroke, CommandFill } from '@weasel-js/paint';\nimport { MULTI_RESIZE_TARGET_ID } from 'core/selection/selectionTarget';\nimport { angleOf, transformOf } from './hitAffordanceRegions';\nimport type { CursorSpec } from '@weasel-js/cursor';\n\n/** Options for `createRotationAffordance` — how thick the rotate band is\n * outside the selection, and how (or whether) it is painted. */\nexport interface RotationAffordanceOptions {\n /** Minimum screen-space thickness of the rotate-zone band outside the selection AABB, so\n * the zone stays hoverable at any zoom and any selection size. Default 24. */\n bandPx?: number;\n /** Paint for the ring. `null` / `false` = invisible. Default is a semi-transparent fill of\n * the band, contracted by `insetPx` screen pixels on the outer edge. Pass a `Stroke` (or\n * `{ fill, stroke, insetPx }`) to override. */\n paint?:\n | CommandStroke\n | { fill?: CommandFill; stroke?: CommandStroke; insetPx?: number }\n | null\n | false;\n /** Cursor while hovering the ring. Defaults to the `rotate` glyph turned\n * with the target, falling back to `'grab'` if the browser rejects the\n * image. */\n cursor?: CursorSpec;\n /** A grab region for a rotate badge painted off the top edge — the one\n * the selection overlay's `rotationHandle` draws. `distancePx` is how far\n * off the edge it sits and `hitRadiusPx` the half-extent of its square,\n * both in screen pixels. Placed by the same `standoff` the painted badge\n * is, so the two cannot drift apart. Omitted, only the ring rotates. */\n handle?: { distancePx: number; hitRadiusPx: number };\n}\n\n/** What a rotation-handle hit hands to the rotate action: what is being\n * rotated, and the world-space pivot it turns around. */\nexport interface RotationScratch extends CommonAffordanceScratch {\n /** Id of the rotation target — single selection id, or\n * `MULTI_RESIZE_TARGET_ID` for multi-selection. */\n targetId: string;\n /** Rotation pivot in world coords — the AABB (or union AABB) center. */\n fixedPoint: { x: number; y: number };\n}\n\ntype AnnulusPaintForm = { fill?: CommandFill; stroke?: CommandStroke; insetPx?: number };\n\nconst isAnnulusForm = (paint: CommandStroke | AnnulusPaintForm): paint is AnnulusPaintForm =>\n 'fill' in paint || 'stroke' in paint || 'insetPx' in paint;\n\nconst DEFAULT_PAINT: AnnulusPaintForm = {\n fill: { paint: { kind: 'solid', color: 'rgba(26, 19, 13, 0.12)' } },\n insetPx: 10,\n};\n\n/**\n * @experimental\n * Rotation affordance for the active selection: an elliptical ring that wraps the selection —\n * the smallest ellipse containing the AABB, minus the AABB itself. Hovering the ring sets the\n * cursor (default the `rotate` glyph) and a drag from it triggers `rotateAction`.\n *\n * The ring is target-local — under target rotation the ellipse rotates with the AABB.\n * Visibility is gated by chrome-caps' `'selection.rotation-handle'` rule. `paint: null` leaves\n * the cursor change as the only cue.\n */\nexport function createRotationAffordance(\n opts: RotationAffordanceOptions = {},\n): Affordance {\n const { bandPx = 24, paint = DEFAULT_PAINT, cursor, handle } = opts;\n\n // A bare `Stroke` carries none of the object form's three keys, and cannot be told apart\n // by its own `paint` since that is optional.\n const annulusPaint:\n | { kind: 'annulus'; fill?: CommandFill; stroke?: CommandStroke; insetPx?: number }\n | null = (() => {\n if (!paint) return null;\n if (!isAnnulusForm(paint)) {\n return { kind: 'annulus' as const, stroke: paint };\n }\n return {\n kind: 'annulus' as const,\n ...(paint.fill ? { fill: paint.fill } : {}),\n ...(paint.stroke ? { stroke: paint.stroke } : {}),\n ...(paint.insetPx !== undefined ? { insetPx: paint.insetPx } : {}),\n };\n })();\n\n return {\n id: 'selection.rotation-handle',\n regions(state: ChromeState): readonly AffordanceRegion[] {\n const target = pickTarget(state);\n if (!target) return [];\n const b = target.bounds;\n\n // The natural ring is the smallest ellipse containing the AABB. `minBandPx` asks the\n // framework to widen it to at least `bandPx` screen pixels outside the rect; the floor is\n // declared in screen units because `ChromeState` carries no view scale.\n const halfW = b.width / 2;\n const halfH = b.height / 2;\n\n // Turned with the target, so the arc follows the selection it rotates.\n const regionCursor: CursorSpec = cursor ?? {\n glyph: 'rotate',\n angle: angleOf(transformOf(state, target.id)),\n fallback: 'grab',\n };\n const bind = (): AffordanceBinding => ({\n initialScratch: {\n targetId: target.id,\n // Pivot. `rotateAction` recomputes its own union pivot for\n // multi-selection, but the single-target case reads this.\n fixedPoint: { x: b.x + halfW, y: b.y + halfH },\n } satisfies RotationScratch,\n });\n\n const region: AffordanceRegion = {\n id: 'selection.rotation-handle',\n targetId: target.id,\n shape: {\n kind: 'annulus',\n cx: b.x + halfW,\n cy: b.y + halfH,\n rx: halfW * Math.SQRT2,\n ry: halfH * Math.SQRT2,\n innerX: b.x,\n innerY: b.y,\n innerWidth: b.width,\n innerHeight: b.height,\n minBandPx: bandPx,\n },\n ...(annulusPaint ? { paint: annulusPaint } : {}),\n hitKind: 'rotate-handle',\n cursor: regionCursor,\n bind,\n };\n if (!handle) return [region];\n const badge: AffordanceRegion = {\n id: 'rotation-badge',\n targetId: target.id,\n shape: {\n kind: 'point',\n x: b.x + halfW,\n y: b.y,\n hitRadiusPx: handle.hitRadiusPx,\n standoff: { px: handle.distancePx, normal: { x: 0, y: -1 } },\n },\n hitKind: 'rotate-handle',\n cursor: regionCursor,\n bind,\n };\n return [region, badge];\n },\n };\n}\n\nfunction pickTarget(state: ChromeState): { id: string; bounds: Bounds } | null {\n if (state.selection.length === 1) {\n const id = state.selection[0];\n // Skip when the selected node's pose-descriptor declares it can't carry a rotation;\n // otherwise the ring would offer a rotate cursor over a node whose write is dropped.\n if (state.canRotate && !state.canRotate(id)) return null;\n const b = state.boundsOf(id);\n return b ? { id, bounds: b } : null;\n }\n // Multi-selection: anchor the ring to the union AABB; `rotateAction` ignores the synthetic\n // id and pivots at its own union center. Every selected id must support rotation — a\n // partial multi-rotate would feel broken.\n if (state.multiActive && state.unionBounds) {\n if (state.canRotate) {\n for (const id of state.selection) {\n if (!state.canRotate(id)) return null;\n }\n }\n return { id: MULTI_RESIZE_TARGET_ID, bounds: state.unionBounds };\n }\n return null;\n}\n"],"mappings":";;;;AA6CA,IAAMA,KAAiB,MACrB,UAAUC,KAAS,YAAYA,KAAS,aAAaA,GAEjDC,IAAkC;CACtC,MAAM,EAAE,OAAO;EAAE,MAAM;EAAS,OAAO;CAAyB,EAAE;CAClE,SAAS;AACX;AAYA,SAAgBC,EACd,IAAkC,CAAC,GACvB;CACZ,IAAM,EAAE,YAAS,IAAI,WAAQD,GAAe,WAAQ,cAAWE,GAIzDC,IAGGJ,IACAD,EAAcC,CAAK,IAGjB;EACL,MAAM;EACN,GAAIA,EAAM,OAAO,EAAE,MAAMA,EAAM,KAAK,IAAI,CAAC;EACzC,GAAIA,EAAM,SAAS,EAAE,QAAQA,EAAM,OAAO,IAAI,CAAC;EAC/C,GAAIA,EAAM,YAAY,KAAA,IAAyC,CAAC,IAA9B,EAAE,SAASA,EAAM,QAAQ;CAC7D,IAPS;EAAE,MAAM;EAAoB,QAAQA;CAAM,IAFhC;CAYvB,OAAO;EACL,IAAI;EACJ,QAAQ,GAAiD;GACvD,IAAMK,IAASC,EAAWC,CAAK;GAC/B,IAAI,CAACF,GAAQ,OAAO,CAAC;GACrB,IAAMG,IAAIH,EAAO,QAKXI,IAAQD,EAAE,QAAQ,GAClBE,IAAQF,EAAE,SAAS,GAGnBG,IAA2BC,KAAU;IACzC,OAAO;IACP,OAAOC,EAAQC,EAAYP,GAAOF,EAAO,EAAE,CAAC;IAC5C,UAAU;GACZ,GACMU,WAAiC,EACrC,gBAAgB;IACd,UAAUV,EAAO;IAGjB,YAAY;KAAE,GAAGG,EAAE,IAAIC;KAAO,GAAGD,EAAE,IAAIE;IAAM;GAC/C,EACF,IAEMM,IAA2B;IAC/B,IAAI;IACJ,UAAUX,EAAO;IACjB,OAAO;KACL,MAAM;KACN,IAAIG,EAAE,IAAIC;KACV,IAAID,EAAE,IAAIE;KACV,IAAID,IAAQ,KAAK;KACjB,IAAIC,IAAQ,KAAK;KACjB,QAAQF,EAAE;KACV,QAAQA,EAAE;KACV,YAAYA,EAAE;KACd,aAAaA,EAAE;KACf,WAAWS;IACb;IACA,GAAIb,IAAe,EAAE,OAAOA,EAAa,IAAI,CAAC;IAC9C,SAAS;IACT,QAAQO;IACR;GACF;GAgBA,OAfKO,IAeE,CAACF,GAAQ;IAbd,IAAI;IACJ,UAAUX,EAAO;IACjB,OAAO;KACL,MAAM;KACN,GAAGG,EAAE,IAAIC;KACT,GAAGD,EAAE;KACL,aAAaU,EAAO;KACpB,UAAU;MAAE,IAAIA,EAAO;MAAY,QAAQ;OAAE,GAAG;OAAG,GAAG;MAAG;KAAE;IAC7D;IACA,SAAS;IACT,QAAQP;IACR;GAEc,CAAK,IAfD,CAACK,CAAM;EAgB7B;CACF;AACF;AAEA,SAASV,EAAW,GAA2D;CAC7E,IAAIC,EAAM,UAAU,WAAW,GAAG;EAChC,IAAMY,IAAKZ,EAAM,UAAU;EAG3B,IAAIA,EAAM,aAAa,CAACA,EAAM,UAAUY,CAAE,GAAG,OAAO;EACpD,IAAMX,IAAID,EAAM,SAASY,CAAE;EAC3B,OAAOX,IAAI;GAAE;GAAI,QAAQA;EAAE,IAAI;CACjC;CAIA,IAAID,EAAM,eAAeA,EAAM,aAAa;EAC1C,IAAIA,EAAM,WACH;QAAA,IAAMY,KAAMZ,EAAM,WACrB,IAAI,CAACA,EAAM,UAAUY,CAAE,GAAG,OAAO;EAAA;EAGrC,OAAO;GAAE,IAAIC;GAAwB,QAAQb,EAAM;EAAY;CACjE;CACA,OAAO;AACT"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/animation/behaviors/coast.ts
|
|
2
|
+
var e = 0, t = () => `momentum:${e++}`, n = (e, t) => e.x === t.x && e.y === t.y && e.width === t.width && e.height === t.height;
|
|
3
|
+
function r(e, t, n) {
|
|
4
|
+
if (!e) return {
|
|
5
|
+
nx: t,
|
|
6
|
+
ny: n,
|
|
7
|
+
hitX: !1,
|
|
8
|
+
hitY: !1
|
|
9
|
+
};
|
|
10
|
+
let r = Math.min(Math.max(t, e.x), e.x + e.width), i = Math.min(Math.max(n, e.y), e.y + e.height);
|
|
11
|
+
return {
|
|
12
|
+
nx: r,
|
|
13
|
+
ny: i,
|
|
14
|
+
hitX: r !== t,
|
|
15
|
+
hitY: i !== n
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { r as clampCorner, t as coastKey, n as sameBounds };
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=coast.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coast.js","names":["nextCoast","coastKey","sameBounds","a","b","clampCorner","bounds","x","y","nx","ny"],"sources":["../../../src/animation/behaviors/coast.ts"],"sourcesContent":["import type { GestureContext } from 'interactions/gestures/types';\nimport type { PoseDescriptor } from 'core/geometry/poseDescriptor';\nimport type { Bounds } from 'core/viewport/fitViewToBounds';\nimport type { Animator } from '@weasel-js/animator';\n\n/** One flick still traveling: the nodes it carries, and how a new drag of one stops it. */\nexport interface Coast {\n ids: readonly string[];\n stop(): void;\n}\n\n/** What a coast is started with. */\nexport interface CoastArgs<TPose> {\n animator: Animator;\n ctx: GestureContext<TPose>;\n /** Release velocity in world units a second. */\n vx: number;\n vy: number;\n friction: number;\n bounds: { x: number; y: number; width: number; height: number } | undefined;\n boundary: 'stop' | 'continue';\n d: PoseDescriptor<TPose>;\n /** The behavior's running coasts. A coast adds itself and takes itself out as it ends. */\n coasts: Set<Coast>;\n}\n\nlet nextCoast = 0;\n\n/** A cancel key no other coast holds. */\nexport const coastKey = (): string => `momentum:${nextCoast++}`;\n\n/** Whether two bounds are the same box. */\nexport const sameBounds = (a: Bounds, b: Bounds): boolean =>\n a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;\n\n/** A top-left corner held inside `bounds`, and which axes that moved. */\nexport function clampCorner(\n bounds: CoastArgs<unknown>['bounds'],\n x: number,\n y: number,\n): { nx: number; ny: number; hitX: boolean; hitY: boolean } {\n if (!bounds) return { nx: x, ny: y, hitX: false, hitY: false };\n const nx = Math.min(Math.max(x, bounds.x), bounds.x + bounds.width);\n const ny = Math.min(Math.max(y, bounds.y), bounds.y + bounds.height);\n return { nx, ny, hitX: nx !== x, hitY: ny !== y };\n}\n"],"mappings":";AA0BA,IAAIA,IAAY,GAGHC,UAAyB,YAAY,OAGrCC,KAAc,GAAW,MACpCC,EAAE,MAAMC,EAAE,KAAKD,EAAE,MAAMC,EAAE,KAAKD,EAAE,UAAUC,EAAE,SAASD,EAAE,WAAWC,EAAE;AAGtE,SAAgBC,EACd,GACA,GACA,GAC0D;CAC1D,IAAI,CAACC,GAAQ,OAAO;EAAE,IAAIC;EAAG,IAAIC;EAAG,MAAM;EAAO,MAAM;CAAM;CAC7D,IAAMC,IAAK,KAAK,IAAI,KAAK,IAAIF,GAAGD,EAAO,CAAC,GAAGA,EAAO,IAAIA,EAAO,KAAK,GAC5DI,IAAK,KAAK,IAAI,KAAK,IAAIF,GAAGF,EAAO,CAAC,GAAGA,EAAO,IAAIA,EAAO,MAAM;CACnE,OAAO;EAAE;EAAI;EAAI,MAAMG,MAAOF;EAAG,MAAMG,MAAOF;CAAE;AAClD"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { translatePoseViaDescriptor as e } from "../../core/geometry/poseDescriptor.js";
|
|
2
|
+
import { createTransformOp as t } from "../../core/ops/transform.js";
|
|
3
|
+
import { clampCorner as n, coastKey as r, sameBounds as i } from "./coast.js";
|
|
4
|
+
//#region src/animation/behaviors/coastByWrite.ts
|
|
5
|
+
function a(a) {
|
|
6
|
+
let { animator: o, ctx: s, d: c, bounds: l, coasts: u } = a, d = s.adapter, f = new Map(s.current), p = {
|
|
7
|
+
x: 0,
|
|
8
|
+
y: 0
|
|
9
|
+
}, m = (e) => {
|
|
10
|
+
if (d.previewPoses) d.previewPoses(e);
|
|
11
|
+
else for (let [t, n] of e) n !== null && d.setPose(t, n);
|
|
12
|
+
}, h = new Set(s.draggedIds), g = /* @__PURE__ */ new Map();
|
|
13
|
+
for (let e of h) d.getNode(e) && g.set(e, c.getBounds(d.getPose(e)));
|
|
14
|
+
let _ = (e) => {
|
|
15
|
+
let t = g.get(e);
|
|
16
|
+
return t !== void 0 && d.getNode(e) !== void 0 && i(c.getBounds(d.getPose(e)), t);
|
|
17
|
+
}, v = /* @__PURE__ */ new Map(), y = r(), b = {
|
|
18
|
+
ids: s.draggedIds.slice(),
|
|
19
|
+
stop: () => {
|
|
20
|
+
if (!o.isActive(y)) {
|
|
21
|
+
u.delete(b);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
x.cancel(), S();
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
u.add(b), m(new Map([...h].flatMap((e) => {
|
|
28
|
+
let t = f.get(e);
|
|
29
|
+
return t === void 0 ? [] : [[e, t]];
|
|
30
|
+
})));
|
|
31
|
+
let x = o.decay({
|
|
32
|
+
from: {
|
|
33
|
+
x: 0,
|
|
34
|
+
y: 0
|
|
35
|
+
},
|
|
36
|
+
velocity: {
|
|
37
|
+
x: a.vx,
|
|
38
|
+
y: a.vy
|
|
39
|
+
},
|
|
40
|
+
friction: a.friction,
|
|
41
|
+
cancelKey: y,
|
|
42
|
+
add: (e, t) => ({
|
|
43
|
+
x: e.x + t.x,
|
|
44
|
+
y: e.y + t.y
|
|
45
|
+
}),
|
|
46
|
+
scale: (e, t) => ({
|
|
47
|
+
x: e.x * t,
|
|
48
|
+
y: e.y * t
|
|
49
|
+
}),
|
|
50
|
+
magnitude: (e) => Math.hypot(e.x, e.y),
|
|
51
|
+
onTick: (t) => {
|
|
52
|
+
p = t;
|
|
53
|
+
let r = l !== void 0, i = /* @__PURE__ */ new Map();
|
|
54
|
+
for (let a of [...h]) {
|
|
55
|
+
if (!_(a)) {
|
|
56
|
+
h.delete(a), i.set(a, null);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
let o = f.get(a);
|
|
60
|
+
if (!o) continue;
|
|
61
|
+
let s = c.getBounds(o), { nx: u, ny: d, hitX: p, hitY: m } = n(l, s.x + t.x, s.y + t.y);
|
|
62
|
+
!p && !m && (r = !1), v.set(a, {
|
|
63
|
+
x: u,
|
|
64
|
+
y: d
|
|
65
|
+
}), i.set(a, e(o, u - s.x, d - s.y, c));
|
|
66
|
+
}
|
|
67
|
+
m(i);
|
|
68
|
+
for (let e of h) g.set(e, c.getBounds(d.getPose(e)));
|
|
69
|
+
if (h.size === 0) {
|
|
70
|
+
u.delete(b), x.cancel();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
a.boundary === "stop" && r && b.stop();
|
|
74
|
+
},
|
|
75
|
+
onDone: () => {
|
|
76
|
+
S();
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
function S() {
|
|
80
|
+
if (!u.delete(b)) return;
|
|
81
|
+
let n = [], r = /* @__PURE__ */ new Map();
|
|
82
|
+
for (let i of h) {
|
|
83
|
+
if (r.set(i, null), !_(i)) continue;
|
|
84
|
+
let a = f.get(i);
|
|
85
|
+
if (!a) continue;
|
|
86
|
+
let o = c.getBounds(a), l = v.get(i) ?? {
|
|
87
|
+
x: o.x + p.x,
|
|
88
|
+
y: o.y + p.y
|
|
89
|
+
}, u = e(a, l.x - o.x, l.y - o.y, c), d = s.origin.get(i) ?? a;
|
|
90
|
+
n.push(t({
|
|
91
|
+
id: i,
|
|
92
|
+
from: d,
|
|
93
|
+
to: u,
|
|
94
|
+
label: "flick"
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
if (n.length > 0) {
|
|
98
|
+
if (d.applyOps) d.applyOps(n, "flick");
|
|
99
|
+
else if (d.previewPoses) for (let e of n) e.apply(d);
|
|
100
|
+
}
|
|
101
|
+
d.previewPoses?.(r);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//#endregion
|
|
105
|
+
export { a as coastByWrite };
|
|
106
|
+
|
|
107
|
+
//# sourceMappingURL=coastByWrite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coastByWrite.js","names":["coastByWrite","adapter","ctx","startPoses","lastValue","show","poses","id","pose","riding","lastSeen","d","stillOurs","seen","sameBounds","finalPositions","cancelKey","coastKey","coast","animator","decayHandle","commitFlick","coasts","start","p","q","v","k","delta","allHit","bounds","frame","o","clampCorner","hitX","hitY","nx","ny","translatePoseViaDescriptor","ops","shown","fp","finalPose","from","createTransformOp","op"],"sources":["../../../src/animation/behaviors/coastByWrite.ts"],"sourcesContent":["import { createTransformOp } from 'core/ops/transform';\nimport type { Op } from 'core/ops/types';\nimport type { Bounds } from 'core/viewport/fitViewToBounds';\nimport { translatePoseViaDescriptor } from 'core/geometry/poseDescriptor';\nimport { clampCorner, coastKey, sameBounds, type Coast, type CoastArgs } from './coast';\n\ninterface Delta { x: number; y: number }\n\n/**\n * A coast over an adapter with no pose targets: one decay of the flick's travel, written to\n * every node it carries each frame, through `previewPoses` where the adapter has it and\n * `setPose` where it does not. Nothing else animating a node adds to it.\n */\nexport function coastByWrite<TPose>(a: CoastArgs<TPose>): void {\n const { animator, ctx, d, bounds, coasts } = a;\n const adapter = ctx.adapter;\n const startPoses = new Map<string, TPose>(ctx.current);\n let lastValue: Delta = { x: 0, y: 0 };\n const show = (poses: Map<string, TPose | null>): void => {\n if (adapter.previewPoses) adapter.previewPoses(poses);\n else for (const [id, pose] of poses) if (pose !== null) adapter.setPose(id, pose);\n };\n // What the scene held for each node right after the coast last wrote it.\n // A node that is gone, or reads back as anything else, has another\n // writer now, an undo or a delete, and leaves the coast unrecorded.\n const riding = new Set(ctx.draggedIds);\n const lastSeen = new Map<string, Bounds>();\n for (const id of riding) {\n if (adapter.getNode(id)) lastSeen.set(id, d.getBounds(adapter.getPose(id)));\n }\n const stillOurs = (id: string): boolean => {\n const seen = lastSeen.get(id);\n return seen !== undefined && adapter.getNode(id) !== undefined\n && sameBounds(d.getBounds(adapter.getPose(id)), seen);\n };\n // Where each node was last put, which under bounds is not its start plus the decay's travel.\n const finalPositions = new Map<string, Delta>();\n const cancelKey = coastKey();\n const coast: Coast = {\n ids: ctx.draggedIds.slice(),\n stop: (): void => {\n // Canceled from outside (cancelAll, unmount), it stopped long ago and somewhere else.\n if (!animator.isActive(cancelKey)) {\n coasts.delete(coast);\n return;\n }\n decayHandle.cancel();\n commitFlick();\n },\n };\n coasts.add(coast);\n // Held from the release itself, so no frame paints the pre-drag pose\n // between the drag's preview going away and the first coast frame.\n show(new Map([...riding].flatMap((id) => {\n const start = startPoses.get(id);\n return start === undefined ? [] : [[id, start] as const];\n })));\n const decayHandle = animator.decay<Delta>({\n from: { x: 0, y: 0 },\n velocity: { x: a.vx, y: a.vy },\n friction: a.friction,\n cancelKey,\n add: (p, q) => ({ x: p.x + q.x, y: p.y + q.y }),\n scale: (v, k) => ({ x: v.x * k, y: v.y * k }),\n magnitude: (v) => Math.hypot(v.x, v.y),\n onTick: (delta) => {\n lastValue = delta;\n let allHit = bounds !== undefined;\n const frame = new Map<string, TPose | null>();\n for (const id of [...riding]) {\n if (!stillOurs(id)) {\n riding.delete(id);\n frame.set(id, null);\n continue;\n }\n const start = startPoses.get(id);\n if (!start) continue;\n const o = d.getBounds(start);\n const { nx, ny, hitX, hitY } = clampCorner(bounds, o.x + delta.x, o.y + delta.y);\n if (!hitX && !hitY) allHit = false;\n finalPositions.set(id, { x: nx, y: ny });\n frame.set(id, translatePoseViaDescriptor(start, nx - o.x, ny - o.y, d));\n }\n show(frame);\n for (const id of riding) lastSeen.set(id, d.getBounds(adapter.getPose(id)));\n if (riding.size === 0) {\n coasts.delete(coast);\n decayHandle.cancel();\n return;\n }\n // Under 'stop', once every node is at the boundary the coast ends\n // there instead of drifting along the edge as friction wears off.\n if (a.boundary === 'stop' && allHit) coast.stop();\n },\n onDone: () => {\n commitFlick();\n },\n });\n\n function commitFlick(): void {\n if (!coasts.delete(coast)) return;\n const ops: Op[] = [];\n const shown = new Map<string, TPose | null>();\n for (const id of riding) {\n shown.set(id, null);\n if (!stillOurs(id)) continue;\n const start = startPoses.get(id);\n if (!start) continue;\n const o = d.getBounds(start);\n const fp = finalPositions.get(id) ?? { x: o.x + lastValue.x, y: o.y + lastValue.y };\n const finalPose = translatePoseViaDescriptor(start, fp.x - o.x, fp.y - o.y, d);\n const from = ctx.origin.get(id) ?? start;\n ops.push(createTransformOp<TPose>({ id, from, to: finalPose, label: 'flick' }));\n }\n // The document first, so the preview never gives way to the pre-drag pose.\n if (ops.length > 0) {\n if (adapter.applyOps) adapter.applyOps(ops, 'flick');\n else if (adapter.previewPoses) for (const op of ops) op.apply(adapter);\n }\n adapter.previewPoses?.(shown);\n }\n}\n"],"mappings":"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"}
|