@weasel-js/core 1.15.0 → 1.15.2
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 +199 -0
- package/dist/WeaselProvider.js +4 -5
- package/dist/affordances/composeAffordanceLayer.js +1 -2
- package/dist/affordances/cornerResize.js +4 -5
- package/dist/affordances/hitAffordanceRegions.js +1 -2
- package/dist/affordances/pathAnchors.js +1 -2
- package/dist/affordances/rotateCursor.js +1 -2
- package/dist/affordances/rotationHandle.js +2 -3
- package/dist/animation/behaviors/coast.js +1 -2
- package/dist/animation/behaviors/coastByWrite.js +2 -3
- package/dist/animation/behaviors/coastOnTargets.js +2 -3
- package/dist/animation/behaviors/momentum.js +1 -2
- package/dist/animation/clipTargets.js +1 -2
- package/dist/animation/departures.js +2 -3
- package/dist/animation/poseHelpers.js +2 -3
- package/dist/animation/poseTarget.js +5 -6
- package/dist/animation/poseTarget.js.map +1 -1
- package/dist/animation/poseTransition.js +1 -2
- package/dist/animation/reflow.js +9 -10
- package/dist/animation/reflow.js.map +1 -1
- package/dist/animation/rewind.js +1 -2
- package/dist/animation/rig/bindRig.js +2 -3
- package/dist/animation/rig/rigNode.js +3 -4
- package/dist/animation/rig/rigNode.js.map +1 -1
- package/dist/animation/rig/rigSeat.js +1 -2
- package/dist/animation/rig/skinBinding.js +1 -2
- package/dist/animation/rig/useRig.js +2 -3
- package/dist/animation/wrappers/animateLifecycle.js +1 -2
- package/dist/animation/wrappers/animateOnSetPose.js +1 -2
- package/dist/animation/wrappers/instantPose.js +1 -2
- package/dist/animation/writtenPoseTarget.js +1 -2
- package/dist/barrel/input.js +2 -1
- package/dist/barrel/interactions.js +2 -1
- package/dist/barrel/paint.js +2 -2
- package/dist/barrel/routing.js +2 -2
- package/dist/barrel/scene.js +2 -2
- package/dist/barrel/viewport.js +3 -3
- package/dist/canvas/Canvas.js +5 -6
- package/dist/canvas/CanvasView.js +6 -7
- package/dist/canvas/CursorCoordsHud.js +2 -3
- package/dist/canvas/DrawCanvas.js +3 -4
- package/dist/canvas/GestureReason.js +1 -2
- package/dist/canvas/GestureReason.module.js +1 -2
- package/dist/canvas/LeanSceneCanvas.js +2 -3
- package/dist/canvas/ModalityHud.js +2 -3
- package/dist/canvas/NodeShape.js +3 -4
- package/dist/canvas/PickHud.js +2 -3
- package/dist/canvas/SceneCanvas/ActionsProviderIfRoot.js +1 -2
- package/dist/canvas/SceneCanvas/CanvasKitProviders.js +3 -4
- package/dist/canvas/SceneCanvas/DepRegistryProviderIfRoot.js +1 -2
- package/dist/canvas/SceneCanvas/DevHuds.js +1 -2
- package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +18 -66
- package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js.map +1 -1
- package/dist/canvas/SceneCanvas/SceneCanvasInput.js +4 -5
- package/dist/canvas/SceneCanvas/SurfaceDeclarations.js +1 -2
- package/dist/canvas/SceneCanvas/brushOverlay.js +1 -2
- package/dist/canvas/SceneCanvas/builtinToolSets.js +1 -2
- package/dist/canvas/SceneCanvas/canvasPassThrough.js +1 -2
- package/dist/canvas/SceneCanvas/contributionFrameHooks.js +1 -2
- package/dist/canvas/SceneCanvas/coordTrace.js +1 -2
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js +3 -4
- package/dist/canvas/SceneCanvas/defaultNodeRouting.js +1 -2
- package/dist/canvas/SceneCanvas/defaultTextEditor.js +4 -5
- package/dist/canvas/SceneCanvas/describePresets.js +1 -2
- package/dist/canvas/SceneCanvas/dispatcherGestureBounds.js +1 -2
- package/dist/canvas/SceneCanvas/features.js +1 -2
- package/dist/canvas/SceneCanvas/insertPreviewCommands.js +1 -2
- package/dist/canvas/SceneCanvas/mergeLayers.js +1 -2
- package/dist/canvas/SceneCanvas/namedPresets.js +5 -6
- package/dist/canvas/SceneCanvas/poseGeometry.js +1 -2
- package/dist/canvas/SceneCanvas/poseRegistrars.js +1 -2
- package/dist/canvas/SceneCanvas/presets/arrange.js +2 -3
- package/dist/canvas/SceneCanvas/presets/baseline.js +1 -2
- package/dist/canvas/SceneCanvas/presets/chrome.js +1 -2
- package/dist/canvas/SceneCanvas/presets/composites.js +1 -2
- package/dist/canvas/SceneCanvas/presets/edit.js +4 -5
- package/dist/canvas/SceneCanvas/presets/ingest.js +1 -2
- package/dist/canvas/SceneCanvas/presets/paths.js +3 -4
- package/dist/canvas/SceneCanvas/presets/select.js +1 -2
- package/dist/canvas/SceneCanvas/presets/toolDriven.js +2 -3
- package/dist/canvas/SceneCanvas/presets/tools.js +1 -2
- package/dist/canvas/SceneCanvas/presets/transform.js +2 -3
- package/dist/canvas/SceneCanvas/presets/view.js +2 -3
- package/dist/canvas/SceneCanvas/props.js +1 -2
- package/dist/canvas/SceneCanvas/scenePointQuery.js +2 -3
- package/dist/canvas/SceneCanvas/shapeGeneratorProperties.js +1 -2
- package/dist/canvas/SceneCanvas/toolRegistry.js +2 -3
- package/dist/canvas/SceneCanvas/useActionTunings.js +1 -2
- package/dist/canvas/SceneCanvas/useActionsPropResolver.js +1 -2
- package/dist/canvas/SceneCanvas/useBakedScene.js +2 -3
- package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js +7 -8
- package/dist/canvas/SceneCanvas/useBuiltinTools.js +2 -3
- package/dist/canvas/SceneCanvas/useCanvasCamera.js +2 -3
- package/dist/canvas/SceneCanvas/useCanvasDevtoolsRoot.js +1 -2
- package/dist/canvas/SceneCanvas/useCanvasDispatcher.js +1 -2
- package/dist/canvas/SceneCanvas/useCanvasSelection.js +8 -6
- package/dist/canvas/SceneCanvas/useCanvasSelection.js.map +1 -1
- package/dist/canvas/SceneCanvas/useCanvasTools.js +2 -3
- package/dist/canvas/SceneCanvas/useChromeAffordances.js +2 -3
- package/dist/canvas/SceneCanvas/useContributionRoles.js +1 -2
- package/dist/canvas/SceneCanvas/useDepartureGhostLayer.js +4 -5
- package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js +2 -3
- package/dist/canvas/SceneCanvas/useHeldModifiers.js +1 -2
- package/dist/canvas/SceneCanvas/useMagnificationCheck.js +41 -0
- package/dist/canvas/SceneCanvas/useMagnificationCheck.js.map +1 -0
- package/dist/canvas/SceneCanvas/useNodeAtPoint.js +1 -2
- package/dist/canvas/SceneCanvas/useNodeKinds.js +2 -3
- package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +10 -11
- package/dist/canvas/SceneCanvas/useSceneCanvasHandle.js +1 -2
- package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js +6 -7
- package/dist/canvas/SceneCanvas/useSceneCanvasPathEdit.js +1 -2
- package/dist/canvas/SceneCanvas/useSceneCanvasTools.js +1 -2
- package/dist/canvas/SceneCanvas/useSceneChrome.js +5 -6
- package/dist/canvas/SceneCanvas/useSceneGestureDispatcher.js +6 -7
- package/dist/canvas/SceneCanvas/useScenePicking.js +5 -6
- package/dist/canvas/SceneCanvas/useSceneRedrawSources.js +1 -2
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js +7 -8
- package/dist/canvas/SceneCanvas/useSceneSlotLayers.js +2 -3
- package/dist/canvas/SceneCanvas/useSceneStandardActions.js +26 -18
- package/dist/canvas/SceneCanvas/useSceneStandardActions.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSelectionOverlayLayer.js +2 -3
- package/dist/canvas/SceneCanvas/useSurfaceRouting.js +1 -2
- package/dist/canvas/SceneCanvas/useSurfaceViewInputs.js +1 -2
- package/dist/canvas/SceneCanvas/useToolKeybindings.js +1 -2
- package/dist/canvas/SceneCanvas/useViewportActions.js +3 -4
- package/dist/canvas/SceneCanvas/worldPointAt.js +1 -2
- package/dist/canvas/SceneCanvas.js +18 -17
- package/dist/canvas/SceneCanvas.js.map +1 -1
- package/dist/canvas/SceneViewCanvas.js +2 -3
- package/dist/canvas/SurfaceCanvas.js +1 -2
- package/dist/canvas/ViewMarker.js +1 -2
- package/dist/canvas/accentColor.js +4 -5
- package/dist/canvas/accentColor.js.map +1 -1
- package/dist/canvas/adapterDerivedPath.js +2 -3
- package/dist/canvas/adapterPickSource.js +1 -2
- package/dist/canvas/affordanceAt.js +2 -3
- package/dist/canvas/buildSceneLayer.js +4 -5
- package/dist/canvas/buildSceneTree.js +4 -5
- package/dist/canvas/canvasRenderer.js +1 -2
- package/dist/canvas/colorOverrides.js +1 -2
- package/dist/canvas/contextAttributes.js +1 -2
- package/dist/canvas/copiesAbove.js +1 -2
- package/dist/canvas/defaultDrawOne.js +1 -2
- package/dist/canvas/deps/areaSelect.js +5 -3
- package/dist/canvas/deps/areaSelect.js.map +1 -1
- package/dist/canvas/deps/booleans.js +5 -6
- package/dist/canvas/deps/changes.js +1 -2
- package/dist/canvas/deps/chromeRules.js +1 -2
- package/dist/canvas/deps/debug.js +1 -2
- package/dist/canvas/deps/dispatchSources.js +1 -2
- package/dist/canvas/deps/dispatcher.js +1 -2
- package/dist/canvas/deps/editAnchors.js +3 -4
- package/dist/canvas/deps/enteredGroup.js +6 -6
- package/dist/canvas/deps/enteredGroup.js.map +1 -1
- package/dist/canvas/deps/geometryProjection.js +1 -2
- package/dist/canvas/deps/hitTestArea.js +4 -5
- package/dist/canvas/deps/ingestion.js +1 -2
- package/dist/canvas/deps/insert.js +3 -4
- package/dist/canvas/deps/insertSite.js +3 -4
- package/dist/canvas/deps/kitSettings.js +1 -2
- package/dist/canvas/deps/lassoSelect.js +5 -3
- package/dist/canvas/deps/lassoSelect.js.map +1 -1
- package/dist/canvas/deps/layout.js +1 -2
- package/dist/canvas/deps/modeDefaultTool.js +1 -2
- package/dist/canvas/deps/nodeAtPoint.js +1 -2
- package/dist/canvas/deps/pathEditCommits.js +4 -5
- package/dist/canvas/deps/pathLeaf.js +1 -2
- package/dist/canvas/deps/pathLeafDeps.js +2 -3
- package/dist/canvas/deps/poseDescriptor.js +1 -2
- package/dist/canvas/deps/previewPaths.js +1 -2
- package/dist/canvas/deps/resizePolicy.js +1 -2
- package/dist/canvas/deps/selectionSnapshot.js +8 -4
- package/dist/canvas/deps/selectionSnapshot.js.map +1 -1
- package/dist/canvas/deps/slice.js +5 -6
- package/dist/canvas/deps/snap.js +3 -4
- package/dist/canvas/deps/surface.js +1 -2
- package/dist/canvas/deps/textEdit.js +1 -2
- package/dist/canvas/deps/transformFollowers.js +1 -2
- package/dist/canvas/deps/view.js +1 -2
- package/dist/canvas/derivedPath.js +6 -7
- package/dist/canvas/doubleClickTarget.js +1 -2
- package/dist/canvas/drawEnvelope.js +1 -2
- package/dist/canvas/drawnBounds.js +4 -5
- package/dist/canvas/getNodeAtPoint.js +1 -2
- package/dist/canvas/hostAnchor.js +1 -2
- package/dist/canvas/hud.module.js +1 -2
- package/dist/canvas/inheritedPaints.js +1 -2
- package/dist/canvas/insertPreviewExtent.js +1 -2
- package/dist/canvas/kitRequirements.js +1 -2
- package/dist/canvas/layerHover.js +1 -2
- package/dist/canvas/layerOrder.js +1 -2
- package/dist/canvas/layerSlots.js +1 -2
- package/dist/canvas/mountedCanvases.js +1 -2
- package/dist/canvas/nodeShapes/derivedPainter.js +2 -3
- package/dist/canvas/nodeShapes/imagePainter.js +1 -2
- package/dist/canvas/nodeShapes/measurePainter.js +2 -3
- package/dist/canvas/nodeShapes/memo.js +1 -2
- package/dist/canvas/nodeShapes/nodePaint.js +1 -2
- package/dist/canvas/nodeShapes/pathPainter.js +3 -4
- package/dist/canvas/nodeShapes/poseBox.js +1 -2
- package/dist/canvas/nodeShapes/rectFallbackPainter.js +1 -2
- package/dist/canvas/nodeShapes/shapePainter.js +2 -3
- package/dist/canvas/nodeShapes/strokedBounds.js +1 -2
- package/dist/canvas/nodeShapes/textPainter.js +1 -2
- package/dist/canvas/overChildren.js +1 -2
- package/dist/canvas/overlayRoleStrokes.js +1 -2
- package/dist/canvas/ownClip.js +1 -2
- package/dist/canvas/paintCull.js +1 -2
- package/dist/canvas/paintedCursorLayer.js +1 -2
- package/dist/canvas/pathOverlay.js +1 -2
- package/dist/canvas/pickIndex/nodeBroadBox.js +3 -4
- package/dist/canvas/pickIndex/scenePickIndex.js +3 -4
- package/dist/canvas/pickReach.js +1 -2
- package/dist/canvas/pickWalk.js +2 -3
- package/dist/canvas/planeClips.js +1 -2
- package/dist/canvas/poseRotation.js +1 -2
- package/dist/canvas/publishPreviews.js +1 -2
- package/dist/canvas/rasterReadback.js +1 -2
- package/dist/canvas/rasterToPng.js +1 -2
- package/dist/canvas/renderDebugSnapshot.js +1 -2
- package/dist/canvas/renderNeeds.js +1 -2
- package/dist/canvas/renderSceneToPixels.js +5 -6
- package/dist/canvas/sceneAdapter.js +37 -27
- package/dist/canvas/sceneAdapter.js.map +1 -1
- package/dist/canvas/sceneClipboard.js +19 -7
- package/dist/canvas/sceneClipboard.js.map +1 -1
- package/dist/canvas/sceneLayerPaint.js +1 -2
- package/dist/canvas/scenePickReads.js +1 -2
- package/dist/canvas/scenePickSource.js +5 -6
- package/dist/canvas/sceneSlotWiring.js +2 -3
- package/dist/canvas/sceneViewRender.js +5 -6
- package/dist/canvas/shownNodes.js +1 -2
- package/dist/canvas/slopsDebugLayer.js +9 -4
- package/dist/canvas/slopsDebugLayer.js.map +1 -1
- package/dist/canvas/surfaceContribution.js +1 -2
- package/dist/canvas/useCanvasElements.js +1 -2
- package/dist/canvas/useCanvasHandle.js +1 -2
- package/dist/canvas/useCanvasPaint.js +2 -3
- package/dist/canvas/useCanvasRenderer.js +1 -2
- package/dist/canvas/useCanvasSurface.js +1 -2
- package/dist/canvas/useCanvasView.js +2 -3
- package/dist/canvas/useClientToWorld.js +1 -2
- package/dist/canvas/useExtraLayers.js +1 -2
- package/dist/canvas/useFrameLoop.js +1 -2
- package/dist/canvas/useHitObserver.js +1 -2
- package/dist/canvas/useHostAnchor.js +1 -2
- package/dist/canvas/useInFlightBounds.js +6 -6
- package/dist/canvas/useInFlightBounds.js.map +1 -1
- package/dist/canvas/useLateContentRedraw.js +1 -2
- package/dist/canvas/useLayerStack.js +2 -3
- package/dist/canvas/usePaintedCursor.js +1 -2
- package/dist/canvas/useRedrawOn.js +1 -2
- package/dist/canvas/useSceneAdapter.js +1 -2
- package/dist/canvas/useSceneLayerList.js +1 -2
- package/dist/canvas/useSurfaceInput.js +1 -2
- package/dist/canvas/useSurfaceSize.js +1 -2
- package/dist/canvas/useToolCursor.js +1 -2
- package/dist/canvas/useViewAim.js +2 -3
- package/dist/canvas/useViewHelpers.js +5 -4
- package/dist/canvas/useViewHelpers.js.map +1 -1
- package/dist/canvas/useViewLayerGate.js +1 -2
- package/dist/canvas/useViewNesting.js +1 -2
- package/dist/canvas/useViewRegistrySurface.js +7 -5
- package/dist/canvas/useViewRegistrySurface.js.map +1 -1
- package/dist/canvas/viewInputs.js +1 -2
- package/dist/canvas/viewMarkers.js +1 -2
- package/dist/canvas/viewRegistry.js +6 -7
- package/dist/canvas/viewRegistry.js.map +1 -1
- package/dist/canvas/viewSnap.js +1 -2
- package/dist/canvas/watchElementMove.js +1 -2
- package/dist/canvas/wrapNodeOutput.js +1 -2
- package/dist/core/adapters/testing/rootsTree.js +1 -2
- package/dist/core/applyOps.js +1 -2
- package/dist/core/device/targets.js +1 -2
- package/dist/core/device/useDeviceProfile.js +1 -2
- package/dist/core/device/useTargetBasePx.js +1 -2
- package/dist/core/device/watchDevicePixelRatio.js +1 -2
- package/dist/core/geometry/autoPoseDescriptor.js +2 -3
- package/dist/core/geometry/booleanOfPaths.js +1 -2
- package/dist/core/geometry/inkExtents.js +1 -2
- package/dist/core/geometry/pathPoseDescriptor.js +1 -2
- package/dist/core/geometry/poseDescriptor.js +1 -2
- package/dist/core/geometry/regionHit.js +1 -2
- package/dist/core/geometry/targetFrame.js +1 -2
- package/dist/core/geometry/unionBounds.js +1 -2
- package/dist/core/layers/backgroundFill.js +1 -2
- package/dist/core/layers/children.js +1 -2
- package/dist/core/layers/gateLayer.js +1 -2
- package/dist/core/layers/layerGroup.js +1 -2
- package/dist/core/layers/redrawSource.js +1 -2
- package/dist/core/layers/render.js +1 -2
- package/dist/core/layers/retain.js +1 -2
- package/dist/core/ops/arrange.js +1 -2
- package/dist/core/ops/create.js +2 -3
- package/dist/core/ops/createHistory.js +2 -3
- package/dist/core/ops/delete.js +2 -3
- package/dist/core/ops/nodeFlags.js +1 -2
- package/dist/core/ops/registry.js +1 -2
- package/dist/core/ops/reorder/algorithms.js +1 -2
- package/dist/core/ops/reorder/index.js +3 -8
- package/dist/core/ops/reorder/index.js.map +1 -1
- package/dist/core/ops/reorder/setChildOrder.js +1 -2
- package/dist/core/ops/reparent.js +1 -2
- package/dist/core/ops/select.js +1 -2
- package/dist/core/ops/setData.js +1 -2
- package/dist/core/ops/setDependsOn.js +1 -2
- package/dist/core/ops/setLayer.js +1 -2
- package/dist/core/ops/setLayout.js +1 -2
- package/dist/core/ops/setPath.js +1 -2
- package/dist/core/ops/setText.js +1 -2
- package/dist/core/ops/slot.js +1 -2
- package/dist/core/ops/transform.js +1 -2
- package/dist/core/ops/writtenBy.js +1 -2
- package/dist/core/pages/fitViewToPage.js +3 -9
- package/dist/core/pages/fitViewToPage.js.map +1 -1
- package/dist/core/pages/pageEdits.js +3 -4
- package/dist/core/pages/pages.js +4 -11
- package/dist/core/pages/pages.js.map +1 -1
- package/dist/core/pages/pagesLayer.js +1 -2
- package/dist/core/paint/meshKind.js +1 -2
- package/dist/core/paint/meshKindLazy.js +18 -23
- package/dist/core/paint/meshKindLazy.js.map +1 -1
- package/dist/core/paint/paintKindEntry.js +1 -2
- package/dist/core/paint/paintKinds.js +1 -2
- package/dist/core/paint/registerMesh.js +1 -2
- package/dist/core/scene/NodeProperties.js +1 -2
- package/dist/core/scene/NodeRouting.js +1 -2
- package/dist/core/scene/annotation.js +1 -2
- package/dist/core/scene/appliedLog.js +1 -2
- package/dist/core/scene/arrivalWindow.js +2 -3
- package/dist/core/scene/arrivals.js +1 -2
- package/dist/core/scene/booleanGroup.js +1 -2
- package/dist/core/scene/booleanOfChildren.js +1 -2
- package/dist/core/scene/boundOps.js +1 -2
- package/dist/core/scene/carryDescendants.js +2 -3
- package/dist/core/scene/clipNothing.js +1 -2
- package/dist/core/scene/composeFrame.js +1 -2
- package/dist/core/scene/composePose.js +1 -2
- package/dist/core/scene/declaredFieldSetters.js +1 -2
- package/dist/core/scene/depFrame.js +1 -2
- package/dist/core/scene/depMemo.js +1 -2
- package/dist/core/scene/dependents.js +1 -2
- package/dist/core/scene/derivedParts.js +1 -2
- package/dist/core/scene/derivedPath.js +2 -3
- package/dist/core/scene/docValues.js +1 -2
- package/dist/core/scene/documentOf.js +1 -2
- package/dist/core/scene/editMode.js +1 -2
- package/dist/core/scene/editPass.js +1 -2
- package/dist/core/scene/effectivePose.js +3 -4
- package/dist/core/scene/fieldEdits.js +1 -2
- package/dist/core/scene/fontReads.js +1 -2
- package/dist/core/scene/historyFacade.js +1 -2
- package/dist/core/scene/historyForm.js +1 -2
- package/dist/core/scene/inheritedPaint.js +1 -2
- package/dist/core/scene/kitOps.js +16 -15
- package/dist/core/scene/kitOps.js.map +1 -1
- package/dist/core/scene/kitRegistry.js +2 -3
- package/dist/core/scene/layerOps.js +1 -2
- package/dist/core/scene/layerStack.js +1 -2
- package/dist/core/scene/layoutPass.js +4 -5
- package/dist/core/scene/lockGuard.js +1 -2
- package/dist/core/scene/minSize.js +1 -2
- package/dist/core/scene/nestedHit.js +1 -2
- package/dist/core/scene/nodeAsShown.js +1 -2
- package/dist/core/scene/nodeFlags.js +1 -2
- package/dist/core/scene/nodeFnFields.js +1 -2
- package/dist/core/scene/nodeGates.js +1 -2
- package/dist/core/scene/nodeMemo.js +1 -2
- package/dist/core/scene/nodeStore.js +2 -3
- package/dist/core/scene/notifier.js +1 -2
- package/dist/core/scene/opTable.js +1 -2
- package/dist/core/scene/outerOps.js +1 -2
- package/dist/core/scene/pathEffects/blend.js +3 -4
- package/dist/core/scene/pathEffects/blend.js.map +1 -1
- package/dist/core/scene/pathEffects/derive.js +2 -3
- package/dist/core/scene/pathEffects/effects.js +1 -2
- package/dist/core/scene/pathEffects/foundHidden.js +1 -2
- package/dist/core/scene/pathEffects/textAlong.js +6 -6
- package/dist/core/scene/pathEffects/textAlong.js.map +1 -1
- package/dist/core/scene/pathEffects/textAlongBands.js +1 -2
- package/dist/core/scene/plyStacks.js +1 -2
- package/dist/core/scene/poseFeed.js +1 -2
- package/dist/core/scene/poseHold.js +1 -2
- package/dist/core/scene/poseOverrides.js +1 -2
- package/dist/core/scene/posePlies.js +1 -2
- package/dist/core/scene/poseRemovals.js +1 -2
- package/dist/core/scene/poseSnapshot.js +1 -2
- package/dist/core/scene/poseWrites.js +1 -2
- package/dist/core/scene/reconcileSpecs.js +26 -3
- package/dist/core/scene/reconcileSpecs.js.map +1 -1
- package/dist/core/scene/recorder.js +1 -2
- package/dist/core/scene/renderOrder.js +1 -2
- package/dist/core/scene/sameValue.js +1 -2
- package/dist/core/scene/scene.js +23 -13
- package/dist/core/scene/scene.js.map +1 -1
- package/dist/core/scene/sceneChanges.js +1 -2
- package/dist/core/scene/sceneEdits.js +1 -2
- package/dist/core/scene/sceneJournals.js +1 -2
- package/dist/core/scene/sceneMutators.js +2 -3
- package/dist/core/scene/scenePoseAdapter.js +1 -2
- package/dist/core/scene/sceneRecording.js +1 -2
- package/dist/core/scene/sceneSelection.js +8 -5
- package/dist/core/scene/sceneSelection.js.map +1 -1
- package/dist/core/scene/sceneState.js +3 -4
- package/dist/core/scene/scrollOffsets.js +1 -2
- package/dist/core/scene/serialization.js +2 -3
- package/dist/core/scene/staleReplay.js +1 -2
- package/dist/core/scene/statedFields.js +1 -2
- package/dist/core/scene/strategyView.js +1 -2
- package/dist/core/scene/treeEdits.js +2 -3
- package/dist/core/scene/treeOrder.js +1 -2
- package/dist/core/scene/treeReads.js +1 -2
- package/dist/core/scene/treeShape.js +1 -2
- package/dist/core/scene/types.js +1 -2
- package/dist/core/scene/types.js.map +1 -1
- package/dist/core/scene/unionOfChildren.js +1 -2
- package/dist/core/scene/unitScopes.js +20 -4
- package/dist/core/scene/unitScopes.js.map +1 -1
- package/dist/core/scene/useScene.js +2 -3
- package/dist/core/scene/worldSave.js +2 -3
- package/dist/core/selection/chromeState.js +1 -2
- package/dist/core/selection/outermostSelection.js +56 -0
- package/dist/core/selection/outermostSelection.js.map +1 -0
- package/dist/core/selection/readOnlySelection.js +1 -2
- package/dist/core/selection/selectionTarget.js +1 -2
- package/dist/core/selection/usePublishSceneSelection.js +1 -2
- package/dist/core/selection/useSelection.js +1 -2
- package/dist/core/shapeKinds.js +1 -2
- package/dist/core/stableStringify.js +1 -2
- package/dist/core/stylus/stylus.js +1 -2
- package/dist/core/stylus/usePointerStylus.js +1 -2
- package/dist/core/usePaintKinds.js +1 -2
- package/dist/core/viewport/clampView.js +1 -2
- package/dist/core/viewport/clientToWorld.js +8 -3
- package/dist/core/viewport/clientToWorld.js.map +1 -1
- package/dist/core/viewport/createVelocityTracker.js +1 -2
- package/dist/core/viewport/fitToBounds.js +1 -2
- package/dist/core/viewport/fitViewToBounds.js +1 -2
- package/dist/core/viewport/interpolateView.js +1 -2
- package/dist/core/viewport/parallax.js +1 -2
- package/dist/core/viewport/sceneNodeClientRect.js +1 -2
- package/dist/core/viewport/screenSlop.js +1 -2
- package/dist/core/viewport/useAutoCenter.js +1 -2
- package/dist/core/viewport/useCanvasSize.js +1 -2
- package/dist/core/viewport/useDecayLoop.js +1 -2
- package/dist/core/viewport/useNodeOverlayFrame.js +1 -2
- package/dist/core/viewport/useVelocityTracker.js +1 -2
- package/dist/core/viewport/useViewAnimation.js +3 -4
- package/dist/core/viewport/view.js +1 -2
- package/dist/core/viewport/viewTransform.js +1 -2
- package/dist/core/viewport/viewportWorldRect.js +1 -2
- package/dist/core/viewport/wheelHandler.js +1 -2
- package/dist/core/viewport/zoomAt.js +7 -8
- package/dist/core/viewport/zoomAt.js.map +1 -1
- package/dist/core/viewport/zoomBounds.js +1 -2
- package/dist/debug/createDebugOverlayLayer.js +1 -2
- package/dist/debug/createDebugSink.js +1 -2
- package/dist/debug/defaultTheme.js +1 -2
- package/dist/debug/features.js +1 -2
- package/dist/debug/frameStats.js +1 -2
- package/dist/debug/overlayPanels.js +1 -2
- package/dist/debug/parseDebugFlags.js +1 -2
- package/dist/debug/useDebugSink.js +2 -3
- package/dist/{depSchema-ChQPzEkW.d.ts → depSchema-C7a_OMt-.d.ts} +61 -52
- package/dist/devtools/handlers.js +1 -2
- package/dist/devtools/history.js +1 -2
- package/dist/devtools/hook.js +1 -2
- package/dist/devtools/label.js +1 -2
- package/dist/devtools/notices.js +1 -2
- package/dist/devtools/protocol.js +1 -2
- package/dist/devtools/registry.js +1 -2
- package/dist/devtools/root.js +12 -6
- package/dist/devtools/root.js.map +1 -1
- package/dist/devtools/serialize.js +1 -2
- package/dist/devtools/session.js +2 -3
- package/dist/devtools/transport.js +13 -18
- package/dist/devtools/transport.js.map +1 -1
- package/dist/devtools/useDevtoolsRoot.js +1 -2
- package/dist/devtools-protocol.d.ts +1 -12
- package/dist/devtools-protocol.js +2 -2
- package/dist/devtools.d.ts +1 -1
- package/dist/devtools.js +1 -2
- package/dist/domains/chrome-caps/buildChromeCtx.js +1 -2
- package/dist/domains/chrome-caps/conditions.js +1 -2
- package/dist/domains/chrome-caps/defaults.js +1 -2
- package/dist/domains/chrome-caps/resolve.js +2 -3
- package/dist/domains/chrome-caps/useChromeCaps.js +1 -2
- package/dist/domains/chrome-caps/useHoverTracking.js +1 -2
- package/dist/domains/ingestion/contentHandlers.js +1 -2
- package/dist/domains/ingestion/ghost.js +2 -3
- package/dist/domains/ingestion/imageHandler.js +1 -2
- package/dist/domains/ingestion/kitHandlers.js +2 -3
- package/dist/domains/ingestion/openFilePicker.js +1 -2
- package/dist/domains/ingestion/placement.js +1 -2
- package/dist/domains/ingestion/svgHandler.js +1 -2
- package/dist/domains/ingestion/textHandler.js +1 -2
- package/dist/domains/ingestion/useCanvasIngestion.js +1 -2
- package/dist/domains/ingestion/weaselJsonHandler.js +2 -3
- package/dist/domains/longPress/longPressFeedback.js +1 -2
- package/dist/domains/measure/actionIds.js +1 -2
- package/dist/domains/measure/measureCommands.js +6 -7
- package/dist/domains/measure/measureContribution.js +3 -4
- package/dist/domains/measure/measureEdits.js +3 -4
- package/dist/domains/measure/measureGestures.js +2 -3
- package/dist/domains/measure/measureHit.js +5 -12
- package/dist/domains/measure/measureHit.js.map +1 -1
- package/dist/domains/measure/measureLayer.js +3 -4
- package/dist/domains/measure/measurement.js +1 -2
- package/dist/domains/measure/measurements.js +1 -2
- package/dist/domains/modes/modeLayers.js +1 -2
- package/dist/domains/modes/modeTriggers.js +1 -2
- package/dist/domains/pathEffects/effectSources.js +2 -3
- package/dist/domains/pathEffects/index.js +1 -2
- package/dist/domains/pathEffects/readSource.js +3 -4
- package/dist/domains/pathEffects/textItems.js +1 -2
- package/dist/domains/pathEffects/useEffectSourcesLayer.js +3 -4
- package/dist/domains/paths/anchorData.js +1 -2
- package/dist/domains/paths/anchorMarkers.js +6 -13
- package/dist/domains/paths/anchorMarkers.js.map +1 -1
- package/dist/domains/paths/editablePath.js +3 -4
- package/dist/domains/paths/originProjection.js +1 -2
- package/dist/domains/paths/pathEditExtension.js +1 -2
- package/dist/domains/paths/pathEditState.js +1 -2
- package/dist/domains/paths/pathEditingOverlayLayer.js +7 -12
- package/dist/domains/paths/pathEditingOverlayLayer.js.map +1 -1
- package/dist/domains/paths/pathLayer.js +1 -2
- package/dist/domains/paths/pathRepresentation.js +1 -2
- package/dist/domains/paths/pathSnap/glyphs.js +1 -2
- package/dist/domains/paths/pathSnap/pathSnapSource.js +1 -2
- package/dist/domains/paths/pathSnap/sceneIndex.js +1 -2
- package/dist/domains/paths/pathSnap/snapGeometry.js +2 -3
- package/dist/domains/paths/penPreviewLayer.js +10 -14
- package/dist/domains/paths/penPreviewLayer.js.map +1 -1
- package/dist/domains/paths/shapeGenerator.js +2 -4
- package/dist/domains/paths/shapeGenerator.js.map +1 -1
- package/dist/domains/paths/strokeOutline.js +2 -3
- package/dist/domains/paths/useAnchorFields.js +1 -2
- package/dist/domains/paths/usePathEdit.js +2 -3
- package/dist/domains/poseRun/usePoseRun.js +1 -2
- package/dist/domains/selection/enteredGroupFrame.js +1 -2
- package/dist/domains/selection/enteredGroupScope.js +1 -2
- package/dist/domains/selection/enteredOperands.js +1 -2
- package/dist/domains/selection/handleCommands.js +2 -3
- package/dist/domains/selection/overlay.js +6 -7
- package/dist/domains/selection/selectionPose.js +2 -3
- package/dist/domains/snap/angle2d.js +3 -3
- package/dist/domains/snap/angle2d.js.map +1 -1
- package/dist/domains/snap/debugCandidates.js +1 -2
- package/dist/domains/snap/gather.js +1 -2
- package/dist/domains/snap/inputSubspace.js +2 -3
- package/dist/domains/snap/lazySession.js +1 -2
- package/dist/domains/snap/marks.js +1 -2
- package/dist/domains/snap/outcomeStore.js +6 -10
- package/dist/domains/snap/outcomeStore.js.map +1 -1
- package/dist/domains/snap/pointSnap.js +1 -2
- package/dist/domains/snap/probes2d.js +1 -2
- package/dist/domains/snap/readoutDraw.js +1 -2
- package/dist/domains/snap/readoutLayer.js +1 -2
- package/dist/domains/snap/registry.js +1 -2
- package/dist/domains/snap/resizeBox.js +1 -2
- package/dist/domains/snap/roles.js +1 -2
- package/dist/domains/snap/rotationSource.js +1 -2
- package/dist/domains/snap/sceneReads.js +2 -3
- package/dist/domains/snap/sceneSession2d.js +2 -3
- package/dist/domains/snap/screen.js +2 -3
- package/dist/domains/snap/session2d.js +4 -5
- package/dist/domains/snap/spanSnap.js +1 -2
- package/dist/domains/snap/stepAngles.js +1 -2
- package/dist/domains/text/editingDrawOne.js +1 -2
- package/dist/domains/text/hostTextEditors.js +1 -2
- package/dist/domains/text/sceneTextDrafts.js +1 -2
- package/dist/domains/text/textHitAt.js +4 -5
- package/dist/domains/text/textLayer.js +12 -2
- package/dist/domains/text/textLayer.js.map +1 -1
- package/dist/domains/text/useSceneTextEdit.js +13 -9
- package/dist/domains/text/useSceneTextEdit.js.map +1 -1
- package/dist/domains/viewports/aim.js +6 -12
- package/dist/domains/viewports/aim.js.map +1 -1
- package/dist/domains/viewports/viewMarker.js +1 -2
- package/dist/domains/viewports/viewMarkerDrag.js +1 -2
- package/dist/domains/viewports/viewResolver.js +6 -5
- package/dist/domains/viewports/viewResolver.js.map +1 -1
- package/dist/domains/viewports/viewportLayer.js +1 -2
- package/dist/iconRegistry/IconRegistryProvider.js +1 -2
- package/dist/iconRegistry/useIconGlyph.js +1 -2
- package/dist/iconRegistry/useIconVariant.js +1 -2
- package/dist/icons.table.js +1 -2
- package/dist/icons2.table.js +1 -2
- package/dist/index.d.ts +70 -27
- package/dist/index.js +7 -5
- package/dist/input/keyState.js +1 -2
- package/dist/input/useKeyModifiers.js +1 -2
- package/dist/input/useKeyState.js +1 -2
- package/dist/input/usePublishPointer.js +59 -0
- package/dist/input/usePublishPointer.js.map +1 -0
- package/dist/interactions/actions/admitsChild.js +1 -2
- package/dist/interactions/actions/align/action.js +6 -7
- package/dist/interactions/actions/align/align.js +6 -7
- package/dist/interactions/actions/booleans/action.js +1 -2
- package/dist/interactions/actions/booleans/booleanGroupAction.js +2 -3
- package/dist/interactions/actions/booleans/booleans.js +1 -2
- package/dist/interactions/actions/booleans/commit.js +4 -5
- package/dist/interactions/actions/booleans/custom.js +2 -3
- package/dist/interactions/actions/booleans/keymap.js +1 -2
- package/dist/interactions/actions/booleans/operands.js +1 -2
- package/dist/interactions/actions/booleans/pieces.js +1 -2
- package/dist/interactions/actions/booleans/placement.js +1 -2
- package/dist/interactions/actions/booleans/useBooleans.js +1 -2
- package/dist/interactions/actions/booleans/useBooleansAdapter.js +1 -2
- package/dist/interactions/actions/clipboard/action.js +2 -3
- package/dist/interactions/actions/clipboard/clipboardOps.js +2 -3
- package/dist/interactions/actions/clipboard/materializePaste.js +1 -2
- package/dist/interactions/actions/clipboard/wireFormat.js +1 -2
- package/dist/interactions/actions/clone/action.js +7 -8
- package/dist/interactions/actions/clone/behaviors.js +4 -5
- package/dist/interactions/actions/defaultCommitAdapter.js +2 -3
- package/dist/interactions/actions/defaults/anchorEditing.js +3 -4
- package/dist/interactions/actions/defaults/anchorFields.js +1 -2
- package/dist/interactions/actions/defaults/anchorHandles.js +2 -3
- package/dist/interactions/actions/defaults/anchorJoin.js +2 -3
- package/dist/interactions/actions/defaults/areaSelect.js +6 -6
- package/dist/interactions/actions/defaults/areaSelect.js.map +1 -1
- package/dist/interactions/actions/defaults/bendSegment.js +3 -4
- package/dist/interactions/actions/defaults/cancelGesture.js +1 -2
- package/dist/interactions/actions/defaults/clearSelection.js +1 -2
- package/dist/interactions/actions/defaults/containerScroll.js +13 -8
- package/dist/interactions/actions/defaults/containerScroll.js.map +1 -1
- package/dist/interactions/actions/defaults/contextMenu.js +6 -7
- package/dist/interactions/actions/defaults/copySubtree.js +2 -3
- package/dist/interactions/actions/defaults/createPaintAction.js +3 -4
- package/dist/interactions/actions/defaults/delete.js +2 -3
- package/dist/interactions/actions/defaults/duplicate.js +5 -6
- package/dist/interactions/actions/defaults/enterGroup.js +5 -6
- package/dist/interactions/actions/defaults/enterGroup.js.map +1 -1
- package/dist/interactions/actions/defaults/enterPathEdit.js +1 -2
- package/dist/interactions/actions/defaults/enterTextEdit.js +1 -2
- package/dist/interactions/actions/defaults/escape.js +1 -2
- package/dist/interactions/actions/defaults/exitPathEdit.js +1 -2
- package/dist/interactions/actions/defaults/group.js +6 -7
- package/dist/interactions/actions/defaults/ingest.js +3 -4
- package/dist/interactions/actions/defaults/insertPathAnchor.js +2 -3
- package/dist/interactions/actions/defaults/nudge.js +3 -4
- package/dist/interactions/actions/defaults/nudgeSteps.js +2 -3
- package/dist/interactions/actions/defaults/nudgeSteps.js.map +1 -1
- package/dist/interactions/actions/defaults/pathEditMarks.js +3 -7
- package/dist/interactions/actions/defaults/pathEditMarks.js.map +1 -1
- package/dist/interactions/actions/defaults/pinchZoom.js +3 -4
- package/dist/interactions/actions/defaults/reorder.js +2 -3
- package/dist/interactions/actions/defaults/requiresSelection.js +1 -2
- package/dist/interactions/actions/defaults/segmentUnder.js +1 -2
- package/dist/interactions/actions/defaults/selectAll.js +1 -2
- package/dist/interactions/actions/defaults/selectDeep.js +1 -2
- package/dist/interactions/actions/defaults/setFill.js +1 -2
- package/dist/interactions/actions/defaults/setFillOpacity.js +1 -2
- package/dist/interactions/actions/defaults/setStroke.js +1 -2
- package/dist/interactions/actions/defaults/setStrokeOpacity.js +1 -2
- package/dist/interactions/actions/defaults/slice.js +1 -2
- package/dist/interactions/actions/defaults/sliceOps.js +1 -2
- package/dist/interactions/actions/defaults/toolActivate.js +1 -2
- package/dist/interactions/actions/defaults/toolResetToDefault.js +1 -2
- package/dist/interactions/actions/defaults/undoRedo.js +1 -2
- package/dist/interactions/actions/defaults/viewportDragPan.js +1 -2
- package/dist/interactions/actions/defaults/viewportWheelPan.js +1 -2
- package/dist/interactions/actions/defaults/viewportZoom.js +3 -4
- package/dist/interactions/actions/distribute/action.js +4 -5
- package/dist/interactions/actions/distribute/distribute.js +5 -6
- package/dist/interactions/actions/distribute/plan.js +1 -2
- package/dist/interactions/actions/drawnBoxes.js +4 -5
- package/dist/interactions/actions/dropVerdict.js +1 -2
- package/dist/interactions/actions/edit-anchors/action.js +4 -5
- package/dist/interactions/actions/edit-anchors/extensionDrags.js +1 -2
- package/dist/interactions/actions/edit-anchors/geometry.js +1 -2
- package/dist/interactions/actions/edit-anchors/handleDrag.js +5 -9
- package/dist/interactions/actions/edit-anchors/handleDrag.js.map +1 -1
- package/dist/interactions/actions/edit-anchors/handles.js +1 -2
- package/dist/interactions/actions/edit-anchors/params.js +1 -2
- package/dist/interactions/actions/edit-anchors/preview.js +1 -2
- package/dist/interactions/actions/edit-anchors/symmetry.js +1 -2
- package/dist/interactions/actions/flip/action.js +8 -9
- package/dist/interactions/actions/flip/helpers.js +1 -2
- package/dist/interactions/actions/geometryProjection.js +1 -2
- package/dist/interactions/actions/gestureFrames.js +3 -4
- package/dist/interactions/actions/gestureLifecycle.js +1 -2
- package/dist/interactions/actions/hitSelection.js +7 -3
- package/dist/interactions/actions/hitSelection.js.map +1 -1
- package/dist/interactions/actions/insert/action.js +6 -7
- package/dist/interactions/actions/insert/commit.js +2 -3
- package/dist/interactions/actions/insert/extras.js +1 -2
- package/dist/interactions/actions/insert/frame.js +1 -2
- package/dist/interactions/actions/insert/geometry.js +1 -2
- package/dist/interactions/actions/insert/params.js +2 -3
- package/dist/interactions/actions/insert/parent.js +1 -2
- package/dist/interactions/actions/insert/placeAction.js +5 -6
- package/dist/interactions/actions/insert/repositionAction.js +1 -2
- package/dist/interactions/actions/insert/rotateAction.js +1 -2
- package/dist/interactions/actions/insert/session.js +5 -6
- package/dist/interactions/actions/insert/shape.js +2 -3
- package/dist/interactions/actions/lasso-select/action.js +9 -9
- package/dist/interactions/actions/lasso-select/action.js.map +1 -1
- package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js +2 -3
- package/dist/interactions/actions/magnification.js +37 -0
- package/dist/interactions/actions/magnification.js.map +1 -0
- package/dist/interactions/actions/move/action.js +2 -3
- package/dist/interactions/actions/move/behaviors/clampMove.js +42 -0
- package/dist/interactions/actions/move/behaviors/clampMove.js.map +1 -0
- package/dist/interactions/actions/move/behaviors/layoutDrop.js +2 -3
- package/dist/interactions/actions/move/behaviors/reparentOnDrop.js +2 -3
- package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js +1 -2
- package/dist/interactions/actions/move/behaviors/snapToContainer.js +2 -3
- package/dist/interactions/actions/move/capture.js +6 -7
- package/dist/interactions/actions/move/commit/index.js +2 -3
- package/dist/interactions/actions/move/commit/layoutDrop.js +4 -5
- package/dist/interactions/actions/move/commit/layoutRelease.js +7 -8
- package/dist/interactions/actions/move/commit/rebase.js +2 -3
- package/dist/interactions/actions/move/commit/reparent.js +5 -6
- package/dist/interactions/actions/move/delta.js +2 -3
- package/dist/interactions/actions/move/frame.js +2 -3
- package/dist/interactions/actions/move/gestureAdapter.js +1 -2
- package/dist/interactions/actions/move/landedDescendants.js +2 -3
- package/dist/interactions/actions/move/layout/container.js +6 -10
- package/dist/interactions/actions/move/layout/container.js.map +1 -1
- package/dist/interactions/actions/move/layout/dragged.js +2 -3
- package/dist/interactions/actions/move/layout/dropPass.js +5 -6
- package/dist/interactions/actions/move/layout/exits.js +4 -5
- package/dist/interactions/actions/move/layout/exits.js.map +1 -1
- package/dist/interactions/actions/move/layout/glide.js +2 -3
- package/dist/interactions/actions/move/layout/view.js +1 -2
- package/dist/interactions/actions/move/refusal.js +2 -3
- package/dist/interactions/actions/move/session.js +4 -5
- package/dist/interactions/actions/move/translate.js +2 -3
- package/dist/interactions/actions/moveNodes.js +5 -6
- package/dist/interactions/actions/notices.js +1 -2
- package/dist/interactions/actions/outlines/createOutlines.js +1 -2
- package/dist/interactions/actions/outlines/createOutlinesAction.js +2 -3
- package/dist/interactions/actions/outlines/outlineStroke.js +2 -3
- package/dist/interactions/actions/outlines/outlineStrokeAction.js +2 -3
- package/dist/interactions/actions/outlines/replaceWithPaths.js +5 -6
- package/dist/interactions/actions/outlines/strokeRegion.js +1 -2
- package/dist/interactions/actions/outlines/useCreateOutlinesAdapter.js +1 -2
- package/dist/interactions/actions/pathCommands/cutJoin.js +3 -4
- package/dist/interactions/actions/pathCommands/livePathEdit.js +3 -4
- package/dist/interactions/actions/pathCommands/pathNodes.js +3 -4
- package/dist/interactions/actions/pathCommands/simplifyOffset.js +2 -3
- package/dist/interactions/actions/pathGestureTags.js +1 -2
- package/dist/interactions/actions/planeInput.js +2 -3
- package/dist/interactions/actions/pointerState.js +1 -2
- package/dist/interactions/actions/poseDescriptorDep.js +1 -2
- package/dist/interactions/actions/poseFrame.js +3 -4
- package/dist/interactions/actions/resize/action.js +3 -4
- package/dist/interactions/actions/resize/aspect.js +1 -2
- package/dist/interactions/actions/resize/behaviors/clampMinSize.js +1 -2
- package/dist/interactions/actions/resize/boxFrame.js +1 -2
- package/dist/interactions/actions/resize/capture.js +7 -8
- package/dist/interactions/actions/resize/commit.js +3 -4
- package/dist/interactions/actions/resize/cornerHandles.js +1 -2
- package/dist/interactions/actions/resize/frame.js +7 -8
- package/dist/interactions/actions/resize/held.js +2 -3
- package/dist/interactions/actions/resize/minimum.js +1 -2
- package/dist/interactions/actions/resize/replay.js +1 -2
- package/dist/interactions/actions/resize/ruleBounds.js +1 -2
- package/dist/interactions/actions/resize/session.js +9 -10
- package/dist/interactions/actions/resolveOverlays.js +1 -2
- package/dist/interactions/actions/resolvePreviews.js +3 -4
- package/dist/interactions/actions/rotate/action.js +5 -6
- package/dist/interactions/actions/rotate/commit.js +2 -3
- package/dist/interactions/actions/rotate/frame.js +3 -4
- package/dist/interactions/actions/rotate/geometry.js +1 -2
- package/dist/interactions/actions/rotate/handle.js +2 -3
- package/dist/interactions/actions/rotate/replay.js +2 -3
- package/dist/interactions/actions/rotate/session.js +10 -11
- package/dist/interactions/actions/selectionSubtree.js +7 -22
- package/dist/interactions/actions/selectionSubtree.js.map +1 -1
- package/dist/interactions/actions/spatialReference.js +1 -2
- package/dist/interactions/actions/testUtils.js +1 -2
- package/dist/interactions/actions/transform-again/action.js +5 -6
- package/dist/interactions/actions/transform-again/memory.js +3 -4
- package/dist/interactions/actions/transform-again/memory.js.map +1 -1
- package/dist/interactions/actions/transformFinish.js +1 -2
- package/dist/interactions/actions/useActionSet.js +1 -2
- package/dist/interactions/actions/useNotices.js +1 -2
- package/dist/interactions/actions/useStandardActions.js +1 -2
- package/dist/interactions/gestures/dragGesture/dragGesture.js +1 -2
- package/dist/interactions/gestures/dragGesture/dragPointOf.js +1 -2
- package/dist/interactions/gestures/dragRadial/dragRadial.js +2 -3
- package/dist/interactions/gestures/dragRect/dragRect.js +2 -3
- package/dist/interactions/gestures/handleDrag/handleDrag.js +1 -2
- package/dist/interactions/gestures/pointerDrag/pointerDrag.js +1 -2
- package/dist/interactions/gestures/shared/originProjection.js +1 -2
- package/dist/interactions/gestures/shared/screenTolerance.js +1 -2
- package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js +1 -2
- package/dist/kitSettingsSchema.js +4 -5
- package/dist/move.d.ts +18 -3
- package/dist/move.js +2 -1
- package/dist/test-hook/createTestHook.js +1 -2
- package/dist/test-hook/install.js +1 -2
- package/dist/test-hook/useTestHook.js +1 -2
- package/dist/test-seams.d.ts +4 -4
- package/dist/test-seams.js +2 -2
- package/dist/tools/builtin/anchors/anchorsTool.js +1 -2
- package/dist/tools/builtin/ellipse/useEllipseTool.js +2 -3
- package/dist/tools/builtin/eyedropper/useEyedropperTool.js +1 -2
- package/dist/tools/builtin/hand/dragPanContribution.js +1 -2
- package/dist/tools/builtin/hand/useHandTool.js +1 -2
- package/dist/tools/builtin/image/useImageTool.js +1 -2
- package/dist/tools/builtin/lasso/useLassoTool.js +1 -2
- package/dist/tools/builtin/line/useLineTool.js +2 -3
- package/dist/tools/builtin/measure/useMeasureTool.js +2 -3
- package/dist/tools/builtin/pen/penHandle.js +1 -2
- package/dist/tools/builtin/pen/usePenTool.js +6 -7
- package/dist/tools/builtin/pencil/usePencilTool.js +1 -2
- package/dist/tools/builtin/pickTopMostHit.js +1 -2
- package/dist/tools/builtin/polygon/usePolygonTool.js +3 -4
- package/dist/tools/builtin/pressTarget.js +1 -2
- package/dist/tools/builtin/rect/useRectTool.js +2 -3
- package/dist/tools/builtin/select/adapterPointQuery.js +3 -4
- package/dist/tools/builtin/select/collapseDeferred.js +1 -2
- package/dist/tools/builtin/select/groupEntry.js +2 -3
- package/dist/tools/builtin/select/pressDecision.js +3 -4
- package/dist/tools/builtin/select/pressDecision.js.map +1 -1
- package/dist/tools/builtin/select/selectionContributions.js +1 -2
- package/dist/tools/builtin/select/useSelectTool.js +5 -6
- package/dist/tools/builtin/shared/insertToolOptions.js +1 -2
- package/dist/tools/builtin/shared/pointerFollower.js +1 -2
- package/dist/tools/builtin/slice/useSliceTool.js +5 -6
- package/dist/tools/builtin/star/useStarTool.js +3 -4
- package/dist/tools/builtin/sticky/stickyNode.js +1 -2
- package/dist/tools/builtin/sticky/useStickyTool.js +2 -3
- package/dist/tools/builtin/text/useTextTool.js +1 -2
- package/dist/tools/index.js +2 -2
- package/dist/tools/overlayBinding.js +1 -2
- package/dist/tools/toolOptions.js +17 -4
- package/dist/tools/toolOptions.js.map +1 -1
- package/dist/tools/useKeybindings.js +1 -2
- package/dist/{types-DW14eu9B.d.ts → types-BUvUXZe5.d.ts} +3 -3
- package/dist/util/color.js +1 -2
- package/dist/util/paint.js +1 -2
- package/dist/version.js +2 -3
- package/package.json +27 -27
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { isRectPose } from "../../../core/geometry/autoPoseDescriptor.js";
|
|
2
|
-
import { findNodeShape } from "../../../canvas/NodeShape.js";
|
|
3
2
|
import { poseOutline } from "../../../core/geometry/regionHit.js";
|
|
3
|
+
import { findNodeShape } from "../../../canvas/NodeShape.js";
|
|
4
4
|
import { nodeOutline } from "../strokeOutline.js";
|
|
5
5
|
import { worldCoords } from "@weasel-js/geom";
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
// src/domains/paths/pathSnap/snapGeometry.ts
|
|
8
8
|
/**
|
|
9
9
|
* The geometry `node` snaps to. A painter that `snapsToBox` — text, an image
|
|
10
10
|
* — gives its pose box through the pose's frame, and the box's center. Any
|
|
@@ -43,6 +43,5 @@ function boxCenter(path) {
|
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
//#endregion
|
|
47
46
|
export { nodeSnapGeometry };
|
|
48
47
|
//# sourceMappingURL=snapGeometry.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { PATH_C, PATH_L, PATH_M, anchorsToPath, circlePath } from "@weasel-js/geom";
|
|
1
|
+
import { PATH_C, PATH_L, PATH_M, anchorsToPath, circlePath, viewWorldToScreen } from "@weasel-js/geom";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// src/domains/paths/penPreviewLayer.ts
|
|
4
4
|
var DEFAULT_STYLE = {
|
|
5
5
|
anchorFill: "#d4c4a8",
|
|
6
6
|
anchorStroke: "#d4c4a8",
|
|
@@ -21,9 +21,6 @@ var radiiOf = (kit) => ({
|
|
|
21
21
|
handleDot: kit?.get("targets.penHandleDotRadiusPx") ?? HANDLE_DOT_RADIUS_PX,
|
|
22
22
|
closeHint: kit?.get("targets.penCloseHintRadiusPx") ?? CLOSE_HINT_RADIUS_PX
|
|
23
23
|
});
|
|
24
|
-
function w2s(wx, wy, view) {
|
|
25
|
-
return [(wx - view.x) * view.scale.x, (wy - view.y) * view.scale.y];
|
|
26
|
-
}
|
|
27
24
|
function approximateCircle(cx, cy, r) {
|
|
28
25
|
return circlePath(cx, cy, r);
|
|
29
26
|
}
|
|
@@ -32,7 +29,7 @@ function approximateCircle(cx, cy, r) {
|
|
|
32
29
|
function subpathToPath(sp, view) {
|
|
33
30
|
if (sp.anchors.length === 0) return null;
|
|
34
31
|
const pt = (p) => {
|
|
35
|
-
const
|
|
32
|
+
const { x, y } = viewWorldToScreen(view, p);
|
|
36
33
|
return {
|
|
37
34
|
x,
|
|
38
35
|
y
|
|
@@ -95,11 +92,11 @@ function createPenPreviewLayer(opts) {
|
|
|
95
92
|
if (cur && cur.anchors.length > 0 && s.cursor && s.draggingHandleAt === null) {
|
|
96
93
|
const last = cur.anchors[cur.anchors.length - 1];
|
|
97
94
|
const out2 = last.outHandle;
|
|
98
|
-
const
|
|
99
|
-
const
|
|
95
|
+
const { x: sx, y: sy } = viewWorldToScreen(view, last);
|
|
96
|
+
const { x: cx, y: cy } = viewWorldToScreen(view, s.cursor);
|
|
100
97
|
let path;
|
|
101
98
|
if (out2) {
|
|
102
|
-
const
|
|
99
|
+
const { x: c1x, y: c1y } = viewWorldToScreen(view, out2);
|
|
103
100
|
path = {
|
|
104
101
|
kind: "polygon",
|
|
105
102
|
commands: new Uint8Array([PATH_M, PATH_C]),
|
|
@@ -141,7 +138,7 @@ function createPenPreviewLayer(opts) {
|
|
|
141
138
|
if (cur) {
|
|
142
139
|
for (let i = 0; i < cur.anchors.length; i++) {
|
|
143
140
|
const a = cur.anchors[i];
|
|
144
|
-
const
|
|
141
|
+
const { x: ax, y: ay } = viewWorldToScreen(view, a);
|
|
145
142
|
out.push({
|
|
146
143
|
kind: "path",
|
|
147
144
|
path: approximateCircle(ax, ay, r.anchor),
|
|
@@ -158,7 +155,7 @@ function createPenPreviewLayer(opts) {
|
|
|
158
155
|
}
|
|
159
156
|
});
|
|
160
157
|
if (i === cur.anchors.length - 1 && a.outHandle) {
|
|
161
|
-
const
|
|
158
|
+
const { x: hx, y: hy } = viewWorldToScreen(view, a.outHandle);
|
|
162
159
|
const linePath = {
|
|
163
160
|
kind: "polygon",
|
|
164
161
|
commands: new Uint8Array([PATH_M, PATH_L]),
|
|
@@ -191,7 +188,7 @@ function createPenPreviewLayer(opts) {
|
|
|
191
188
|
});
|
|
192
189
|
const inSide = a.inHandle;
|
|
193
190
|
if (inSide) {
|
|
194
|
-
const
|
|
191
|
+
const { x: mx, y: my } = viewWorldToScreen(view, inSide);
|
|
195
192
|
const inLine = {
|
|
196
193
|
kind: "polygon",
|
|
197
194
|
commands: new Uint8Array([PATH_M, PATH_L]),
|
|
@@ -227,7 +224,7 @@ function createPenPreviewLayer(opts) {
|
|
|
227
224
|
}
|
|
228
225
|
if (s.closeHintActive && cur.anchors.length >= 3) {
|
|
229
226
|
const first = cur.anchors[0];
|
|
230
|
-
const
|
|
227
|
+
const { x: fx, y: fy } = viewWorldToScreen(view, first);
|
|
231
228
|
out.push({
|
|
232
229
|
kind: "path",
|
|
233
230
|
path: approximateCircle(fx, fy, r.closeHint),
|
|
@@ -246,6 +243,5 @@ function createPenPreviewLayer(opts) {
|
|
|
246
243
|
};
|
|
247
244
|
}
|
|
248
245
|
|
|
249
|
-
//#endregion
|
|
250
246
|
export { ANCHOR_RADIUS_PX, CLOSE_HINT_RADIUS_PX, HANDLE_DOT_RADIUS_PX, PEN_CLOSE_HIT_PX, createPenPreviewLayer, penReachOf };
|
|
251
247
|
//# sourceMappingURL=penPreviewLayer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"penPreviewLayer.js","names":[],"sources":["../../../src/domains/paths/penPreviewLayer.ts"],"sourcesContent":["/**\n * Screen-space preview layer for `usePenTool`. Reads the pen's state each\n * frame and renders the in-progress path: finished\n * subpaths (faded), the current subpath (bright + anchor dots + handles),\n * a rubber-band segment from the latest anchor to the cursor, and a\n * close-hint ring on the first anchor when the tool flags it as hot.\n *\n * Runs in screen space so anchor/handle sizes stay constant under zoom.\n * All world-space coords go through `worldToScreen` via the layer's `view`\n * argument.\n */\n\nimport type { DrawCommand } from '@weasel-js/renderer';\nimport type { RenderLayer } from 'core/layers/render';\nimport type { KitSettingsStore } from '@weasel-js/react';\nimport type { PenScratch, PenAnchor, PenSubpath } from 'tools/builtin/pen';\nimport { PATH_C, PATH_L, PATH_M, type PolygonPath, anchorsToPath, circlePath } from '@weasel-js/geom';\n\n/** Appearance of the pen tool's in-progress path. */\nexport interface PenPreviewStyle {\n anchorFill?: string;\n anchorStroke?: string;\n handleStroke?: string;\n rubberBandStroke?: string;\n closeHintFill?: string;\n finishedSubpathStroke?: string;\n}\n\n/** Options for `createPenPreviewLayer`. */\nexport interface CreatePenPreviewLayerOptions {\n /** The pen's state. One object for the pen's life, changed in place, so\n * the layer reads the same one on every frame. */\n state: PenScratch;\n style?: PenPreviewStyle;\n /** The kit settings whose `targets.pen*RadiusPx` size the dots, read each frame. */\n kitSettings?: () => KitSettingsStore;\n}\n\nconst DEFAULT_STYLE: Required<PenPreviewStyle> = {\n anchorFill: '#d4c4a8',\n anchorStroke: '#d4c4a8',\n handleStroke: '#d4c4a8',\n rubberBandStroke: '#d4c4a8',\n closeHintFill: '#d4c4a8',\n finishedSubpathStroke: '#8a7a5e',\n};\n\nexport const ANCHOR_RADIUS_PX = 4;\nexport const HANDLE_DOT_RADIUS_PX = 3;\nexport const CLOSE_HINT_RADIUS_PX = 8;\n\n/** How near the pen's first anchor, in screen px, a click closes the subpath. */\nexport const PEN_CLOSE_HIT_PX = 8;\n\n/** The pen's reach in screen px: its own option, else the kit setting, else the constant. */\nexport const penReachOf = (o: { closeHitRadius?: number; kitSettings?: KitSettingsStore }) => ({\n close: o.closeHitRadius ?? o.kitSettings?.get('targets.penCloseHitPx') ?? PEN_CLOSE_HIT_PX,\n});\n\nconst radiiOf = (kit: KitSettingsStore | undefined) => ({\n anchor: kit?.get('targets.penAnchorRadiusPx') ?? ANCHOR_RADIUS_PX,\n handleDot: kit?.get('targets.penHandleDotRadiusPx') ?? HANDLE_DOT_RADIUS_PX,\n closeHint: kit?.get('targets.penCloseHintRadiusPx') ?? CLOSE_HINT_RADIUS_PX,\n});\n\nfunction w2s(wx: number, wy: number, view: { x: number; y: number; scale: { x: number; y: number } }): [number, number] {\n return [(wx - view.x) * view.scale.x, (wy - view.y) * view.scale.y];\n}\n\n// approximateCircle has moved to `./markers.ts` as `circlePath`. Re-exported\n// locally so we don't rename callers in this file.\nfunction approximateCircle(cx: number, cy: number, r: number): PolygonPath {\n return circlePath(cx, cy, r);\n}\n\n/** A pen subpath as a screen-space `PolygonPath`, segmented by the same rule\n * the pen commits with. */\nfunction subpathToPath(\n sp: PenSubpath,\n view: { x: number; y: number; scale: { x: number; y: number } },\n): PolygonPath | null {\n if (sp.anchors.length === 0) return null;\n const pt = (p: { x: number; y: number }) => {\n const [x, y] = w2s(p.x, p.y, view);\n return { x, y };\n };\n const anchors = sp.anchors.map((a: PenAnchor) => ({\n ...pt(a),\n ...(a.inHandle ? { inHandle: pt(a.inHandle) } : {}),\n ...(a.outHandle ? { outHandle: pt(a.outHandle) } : {}),\n }));\n return anchorsToPath([anchors], [sp.closed]);\n}\n\n/** Render layer that draws the pen tool's path as it is being placed —\n * committed anchors, the rubber band to the cursor, and the close hint. Draws\n * nothing when the pen is idle. */\nexport function createPenPreviewLayer(\n opts: CreatePenPreviewLayerOptions,\n): RenderLayer<unknown> {\n const style = { ...DEFAULT_STYLE, ...(opts.style ?? {}) };\n const s = opts.state;\n\n return {\n id: 'penPreview',\n label: 'Pen preview',\n space: 'screen',\n draw: (_data, view) => {\n const out: DrawCommand[] = [];\n const r = radiiOf(opts.kitSettings?.());\n // (1) Finished subpaths — faded outline.\n for (const sp of s.finishedSubpaths) {\n const path = subpathToPath(sp, view);\n if (path === null) continue;\n out.push({\n kind: 'path',\n path,\n stroke: { paint: { kind: 'solid', color: style.finishedSubpathStroke }, width: 1 },\n });\n }\n\n const cur = s.current;\n if (!cur && s.cursor === null) return out;\n\n // (2) Current subpath — bright outline.\n if (cur) {\n const path = subpathToPath(cur, view);\n if (path !== null) {\n out.push({\n kind: 'path',\n path,\n stroke: { paint: { kind: 'solid', color: style.rubberBandStroke }, width: 1 },\n });\n }\n }\n\n // (3) Rubber-band from latest anchor to cursor.\n if (cur && cur.anchors.length > 0 && s.cursor && s.draggingHandleAt === null) {\n const last = cur.anchors[cur.anchors.length - 1];\n const out2 = last.outHandle;\n const [sx, sy] = w2s(last.x, last.y, view);\n const [cx, cy] = w2s(s.cursor.x, s.cursor.y, view);\n let path: PolygonPath;\n if (out2) {\n const [c1x, c1y] = w2s(out2.x, out2.y, view);\n path = {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_C]),\n coords: new Float32Array([sx, sy, c1x, c1y, cx, cy, cx, cy]),\n fillRule: 'nonzero',\n };\n } else {\n path = {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_L]),\n coords: new Float32Array([sx, sy, cx, cy]),\n fillRule: 'nonzero',\n };\n }\n out.push({\n kind: 'path',\n path,\n stroke: { paint: { kind: 'solid', color: style.rubberBandStroke }, width: 1 },\n });\n }\n\n // (4) Anchor dots + handles.\n if (cur) {\n for (let i = 0; i < cur.anchors.length; i++) {\n const a = cur.anchors[i];\n const [ax, ay] = w2s(a.x, a.y, view);\n out.push({\n kind: 'path',\n path: approximateCircle(ax, ay, r.anchor),\n fill: { paint: { kind: 'solid', color: style.anchorFill } },\n stroke: { paint: { kind: 'solid', color: style.anchorStroke }, width: 1 },\n });\n // Handle line + dot (only the latest anchor, per spec).\n if (i === cur.anchors.length - 1 && a.outHandle) {\n const [hx, hy] = w2s(a.outHandle.x, a.outHandle.y, view);\n const linePath: PolygonPath = {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_L]),\n coords: new Float32Array([ax, ay, hx, hy]),\n fillRule: 'nonzero',\n };\n out.push({\n kind: 'path',\n path: linePath,\n stroke: { paint: { kind: 'solid', color: style.handleStroke }, width: 1 },\n });\n out.push({\n kind: 'path',\n path: approximateCircle(hx, hy, r.handleDot),\n fill: { paint: { kind: 'solid', color: style.handleStroke } },\n });\n const inSide = a.inHandle;\n if (inSide) {\n const [mx, my] = w2s(inSide.x, inSide.y, view);\n const inLine: PolygonPath = {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_L]),\n coords: new Float32Array([ax, ay, mx, my]),\n fillRule: 'nonzero',\n };\n out.push({\n kind: 'path',\n path: inLine,\n stroke: { paint: { kind: 'solid', color: style.handleStroke }, width: 1 },\n });\n out.push({\n kind: 'path',\n path: approximateCircle(mx, my, r.handleDot),\n fill: { paint: { kind: 'solid', color: style.handleStroke } },\n });\n }\n }\n }\n\n // (5) Close-hint ring on first anchor.\n if (s.closeHintActive && cur.anchors.length >= 3) {\n const first = cur.anchors[0];\n const [fx, fy] = w2s(first.x, first.y, view);\n out.push({\n kind: 'path',\n path: approximateCircle(fx, fy, r.closeHint),\n stroke: { paint: { kind: 'solid', color: style.closeHintFill }, width: 1.5 },\n });\n }\n }\n\n return out;\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"penPreviewLayer.js","names":[],"sources":["../../../src/domains/paths/penPreviewLayer.ts"],"sourcesContent":["/**\n * Screen-space preview layer for `usePenTool`. Reads the pen's state each\n * frame and renders the in-progress path: finished\n * subpaths (faded), the current subpath (bright + anchor dots + handles),\n * a rubber-band segment from the latest anchor to the cursor, and a\n * close-hint ring on the first anchor when the tool flags it as hot.\n *\n * Runs in screen space so anchor/handle sizes stay constant under zoom.\n * All world-space coords go through `viewWorldToScreen` with the layer's `view`\n * argument.\n */\n\nimport type { DrawCommand } from '@weasel-js/renderer';\nimport type { RenderLayer } from 'core/layers/render';\nimport type { KitSettingsStore } from '@weasel-js/react';\nimport type { PenScratch, PenAnchor, PenSubpath } from 'tools/builtin/pen';\nimport { PATH_C, PATH_L, PATH_M, type PolygonPath, anchorsToPath, circlePath, viewWorldToScreen } from '@weasel-js/geom';\n\n/** Appearance of the pen tool's in-progress path. */\nexport interface PenPreviewStyle {\n anchorFill?: string;\n anchorStroke?: string;\n handleStroke?: string;\n rubberBandStroke?: string;\n closeHintFill?: string;\n finishedSubpathStroke?: string;\n}\n\n/** Options for `createPenPreviewLayer`. */\nexport interface CreatePenPreviewLayerOptions {\n /** The pen's state. One object for the pen's life, changed in place, so\n * the layer reads the same one on every frame. */\n state: PenScratch;\n style?: PenPreviewStyle;\n /** The kit settings whose `targets.pen*RadiusPx` size the dots, read each frame. */\n kitSettings?: () => KitSettingsStore;\n}\n\nconst DEFAULT_STYLE: Required<PenPreviewStyle> = {\n anchorFill: '#d4c4a8',\n anchorStroke: '#d4c4a8',\n handleStroke: '#d4c4a8',\n rubberBandStroke: '#d4c4a8',\n closeHintFill: '#d4c4a8',\n finishedSubpathStroke: '#8a7a5e',\n};\n\nexport const ANCHOR_RADIUS_PX = 4;\nexport const HANDLE_DOT_RADIUS_PX = 3;\nexport const CLOSE_HINT_RADIUS_PX = 8;\n\n/** How near the pen's first anchor, in screen px, a click closes the subpath. */\nexport const PEN_CLOSE_HIT_PX = 8;\n\n/** The pen's reach in screen px: its own option, else the kit setting, else the constant. */\nexport const penReachOf = (o: { closeHitRadius?: number; kitSettings?: KitSettingsStore }) => ({\n close: o.closeHitRadius ?? o.kitSettings?.get('targets.penCloseHitPx') ?? PEN_CLOSE_HIT_PX,\n});\n\nconst radiiOf = (kit: KitSettingsStore | undefined) => ({\n anchor: kit?.get('targets.penAnchorRadiusPx') ?? ANCHOR_RADIUS_PX,\n handleDot: kit?.get('targets.penHandleDotRadiusPx') ?? HANDLE_DOT_RADIUS_PX,\n closeHint: kit?.get('targets.penCloseHintRadiusPx') ?? CLOSE_HINT_RADIUS_PX,\n});\n\n// approximateCircle has moved to `./markers.ts` as `circlePath`. Re-exported\n// locally so we don't rename callers in this file.\nfunction approximateCircle(cx: number, cy: number, r: number): PolygonPath {\n return circlePath(cx, cy, r);\n}\n\n/** A pen subpath as a screen-space `PolygonPath`, segmented by the same rule\n * the pen commits with. */\nfunction subpathToPath(\n sp: PenSubpath,\n view: { x: number; y: number; scale: { x: number; y: number } },\n): PolygonPath | null {\n if (sp.anchors.length === 0) return null;\n const pt = (p: { x: number; y: number }) => {\n const { x: x, y: y } = viewWorldToScreen(view, p);\n return { x, y };\n };\n const anchors = sp.anchors.map((a: PenAnchor) => ({\n ...pt(a),\n ...(a.inHandle ? { inHandle: pt(a.inHandle) } : {}),\n ...(a.outHandle ? { outHandle: pt(a.outHandle) } : {}),\n }));\n return anchorsToPath([anchors], [sp.closed]);\n}\n\n/** Render layer that draws the pen tool's path as it is being placed —\n * committed anchors, the rubber band to the cursor, and the close hint. Draws\n * nothing when the pen is idle. */\nexport function createPenPreviewLayer(\n opts: CreatePenPreviewLayerOptions,\n): RenderLayer<unknown> {\n const style = { ...DEFAULT_STYLE, ...(opts.style ?? {}) };\n const s = opts.state;\n\n return {\n id: 'penPreview',\n label: 'Pen preview',\n space: 'screen',\n draw: (_data, view) => {\n const out: DrawCommand[] = [];\n const r = radiiOf(opts.kitSettings?.());\n // (1) Finished subpaths — faded outline.\n for (const sp of s.finishedSubpaths) {\n const path = subpathToPath(sp, view);\n if (path === null) continue;\n out.push({\n kind: 'path',\n path,\n stroke: { paint: { kind: 'solid', color: style.finishedSubpathStroke }, width: 1 },\n });\n }\n\n const cur = s.current;\n if (!cur && s.cursor === null) return out;\n\n // (2) Current subpath — bright outline.\n if (cur) {\n const path = subpathToPath(cur, view);\n if (path !== null) {\n out.push({\n kind: 'path',\n path,\n stroke: { paint: { kind: 'solid', color: style.rubberBandStroke }, width: 1 },\n });\n }\n }\n\n // (3) Rubber-band from latest anchor to cursor.\n if (cur && cur.anchors.length > 0 && s.cursor && s.draggingHandleAt === null) {\n const last = cur.anchors[cur.anchors.length - 1];\n const out2 = last.outHandle;\n const { x: sx, y: sy } = viewWorldToScreen(view, last);\n const { x: cx, y: cy } = viewWorldToScreen(view, s.cursor);\n let path: PolygonPath;\n if (out2) {\n const { x: c1x, y: c1y } = viewWorldToScreen(view, out2);\n path = {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_C]),\n coords: new Float32Array([sx, sy, c1x, c1y, cx, cy, cx, cy]),\n fillRule: 'nonzero',\n };\n } else {\n path = {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_L]),\n coords: new Float32Array([sx, sy, cx, cy]),\n fillRule: 'nonzero',\n };\n }\n out.push({\n kind: 'path',\n path,\n stroke: { paint: { kind: 'solid', color: style.rubberBandStroke }, width: 1 },\n });\n }\n\n // (4) Anchor dots + handles.\n if (cur) {\n for (let i = 0; i < cur.anchors.length; i++) {\n const a = cur.anchors[i];\n const { x: ax, y: ay } = viewWorldToScreen(view, a);\n out.push({\n kind: 'path',\n path: approximateCircle(ax, ay, r.anchor),\n fill: { paint: { kind: 'solid', color: style.anchorFill } },\n stroke: { paint: { kind: 'solid', color: style.anchorStroke }, width: 1 },\n });\n // Handle line + dot (only the latest anchor, per spec).\n if (i === cur.anchors.length - 1 && a.outHandle) {\n const { x: hx, y: hy } = viewWorldToScreen(view, a.outHandle);\n const linePath: PolygonPath = {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_L]),\n coords: new Float32Array([ax, ay, hx, hy]),\n fillRule: 'nonzero',\n };\n out.push({\n kind: 'path',\n path: linePath,\n stroke: { paint: { kind: 'solid', color: style.handleStroke }, width: 1 },\n });\n out.push({\n kind: 'path',\n path: approximateCircle(hx, hy, r.handleDot),\n fill: { paint: { kind: 'solid', color: style.handleStroke } },\n });\n const inSide = a.inHandle;\n if (inSide) {\n const { x: mx, y: my } = viewWorldToScreen(view, inSide);\n const inLine: PolygonPath = {\n kind: 'polygon',\n commands: new Uint8Array([PATH_M, PATH_L]),\n coords: new Float32Array([ax, ay, mx, my]),\n fillRule: 'nonzero',\n };\n out.push({\n kind: 'path',\n path: inLine,\n stroke: { paint: { kind: 'solid', color: style.handleStroke }, width: 1 },\n });\n out.push({\n kind: 'path',\n path: approximateCircle(mx, my, r.handleDot),\n fill: { paint: { kind: 'solid', color: style.handleStroke } },\n });\n }\n }\n }\n\n // (5) Close-hint ring on first anchor.\n if (s.closeHintActive && cur.anchors.length >= 3) {\n const first = cur.anchors[0];\n const { x: fx, y: fy } = viewWorldToScreen(view, first);\n out.push({\n kind: 'path',\n path: approximateCircle(fx, fy, r.closeHint),\n stroke: { paint: { kind: 'solid', color: style.closeHintFill }, width: 1.5 },\n });\n }\n }\n\n return out;\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { boundsOfPath, boxToBox, originOf, poseFrameOf, regularPolygonPath, starPath, transformPath, worldCoords, worldEditToStorage } from "@weasel-js/geom";
|
|
1
|
+
import { boundsOfPath, boxToBox, clamp, originOf, poseFrameOf, regularPolygonPath, starPath, transformPath, worldCoords, worldEditToStorage } from "@weasel-js/geom";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// src/domains/paths/shapeGenerator.ts
|
|
4
4
|
/**
|
|
5
5
|
* The parameters a polygon or star was drawn with, kept on the node beside the
|
|
6
6
|
* geometry they made (`data.generator` beside `data.path`), so the shape stays
|
|
@@ -37,7 +37,6 @@ function shapeGeneratorOf(data) {
|
|
|
37
37
|
const g = data?.generator;
|
|
38
38
|
return isShapeGenerator(g) ? g : null;
|
|
39
39
|
}
|
|
40
|
-
var clamp = (v, lo, hi) => Math.min(hi, Math.max(lo, v));
|
|
41
40
|
var count = (v) => clamp(Math.round(v), SHAPE_COUNT_RANGE.min, SHAPE_COUNT_RANGE.max);
|
|
42
41
|
/** `g` with its counts rounded and every field held in range. */
|
|
43
42
|
function clampShapeGenerator(g) {
|
|
@@ -138,6 +137,5 @@ function settleShapeGenerator(next, prev) {
|
|
|
138
137
|
};
|
|
139
138
|
}
|
|
140
139
|
|
|
141
|
-
//#endregion
|
|
142
140
|
export { SHAPE_COUNT_RANGE, STAR_RATIO_RANGE, clampShapeGenerator, isShapeGenerator, regenerateShape, settleShapeGenerator, shapeGeneratorOf, shapeGeneratorPath, withoutShapeGenerator };
|
|
143
141
|
//# sourceMappingURL=shapeGenerator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shapeGenerator.js","names":[],"sources":["../../../src/domains/paths/shapeGenerator.ts"],"sourcesContent":["/**\n * The parameters a polygon or star was drawn with, kept on the node beside the\n * geometry they made (`data.generator` beside `data.path`), so the shape stays\n * editable as a polygon or a star after it is drawn.\n *\n * `data.path` stays the geometry every reader uses; the generator only says how\n * to make it again. Editing the path itself turns the shape into plain\n * geometry: the generator is dropped, since it could no longer reproduce what\n * is drawn. A generator whose path no longer matches it (a writer that changed\n * the path without dropping it) is treated the same way.\n */\nimport {\n boundsOfPath,\n boxToBox,\n poseFrameOf,\n regularPolygonPath,\n starPath,\n transformPath,\n originOf,\n worldCoords,\n worldEditToStorage,\n type PathInWorldPose,\n type PolygonPath,\n} from '@weasel-js/geom';\n\n/** A regular polygon's parameters. `rotation` is the angle of its first\n * vertex, in radians, inside the pose's own rotation. */\nexport interface PolygonGenerator {\n kind: 'polygon';\n sides: number;\n rotation: number;\n}\n\n/** A star's parameters. `innerRadiusRatio` is the inner radius over the outer\n * one; `rotation` is the angle of its first point, in radians, inside the\n * pose's own rotation. */\nexport interface StarGenerator {\n kind: 'star';\n points: number;\n innerRadiusRatio: number;\n rotation: number;\n}\n\n/** The parameters a node's `data.path` was generated from. */\nexport type ShapeGenerator = PolygonGenerator | StarGenerator;\n\n/** The range of a polygon's side count and a star's point count. */\nexport const SHAPE_COUNT_RANGE = { min: 3, max: 32 } as const;\n\n/** The range of a star's `innerRadiusRatio`. */\nexport const STAR_RATIO_RANGE = { min: 0.01, max: 1 } as const;\n\nconst finite = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);\n\n/** Whether `v` is a well-formed {@link ShapeGenerator}. */\nexport function isShapeGenerator(v: unknown): v is ShapeGenerator {\n if (v === null || typeof v !== 'object') return false;\n const g = v as Record<string, unknown>;\n if (!finite(g.rotation)) return false;\n if (g.kind === 'polygon') return finite(g.sides);\n if (g.kind === 'star') return finite(g.points) && finite(g.innerRadiusRatio);\n return false;\n}\n\n/** The generator a node's `data` holds, or `null`. */\nexport function shapeGeneratorOf(data: unknown): ShapeGenerator | null {\n const g = (data as { generator?: unknown } | null | undefined)?.generator;\n return isShapeGenerator(g) ? g : null;\n}\n\nconst clamp = (v: number, lo: number, hi: number): number => Math.min(hi, Math.max(lo, v));\nconst count = (v: number): number => clamp(Math.round(v), SHAPE_COUNT_RANGE.min, SHAPE_COUNT_RANGE.max);\n\n/** `g` with its counts rounded and every field held in range. */\nexport function clampShapeGenerator(g: ShapeGenerator): ShapeGenerator {\n if (g.kind === 'polygon') return { kind: 'polygon', sides: count(g.sides), rotation: g.rotation };\n return {\n kind: 'star',\n points: count(g.points),\n innerRadiusRatio: clamp(g.innerRadiusRatio, STAR_RATIO_RANGE.min, STAR_RATIO_RANGE.max),\n rotation: g.rotation,\n };\n}\n\n/** The shape `g` makes, on a circle of `radius` around `center`. */\nexport function shapeGeneratorPath(\n g: ShapeGenerator,\n center: { x: number; y: number } = { x: 0, y: 0 },\n radius = 1,\n): PolygonPath {\n const c = clampShapeGenerator(g);\n return c.kind === 'polygon'\n ? regularPolygonPath(center, radius, c.sides, c.rotation)\n : starPath(center, radius, c.points, radius * c.innerRadiusRatio, c.rotation);\n}\n\n/** `data` without its generator: the shape as plain geometry. */\nexport function withoutShapeGenerator<T>(data: T): T {\n if (data === null || typeof data !== 'object' || !('generator' in data)) return data;\n const { generator: _dropped, ...rest } = data as Record<string, unknown>;\n void _dropped;\n return rest as T;\n}\n\n/** Whether `path` is what `g` makes, up to the box-to-box map storage applies. */\nfunction pathMatches(path: unknown, g: ShapeGenerator): boolean {\n const p = path as PolygonPath | undefined;\n if (p?.kind !== 'polygon') return false;\n const unit = shapeGeneratorPath(g);\n if (p.coords.length !== unit.coords.length) return false;\n const u = boundsOfPath(unit);\n const b = boundsOfPath(p);\n const m = boxToBox(u.x, u.y, u.width, u.height, b.x, b.y, b.width, b.height);\n // Paths store float32 coordinates, so the slack scales with how far they are from the point they are measured from.\n const o = originOf(p);\n const tol = 1e-4 * Math.max(1, Math.abs(b.x - o.x) + b.width, Math.abs(b.y - o.y) + b.height);\n const at = worldCoords(p);\n for (let i = 0; i + 1 < unit.coords.length; i += 2) {\n const x = m[0] * unit.coords[i] + m[4];\n const y = m[3] * unit.coords[i + 1] + m[5];\n if (Math.abs(x - at[i]) > tol || Math.abs(y - at[i + 1]) > tol) return false;\n }\n return true;\n}\n\n/** A node's two halves, as a regeneration reads and writes them. */\nexport interface GeneratedShape<P extends PathInWorldPose = PathInWorldPose> {\n pose: P;\n data: unknown;\n}\n\n/**\n * `node` made again from `next`, in place: the new shape takes the box the old\n * one's circle had, under the same rotation and transform, so a star given\n * more points keeps its center and its size. Returns `null` when the node holds\n * no generator, or its path no longer matches the one it holds.\n */\nexport function regenerateShape<P extends PathInWorldPose>(\n node: GeneratedShape<P>,\n next: ShapeGenerator,\n): GeneratedShape<P> | null {\n const held = shapeGeneratorOf(node.data);\n if (!held || !pathMatches((node.data as { path?: unknown }).path, held)) return null;\n const g = clampShapeGenerator(next);\n const was = boundsOfPath(shapeGeneratorPath(held));\n const { pose } = node;\n // Where the unit circle of the held generator lands in the pose's local frame.\n const toLocal = boxToBox(was.x, was.y, was.width, was.height, pose.x, pose.y, pose.width, pose.height);\n const local = transformPath(shapeGeneratorPath(g), toLocal) as PolygonPath;\n const frame = poseFrameOf(pose);\n const world = frame ? (transformPath(local, frame) as PolygonPath) : local;\n const stored = worldEditToStorage(pose, world);\n return { pose: stored.pose, data: { ...(node.data as object), path: stored.path, generator: g } };\n}\n\n/**\n * What a write that left a node as `next`, from `prev`, stores: when the write\n * changed the generator, the shape made again from it. A generator written\n * onto a node that held none, or of another kind, or onto one whose path no\n * longer matches, is dropped, leaving the shape as plain geometry. Any other\n * write is stored as written. Fits `NodePropertiesEntry.settle`.\n */\nexport function settleShapeGenerator<N extends { pose: unknown; data: unknown }>(next: N, prev: N): N {\n const data = next.data as Record<string, unknown> | null;\n if (data === null || typeof data !== 'object' || !('generator' in data)) return next;\n const raw = data.generator;\n const held = shapeGeneratorOf(prev.data);\n if (held !== null && JSON.stringify(raw) === JSON.stringify(held)) return next;\n const regenerated = held !== null && isShapeGenerator(raw) && raw.kind === held.kind\n ? regenerateShape({ pose: next.pose as PathInWorldPose, data: { ...data, generator: held } }, raw)\n : null;\n return { ...next, ...(regenerated ?? { data: withoutShapeGenerator(next.data) }) };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"shapeGenerator.js","names":[],"sources":["../../../src/domains/paths/shapeGenerator.ts"],"sourcesContent":["/**\n * The parameters a polygon or star was drawn with, kept on the node beside the\n * geometry they made (`data.generator` beside `data.path`), so the shape stays\n * editable as a polygon or a star after it is drawn.\n *\n * `data.path` stays the geometry every reader uses; the generator only says how\n * to make it again. Editing the path itself turns the shape into plain\n * geometry: the generator is dropped, since it could no longer reproduce what\n * is drawn. A generator whose path no longer matches it (a writer that changed\n * the path without dropping it) is treated the same way.\n */\nimport {\n boundsOfPath,\n boxToBox,\n clamp,\n poseFrameOf,\n regularPolygonPath,\n starPath,\n transformPath,\n originOf,\n worldCoords,\n worldEditToStorage,\n type PathInWorldPose,\n type PolygonPath,\n} from '@weasel-js/geom';\n\n/** A regular polygon's parameters. `rotation` is the angle of its first\n * vertex, in radians, inside the pose's own rotation. */\nexport interface PolygonGenerator {\n kind: 'polygon';\n sides: number;\n rotation: number;\n}\n\n/** A star's parameters. `innerRadiusRatio` is the inner radius over the outer\n * one; `rotation` is the angle of its first point, in radians, inside the\n * pose's own rotation. */\nexport interface StarGenerator {\n kind: 'star';\n points: number;\n innerRadiusRatio: number;\n rotation: number;\n}\n\n/** The parameters a node's `data.path` was generated from. */\nexport type ShapeGenerator = PolygonGenerator | StarGenerator;\n\n/** The range of a polygon's side count and a star's point count. */\nexport const SHAPE_COUNT_RANGE = { min: 3, max: 32 } as const;\n\n/** The range of a star's `innerRadiusRatio`. */\nexport const STAR_RATIO_RANGE = { min: 0.01, max: 1 } as const;\n\nconst finite = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);\n\n/** Whether `v` is a well-formed {@link ShapeGenerator}. */\nexport function isShapeGenerator(v: unknown): v is ShapeGenerator {\n if (v === null || typeof v !== 'object') return false;\n const g = v as Record<string, unknown>;\n if (!finite(g.rotation)) return false;\n if (g.kind === 'polygon') return finite(g.sides);\n if (g.kind === 'star') return finite(g.points) && finite(g.innerRadiusRatio);\n return false;\n}\n\n/** The generator a node's `data` holds, or `null`. */\nexport function shapeGeneratorOf(data: unknown): ShapeGenerator | null {\n const g = (data as { generator?: unknown } | null | undefined)?.generator;\n return isShapeGenerator(g) ? g : null;\n}\n\nconst count = (v: number): number => clamp(Math.round(v), SHAPE_COUNT_RANGE.min, SHAPE_COUNT_RANGE.max);\n\n/** `g` with its counts rounded and every field held in range. */\nexport function clampShapeGenerator(g: ShapeGenerator): ShapeGenerator {\n if (g.kind === 'polygon') return { kind: 'polygon', sides: count(g.sides), rotation: g.rotation };\n return {\n kind: 'star',\n points: count(g.points),\n innerRadiusRatio: clamp(g.innerRadiusRatio, STAR_RATIO_RANGE.min, STAR_RATIO_RANGE.max),\n rotation: g.rotation,\n };\n}\n\n/** The shape `g` makes, on a circle of `radius` around `center`. */\nexport function shapeGeneratorPath(\n g: ShapeGenerator,\n center: { x: number; y: number } = { x: 0, y: 0 },\n radius = 1,\n): PolygonPath {\n const c = clampShapeGenerator(g);\n return c.kind === 'polygon'\n ? regularPolygonPath(center, radius, c.sides, c.rotation)\n : starPath(center, radius, c.points, radius * c.innerRadiusRatio, c.rotation);\n}\n\n/** `data` without its generator: the shape as plain geometry. */\nexport function withoutShapeGenerator<T>(data: T): T {\n if (data === null || typeof data !== 'object' || !('generator' in data)) return data;\n const { generator: _dropped, ...rest } = data as Record<string, unknown>;\n void _dropped;\n return rest as T;\n}\n\n/** Whether `path` is what `g` makes, up to the box-to-box map storage applies. */\nfunction pathMatches(path: unknown, g: ShapeGenerator): boolean {\n const p = path as PolygonPath | undefined;\n if (p?.kind !== 'polygon') return false;\n const unit = shapeGeneratorPath(g);\n if (p.coords.length !== unit.coords.length) return false;\n const u = boundsOfPath(unit);\n const b = boundsOfPath(p);\n const m = boxToBox(u.x, u.y, u.width, u.height, b.x, b.y, b.width, b.height);\n // Paths store float32 coordinates, so the slack scales with how far they are from the point they are measured from.\n const o = originOf(p);\n const tol = 1e-4 * Math.max(1, Math.abs(b.x - o.x) + b.width, Math.abs(b.y - o.y) + b.height);\n const at = worldCoords(p);\n for (let i = 0; i + 1 < unit.coords.length; i += 2) {\n const x = m[0] * unit.coords[i] + m[4];\n const y = m[3] * unit.coords[i + 1] + m[5];\n if (Math.abs(x - at[i]) > tol || Math.abs(y - at[i + 1]) > tol) return false;\n }\n return true;\n}\n\n/** A node's two halves, as a regeneration reads and writes them. */\nexport interface GeneratedShape<P extends PathInWorldPose = PathInWorldPose> {\n pose: P;\n data: unknown;\n}\n\n/**\n * `node` made again from `next`, in place: the new shape takes the box the old\n * one's circle had, under the same rotation and transform, so a star given\n * more points keeps its center and its size. Returns `null` when the node holds\n * no generator, or its path no longer matches the one it holds.\n */\nexport function regenerateShape<P extends PathInWorldPose>(\n node: GeneratedShape<P>,\n next: ShapeGenerator,\n): GeneratedShape<P> | null {\n const held = shapeGeneratorOf(node.data);\n if (!held || !pathMatches((node.data as { path?: unknown }).path, held)) return null;\n const g = clampShapeGenerator(next);\n const was = boundsOfPath(shapeGeneratorPath(held));\n const { pose } = node;\n // Where the unit circle of the held generator lands in the pose's local frame.\n const toLocal = boxToBox(was.x, was.y, was.width, was.height, pose.x, pose.y, pose.width, pose.height);\n const local = transformPath(shapeGeneratorPath(g), toLocal) as PolygonPath;\n const frame = poseFrameOf(pose);\n const world = frame ? (transformPath(local, frame) as PolygonPath) : local;\n const stored = worldEditToStorage(pose, world);\n return { pose: stored.pose, data: { ...(node.data as object), path: stored.path, generator: g } };\n}\n\n/**\n * What a write that left a node as `next`, from `prev`, stores: when the write\n * changed the generator, the shape made again from it. A generator written\n * onto a node that held none, or of another kind, or onto one whose path no\n * longer matches, is dropped, leaving the shape as plain geometry. Any other\n * write is stored as written. Fits `NodePropertiesEntry.settle`.\n */\nexport function settleShapeGenerator<N extends { pose: unknown; data: unknown }>(next: N, prev: N): N {\n const data = next.data as Record<string, unknown> | null;\n if (data === null || typeof data !== 'object' || !('generator' in data)) return next;\n const raw = data.generator;\n const held = shapeGeneratorOf(prev.data);\n if (held !== null && JSON.stringify(raw) === JSON.stringify(held)) return next;\n const regenerated = held !== null && isShapeGenerator(raw) && raw.kind === held.kind\n ? regenerateShape({ pose: next.pose as PathInWorldPose, data: { ...data, generator: held } }, raw)\n : null;\n return { ...next, ...(regenerated ?? { data: withoutShapeGenerator(next.data) }) };\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { findShapeSilhouette } from "../../canvas/NodeShape.js";
|
|
2
1
|
import { isSilhouettePose } from "../../core/geometry/regionHit.js";
|
|
2
|
+
import { findShapeSilhouette } from "../../canvas/NodeShape.js";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// src/domains/paths/strokeOutline.ts
|
|
5
5
|
/** The outline `node` is drawn with, in world coords: its pose when the pose
|
|
6
6
|
* is a polygon, else its painter's silhouette. Null for a node with neither. */
|
|
7
7
|
function nodeOutline(node) {
|
|
@@ -10,6 +10,5 @@ function nodeOutline(node) {
|
|
|
10
10
|
return findShapeSilhouette(node, pose);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
//#endregion
|
|
14
13
|
export { nodeOutline };
|
|
15
14
|
//# sourceMappingURL=strokeOutline.js.map
|
|
@@ -2,7 +2,7 @@ import { anchorFieldsOf } from "../../interactions/actions/defaults/anchorFields
|
|
|
2
2
|
import { useMemo, useSyncExternalStore } from "react";
|
|
3
3
|
import { useActionsRegistry, useOptionalDepRegistry } from "@weasel-js/routing/react";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// src/domains/paths/useAnchorFields.ts
|
|
6
6
|
/**
|
|
7
7
|
* The anchor fields of the path being edited, for chrome beside the canvas:
|
|
8
8
|
* a panel showing the selected anchors' numbers and writing typed ones back.
|
|
@@ -30,6 +30,5 @@ function useAnchorFields() {
|
|
|
30
30
|
}), [json, actions]);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
//#endregion
|
|
34
33
|
export { useAnchorFields };
|
|
35
34
|
//# sourceMappingURL=useAnchorFields.js.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { rectFromPlane } from "../../core/viewport/parallax.js";
|
|
2
2
|
import { liveAnchorMarkers, liveEditablePath } from "./editablePath.js";
|
|
3
|
-
import { createPathEditState } from "./pathEditState.js";
|
|
4
3
|
import { createPathEditingOverlayLayer } from "./pathEditingOverlayLayer.js";
|
|
4
|
+
import { createPathEditState } from "./pathEditState.js";
|
|
5
5
|
import { useEffect, useMemo, useState } from "react";
|
|
6
6
|
import { useLatest } from "@weasel-js/react";
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
// src/domains/paths/usePathEdit.ts
|
|
9
9
|
/**
|
|
10
10
|
* The path-edit state and its anchor overlay for one canvas surface.
|
|
11
11
|
*/
|
|
@@ -59,6 +59,5 @@ function usePathEditOverlayLayer(state, inputs, config) {
|
|
|
59
59
|
]);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
//#endregion
|
|
63
62
|
export { usePathEditOverlayLayer, usePathEditState };
|
|
64
63
|
//# sourceMappingURL=usePathEdit.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useCallback, useEffect, useMemo, useRef } from "react";
|
|
2
2
|
import { useLatest, useVisibleRaf } from "@weasel-js/react";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// src/domains/poseRun/usePoseRun.ts
|
|
5
5
|
/**
|
|
6
6
|
* A pose run: poses published per frame, committed once.
|
|
7
7
|
*
|
|
@@ -124,6 +124,5 @@ function usePoseRun(opts) {
|
|
|
124
124
|
}), [loop]);
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
//#endregion
|
|
128
127
|
export { usePoseRun };
|
|
129
128
|
//# sourceMappingURL=usePoseRun.js.map
|
|
@@ -5,7 +5,7 @@ import { enteredOperandOutlines } from "./enteredOperands.js";
|
|
|
5
5
|
import { transformPath } from "@weasel-js/geom";
|
|
6
6
|
import { useMemo } from "react";
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
// src/domains/selection/enteredGroupFrame.ts
|
|
9
9
|
/** The theme token the frame reads its color from, set on the canvas or any element above it. */
|
|
10
10
|
var ENTERED_FRAME_TOKEN = "--wzl-entered-group";
|
|
11
11
|
/** The frame's color where nothing sets {@link ENTERED_FRAME_TOKEN}. */
|
|
@@ -99,6 +99,5 @@ function useEnteredGroupFrameLayer(entered, boundsOf, color, scene) {
|
|
|
99
99
|
]);
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
//#endregion
|
|
103
102
|
export { ENTERED_FRAME_COLOR, ENTERED_FRAME_TOKEN, createEnteredGroupFrameLayer, useEnteredGroupFrameLayer };
|
|
104
103
|
//# sourceMappingURL=enteredGroupFrame.js.map
|
|
@@ -2,7 +2,7 @@ import { reachableInGroup } from "../../canvas/deps/enteredGroup.js";
|
|
|
2
2
|
import { createEmitter } from "@weasel-js/registry";
|
|
3
3
|
import { OUT_OF_SCOPE_ALPHA } from "@weasel-js/modes";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// src/domains/selection/enteredGroupScope.ts
|
|
6
6
|
/**
|
|
7
7
|
* The entered group as a scope: everything outside its subtree dims and stops taking hits, and
|
|
8
8
|
* so does the group itself, whose empty box is empty canvas while it is entered. With nothing
|
|
@@ -39,6 +39,5 @@ function createEnteredGroupScope(opts) {
|
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
//#endregion
|
|
43
42
|
export { createEnteredGroupScope };
|
|
44
43
|
//# sourceMappingURL=enteredGroupScope.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { operandOf } from "../../core/scene/booleanOfChildren.js";
|
|
2
2
|
import { sceneDepLookup } from "../../canvas/derivedPath.js";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// src/domains/selection/enteredOperands.ts
|
|
5
5
|
/** The world outline of each shown node under the outermost node at or above `entered` that
|
|
6
6
|
* consumes its children, a group's members each on their own; none when no such node is. */
|
|
7
7
|
function enteredOperandOutlines(scene, entered) {
|
|
@@ -24,6 +24,5 @@ function enteredOperandOutlines(scene, entered) {
|
|
|
24
24
|
return out;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
//#endregion
|
|
28
27
|
export { enteredOperandOutlines };
|
|
29
28
|
//# sourceMappingURL=enteredOperands.js.map
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
+
import { angleOf, localToWorld, targetTransformOf } from "../../core/geometry/targetFrame.js";
|
|
1
2
|
import { viewToTransform } from "../../core/viewport/view.js";
|
|
2
3
|
import { worldToScreen } from "../../core/viewport/viewTransform.js";
|
|
3
4
|
import { HANDLE_BASE_PX } from "../../core/device/targets.js";
|
|
4
|
-
import { angleOf, localToWorld, targetTransformOf } from "../../core/geometry/targetFrame.js";
|
|
5
5
|
import { handlePoint, resizeHandlesFor } from "../../interactions/actions/resize/cornerHandles.js";
|
|
6
6
|
import { screenAngleOf } from "@weasel-js/geom";
|
|
7
7
|
import { alignedStrokeRect } from "@weasel-js/paint";
|
|
8
8
|
import { resolveStrokeWidth } from "@weasel-js/stroke";
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
// src/domains/selection/handleCommands.ts
|
|
11
11
|
var DEFAULT_HANDLE_FILL = { paint: {
|
|
12
12
|
kind: "solid",
|
|
13
13
|
color: "#d4c4a8"
|
|
@@ -111,6 +111,5 @@ function handleCommandsFor(ids, resolveBounds, handles, handlesOf, layoutOpts, v
|
|
|
111
111
|
return out;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
//#endregion
|
|
115
114
|
export { handleCommandsFor, rectPathFor, resolveHandles };
|
|
116
115
|
//# sourceMappingURL=handleCommands.js.map
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { viewToTransform } from "../../core/viewport/view.js";
|
|
2
|
-
import { worldToScreen } from "../../core/viewport/viewTransform.js";
|
|
3
|
-
import { AUTO_POSE_DESCRIPTOR } from "../../core/geometry/autoPoseDescriptor.js";
|
|
4
|
-
import { targetCorners, targetTransformOf } from "../../core/geometry/targetFrame.js";
|
|
5
|
-
import { MULTI_RESIZE_TARGET_ID } from "../../core/selection/selectionTarget.js";
|
|
6
1
|
import { composeSelectionPose, containerAwareBoundsResolver } from "./selectionPose.js";
|
|
2
|
+
import { targetCorners, targetTransformOf } from "../../core/geometry/targetFrame.js";
|
|
3
|
+
import { AUTO_POSE_DESCRIPTOR } from "../../core/geometry/autoPoseDescriptor.js";
|
|
7
4
|
import { DEFAULT_ROTATION_HANDLE_DISTANCE, rotationHandle } from "../../interactions/actions/rotate/handle.js";
|
|
5
|
+
import { MULTI_RESIZE_TARGET_ID } from "../../core/selection/selectionTarget.js";
|
|
6
|
+
import { viewToTransform } from "../../core/viewport/view.js";
|
|
7
|
+
import { worldToScreen } from "../../core/viewport/viewTransform.js";
|
|
8
8
|
import { handleCommandsFor, rectPathFor, resolveHandles } from "./handleCommands.js";
|
|
9
9
|
import { mat3 } from "@weasel-js/renderer";
|
|
10
10
|
import { PATH_L, PATH_M, PATH_Z } from "@weasel-js/geom";
|
|
11
11
|
import { alignedStrokeRect } from "@weasel-js/paint";
|
|
12
12
|
import { resolveStrokeWidth } from "@weasel-js/stroke";
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
// src/domains/selection/overlay.ts
|
|
15
15
|
/** Project world AABB into screen-space AABB using the active view. */
|
|
16
16
|
function projectBounds(b, view) {
|
|
17
17
|
const t = viewToTransform(view);
|
|
@@ -389,6 +389,5 @@ function asChromeState(data) {
|
|
|
389
389
|
return null;
|
|
390
390
|
}
|
|
391
391
|
|
|
392
|
-
//#endregion
|
|
393
392
|
export { composeSelectionPose, createSelectionHandlesLayer, createSelectionOutlineLayer, createSelectionOverlayLayer, rotationBadgeOf };
|
|
394
393
|
//# sourceMappingURL=overlay.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { drawnAABBOf, drawnBoundsOf } from "../../canvas/drawnBounds.js";
|
|
1
2
|
import { unionAABB } from "../../core/geometry/unionBounds.js";
|
|
2
3
|
import { framedBounds, visualBoundsViaDescriptor } from "../../core/geometry/poseDescriptor.js";
|
|
3
4
|
import { AUTO_POSE_DESCRIPTOR } from "../../core/geometry/autoPoseDescriptor.js";
|
|
4
|
-
import { drawnAABBOf, drawnBoundsOf } from "../../canvas/drawnBounds.js";
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
// src/domains/selection/selectionPose.ts
|
|
7
7
|
/**
|
|
8
8
|
* Transitive leaf ids under `id`. A childless node is a leaf only if it is not
|
|
9
9
|
* itself a container: an empty container contributes no bounds, and its own
|
|
@@ -107,6 +107,5 @@ function containerAwareBoundsResolver(getPose, d, getChildren, isContainer, scen
|
|
|
107
107
|
};
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
//#endregion
|
|
111
110
|
export { composeSelectionPose, containerAwareBoundsResolver };
|
|
112
111
|
//# sourceMappingURL=selectionPose.js.map
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { distinct, markFromPlane } from "./marks.js";
|
|
2
2
|
import { screenOf } from "./screen.js";
|
|
3
3
|
import { stepAngles } from "./stepAngles.js";
|
|
4
|
+
import { wrapPositive } from "@weasel-js/geom";
|
|
4
5
|
import { resolveSnap } from "@weasel-js/geom/nd";
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
// src/domains/snap/angle2d.ts
|
|
7
8
|
/** A snap session's one-dimensional path: an angle about a pivot, snapped by
|
|
8
9
|
* the same resolver as a point, with reach carried through the radius. */
|
|
9
10
|
var TURN = Math.PI * 2;
|
|
@@ -140,7 +141,7 @@ function rayMarks(inputs, theta) {
|
|
|
140
141
|
x: pivot.x + r * Math.cos(dir),
|
|
141
142
|
y: pivot.y + r * Math.sin(dir)
|
|
142
143
|
};
|
|
143
|
-
const deg = (Math.round(theta * 180 / Math.PI)
|
|
144
|
+
const deg = wrapPositive(Math.round(theta * 180 / Math.PI), 360);
|
|
144
145
|
return [{
|
|
145
146
|
kind: "line",
|
|
146
147
|
from: pivot,
|
|
@@ -153,6 +154,5 @@ function rayMarks(inputs, theta) {
|
|
|
153
154
|
}];
|
|
154
155
|
}
|
|
155
156
|
|
|
156
|
-
//#endregion
|
|
157
157
|
export { angleAt };
|
|
158
158
|
//# sourceMappingURL=angle2d.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"angle2d.js","names":[],"sources":["../../../src/domains/snap/angle2d.ts"],"sourcesContent":["/** A snap session's one-dimensional path: an angle about a pivot, snapped by\n * the same resolver as a point, with reach carried through the radius. */\nimport { resolveSnap, type SnapCandidate } from '@weasel-js/geom/nd';\nimport type { SnapMods } from 'interactions/actions/snapDep';\nimport { distinct, markFromPlane } from './marks';\nimport { screenOf } from './screen';\nimport { stepAngles } from './stepAngles';\nimport type { Session2dInputs } from './session2d';\nimport type { AngleCollect, SnapMark, SnapMarks, SnapSource } from './types';\n\nconst TURN = Math.PI * 2;\nconst PROBE = 'angle';\n/** A press near the pivot turns px reach into a wide angle; it reaches no\n * further than this. */\nconst MAX_REACH_RAD = Math.PI / 6;\n\n/** Where `theta` lands, and what it met. Writes the marks to the store. */\nexport function angleAt(\n inputs: Session2dInputs, sources: readonly SnapSource[], theta: number, mods: SnapMods,\n): { theta: number; marks: readonly SnapMark[] } {\n const { req, store } = inputs;\n // Screen px per radian, or 1 when the gesture gives its reach in radians.\n const scale = req.reachRad !== undefined ? 1 : pressRadiusPx(inputs);\n const reachOf = (s: SnapSource) => req.reachRad\n ?? Math.min(s.reachPx ?? inputs.reachPx, MAX_REACH_RAD * scale);\n const candidates = collectAngles(inputs, sources, theta, mods, reachOf);\n if (candidates.length === 0) {\n store.set([]);\n return { theta, marks: [] };\n }\n const res = resolveSnap({\n probes: [{ id: PROBE, at: [0], role: 'pointer' }],\n input: { at: [0], dirs: [[1]] },\n delta0: [theta],\n candidates,\n // No radius, no reach: only a required angle can win.\n toScreen: ([t]) => [scale > 0 ? t * scale : NaN],\n });\n const out = res.delta[0];\n const marks = distinct(res.satisfied.flatMap((c) => {\n const m = c.mark ?? rayMarks(inputs, out);\n return 'kind' in m ? [m] : m;\n }));\n const plane = req.plane?.() ?? null;\n store.set(plane ? marks.map((m) => markFromPlane(m, plane)) : marks);\n return { theta: out, marks };\n}\n\nfunction collectAngles(\n inputs: Session2dInputs, sources: readonly SnapSource[], theta: number, mods: SnapMods,\n reachOf: (s: SnapSource) => number,\n): SnapCandidate<SnapMarks>[] {\n const { req } = inputs;\n const out: SnapCandidate<SnapMarks>[] = [];\n const c = req.constrain;\n if (mods.constrain && typeof c === 'object' && c.step > 0) {\n for (const at of stepAngles(theta, c.step)) {\n out.push({ probe: PROBE, locus: { at: [at], dirs: [] }, source: 'constrain', order: -1, tier: 'target', reachPx: 0, required: true });\n }\n }\n const theta0 = req.theta0 ?? 0;\n if (mods.hold) {\n const at = theta0 + TURN * Math.round((theta - theta0) / TURN);\n out.push({ probe: PROBE, locus: { at: [at], dirs: [] }, source: 'hold', order: -1, tier: 'target', reachPx: 0, required: true, mark: [] });\n }\n if (mods.suspend) return out;\n const q: AngleCollect = {\n pivot: req.pivot ?? req.press,\n press: req.press,\n theta0,\n theta,\n ids: req.ids ?? [],\n exclude: inputs.exclude ?? req.ids ?? [],\n mods,\n ...(req.also ? { also: req.also } : {}),\n ...(inputs.scene ? { scene: inputs.scene } : {}),\n ...(inputs.rotationOf ? { rotationOf: inputs.rotationOf } : {}),\n };\n // Runs across sources and their yields: an earlier source, then an earlier\n // yield, wins a tie.\n let order = 0;\n sources.forEach((source) => {\n if (!source.angles) return;\n const reachPx = reachOf(source);\n for (const a of source.angles(q)) {\n // The whole turn of the angle nearest `theta`: 0 catches 359°.\n const at = a.angle + TURN * Math.round((theta - a.angle) / TURN);\n out.push({\n probe: PROBE, locus: { at: [at], dirs: [] }, source: source.id, order: order++, tier: source.tier ?? 'target', reachPx,\n ...(a.required ? { required: true } : {}),\n ...(a.mark ? { mark: a.mark } : {}),\n });\n }\n });\n return out;\n}\n\n/** The screen distance from the pivot to the press: what turns reach in px\n * into radians. */\nfunction pressRadiusPx(inputs: Session2dInputs): number {\n const { req } = inputs;\n const pivot = req.pivot ?? req.press;\n const toScreen = screenOf(inputs.view(), req.plane?.() ?? null);\n const [ax, ay] = toScreen([pivot.x, pivot.y]);\n const [bx, by] = toScreen([req.press.x, req.press.y]);\n return Math.hypot(bx - ax, by - ay);\n}\n\n/** A ray from the pivot out to the press radius, along where the pointer\n * lands at `theta`, labeled with `theta` in degrees. */\nfunction rayMarks(inputs: Session2dInputs, theta: number): SnapMark[] {\n const { req } = inputs;\n const pivot = req.pivot ?? req.press;\n const r = Math.hypot(req.press.x - pivot.x, req.press.y - pivot.y);\n const dir = Math.atan2(req.press.y - pivot.y, req.press.x - pivot.x) + theta - (req.theta0 ?? 0);\n const end = { x: pivot.x + r * Math.cos(dir), y: pivot.y + r * Math.sin(dir) };\n const deg = (
|
|
1
|
+
{"version":3,"file":"angle2d.js","names":[],"sources":["../../../src/domains/snap/angle2d.ts"],"sourcesContent":["/** A snap session's one-dimensional path: an angle about a pivot, snapped by\n * the same resolver as a point, with reach carried through the radius. */\nimport { wrapPositive } from '@weasel-js/geom';\nimport { resolveSnap, type SnapCandidate } from '@weasel-js/geom/nd';\nimport type { SnapMods } from 'interactions/actions/snapDep';\nimport { distinct, markFromPlane } from './marks';\nimport { screenOf } from './screen';\nimport { stepAngles } from './stepAngles';\nimport type { Session2dInputs } from './session2d';\nimport type { AngleCollect, SnapMark, SnapMarks, SnapSource } from './types';\n\nconst TURN = Math.PI * 2;\nconst PROBE = 'angle';\n/** A press near the pivot turns px reach into a wide angle; it reaches no\n * further than this. */\nconst MAX_REACH_RAD = Math.PI / 6;\n\n/** Where `theta` lands, and what it met. Writes the marks to the store. */\nexport function angleAt(\n inputs: Session2dInputs, sources: readonly SnapSource[], theta: number, mods: SnapMods,\n): { theta: number; marks: readonly SnapMark[] } {\n const { req, store } = inputs;\n // Screen px per radian, or 1 when the gesture gives its reach in radians.\n const scale = req.reachRad !== undefined ? 1 : pressRadiusPx(inputs);\n const reachOf = (s: SnapSource) => req.reachRad\n ?? Math.min(s.reachPx ?? inputs.reachPx, MAX_REACH_RAD * scale);\n const candidates = collectAngles(inputs, sources, theta, mods, reachOf);\n if (candidates.length === 0) {\n store.set([]);\n return { theta, marks: [] };\n }\n const res = resolveSnap({\n probes: [{ id: PROBE, at: [0], role: 'pointer' }],\n input: { at: [0], dirs: [[1]] },\n delta0: [theta],\n candidates,\n // No radius, no reach: only a required angle can win.\n toScreen: ([t]) => [scale > 0 ? t * scale : NaN],\n });\n const out = res.delta[0];\n const marks = distinct(res.satisfied.flatMap((c) => {\n const m = c.mark ?? rayMarks(inputs, out);\n return 'kind' in m ? [m] : m;\n }));\n const plane = req.plane?.() ?? null;\n store.set(plane ? marks.map((m) => markFromPlane(m, plane)) : marks);\n return { theta: out, marks };\n}\n\nfunction collectAngles(\n inputs: Session2dInputs, sources: readonly SnapSource[], theta: number, mods: SnapMods,\n reachOf: (s: SnapSource) => number,\n): SnapCandidate<SnapMarks>[] {\n const { req } = inputs;\n const out: SnapCandidate<SnapMarks>[] = [];\n const c = req.constrain;\n if (mods.constrain && typeof c === 'object' && c.step > 0) {\n for (const at of stepAngles(theta, c.step)) {\n out.push({ probe: PROBE, locus: { at: [at], dirs: [] }, source: 'constrain', order: -1, tier: 'target', reachPx: 0, required: true });\n }\n }\n const theta0 = req.theta0 ?? 0;\n if (mods.hold) {\n const at = theta0 + TURN * Math.round((theta - theta0) / TURN);\n out.push({ probe: PROBE, locus: { at: [at], dirs: [] }, source: 'hold', order: -1, tier: 'target', reachPx: 0, required: true, mark: [] });\n }\n if (mods.suspend) return out;\n const q: AngleCollect = {\n pivot: req.pivot ?? req.press,\n press: req.press,\n theta0,\n theta,\n ids: req.ids ?? [],\n exclude: inputs.exclude ?? req.ids ?? [],\n mods,\n ...(req.also ? { also: req.also } : {}),\n ...(inputs.scene ? { scene: inputs.scene } : {}),\n ...(inputs.rotationOf ? { rotationOf: inputs.rotationOf } : {}),\n };\n // Runs across sources and their yields: an earlier source, then an earlier\n // yield, wins a tie.\n let order = 0;\n sources.forEach((source) => {\n if (!source.angles) return;\n const reachPx = reachOf(source);\n for (const a of source.angles(q)) {\n // The whole turn of the angle nearest `theta`: 0 catches 359°.\n const at = a.angle + TURN * Math.round((theta - a.angle) / TURN);\n out.push({\n probe: PROBE, locus: { at: [at], dirs: [] }, source: source.id, order: order++, tier: source.tier ?? 'target', reachPx,\n ...(a.required ? { required: true } : {}),\n ...(a.mark ? { mark: a.mark } : {}),\n });\n }\n });\n return out;\n}\n\n/** The screen distance from the pivot to the press: what turns reach in px\n * into radians. */\nfunction pressRadiusPx(inputs: Session2dInputs): number {\n const { req } = inputs;\n const pivot = req.pivot ?? req.press;\n const toScreen = screenOf(inputs.view(), req.plane?.() ?? null);\n const [ax, ay] = toScreen([pivot.x, pivot.y]);\n const [bx, by] = toScreen([req.press.x, req.press.y]);\n return Math.hypot(bx - ax, by - ay);\n}\n\n/** A ray from the pivot out to the press radius, along where the pointer\n * lands at `theta`, labeled with `theta` in degrees. */\nfunction rayMarks(inputs: Session2dInputs, theta: number): SnapMark[] {\n const { req } = inputs;\n const pivot = req.pivot ?? req.press;\n const r = Math.hypot(req.press.x - pivot.x, req.press.y - pivot.y);\n const dir = Math.atan2(req.press.y - pivot.y, req.press.x - pivot.x) + theta - (req.theta0 ?? 0);\n const end = { x: pivot.x + r * Math.cos(dir), y: pivot.y + r * Math.sin(dir) };\n const deg = wrapPositive(Math.round(theta * 180 / Math.PI), 360);\n return [\n { kind: 'line', from: pivot, to: end },\n { kind: 'point', at: end, glyph: 'quadrant', label: `${deg}°` },\n ];\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { fromPlane } from "../../core/viewport/parallax.js";
|
|
2
2
|
import { closestOnFlat } from "@weasel-js/geom/nd";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// src/domains/snap/debugCandidates.ts
|
|
5
5
|
/** Replaces the sink's snap records with one frame's candidates: where each
|
|
6
6
|
* would put its probe, accepted when the result meets it. Camera world. */
|
|
7
7
|
function recordSnapCandidates(debug, candidates, satisfied, probes, delta0, plane) {
|
|
@@ -22,6 +22,5 @@ function recordSnapCandidates(debug, candidates, satisfied, probes, delta0, plan
|
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
//#endregion
|
|
26
25
|
export { recordSnapCandidates };
|
|
27
26
|
//# sourceMappingURL=debugCandidates.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { distinct } from "./marks.js";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// src/domains/snap/gather.ts
|
|
4
4
|
var DEFAULT_GESTURES = [
|
|
5
5
|
"point",
|
|
6
6
|
"move",
|
|
@@ -74,6 +74,5 @@ function marksOf(mark, delta) {
|
|
|
74
74
|
return "kind" in m ? [m] : m;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
//#endregion
|
|
78
77
|
export { assertSnapSourceIds, gatherSnapCandidates, resolvedSnapMarks, snapSourcesFor };
|
|
79
78
|
//# sourceMappingURL=gather.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { SNAP_AXIS_STEP } from "./roles.js";
|
|
2
1
|
import { diagonal, edgeAxis } from "./resizeBox.js";
|
|
2
|
+
import { SNAP_AXIS_STEP } from "./roles.js";
|
|
3
3
|
import { stepLine } from "@weasel-js/geom/nd";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// src/domains/snap/inputSubspace.ts
|
|
6
6
|
var PLANE = {
|
|
7
7
|
at: [0, 0],
|
|
8
8
|
dirs: [[1, 0], [0, 1]]
|
|
@@ -41,6 +41,5 @@ function inputFlat(req, mods, delta0, resize) {
|
|
|
41
41
|
return stepLine([origin.x - req.press.x, origin.y - req.press.y], [delta0.x, delta0.y], AXES, c.step);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
//#endregion
|
|
45
44
|
export { inputFlat };
|
|
46
45
|
//# sourceMappingURL=inputSubspace.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/domains/snap/lazySession.ts
|
|
2
2
|
/** A session of `dep` that begins on its first `at` or `angle`, so a press
|
|
3
3
|
* that never moves reads nothing of the scene. Null without a dep. */
|
|
4
4
|
function lazySnapSession(dep, req) {
|
|
@@ -12,6 +12,5 @@ function lazySnapSession(dep, req) {
|
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
//#endregion
|
|
16
15
|
export { lazySnapSession };
|
|
17
16
|
//# sourceMappingURL=lazySession.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { fromPlane } from "../../core/viewport/parallax.js";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// src/domains/snap/marks.ts
|
|
4
4
|
/** `marks` with repeats dropped, so a target several probes meet is drawn once. */
|
|
5
5
|
function distinct(marks) {
|
|
6
6
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -24,6 +24,5 @@ function markFromPlane(m, plane) {
|
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
//#endregion
|
|
28
27
|
export { distinct, markFromPlane };
|
|
29
28
|
//# sourceMappingURL=marks.js.map
|
|
@@ -1,25 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
import { createEmitter } from "@weasel-js/registry";
|
|
2
|
+
|
|
3
|
+
// src/domains/snap/outcomeStore.ts
|
|
2
4
|
var NONE = [];
|
|
3
5
|
/** An empty outcome store, which notifies only when the marks change. */
|
|
4
6
|
function createSnapOutcomeStore() {
|
|
5
7
|
let marks = NONE;
|
|
6
|
-
const
|
|
8
|
+
const changed = createEmitter();
|
|
7
9
|
return {
|
|
8
10
|
get: () => marks,
|
|
9
11
|
set(next) {
|
|
10
12
|
if (next.length === 0 && marks.length === 0) return;
|
|
11
13
|
marks = next.length === 0 ? NONE : next;
|
|
12
|
-
|
|
14
|
+
changed.emit();
|
|
13
15
|
},
|
|
14
|
-
subscribe
|
|
15
|
-
listeners.add(listener);
|
|
16
|
-
return () => {
|
|
17
|
-
listeners.delete(listener);
|
|
18
|
-
};
|
|
19
|
-
}
|
|
16
|
+
subscribe: changed.subscribe
|
|
20
17
|
};
|
|
21
18
|
}
|
|
22
19
|
|
|
23
|
-
//#endregion
|
|
24
20
|
export { createSnapOutcomeStore };
|
|
25
21
|
//# sourceMappingURL=outcomeStore.js.map
|