@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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"outcomeStore.js","names":[],"sources":["../../../src/domains/snap/outcomeStore.ts"],"sourcesContent":["import type { SnapMark } from './types';\nimport type { Point } from '@weasel-js/geom';\n\n/** The marks of the snap in flight, for the readout to draw. */\nexport interface SnapOutcomeStore<P = Point> {\n get(): readonly SnapMark<P>[];\n set(marks: readonly SnapMark<P>[]): void;\n subscribe(listener: () => void): () => void;\n}\n\nconst NONE: readonly never[] = [];\n\n/** An empty outcome store, which notifies only when the marks change. */\nexport function createSnapOutcomeStore<P = Point>(): SnapOutcomeStore<P> {\n let marks: readonly SnapMark<P>[] = NONE;\n const
|
|
1
|
+
{"version":3,"file":"outcomeStore.js","names":[],"sources":["../../../src/domains/snap/outcomeStore.ts"],"sourcesContent":["import type { SnapMark } from './types';\nimport type { Point } from '@weasel-js/geom';\nimport { createEmitter } from '@weasel-js/registry';\n\n/** The marks of the snap in flight, for the readout to draw. */\nexport interface SnapOutcomeStore<P = Point> {\n get(): readonly SnapMark<P>[];\n set(marks: readonly SnapMark<P>[]): void;\n subscribe(listener: () => void): () => void;\n}\n\nconst NONE: readonly never[] = [];\n\n/** An empty outcome store, which notifies only when the marks change. */\nexport function createSnapOutcomeStore<P = Point>(): SnapOutcomeStore<P> {\n let marks: readonly SnapMark<P>[] = NONE;\n const changed = createEmitter();\n return {\n get: () => marks,\n set(next) {\n if (next.length === 0 && marks.length === 0) return;\n marks = next.length === 0 ? NONE : next;\n changed.emit();\n },\n subscribe: changed.subscribe,\n };\n}\n"],"mappings":";;;AAWA,IAAM,OAAyB,CAAC;;AAGhC,SAAgB,yBAAyD;CACvE,IAAI,QAAgC;CACpC,MAAM,UAAU,cAAc;CAC9B,OAAO;EACL,WAAW;EACX,IAAI,MAAM;GACR,IAAI,KAAK,WAAW,KAAK,MAAM,WAAW,GAAG;GAC7C,QAAQ,KAAK,WAAW,IAAI,OAAO;GACnC,QAAQ,KAAK;EACf;EACA,WAAW,QAAQ;CACrB;AACF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { inputSession } from "./session2d.js";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// src/domains/snap/pointSnap.ts
|
|
4
4
|
var FREE = {
|
|
5
5
|
suspend: false,
|
|
6
6
|
constrain: false
|
|
@@ -43,6 +43,5 @@ function pointSnap() {
|
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
//#endregion
|
|
47
46
|
export { pointSnap };
|
|
48
47
|
//# sourceMappingURL=pointSnap.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { unionBounds } from "../../core/geometry/unionBounds.js";
|
|
2
2
|
import { resizeProbes, resizeSubject } from "./resizeBox.js";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// src/domains/snap/probes2d.ts
|
|
5
5
|
/** The union drawn box of the subjects, or null when none is left. */
|
|
6
6
|
function subjectBox(ids, reads) {
|
|
7
7
|
const boxes = [];
|
|
@@ -99,6 +99,5 @@ function moveProbes(press, ids, reads, box) {
|
|
|
99
99
|
return out;
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
//#endregion
|
|
103
102
|
export { buildProbes, subjectBox, subjectOf };
|
|
104
103
|
//# sourceMappingURL=probes2d.js.map
|
|
@@ -2,7 +2,7 @@ import { pathSnapGlyph } from "../paths/pathSnap/glyphs.js";
|
|
|
2
2
|
import { textCommand, textCommandFromRuns } from "@weasel-js/renderer";
|
|
3
3
|
import { PATH_L, PATH_M, pathFromD, rectPath } from "@weasel-js/geom";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// src/domains/snap/readoutDraw.ts
|
|
6
6
|
/**
|
|
7
7
|
* The screen-space drawing the snap readout and the guides overlay share:
|
|
8
8
|
* ticked segments, number pills, and the glyph-and-label of a point mark.
|
|
@@ -88,6 +88,5 @@ function glyphCommands(glyph, x, y, label, color, r = 5, fontSize = 11) {
|
|
|
88
88
|
return out;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
//#endregion
|
|
92
91
|
export { glyphCommands, measuredSegmentCommands, pillCommands, tickedSegment };
|
|
93
92
|
//# sourceMappingURL=readoutDraw.js.map
|
|
@@ -2,7 +2,7 @@ import { viewToTransform } from "../../core/viewport/view.js";
|
|
|
2
2
|
import { worldToScreen } from "../../core/viewport/viewTransform.js";
|
|
3
3
|
import { glyphCommands, measuredSegmentCommands } from "./readoutDraw.js";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// src/domains/snap/readoutLayer.ts
|
|
6
6
|
var TICK = 6;
|
|
7
7
|
/** A screen-space layer drawing the marks in `store`, redrawn when they change. */
|
|
8
8
|
function createSnapReadoutLayer(store, style = {}) {
|
|
@@ -44,6 +44,5 @@ function createSnapReadoutLayer(store, style = {}) {
|
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
//#endregion
|
|
48
47
|
export { createSnapReadoutLayer };
|
|
49
48
|
//# sourceMappingURL=readoutLayer.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createContext, useContext, useEffect } from "react";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// src/domains/snap/registry.ts
|
|
4
4
|
function createSnapSourceRegistry() {
|
|
5
5
|
let sources = [];
|
|
6
6
|
return {
|
|
@@ -22,6 +22,5 @@ function useSnapSource(source) {
|
|
|
22
22
|
useEffect(() => registry.add(source), [registry, source]);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
//#endregion
|
|
26
25
|
export { SnapSourceRegistryContext, createSnapSourceRegistry, useSnapSource };
|
|
27
26
|
//# sourceMappingURL=registry.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { fixedCornerOf, movedEdges, movingPoint } from "../../interactions/actions/resize/cornerHandles.js";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// src/domains/snap/resizeBox.ts
|
|
4
4
|
var EPS = 1e-9;
|
|
5
5
|
function resizeSubject(box, handle) {
|
|
6
6
|
const at = box.toWorld ?? ((p) => p);
|
|
@@ -153,6 +153,5 @@ function resizeSides(s, delta) {
|
|
|
153
153
|
return out;
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
//#endregion
|
|
157
156
|
export { EPS, diagonal, edgeAxis, resizeProbes, resizeSides, resizeSubject, resizedBox };
|
|
158
157
|
//# sourceMappingURL=resizeBox.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { roleReader } from "@weasel-js/routing";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// src/domains/snap/roles.ts
|
|
4
4
|
/** The modifier roles a snapping action declares. */
|
|
5
5
|
var SNAP_ROLES = {
|
|
6
6
|
"snap.suspend": {
|
|
@@ -27,6 +27,5 @@ function snapMods(ctx) {
|
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
//#endregion
|
|
31
30
|
export { SNAP_ANGLE_STEP, SNAP_AXIS_STEP, SNAP_ROLES, snapMods };
|
|
32
31
|
//# sourceMappingURL=roles.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/domains/snap/rotationSource.ts
|
|
2
2
|
var QUARTER = Math.PI / 2;
|
|
3
3
|
/**
|
|
4
4
|
* A rotate's angle targets: every quarter turn, and the world rotation of
|
|
@@ -42,6 +42,5 @@ function rotationSnapSource() {
|
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
//#endregion
|
|
46
45
|
export { rotationSnapSource };
|
|
47
46
|
//# sourceMappingURL=rotationSource.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { sceneBoxFrames, scenePoseFrame } from "../../interactions/actions/poseFrame.js";
|
|
2
1
|
import { nodeDescriptors, poseDescriptorOf } from "../../interactions/actions/poseDescriptorDep.js";
|
|
2
|
+
import { sceneBoxFrames, scenePoseFrame } from "../../interactions/actions/poseFrame.js";
|
|
3
3
|
import { AUTO_ORIGIN_PROJECTION } from "../../interactions/gestures/shared/originProjection.js";
|
|
4
4
|
import { applyToPoint, invert } from "@weasel-js/geom";
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
// src/domains/snap/sceneReads.ts
|
|
7
7
|
/** {@link ProbeReads} over a canvas's scene, read when a session begins.
|
|
8
8
|
* `boxes` is the canvas's `drawnBoxes`, which alignment measures with too. */
|
|
9
9
|
function sceneProbeReads(args) {
|
|
@@ -71,6 +71,5 @@ function withSubtrees(scene, ids) {
|
|
|
71
71
|
return [...out];
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
//#endregion
|
|
75
74
|
export { sceneProbeReads, sceneRotations, sceneSnapFrames, withSubtrees };
|
|
76
75
|
//# sourceMappingURL=sceneReads.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { drawnBoxes } from "../../interactions/actions/drawnBoxes.js";
|
|
2
2
|
import { createSnapOutcomeStore } from "./outcomeStore.js";
|
|
3
|
-
import { DEFAULT_SNAP_PX, createSession2d } from "./session2d.js";
|
|
4
3
|
import { buildProbes, subjectOf } from "./probes2d.js";
|
|
5
4
|
import { sceneProbeReads, sceneRotations, sceneSnapFrames, withSubtrees } from "./sceneReads.js";
|
|
5
|
+
import { DEFAULT_SNAP_PX, createSession2d } from "./session2d.js";
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
// src/domains/snap/sceneSession2d.ts
|
|
8
8
|
/** A 2D session whose probes are the subject's, read from the scene at press. */
|
|
9
9
|
function sceneSession2d(i) {
|
|
10
10
|
const reads = sceneProbeReads({
|
|
@@ -79,6 +79,5 @@ function createSnapSession2d(opts) {
|
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
//#endregion
|
|
83
82
|
export { createSnapSession2d, sceneSession2d };
|
|
84
83
|
//# sourceMappingURL=sceneSession2d.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { viewToTransform } from "../../core/viewport/view.js";
|
|
2
|
-
import { fromPlane } from "../../core/viewport/parallax.js";
|
|
3
2
|
import { worldToScreen } from "../../core/viewport/viewTransform.js";
|
|
3
|
+
import { fromPlane } from "../../core/viewport/parallax.js";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// src/domains/snap/screen.ts
|
|
6
6
|
/** A point in the gesture's plane to screen px. */
|
|
7
7
|
function screenOf(view, plane) {
|
|
8
8
|
const t = view ? viewToTransform(view) : null;
|
|
@@ -18,6 +18,5 @@ function screenOf(view, plane) {
|
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
//#endregion
|
|
22
21
|
export { screenOf };
|
|
23
22
|
//# sourceMappingURL=screen.js.map
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { resizeSides, resizeSubject, resizedBox } from "./resizeBox.js";
|
|
2
|
-
import { markFromPlane } from "./marks.js";
|
|
3
|
-
import { screenOf } from "./screen.js";
|
|
4
1
|
import { angleAt } from "./angle2d.js";
|
|
5
2
|
import { inputFlat } from "./inputSubspace.js";
|
|
6
3
|
import { gatherSnapCandidates, resolvedSnapMarks, snapSourcesFor } from "./gather.js";
|
|
7
4
|
import { recordSnapCandidates } from "./debugCandidates.js";
|
|
5
|
+
import { markFromPlane } from "./marks.js";
|
|
8
6
|
import { createSnapOutcomeStore } from "./outcomeStore.js";
|
|
7
|
+
import { resizeSides, resizeSubject, resizedBox } from "./resizeBox.js";
|
|
8
|
+
import { screenOf } from "./screen.js";
|
|
9
9
|
import { closestOnFlat, resolveSnap } from "@weasel-js/geom/nd";
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
// src/domains/snap/session2d.ts
|
|
12
12
|
/** The canvas's reach when neither a source nor the kit settings name one. */
|
|
13
13
|
var DEFAULT_SNAP_PX = 8;
|
|
14
14
|
/** A snap session over a 2D canvas: ctx points are world points. */
|
|
@@ -146,6 +146,5 @@ function inputSession(req) {
|
|
|
146
146
|
});
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
//#endregion
|
|
150
149
|
export { DEFAULT_SNAP_PX, createSession2d, inputSession };
|
|
151
150
|
//# sourceMappingURL=session2d.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { inputSession } from "./session2d.js";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// src/domains/snap/spanSnap.ts
|
|
4
4
|
/**
|
|
5
5
|
* A `point` session for each end of a span. The end's session has the
|
|
6
6
|
* snapped start as its `origin`, so a `constrain` step turns about the start
|
|
@@ -75,6 +75,5 @@ function spanSnap(dep, constrain = () => void 0, common = {}) {
|
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
//#endregion
|
|
79
78
|
export { spanSnap };
|
|
80
79
|
//# sourceMappingURL=spanSnap.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/domains/snap/stepAngles.ts
|
|
2
2
|
/** The multiples of `step` either side of `theta`, and the nearest: the
|
|
3
3
|
* angles an angle step offers a direction at `theta`. Radians. */
|
|
4
4
|
function stepAngles(theta, step) {
|
|
@@ -10,6 +10,5 @@ function stepAngles(theta, step) {
|
|
|
10
10
|
].map((i) => i * step);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
//#endregion
|
|
14
13
|
export { stepAngles };
|
|
15
14
|
//# sourceMappingURL=stepAngles.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defaultDrawOne } from "../../canvas/defaultDrawOne.js";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// src/domains/text/editingDrawOne.ts
|
|
4
4
|
/** `base`, `defaultDrawOne` by default, less the text commands of the node `editingId` names. */
|
|
5
5
|
function drawOneEditing(editingId, base = defaultDrawOne) {
|
|
6
6
|
return (node, pose, view, ctx) => {
|
|
@@ -27,6 +27,5 @@ function withoutText(cmds) {
|
|
|
27
27
|
return out;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
//#endregion
|
|
31
30
|
export { drawOneEditing };
|
|
32
31
|
//# sourceMappingURL=editingDrawOne.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/domains/text/hostTextEditors.ts
|
|
2
2
|
/**
|
|
3
3
|
* The containers of every text editor a host mounted with `useSceneTextEdit`.
|
|
4
4
|
* `<SceneCanvas>`'s own editor stands down for a canvas inside one, so a host
|
|
@@ -19,6 +19,5 @@ function hostTextEditorHolds(el) {
|
|
|
19
19
|
return false;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
//#endregion
|
|
23
22
|
export { hostTextEditorHolds, registerHostTextEditor };
|
|
24
23
|
//# sourceMappingURL=hostTextEditors.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { asNodeId } from "../../core/scene/types.js";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// src/domains/text/sceneTextDrafts.ts
|
|
4
4
|
/**
|
|
5
5
|
* A text edit shown to the scene keystroke by keystroke, for the readers that
|
|
6
6
|
* see a node somewhere besides the overlay: text something derives from, such
|
|
@@ -59,6 +59,5 @@ function sceneTextDrafts(sceneRef, optsRef) {
|
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
//#endregion
|
|
63
62
|
export { editedData, sceneTextDrafts };
|
|
64
63
|
//# sourceMappingURL=sceneTextDrafts.js.map
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
+
import { sceneDerivedPathOf, scenePaintedPoseOf } from "../../canvas/derivedPath.js";
|
|
1
2
|
import { derivedPartsOf } from "../../core/scene/derivedParts.js";
|
|
2
3
|
import { nodesAsShown, shownLookup } from "../../core/scene/nodeAsShown.js";
|
|
3
|
-
import {
|
|
4
|
+
import { effectSourceFor } from "../pathEffects/effectSources.js";
|
|
4
5
|
import { targetTransformOf, worldToLocal } from "../../core/geometry/targetFrame.js";
|
|
5
6
|
import { textBoxOf } from "../../canvas/nodeShapes/textPainter.js";
|
|
6
|
-
import {
|
|
7
|
+
import { AUTO_POSE_DESCRIPTOR } from "../../core/geometry/autoPoseDescriptor.js";
|
|
7
8
|
import { indexedCandidates } from "../../canvas/pickIndex/scenePickIndex.js";
|
|
8
|
-
import { effectSourceFor } from "../pathEffects/effectSources.js";
|
|
9
9
|
import { boundsOfPath, pathContainsPoint } from "@weasel-js/geom";
|
|
10
10
|
import { caretIndexAt, pointInTextPose } from "@weasel-js/text";
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
// src/domains/text/textHitAt.ts
|
|
13
13
|
/**
|
|
14
14
|
* The top-most unlocked text node at world `(cx, cy)`, and the caret there.
|
|
15
15
|
*
|
|
@@ -93,6 +93,5 @@ function onAGlyph(path, x, y) {
|
|
|
93
93
|
});
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
//#endregion
|
|
97
96
|
export { textHitAt };
|
|
98
97
|
//# sourceMappingURL=textHitAt.js.map
|
|
@@ -2,7 +2,18 @@ import { clippedToBox } from "../../canvas/nodeShapes/textPainter.js";
|
|
|
2
2
|
import { textCommandFromPose } from "@weasel-js/renderer";
|
|
3
3
|
import { runsToPlainText } from "@weasel-js/text";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// src/domains/text/textLayer.ts
|
|
6
|
+
/**
|
|
7
|
+
* Text RenderLayer for text that is not in a scene: one `textCommandFromPose`
|
|
8
|
+
* command per item, the same command the `kit:text` node painter emits, so an
|
|
9
|
+
* item lays out — and wraps, or doesn't, per its style — as a node would.
|
|
10
|
+
*
|
|
11
|
+
* The GL renderer uses MSDF text. The resolved style's `fontFamily` must
|
|
12
|
+
* be registered via `registerFont(family, variant, metricsUrl, atlasUrl)`
|
|
13
|
+
* from the renderer module *before* the GL backend dispatches this layer.
|
|
14
|
+
* Unregistered families render with a warning and no glyphs (see
|
|
15
|
+
* `TextDrawCommand`'s contract).
|
|
16
|
+
*/
|
|
6
17
|
/** Build a `RenderLayer` that emits one `TextDrawCommand` per text node. */
|
|
7
18
|
function createTextLayer(opts) {
|
|
8
19
|
const { id = "text", label = "Text", getTexts, getPose, isHidden, clipToBounds = false } = opts;
|
|
@@ -24,6 +35,5 @@ function createTextLayer(opts) {
|
|
|
24
35
|
};
|
|
25
36
|
}
|
|
26
37
|
|
|
27
|
-
//#endregion
|
|
28
38
|
export { createTextLayer };
|
|
29
39
|
//# sourceMappingURL=textLayer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textLayer.js","names":[],"sources":["../../../src/domains/text/textLayer.ts"],"sourcesContent":["/**\n * Text RenderLayer for text that is not in a scene: one `textCommandFromPose`\n * command per item, the same command the `kit:text` node painter emits, so an\n * item lays out — and wraps, or doesn't, per its style — as a node would.\n *\n * The GL renderer uses MSDF text. The resolved style's `fontFamily` must\n * be registered via `registerFont(family, variant, metricsUrl, atlasUrl)`\n * from the renderer module *before* the GL backend dispatches this layer.\n * Unregistered families render with a warning and no glyphs (see\n * `TextDrawCommand`'s contract).\n */\n\nimport { type DrawCommand } from '@weasel-js/renderer';\nimport type { TextPose } from '@weasel-js/text';\n\nimport type { RenderLayer } from 'core/layers/render';\nimport { textCommandFromPose } from '@weasel-js/renderer';\nimport { runsToPlainText } from '@weasel-js/text';\nimport { clippedToBox } from '../../canvas/nodeShapes/textPainter';\n\n\n/** Options for `createTextLayer`. */\nexport interface CreateTextLayerOpts<T> {\n id?: string;\n label?: string;\n getTexts: () => readonly T[];\n getPose: (node: T) => TextPose;\n /** Optional per-node hide hook (e.g., suppress while editing). */\n isHidden?: (node: T) => boolean;\n /** When `true`, each text command is wrapped in a clipped group so any\n * overflow beyond the pose's `(width × height)` is hidden. Default\n * `false` (legacy: text can spill outside the declared bounds). Opt-in\n * so existing consumers who rely on overflow keep working. */\n clipToBounds?: boolean;\n}\n\n/** Build a `RenderLayer` that emits one `TextDrawCommand` per text node. */\nexport function createTextLayer<T>(opts: CreateTextLayerOpts<T>): RenderLayer<unknown> {\n const { id = 'text', label = 'Text', getTexts, getPose, isHidden, clipToBounds = false } = opts;\n return {\n id,\n label,\n draw: (_data, view) => {\n // A world-space layer, so a `{ px }` size in a pose's style resolves\n // against the live camera. Radial in effect — one factor for both axes.\n const scale = (view.scale.x + view.scale.y) / 2;\n const children: DrawCommand[] = [];\n for (const node of getTexts()) {\n if (isHidden?.(node)) continue;\n const pose = getPose(node);\n if (pose.runs && pose.runs.length > 0 && runsToPlainText(pose.runs) !== pose.text) {\n throw new Error(\n `weasel createTextLayer: TextPose invariant violated — ` +\n `runsToPlainText(runs) !== text. Either omit \\`runs\\` or keep it ` +\n `synchronized with \\`text\\`.`,\n );\n }\n const textCmd = textCommandFromPose(pose, scale);\n children.push(clipToBounds ? clippedToBox(textCmd, pose) : textCmd);\n }\n // World-space commands; drawLayers wraps in viewToMat3 automatically.\n return children;\n },\n };\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"textLayer.js","names":[],"sources":["../../../src/domains/text/textLayer.ts"],"sourcesContent":["/**\n * Text RenderLayer for text that is not in a scene: one `textCommandFromPose`\n * command per item, the same command the `kit:text` node painter emits, so an\n * item lays out — and wraps, or doesn't, per its style — as a node would.\n *\n * The GL renderer uses MSDF text. The resolved style's `fontFamily` must\n * be registered via `registerFont(family, variant, metricsUrl, atlasUrl)`\n * from the renderer module *before* the GL backend dispatches this layer.\n * Unregistered families render with a warning and no glyphs (see\n * `TextDrawCommand`'s contract).\n */\n\nimport { type DrawCommand } from '@weasel-js/renderer';\nimport type { TextPose } from '@weasel-js/text';\n\nimport type { RenderLayer } from 'core/layers/render';\nimport { textCommandFromPose } from '@weasel-js/renderer';\nimport { runsToPlainText } from '@weasel-js/text';\nimport { clippedToBox } from '../../canvas/nodeShapes/textPainter';\n\n\n/** Options for `createTextLayer`. */\nexport interface CreateTextLayerOpts<T> {\n id?: string;\n label?: string;\n getTexts: () => readonly T[];\n getPose: (node: T) => TextPose;\n /** Optional per-node hide hook (e.g., suppress while editing). */\n isHidden?: (node: T) => boolean;\n /** When `true`, each text command is wrapped in a clipped group so any\n * overflow beyond the pose's `(width × height)` is hidden. Default\n * `false` (legacy: text can spill outside the declared bounds). Opt-in\n * so existing consumers who rely on overflow keep working. */\n clipToBounds?: boolean;\n}\n\n/** Build a `RenderLayer` that emits one `TextDrawCommand` per text node. */\nexport function createTextLayer<T>(opts: CreateTextLayerOpts<T>): RenderLayer<unknown> {\n const { id = 'text', label = 'Text', getTexts, getPose, isHidden, clipToBounds = false } = opts;\n return {\n id,\n label,\n draw: (_data, view) => {\n // A world-space layer, so a `{ px }` size in a pose's style resolves\n // against the live camera. Radial in effect — one factor for both axes.\n const scale = (view.scale.x + view.scale.y) / 2;\n const children: DrawCommand[] = [];\n for (const node of getTexts()) {\n if (isHidden?.(node)) continue;\n const pose = getPose(node);\n if (pose.runs && pose.runs.length > 0 && runsToPlainText(pose.runs) !== pose.text) {\n throw new Error(\n `weasel createTextLayer: TextPose invariant violated — ` +\n `runsToPlainText(runs) !== text. Either omit \\`runs\\` or keep it ` +\n `synchronized with \\`text\\`.`,\n );\n }\n const textCmd = textCommandFromPose(pose, scale);\n children.push(clipToBounds ? clippedToBox(textCmd, pose) : textCmd);\n }\n // World-space commands; drawLayers wraps in viewToMat3 automatically.\n return children;\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAqCA,SAAgB,gBAAmB,MAAoD;CACrF,MAAM,EAAE,KAAK,QAAQ,QAAQ,QAAQ,UAAU,SAAS,UAAU,eAAe,UAAU;CAC3F,OAAO;EACL;EACA;EACA,OAAO,OAAO,SAAS;GAGrB,MAAM,SAAS,KAAK,MAAM,IAAI,KAAK,MAAM,KAAK;GAC9C,MAAM,WAA0B,CAAC;GACjC,KAAK,MAAM,QAAQ,SAAS,GAAG;IAC7B,IAAI,WAAW,IAAI,GAAG;IACtB,MAAM,OAAO,QAAQ,IAAI;IACzB,IAAI,KAAK,QAAQ,KAAK,KAAK,SAAS,KAAK,gBAAgB,KAAK,IAAI,MAAM,KAAK,MAC3E,MAAM,IAAI,MACR,+IAGF;IAEF,MAAM,UAAU,oBAAoB,MAAM,KAAK;IAC/C,SAAS,KAAK,eAAe,aAAa,SAAS,IAAI,IAAI,OAAO;GACpE;GAEA,OAAO;EACT;CACF;AACF"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { inheritedPaintIn, withInheritedPaint } from "../../core/scene/inheritedPaint.js";
|
|
2
|
-
import { textBoxOf } from "../../canvas/nodeShapes/textPainter.js";
|
|
3
1
|
import { asNodeId } from "../../core/scene/types.js";
|
|
4
2
|
import { scenePaintedPoseOf } from "../../canvas/derivedPath.js";
|
|
5
|
-
import { findMountedCanvas } from "../../canvas/mountedCanvases.js";
|
|
6
3
|
import { drawOneEditing } from "./editingDrawOne.js";
|
|
7
4
|
import { textHitAt } from "./textHitAt.js";
|
|
8
5
|
import { registerHostTextEditor } from "./hostTextEditors.js";
|
|
9
6
|
import { editedData, sceneTextDrafts } from "./sceneTextDrafts.js";
|
|
10
|
-
import {
|
|
7
|
+
import { inheritedPaintIn, withInheritedPaint } from "../../core/scene/inheritedPaint.js";
|
|
8
|
+
import { findMountedCanvas } from "../../canvas/mountedCanvases.js";
|
|
9
|
+
import { textBoxOf } from "../../canvas/nodeShapes/textPainter.js";
|
|
10
|
+
import { poseFrameOf, viewScreenToWorld } from "@weasel-js/geom";
|
|
11
11
|
import { useCallback, useEffect, useMemo, useRef } from "react";
|
|
12
12
|
import { useLatest } from "@weasel-js/react";
|
|
13
13
|
import { clientToCanvas } from "@weasel-js/routing";
|
|
@@ -15,7 +15,7 @@ import { resolveScreenLength } from "@weasel-js/paint";
|
|
|
15
15
|
import { isTextData } from "@weasel-js/text";
|
|
16
16
|
import { useTextEdit } from "@weasel-js/text-dom";
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
// src/domains/text/useSceneTextEdit.ts
|
|
19
19
|
/**
|
|
20
20
|
* `useSceneTextEdit` — scene-aware wrapper around `useTextEdit`: scene
|
|
21
21
|
* lookups for text / style / runs / screen-pose, and
|
|
@@ -132,9 +132,14 @@ function useSceneTextEditor(scene, container, options = {}) {
|
|
|
132
132
|
const [canvasX, canvasY] = clientToCanvas(canvas, e.clientX, e.clientY);
|
|
133
133
|
const root = containerRef.current;
|
|
134
134
|
const view = resolveView(optsRef.current.view) ?? (root ? findMountedCanvas(root, canvas)?.getView() : void 0);
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
135
|
+
const at = view ? viewScreenToWorld(view, {
|
|
136
|
+
x: canvasX,
|
|
137
|
+
y: canvasY
|
|
138
|
+
}) : {
|
|
139
|
+
x: canvasX,
|
|
140
|
+
y: canvasY
|
|
141
|
+
};
|
|
142
|
+
const hit = textHitAt(sceneRef.current, read, at.x, at.y);
|
|
138
143
|
if (!hit) return;
|
|
139
144
|
openedOnRef.current = canvas;
|
|
140
145
|
edit.startEdit(hit.id, { caret: hit.caret });
|
|
@@ -232,6 +237,5 @@ function shownTextPaint(scene, node) {
|
|
|
232
237
|
};
|
|
233
238
|
}
|
|
234
239
|
|
|
235
|
-
//#endregion
|
|
236
240
|
export { useSceneTextEdit, useSceneTextEditor };
|
|
237
241
|
//# sourceMappingURL=useSceneTextEdit.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSceneTextEdit.js","names":[],"sources":["../../../src/domains/text/useSceneTextEdit.ts"],"sourcesContent":["/**\n * `useSceneTextEdit` — scene-aware wrapper around `useTextEdit`: scene\n * lookups for text / style / runs / screen-pose, and\n * `scene.update(id, { data })` for commits. The overlay and a double-click\n * both read the pose a node is painted at, so text inside a container whose\n * pose is a frame is edited where it is drawn.\n *\n * Defaults assume the node's `data` carries `text` / `style` / `runs`\n * directly. For custom data shapes, override any of the optional projections.\n * Consumers with non-rect poses should drop down to raw `useTextEdit` and\n * supply their own `getScreenPose`.\n */\nimport { useCallback, useEffect, useMemo, useRef } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport { asNodeId } from '../../core/scene/types';\nimport { scenePaintedPoseOf } from '../../canvas/derivedPath';\nimport type { Scene } from '../../core/scene/types';\nimport { drawOneEditing, type EditingDrawOne } from './editingDrawOne';\nimport { textHitAt } from './textHitAt';\nimport { registerHostTextEditor } from './hostTextEditors';\nimport { editedData, sceneTextDrafts } from './sceneTextDrafts';\nimport type { Stroke, Fill, Inherit } from '@weasel-js/paint';\nimport { resolveScreenLength } from '@weasel-js/paint';\nimport { inheritedPaintIn } from '../../canvas/inheritedPaints';\nimport { withInheritedPaint } from '../../core/scene/inheritedPaint';\nimport { clientToCanvas } from '@weasel-js/routing';\nimport { findMountedCanvas, type MountedCanvas } from '../../canvas/mountedCanvases';\nimport type { View } from '../../core/viewport/view';\nimport type { RectPose } from 'core/geometry/unionBounds';\nimport { poseFrameOf } from '@weasel-js/geom';\nimport { isTextData, type StyledRun, type TextPaint, type TextStyle, type TextVerticalAlign } from '@weasel-js/text';\nimport { textBoxOf, type TextOverflow } from '../../canvas/nodeShapes/textPainter';\nimport { useTextEdit, type TextEditClipRect, type TextEditScreenPose, type UseTextEditReturn } from '@weasel-js/text-dom';\n\n/** Shape the default projections expect `data` to satisfy. All fields\n * optional so any object satisfies the constraint — projections fill in\n * the gaps for non-default shapes. */\nexport interface DefaultTextData {\n text?: string;\n style?: TextStyle;\n runs?: readonly StyledRun[];\n fill?: Fill | Inherit | null;\n stroke?: Stroke | Inherit | null;\n verticalAlign?: TextVerticalAlign;\n padding?: number;\n overflow?: TextOverflow;\n}\n\n/** All-optional projections + fontSize fallback. */\nexport interface UseSceneTextEditOptions<TData> {\n /**\n * Is this node text? A double-click opens an edit only on a node that\n * answers yes, and passes through any other to the text under it. Default:\n * `isTextData`, the test `inferredNodeRouting` classifies a text node by. Pass one when `getText` reads some other shape.\n */\n isText?: (data: TData) => boolean;\n /** Read plain text from `data`. Default: `data.text ?? ''`. */\n getText?: (data: TData) => string;\n /** Read style from `data`. Default: `data.style`. */\n getStyle?: (data: TData) => TextStyle | undefined;\n /** Read the node's paint from `data`. Default: `data.fill` / `data.stroke`. */\n getPaint?: (data: TData) => TextPaint | undefined;\n /** Read rich-text runs from `data`. Default: `data.runs`. */\n getRuns?: (data: TData) => readonly StyledRun[] | undefined;\n /** Read the box vertical alignment from `data`. Default: `data.verticalAlign`. */\n getVerticalAlign?: (data: TData) => TextVerticalAlign | undefined;\n /** Read the inset from the node's box to its text from `data`. Default: `data.padding`. */\n getPadding?: (data: TData) => number | undefined;\n /** Read whether the node cuts its text at its box from `data`, which the\n * overlay then does too. Default: `data.overflow`. */\n getOverflow?: (data: TData) => TextOverflow | undefined;\n /** Produce updated data with new text. Default: `{ ...data, text }`. */\n setText?: (data: TData, text: string) => TData;\n /** Produce updated data with new runs. Default: `{ ...data, runs }`. */\n setRuns?: (data: TData, runs: StyledRun[]) => TData;\n /**\n * Produce updated data with a new node-wide style. Default:\n * `{ ...data, style }`. Written only when a range toggle has to *clear* a\n * flag the node itself sets — the run algebra is additive, so that edit\n * lowers the node flag and raises it on the runs outside the range. See\n * `useTextEdit`'s `setStyle`.\n *\n * An edit's text, runs, and style are folded through these three and\n * written as one `scene.update`, so a commit is one undo step.\n */\n setStyle?: (data: TData, style: TextStyle) => TData;\n /** Fallback fontSize when `style.fontSize` is unset. Default `16`. */\n defaultFontSize?: number;\n /**\n * The view to project through. Omit it and the view is read live from the\n * weasel canvas mounted inside `container` (the one a double-click landed\n * on, when there are several). With no canvas there, the node's world box\n * is passed through as screen pixels.\n *\n * A thunk is re-read on every projection; a plain `View` is the value from\n * the render that supplied it.\n */\n view?: View | (() => View);\n /**\n * Forwarded to `useTextEdit`: is `el` part of the editor's own chrome?\n * Focus moving into it does not end the edit. Wire it to whatever renders\n * the character controls.\n */\n isEditorChrome?: (el: Element) => boolean;\n /** Forwarded to `useTextEdit`: what Escape does to the edit. */\n escape?: 'cancel' | 'commit';\n /** Forwarded to `useTextEdit`: how long an edit waits for its face. */\n fontHold?: number;\n /** Forwarded to `useTextEdit`: called as an edit of the node `id` opens,\n * whichever way it was started. */\n onStart?: (id: string) => void;\n /** Forwarded to `useTextEdit`: called as the edit of `id` closes, after\n * any commit has been written to the scene. */\n onEnd?: (id: string) => void;\n}\n\nfunction resolveView(view: View | (() => View) | undefined): View | undefined {\n return typeof view === 'function' ? view() : view;\n}\n\n/** What `onDoubleClick` reads of the event: a React or a DOM `MouseEvent`. */\nexport type TextEditDoubleClick = Pick<MouseEvent, 'target' | 'clientX' | 'clientY'>;\n\n/** Return shape extends `UseTextEditReturn` with an `onDoubleClick`\n * binding for the canvas container. Double-clicking inside a text\n * node enters edit mode with the caret seeded at the clicked glyph. */\nexport interface UseSceneTextEditReturn extends UseTextEditReturn {\n /** Bind to the element wrapping `<SceneCanvas>` (the same element\n * passed as `container`, or any ancestor that receives the dblclick\n * bubble). Starts an edit on the top-most text node under the cursor. */\n onDoubleClick: (e: TextEditDoubleClick) => void;\n /** The `isText` option asked of the node with this id: what\n * `TextEditDep.isTextNode` wants, so both ways into an edit agree. */\n isTextNode: (id: string) => boolean;\n /**\n * `defaultDrawOne`, less the glyphs of the node being edited: the overlay\n * stands in for its text, and the rest of the node, a `background` among\n * it, goes on painting. Pass it as `layers.scene.drawOne`, with\n * `paintBounds: defaultPaintBounds`, in place of an `alphaFor` that hides\n * the whole node.\n */\n drawOne: EditingDrawOne;\n}\n\n/** How each field is read from a node's `data`: the option's projection, else the default shape. */\nfunction projectionsOf<TData extends DefaultTextData>(opts: { readonly current: UseSceneTextEditOptions<TData> }) {\n return {\n isText: (data: TData): boolean =>\n opts.current.isText ? opts.current.isText(data) : isTextData(data),\n text: (data: TData): string =>\n opts.current.getText ? opts.current.getText(data) : (data.text ?? ''),\n style: (data: TData): TextStyle | undefined =>\n opts.current.getStyle ? opts.current.getStyle(data) : data.style,\n runs: (data: TData): readonly StyledRun[] | undefined =>\n opts.current.getRuns ? opts.current.getRuns(data) : data.runs,\n verticalAlign: (data: TData): TextVerticalAlign | undefined =>\n opts.current.getVerticalAlign ? opts.current.getVerticalAlign(data) : data.verticalAlign,\n padding: (data: TData): number | undefined =>\n opts.current.getPadding ? opts.current.getPadding(data) : data.padding,\n overflow: (data: TData): TextOverflow | undefined =>\n opts.current.getOverflow ? opts.current.getOverflow(data) : data.overflow,\n };\n}\n\n/** Wire double-click-to-edit text on a scene: mounts a DOM editing overlay\n * over the node being edited and writes the result back as an undoable op.\n * `<SceneCanvas>`'s own editor stands down for any canvas inside `container`. */\nexport function useSceneTextEdit<\n TData extends DefaultTextData,\n TLayer extends string,\n TPose extends RectPose = RectPose,\n>(\n scene: Scene<TData, TLayer, TPose>,\n container: HTMLElement | null,\n options: UseSceneTextEditOptions<TData> = {},\n): UseSceneTextEditReturn {\n useEffect(() => (container ? registerHostTextEditor(container) : undefined), [container]);\n return useSceneTextEditor(scene, container, options);\n}\n\n/** `useSceneTextEdit` without announcing itself as a host's editor: what\n * `<SceneCanvas>` mounts as its own. */\nexport function useSceneTextEditor<\n TData extends DefaultTextData,\n TLayer extends string,\n TPose extends RectPose = RectPose,\n>(\n scene: Scene<TData, TLayer, TPose>,\n container: HTMLElement | null,\n options: UseSceneTextEditOptions<TData> = {},\n): UseSceneTextEditReturn {\n // Refs, so the useTextEdit callbacks always see the current values\n // without re-binding.\n const sceneRef = useLatest(scene);\n const optsRef = useLatest(options);\n const containerRef = useLatest(container);\n // The last double-click's target, so the overlay projects through the\n // canvas the edit was opened on.\n const openedOnRef = useRef<EventTarget | null>(null);\n const drafts = useMemo(() => sceneTextDrafts(sceneRef, optsRef), [sceneRef, optsRef]);\n useEffect(() => () => drafts.close(), [drafts]);\n\n // The canvas's box in container pixels is both the origin its view projects\n // from and the region its glyphs are clipped to.\n const surface = (): { canvas: MountedCanvas; box: TextEditClipRect } | null => {\n const root = containerRef.current;\n const canvas = root ? findMountedCanvas(root, openedOnRef.current) : null;\n if (!root || !canvas) return null;\n const a = canvas.element.getBoundingClientRect();\n const b = root.getBoundingClientRect();\n return {\n canvas,\n box: {\n x: a.left - b.left - root.clientLeft + root.scrollLeft,\n y: a.top - b.top - root.clientTop + root.scrollTop,\n width: a.width,\n height: a.height,\n },\n };\n };\n\n const read = useMemo(() => projectionsOf(optsRef), [optsRef]);\n\n const edit = useTextEdit({\n container,\n isEditorChrome: (el) => optsRef.current.isEditorChrome?.(el) ?? false,\n escape: options.escape,\n fontHold: options.fontHold,\n onStart: (id) => optsRef.current.onStart?.(id),\n onEnd: (id) => {\n drafts.end(id);\n optsRef.current.onEnd?.(id);\n },\n onDraft: drafts.draft,\n getText: (id) => {\n const node = sceneRef.current.get(asNodeId(id));\n return node ? read.text(node.data) : '';\n },\n getStyle: (id) => {\n const node = sceneRef.current.get(asNodeId(id));\n return node ? read.style(node.data) : undefined;\n },\n getPaint: (id) => {\n const node = sceneRef.current.get(asNodeId(id));\n if (!node) return undefined;\n const get = optsRef.current.getPaint;\n return get ? get(node.data) : shownTextPaint(sceneRef.current, node);\n },\n getScreenPose: (id) => {\n const scene = sceneRef.current;\n const node = scene.get(asNodeId(id));\n if (!node) return null;\n const at = surface();\n const view = resolveView(optsRef.current.view) ?? at?.canvas.getView();\n return screenPoseOf(node.data, scenePaintedPoseOf(scene)(node), read, view, at?.box, optsRef.current.defaultFontSize);\n },\n getClipRect: () => surface()?.box ?? null,\n getRuns: (id) => {\n const node = sceneRef.current.get(asNodeId(id));\n return node ? read.runs(node.data) : undefined;\n },\n commit: (id, { text, runs, style }) => {\n const nid = asNodeId(id);\n const node = sceneRef.current.get(nid);\n if (!node) return;\n drafts.commit(id, editedData(node.data, { text, runs, style }, optsRef.current));\n },\n });\n\n const onDoubleClick = useCallback((e: TextEditDoubleClick) => {\n // The dblclick bubbles from the canvas up to any wrapping container; the\n // element it started on is what the click coordinates are relative to.\n const canvas = e.target instanceof HTMLElement ? e.target : null;\n if (!canvas) return;\n // Inside the editor a double-click selects a word, and its target is a run\n // span whose box the click would be measured against as if it were a canvas.\n if (canvas.closest('[contenteditable=\"true\"]')) return;\n\n // The click is un-projected here; `textHitAt` takes it back through the\n // frame the node is drawn in.\n const [canvasX, canvasY] = clientToCanvas(canvas, e.clientX, e.clientY);\n const root = containerRef.current;\n const view = resolveView(optsRef.current.view)\n ?? (root ? findMountedCanvas(root, canvas)?.getView() : undefined);\n const cx = view ? canvasX / view.scale.x + view.x : canvasX;\n const cy = view ? canvasY / view.scale.y + view.y : canvasY;\n const hit = textHitAt(sceneRef.current, read, cx, cy);\n if (!hit) return;\n openedOnRef.current = canvas;\n edit.startEdit(hit.id, { caret: hit.caret });\n }, [edit, containerRef, optsRef, read, sceneRef]);\n\n const isTextNode = useCallback((id: string): boolean => {\n const node = sceneRef.current.get(asNodeId(id));\n return node !== undefined && read.isText(node.data);\n }, [read, sceneRef]);\n\n const drawOne = useMemo(() => drawOneEditing(edit.editingId), [edit.editingId]);\n return { ...edit, onDoubleClick, isTextNode, drawOne };\n}\n\n/** The overlay's pose for a node painted at `painted`: its text box, inset\n * about the box center, which is all the overlay's frame needs, projected\n * through `view`. */\nfunction screenPoseOf<TData extends DefaultTextData>(\n d: TData,\n painted: RectPose,\n read: ReturnType<typeof projectionsOf<TData>>,\n view: View | undefined,\n origin: TextEditClipRect | undefined,\n defaultFontSize = 16,\n): TextEditScreenPose {\n const inset = textBoxOf({ padding: read.padding(d) }, painted);\n const box = screenBoxOf({ ...painted, ...inset }, view, origin);\n return {\n ...box,\n // Against `zoom`, the same factor the overlay scales back up by, so a\n // `{ px }` size arrives on screen at the pixel count it names.\n fontSize: resolveScreenLength(read.style(d)?.fontSize ?? defaultFontSize, box.zoom),\n verticalAlign: read.verticalAlign(d),\n ...(read.overflow(d) === 'clip' ? { clip: clipToBox(inset, painted) } : {}),\n };\n}\n\n/** How far `box` reaches past `inner` on each side: the overlay's cut at\n * `box` when its own pose is `inner`. */\nfunction clipToBox(inner: RectPose, box: RectPose): NonNullable<TextEditScreenPose['clip']> {\n return {\n top: inner.y - box.y,\n left: inner.x - box.x,\n bottom: box.y + box.height - (inner.y + inner.height),\n right: box.x + box.width - (inner.x + inner.width),\n };\n}\n\n/**\n * `pose`'s box as the overlay takes it, `origin` being the canvas's corner in\n * container pixels. Only the box center is projected, since the overlay's\n * frame is about it. Width and height stay in world units and reach the\n * screen through the overlay's own `scale(zoom)` — see\n * `TextEditScreenPose.zoom`.\n */\nfunction screenBoxOf(\n pose: RectPose,\n view: View | undefined,\n origin: { x: number; y: number } | undefined,\n): Pick<TextEditScreenPose, 'x' | 'y' | 'width' | 'height' | 'frame'> & { zoom: number } {\n const zoom = view ? view.scale.x : 1;\n const zoomY = view ? view.scale.y : 1;\n const cx = (origin?.x ?? 0) + (pose.x + pose.width / 2 - (view?.x ?? 0)) * zoom;\n const cy = (origin?.y ?? 0) + (pose.y + pose.height / 2 - (view?.y ?? 0)) * zoomY;\n return {\n x: cx - (pose.width * zoom) / 2,\n y: cy - (pose.height * zoom) / 2,\n width: pose.width,\n height: pose.height,\n zoom,\n frame: frameLinearOf(pose, zoomY / zoom),\n };\n}\n\n/** The linear part of the frame `pose` is drawn in, as the overlay takes it.\n * `stretch` is the view's y scale over its x scale: the overlay scales both\n * axes by the x scale, so the frame carries what is left of y. */\nfunction frameLinearOf(pose: unknown, stretch: number): TextEditScreenPose['frame'] {\n const m = poseFrameOf(pose);\n if (!m && stretch === 1) return undefined;\n const [a, b, c, d] = m ?? [1, 0, 0, 1];\n return [a, b * stretch, c, d * stretch];\n}\n\n/** A text node's paint as the canvas paints it: an inherited one is its container's. */\nfunction shownTextPaint<TData extends DefaultTextData>(\n scene: Scene<TData, string, unknown>,\n node: NonNullable<ReturnType<Scene<TData, string, unknown>['get']>>,\n): TextPaint {\n const { fill, stroke } = withInheritedPaint(node.data, inheritedPaintIn(scene, node));\n return { fill, stroke };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useSceneTextEdit.js","names":[],"sources":["../../../src/domains/text/useSceneTextEdit.ts"],"sourcesContent":["/**\n * `useSceneTextEdit` — scene-aware wrapper around `useTextEdit`: scene\n * lookups for text / style / runs / screen-pose, and\n * `scene.update(id, { data })` for commits. The overlay and a double-click\n * both read the pose a node is painted at, so text inside a container whose\n * pose is a frame is edited where it is drawn.\n *\n * Defaults assume the node's `data` carries `text` / `style` / `runs`\n * directly. For custom data shapes, override any of the optional projections.\n * Consumers with non-rect poses should drop down to raw `useTextEdit` and\n * supply their own `getScreenPose`.\n */\nimport { useCallback, useEffect, useMemo, useRef } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport { asNodeId } from '../../core/scene/types';\nimport { scenePaintedPoseOf } from '../../canvas/derivedPath';\nimport type { Scene } from '../../core/scene/types';\nimport { drawOneEditing, type EditingDrawOne } from './editingDrawOne';\nimport { textHitAt } from './textHitAt';\nimport { registerHostTextEditor } from './hostTextEditors';\nimport { editedData, sceneTextDrafts } from './sceneTextDrafts';\nimport type { Stroke, Fill, Inherit } from '@weasel-js/paint';\nimport { resolveScreenLength } from '@weasel-js/paint';\nimport { inheritedPaintIn } from '../../canvas/inheritedPaints';\nimport { withInheritedPaint } from '../../core/scene/inheritedPaint';\nimport { clientToCanvas } from '@weasel-js/routing';\nimport { findMountedCanvas, type MountedCanvas } from '../../canvas/mountedCanvases';\nimport type { View } from '../../core/viewport/view';\nimport type { RectPose } from 'core/geometry/unionBounds';\nimport { poseFrameOf, viewScreenToWorld } from '@weasel-js/geom';\nimport { isTextData, type StyledRun, type TextPaint, type TextStyle, type TextVerticalAlign } from '@weasel-js/text';\nimport { textBoxOf, type TextOverflow } from '../../canvas/nodeShapes/textPainter';\nimport { useTextEdit, type TextEditClipRect, type TextEditScreenPose, type UseTextEditReturn } from '@weasel-js/text-dom';\n\n/** Shape the default projections expect `data` to satisfy. All fields\n * optional so any object satisfies the constraint — projections fill in\n * the gaps for non-default shapes. */\nexport interface DefaultTextData {\n text?: string;\n style?: TextStyle;\n runs?: readonly StyledRun[];\n fill?: Fill | Inherit | null;\n stroke?: Stroke | Inherit | null;\n verticalAlign?: TextVerticalAlign;\n padding?: number;\n overflow?: TextOverflow;\n}\n\n/** All-optional projections + fontSize fallback. */\nexport interface UseSceneTextEditOptions<TData> {\n /**\n * Is this node text? A double-click opens an edit only on a node that\n * answers yes, and passes through any other to the text under it. Default:\n * `isTextData`, the test `inferredNodeRouting` classifies a text node by. Pass one when `getText` reads some other shape.\n */\n isText?: (data: TData) => boolean;\n /** Read plain text from `data`. Default: `data.text ?? ''`. */\n getText?: (data: TData) => string;\n /** Read style from `data`. Default: `data.style`. */\n getStyle?: (data: TData) => TextStyle | undefined;\n /** Read the node's paint from `data`. Default: `data.fill` / `data.stroke`. */\n getPaint?: (data: TData) => TextPaint | undefined;\n /** Read rich-text runs from `data`. Default: `data.runs`. */\n getRuns?: (data: TData) => readonly StyledRun[] | undefined;\n /** Read the box vertical alignment from `data`. Default: `data.verticalAlign`. */\n getVerticalAlign?: (data: TData) => TextVerticalAlign | undefined;\n /** Read the inset from the node's box to its text from `data`. Default: `data.padding`. */\n getPadding?: (data: TData) => number | undefined;\n /** Read whether the node cuts its text at its box from `data`, which the\n * overlay then does too. Default: `data.overflow`. */\n getOverflow?: (data: TData) => TextOverflow | undefined;\n /** Produce updated data with new text. Default: `{ ...data, text }`. */\n setText?: (data: TData, text: string) => TData;\n /** Produce updated data with new runs. Default: `{ ...data, runs }`. */\n setRuns?: (data: TData, runs: StyledRun[]) => TData;\n /**\n * Produce updated data with a new node-wide style. Default:\n * `{ ...data, style }`. Written only when a range toggle has to *clear* a\n * flag the node itself sets — the run algebra is additive, so that edit\n * lowers the node flag and raises it on the runs outside the range. See\n * `useTextEdit`'s `setStyle`.\n *\n * An edit's text, runs, and style are folded through these three and\n * written as one `scene.update`, so a commit is one undo step.\n */\n setStyle?: (data: TData, style: TextStyle) => TData;\n /** Fallback fontSize when `style.fontSize` is unset. Default `16`. */\n defaultFontSize?: number;\n /**\n * The view to project through. Omit it and the view is read live from the\n * weasel canvas mounted inside `container` (the one a double-click landed\n * on, when there are several). With no canvas there, the node's world box\n * is passed through as screen pixels.\n *\n * A thunk is re-read on every projection; a plain `View` is the value from\n * the render that supplied it.\n */\n view?: View | (() => View);\n /**\n * Forwarded to `useTextEdit`: is `el` part of the editor's own chrome?\n * Focus moving into it does not end the edit. Wire it to whatever renders\n * the character controls.\n */\n isEditorChrome?: (el: Element) => boolean;\n /** Forwarded to `useTextEdit`: what Escape does to the edit. */\n escape?: 'cancel' | 'commit';\n /** Forwarded to `useTextEdit`: how long an edit waits for its face. */\n fontHold?: number;\n /** Forwarded to `useTextEdit`: called as an edit of the node `id` opens,\n * whichever way it was started. */\n onStart?: (id: string) => void;\n /** Forwarded to `useTextEdit`: called as the edit of `id` closes, after\n * any commit has been written to the scene. */\n onEnd?: (id: string) => void;\n}\n\nfunction resolveView(view: View | (() => View) | undefined): View | undefined {\n return typeof view === 'function' ? view() : view;\n}\n\n/** What `onDoubleClick` reads of the event: a React or a DOM `MouseEvent`. */\nexport type TextEditDoubleClick = Pick<MouseEvent, 'target' | 'clientX' | 'clientY'>;\n\n/** Return shape extends `UseTextEditReturn` with an `onDoubleClick`\n * binding for the canvas container. Double-clicking inside a text\n * node enters edit mode with the caret seeded at the clicked glyph. */\nexport interface UseSceneTextEditReturn extends UseTextEditReturn {\n /** Bind to the element wrapping `<SceneCanvas>` (the same element\n * passed as `container`, or any ancestor that receives the dblclick\n * bubble). Starts an edit on the top-most text node under the cursor. */\n onDoubleClick: (e: TextEditDoubleClick) => void;\n /** The `isText` option asked of the node with this id: what\n * `TextEditDep.isTextNode` wants, so both ways into an edit agree. */\n isTextNode: (id: string) => boolean;\n /**\n * `defaultDrawOne`, less the glyphs of the node being edited: the overlay\n * stands in for its text, and the rest of the node, a `background` among\n * it, goes on painting. Pass it as `layers.scene.drawOne`, with\n * `paintBounds: defaultPaintBounds`, in place of an `alphaFor` that hides\n * the whole node.\n */\n drawOne: EditingDrawOne;\n}\n\n/** How each field is read from a node's `data`: the option's projection, else the default shape. */\nfunction projectionsOf<TData extends DefaultTextData>(opts: { readonly current: UseSceneTextEditOptions<TData> }) {\n return {\n isText: (data: TData): boolean =>\n opts.current.isText ? opts.current.isText(data) : isTextData(data),\n text: (data: TData): string =>\n opts.current.getText ? opts.current.getText(data) : (data.text ?? ''),\n style: (data: TData): TextStyle | undefined =>\n opts.current.getStyle ? opts.current.getStyle(data) : data.style,\n runs: (data: TData): readonly StyledRun[] | undefined =>\n opts.current.getRuns ? opts.current.getRuns(data) : data.runs,\n verticalAlign: (data: TData): TextVerticalAlign | undefined =>\n opts.current.getVerticalAlign ? opts.current.getVerticalAlign(data) : data.verticalAlign,\n padding: (data: TData): number | undefined =>\n opts.current.getPadding ? opts.current.getPadding(data) : data.padding,\n overflow: (data: TData): TextOverflow | undefined =>\n opts.current.getOverflow ? opts.current.getOverflow(data) : data.overflow,\n };\n}\n\n/** Wire double-click-to-edit text on a scene: mounts a DOM editing overlay\n * over the node being edited and writes the result back as an undoable op.\n * `<SceneCanvas>`'s own editor stands down for any canvas inside `container`. */\nexport function useSceneTextEdit<\n TData extends DefaultTextData,\n TLayer extends string,\n TPose extends RectPose = RectPose,\n>(\n scene: Scene<TData, TLayer, TPose>,\n container: HTMLElement | null,\n options: UseSceneTextEditOptions<TData> = {},\n): UseSceneTextEditReturn {\n useEffect(() => (container ? registerHostTextEditor(container) : undefined), [container]);\n return useSceneTextEditor(scene, container, options);\n}\n\n/** `useSceneTextEdit` without announcing itself as a host's editor: what\n * `<SceneCanvas>` mounts as its own. */\nexport function useSceneTextEditor<\n TData extends DefaultTextData,\n TLayer extends string,\n TPose extends RectPose = RectPose,\n>(\n scene: Scene<TData, TLayer, TPose>,\n container: HTMLElement | null,\n options: UseSceneTextEditOptions<TData> = {},\n): UseSceneTextEditReturn {\n // Refs, so the useTextEdit callbacks always see the current values\n // without re-binding.\n const sceneRef = useLatest(scene);\n const optsRef = useLatest(options);\n const containerRef = useLatest(container);\n // The last double-click's target, so the overlay projects through the\n // canvas the edit was opened on.\n const openedOnRef = useRef<EventTarget | null>(null);\n const drafts = useMemo(() => sceneTextDrafts(sceneRef, optsRef), [sceneRef, optsRef]);\n useEffect(() => () => drafts.close(), [drafts]);\n\n // The canvas's box in container pixels is both the origin its view projects\n // from and the region its glyphs are clipped to.\n const surface = (): { canvas: MountedCanvas; box: TextEditClipRect } | null => {\n const root = containerRef.current;\n const canvas = root ? findMountedCanvas(root, openedOnRef.current) : null;\n if (!root || !canvas) return null;\n const a = canvas.element.getBoundingClientRect();\n const b = root.getBoundingClientRect();\n return {\n canvas,\n box: {\n x: a.left - b.left - root.clientLeft + root.scrollLeft,\n y: a.top - b.top - root.clientTop + root.scrollTop,\n width: a.width,\n height: a.height,\n },\n };\n };\n\n const read = useMemo(() => projectionsOf(optsRef), [optsRef]);\n\n const edit = useTextEdit({\n container,\n isEditorChrome: (el) => optsRef.current.isEditorChrome?.(el) ?? false,\n escape: options.escape,\n fontHold: options.fontHold,\n onStart: (id) => optsRef.current.onStart?.(id),\n onEnd: (id) => {\n drafts.end(id);\n optsRef.current.onEnd?.(id);\n },\n onDraft: drafts.draft,\n getText: (id) => {\n const node = sceneRef.current.get(asNodeId(id));\n return node ? read.text(node.data) : '';\n },\n getStyle: (id) => {\n const node = sceneRef.current.get(asNodeId(id));\n return node ? read.style(node.data) : undefined;\n },\n getPaint: (id) => {\n const node = sceneRef.current.get(asNodeId(id));\n if (!node) return undefined;\n const get = optsRef.current.getPaint;\n return get ? get(node.data) : shownTextPaint(sceneRef.current, node);\n },\n getScreenPose: (id) => {\n const scene = sceneRef.current;\n const node = scene.get(asNodeId(id));\n if (!node) return null;\n const at = surface();\n const view = resolveView(optsRef.current.view) ?? at?.canvas.getView();\n return screenPoseOf(node.data, scenePaintedPoseOf(scene)(node), read, view, at?.box, optsRef.current.defaultFontSize);\n },\n getClipRect: () => surface()?.box ?? null,\n getRuns: (id) => {\n const node = sceneRef.current.get(asNodeId(id));\n return node ? read.runs(node.data) : undefined;\n },\n commit: (id, { text, runs, style }) => {\n const nid = asNodeId(id);\n const node = sceneRef.current.get(nid);\n if (!node) return;\n drafts.commit(id, editedData(node.data, { text, runs, style }, optsRef.current));\n },\n });\n\n const onDoubleClick = useCallback((e: TextEditDoubleClick) => {\n // The dblclick bubbles from the canvas up to any wrapping container; the\n // element it started on is what the click coordinates are relative to.\n const canvas = e.target instanceof HTMLElement ? e.target : null;\n if (!canvas) return;\n // Inside the editor a double-click selects a word, and its target is a run\n // span whose box the click would be measured against as if it were a canvas.\n if (canvas.closest('[contenteditable=\"true\"]')) return;\n\n // The click is un-projected here; `textHitAt` takes it back through the\n // frame the node is drawn in.\n const [canvasX, canvasY] = clientToCanvas(canvas, e.clientX, e.clientY);\n const root = containerRef.current;\n const view = resolveView(optsRef.current.view)\n ?? (root ? findMountedCanvas(root, canvas)?.getView() : undefined);\n const at = view ? viewScreenToWorld(view, { x: canvasX, y: canvasY }) : { x: canvasX, y: canvasY };\n const hit = textHitAt(sceneRef.current, read, at.x, at.y);\n if (!hit) return;\n openedOnRef.current = canvas;\n edit.startEdit(hit.id, { caret: hit.caret });\n }, [edit, containerRef, optsRef, read, sceneRef]);\n\n const isTextNode = useCallback((id: string): boolean => {\n const node = sceneRef.current.get(asNodeId(id));\n return node !== undefined && read.isText(node.data);\n }, [read, sceneRef]);\n\n const drawOne = useMemo(() => drawOneEditing(edit.editingId), [edit.editingId]);\n return { ...edit, onDoubleClick, isTextNode, drawOne };\n}\n\n/** The overlay's pose for a node painted at `painted`: its text box, inset\n * about the box center, which is all the overlay's frame needs, projected\n * through `view`. */\nfunction screenPoseOf<TData extends DefaultTextData>(\n d: TData,\n painted: RectPose,\n read: ReturnType<typeof projectionsOf<TData>>,\n view: View | undefined,\n origin: TextEditClipRect | undefined,\n defaultFontSize = 16,\n): TextEditScreenPose {\n const inset = textBoxOf({ padding: read.padding(d) }, painted);\n const box = screenBoxOf({ ...painted, ...inset }, view, origin);\n return {\n ...box,\n // Against `zoom`, the same factor the overlay scales back up by, so a\n // `{ px }` size arrives on screen at the pixel count it names.\n fontSize: resolveScreenLength(read.style(d)?.fontSize ?? defaultFontSize, box.zoom),\n verticalAlign: read.verticalAlign(d),\n ...(read.overflow(d) === 'clip' ? { clip: clipToBox(inset, painted) } : {}),\n };\n}\n\n/** How far `box` reaches past `inner` on each side: the overlay's cut at\n * `box` when its own pose is `inner`. */\nfunction clipToBox(inner: RectPose, box: RectPose): NonNullable<TextEditScreenPose['clip']> {\n return {\n top: inner.y - box.y,\n left: inner.x - box.x,\n bottom: box.y + box.height - (inner.y + inner.height),\n right: box.x + box.width - (inner.x + inner.width),\n };\n}\n\n/**\n * `pose`'s box as the overlay takes it, `origin` being the canvas's corner in\n * container pixels. Only the box center is projected, since the overlay's\n * frame is about it. Width and height stay in world units and reach the\n * screen through the overlay's own `scale(zoom)` — see\n * `TextEditScreenPose.zoom`.\n */\nfunction screenBoxOf(\n pose: RectPose,\n view: View | undefined,\n origin: { x: number; y: number } | undefined,\n): Pick<TextEditScreenPose, 'x' | 'y' | 'width' | 'height' | 'frame'> & { zoom: number } {\n const zoom = view ? view.scale.x : 1;\n const zoomY = view ? view.scale.y : 1;\n const cx = (origin?.x ?? 0) + (pose.x + pose.width / 2 - (view?.x ?? 0)) * zoom;\n const cy = (origin?.y ?? 0) + (pose.y + pose.height / 2 - (view?.y ?? 0)) * zoomY;\n return {\n x: cx - (pose.width * zoom) / 2,\n y: cy - (pose.height * zoom) / 2,\n width: pose.width,\n height: pose.height,\n zoom,\n frame: frameLinearOf(pose, zoomY / zoom),\n };\n}\n\n/** The linear part of the frame `pose` is drawn in, as the overlay takes it.\n * `stretch` is the view's y scale over its x scale: the overlay scales both\n * axes by the x scale, so the frame carries what is left of y. */\nfunction frameLinearOf(pose: unknown, stretch: number): TextEditScreenPose['frame'] {\n const m = poseFrameOf(pose);\n if (!m && stretch === 1) return undefined;\n const [a, b, c, d] = m ?? [1, 0, 0, 1];\n return [a, b * stretch, c, d * stretch];\n}\n\n/** A text node's paint as the canvas paints it: an inherited one is its container's. */\nfunction shownTextPaint<TData extends DefaultTextData>(\n scene: Scene<TData, string, unknown>,\n node: NonNullable<ReturnType<Scene<TData, string, unknown>['get']>>,\n): TextPaint {\n const { fill, stroke } = withInheritedPaint(node.data, inheritedPaintIn(scene, node));\n return { fill, stroke };\n}\n"],"mappings":"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"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { ZOOM_FLOOR } from "../../core/viewport/zoomBounds.js";
|
|
2
|
-
import { normalizeView } from "../../core/viewport/view.js";
|
|
3
1
|
import { fitViewToBounds } from "../../core/viewport/fitViewToBounds.js";
|
|
2
|
+
import { normalizeView } from "../../core/viewport/view.js";
|
|
3
|
+
import { ZOOM_FLOOR } from "../../core/viewport/zoomBounds.js";
|
|
4
|
+
import { viewScreenToWorld, viewWorldToScreen } from "@weasel-js/geom";
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
// src/domains/viewports/aim.ts
|
|
6
7
|
/** The aim of view `viewId` (`null`: a surface's root) showing world rect `rect`. */
|
|
7
8
|
function rectAim(viewId, rect) {
|
|
8
9
|
return {
|
|
@@ -61,14 +62,8 @@ function aimSpace2d(viewId, view, size) {
|
|
|
61
62
|
width: size.width,
|
|
62
63
|
height: size.height
|
|
63
64
|
},
|
|
64
|
-
project: (p) => (
|
|
65
|
-
|
|
66
|
-
y: (p.y - view.y) * view.scale.y
|
|
67
|
-
}),
|
|
68
|
-
unproject: (px) => ({
|
|
69
|
-
x: px.x / view.scale.x + view.x,
|
|
70
|
-
y: px.y / view.scale.y + view.y
|
|
71
|
-
})
|
|
65
|
+
project: (p) => viewWorldToScreen(view, p),
|
|
66
|
+
unproject: (px) => viewScreenToWorld(view, px)
|
|
72
67
|
};
|
|
73
68
|
}
|
|
74
69
|
var UNUSED_CURRENT = {
|
|
@@ -100,6 +95,5 @@ function viewForAim(rect, size, fit) {
|
|
|
100
95
|
}));
|
|
101
96
|
}
|
|
102
97
|
|
|
103
|
-
//#endregion
|
|
104
98
|
export { aimSpace2d, isRectAim, rectAim, viewForAim };
|
|
105
99
|
//# sourceMappingURL=aim.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aim.js","names":[],"sources":["../../../src/domains/viewports/aim.ts"],"sourcesContent":["import { fitViewToBounds, type Bounds } from 'core/viewport/fitViewToBounds';\nimport type { Dims } from 'core/layers/render';\nimport { normalizeView, type View } from 'core/viewport/view';\nimport { ZOOM_FLOOR } from 'core/viewport/zoomBounds';\n\n/** A point in a view's world. A 2D world is the plane z = 0, so `z` is absent there. */\nexport interface AimPoint {\n x: number;\n y: number;\n z?: number;\n}\n\n/** A closed outline in a frame's CSS px, from the frame's top-left; at least 3 points. */\nexport type AimOutline = readonly { x: number; y: number }[];\n\n/** A target view, as an aim is drawn into it: its world, and its frame. */\nexport interface AimSpace {\n /** The view whose frame this is; `null` for a surface's root view. */\n readonly viewId: string | null;\n /** `'2d'` for core's views; any other value is its owner's (kernel3d: `'3d'`). */\n readonly kind: string;\n readonly size: { width: number; height: number };\n /** World point to frame px; `null` where the point does not draw (behind a 3D camera). */\n project(p: AimPoint): { x: number; y: number } | null;\n /** Frame px to the world point under it; `null` where there is none (a 3D ray missing its plane). */\n unproject(px: { x: number; y: number }): AimPoint | null;\n}\n\n/** What a viewport shows, read in the world of the view it names. */\nexport interface ViewAim<TExtent = unknown> {\n readonly viewId: string | null;\n /** Discriminates `extent`: `'rect'` for core's 2D views. */\n readonly kind: string;\n /** Where the aim lies in its world, in its owner's own terms. */\n readonly extent: TExtent;\n /** The aim's outline in `space`'s frame, or `null` when it cannot be drawn there. */\n outlineIn(space: AimSpace): AimOutline | null;\n /** This aim moved so the world point under frame px `from` in `space` ends up under `to`; `null` when either misses. */\n pannedIn(space: AimSpace, from: { x: number; y: number }, to: { x: number; y: number }): ViewAim<TExtent> | null;\n}\n\n/** Core's 2D aim: a world rect a view shows. */\nexport type RectAim = ViewAim<Bounds> & { readonly kind: 'rect' };\n\n/** The aim of view `viewId` (`null`: a surface's root) showing world rect `rect`. */\nexport function rectAim(viewId: string | null, rect: Bounds): RectAim {\n return {\n viewId,\n kind: 'rect',\n extent: rect,\n outlineIn(space) {\n const { x, y, width, height } = rect;\n const out: { x: number; y: number }[] = [];\n for (const corner of [\n { x, y },\n { x: x + width, y },\n { x: x + width, y: y + height },\n { x, y: y + height },\n ]) {\n const p = space.project(corner);\n if (!p) return null;\n out.push(p);\n }\n return out;\n },\n pannedIn(space, from, to) {\n const a = space.unproject(from);\n const b = space.unproject(to);\n if (!a || !b) return null;\n return rectAim(viewId, { ...rect, x: rect.x + (b.x - a.x), y: rect.y + (b.y - a.y) });\n },\n };\n}\n\n/** Whether `aim` is core's 2D rect aim, so its `extent` is a world rect. */\nexport function isRectAim(aim: ViewAim): aim is RectAim {\n return aim.kind === 'rect';\n}\n\n/** A 2D view's frame: `view` is its camera and `size` its frame; frame px are measured from the frame's top-left. */\nexport function aimSpace2d(viewId: string | null, view: View, size: Dims): AimSpace {\n return {\n viewId,\n kind: '2d',\n size: { width: size.width, height: size.height },\n project: (p) => (
|
|
1
|
+
{"version":3,"file":"aim.js","names":[],"sources":["../../../src/domains/viewports/aim.ts"],"sourcesContent":["import { fitViewToBounds, type Bounds } from 'core/viewport/fitViewToBounds';\nimport type { Dims } from 'core/layers/render';\nimport { normalizeView, type View } from 'core/viewport/view';\nimport { ZOOM_FLOOR } from 'core/viewport/zoomBounds';\nimport { viewScreenToWorld, viewWorldToScreen } from '@weasel-js/geom';\n\n/** A point in a view's world. A 2D world is the plane z = 0, so `z` is absent there. */\nexport interface AimPoint {\n x: number;\n y: number;\n z?: number;\n}\n\n/** A closed outline in a frame's CSS px, from the frame's top-left; at least 3 points. */\nexport type AimOutline = readonly { x: number; y: number }[];\n\n/** A target view, as an aim is drawn into it: its world, and its frame. */\nexport interface AimSpace {\n /** The view whose frame this is; `null` for a surface's root view. */\n readonly viewId: string | null;\n /** `'2d'` for core's views; any other value is its owner's (kernel3d: `'3d'`). */\n readonly kind: string;\n readonly size: { width: number; height: number };\n /** World point to frame px; `null` where the point does not draw (behind a 3D camera). */\n project(p: AimPoint): { x: number; y: number } | null;\n /** Frame px to the world point under it; `null` where there is none (a 3D ray missing its plane). */\n unproject(px: { x: number; y: number }): AimPoint | null;\n}\n\n/** What a viewport shows, read in the world of the view it names. */\nexport interface ViewAim<TExtent = unknown> {\n readonly viewId: string | null;\n /** Discriminates `extent`: `'rect'` for core's 2D views. */\n readonly kind: string;\n /** Where the aim lies in its world, in its owner's own terms. */\n readonly extent: TExtent;\n /** The aim's outline in `space`'s frame, or `null` when it cannot be drawn there. */\n outlineIn(space: AimSpace): AimOutline | null;\n /** This aim moved so the world point under frame px `from` in `space` ends up under `to`; `null` when either misses. */\n pannedIn(space: AimSpace, from: { x: number; y: number }, to: { x: number; y: number }): ViewAim<TExtent> | null;\n}\n\n/** Core's 2D aim: a world rect a view shows. */\nexport type RectAim = ViewAim<Bounds> & { readonly kind: 'rect' };\n\n/** The aim of view `viewId` (`null`: a surface's root) showing world rect `rect`. */\nexport function rectAim(viewId: string | null, rect: Bounds): RectAim {\n return {\n viewId,\n kind: 'rect',\n extent: rect,\n outlineIn(space) {\n const { x, y, width, height } = rect;\n const out: { x: number; y: number }[] = [];\n for (const corner of [\n { x, y },\n { x: x + width, y },\n { x: x + width, y: y + height },\n { x, y: y + height },\n ]) {\n const p = space.project(corner);\n if (!p) return null;\n out.push(p);\n }\n return out;\n },\n pannedIn(space, from, to) {\n const a = space.unproject(from);\n const b = space.unproject(to);\n if (!a || !b) return null;\n return rectAim(viewId, { ...rect, x: rect.x + (b.x - a.x), y: rect.y + (b.y - a.y) });\n },\n };\n}\n\n/** Whether `aim` is core's 2D rect aim, so its `extent` is a world rect. */\nexport function isRectAim(aim: ViewAim): aim is RectAim {\n return aim.kind === 'rect';\n}\n\n/** A 2D view's frame: `view` is its camera and `size` its frame; frame px are measured from the frame's top-left. */\nexport function aimSpace2d(viewId: string | null, view: View, size: Dims): AimSpace {\n return {\n viewId,\n kind: '2d',\n size: { width: size.width, height: size.height },\n project: (p) => viewWorldToScreen(view, p),\n unproject: (px) => viewScreenToWorld(view, px),\n };\n}\n\nconst UNUSED_CURRENT: View = { x: 0, y: 0, scale: { x: 1, y: 1 } };\n\n/**\n * The camera that shows `rect` in a frame of `size`: `'exact'` per axis (the inverse of `viewportWorldRect`),\n * `'contain'` uniform and centered. Not clamped to a zoom range, and finite for an empty rect or frame. Normalized.\n */\nexport function viewForAim(rect: Bounds, size: Dims, fit: 'exact' | 'contain'): View {\n if (!(rect.width > 0 && rect.height > 0 && size.width > 0 && size.height > 0)) {\n return normalizeView({ x: rect.x, y: rect.y, scale: { x: ZOOM_FLOOR, y: ZOOM_FLOOR } });\n }\n return normalizeView(fitViewToBounds(rect, size, UNUSED_CURRENT, {\n mode: fit === 'exact' ? 'stretch' : 'contain', padding: 0, minScale: 0, maxScale: Infinity,\n }));\n}\n"],"mappings":";;;;;;;AA8CA,SAAgB,QAAQ,QAAuB,MAAuB;CACpE,OAAO;EACL;EACA,MAAM;EACN,QAAQ;EACR,UAAU,OAAO;GACf,MAAM,EAAE,GAAG,GAAG,OAAO,WAAW;GAChC,MAAM,MAAkC,CAAC;GACzC,KAAK,MAAM,UAAU;IACnB;KAAE;KAAG;IAAE;IACP;KAAE,GAAG,IAAI;KAAO;IAAE;IAClB;KAAE,GAAG,IAAI;KAAO,GAAG,IAAI;IAAO;IAC9B;KAAE;KAAG,GAAG,IAAI;IAAO;GACrB,GAAG;IACD,MAAM,IAAI,MAAM,QAAQ,MAAM;IAC9B,IAAI,CAAC,GAAG,OAAO;IACf,IAAI,KAAK,CAAC;GACZ;GACA,OAAO;EACT;EACA,SAAS,OAAO,MAAM,IAAI;GACxB,MAAM,IAAI,MAAM,UAAU,IAAI;GAC9B,MAAM,IAAI,MAAM,UAAU,EAAE;GAC5B,IAAI,CAAC,KAAK,CAAC,GAAG,OAAO;GACrB,OAAO,QAAQ,QAAQ;IAAE,GAAG;IAAM,GAAG,KAAK,KAAK,EAAE,IAAI,EAAE;IAAI,GAAG,KAAK,KAAK,EAAE,IAAI,EAAE;GAAG,CAAC;EACtF;CACF;AACF;;AAGA,SAAgB,UAAU,KAA8B;CACtD,OAAO,IAAI,SAAS;AACtB;;AAGA,SAAgB,WAAW,QAAuB,MAAY,MAAsB;CAClF,OAAO;EACL;EACA,MAAM;EACN,MAAM;GAAE,OAAO,KAAK;GAAO,QAAQ,KAAK;EAAO;EAC/C,UAAU,MAAM,kBAAkB,MAAM,CAAC;EACzC,YAAY,OAAO,kBAAkB,MAAM,EAAE;CAC/C;AACF;AAEA,IAAM,iBAAuB;CAAE,GAAG;CAAG,GAAG;CAAG,OAAO;EAAE,GAAG;EAAG,GAAG;CAAE;AAAE;;;;;AAMjE,SAAgB,WAAW,MAAc,MAAY,KAAgC;CACnF,IAAI,EAAE,KAAK,QAAQ,KAAK,KAAK,SAAS,KAAK,KAAK,QAAQ,KAAK,KAAK,SAAS,IACzE,OAAO,cAAc;EAAE,GAAG,KAAK;EAAG,GAAG,KAAK;EAAG,OAAO;GAAE,GAAG;GAAY,GAAG;EAAW;CAAE,CAAC;CAExF,OAAO,cAAc,gBAAgB,MAAM,MAAM,gBAAgB;EAC/D,MAAM,QAAQ,UAAU,YAAY;EAAW,SAAS;EAAG,UAAU;EAAG,UAAU;CACpF,CAAC,CAAC;AACJ"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { aimSpace2d } from "./aim.js";
|
|
2
2
|
import { pointInPolygon, pointSegmentDist2, polygonFromPoints } from "@weasel-js/geom";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// src/domains/viewports/viewMarker.ts
|
|
5
5
|
/** The marker style a {@link ViewMarkerProps.style} fills in from: the minimap indicator's. */
|
|
6
6
|
var VIEW_MARKER_DEFAULT_STYLE = {
|
|
7
7
|
stroke: "#ffffff",
|
|
@@ -95,6 +95,5 @@ function outlineHolds(outline, p, slop, interior) {
|
|
|
95
95
|
return false;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
//#endregion
|
|
99
98
|
export { VIEW_MARKER_DEFAULT_STYLE, VIEW_MARKER_HIT_SLOP_PX, createViewMarkerLayer, grabViewMarker, markerSourceAim };
|
|
100
99
|
//# sourceMappingURL=viewMarker.js.map
|