@weasel-js/core 1.11.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +611 -0
- package/README.md +1 -1
- package/dist/WeaselProvider.js +1 -1
- package/dist/affordances/pathAnchors.js +10 -6
- package/dist/affordances/pathAnchors.js.map +1 -1
- package/dist/animation/index.js +3 -3
- package/dist/animation/rig/bindRig.js +1 -1
- package/dist/animation/rig/rigNode.js.map +1 -1
- package/dist/barrel/canvas.js +9 -3
- package/dist/barrel/interactions.js +5 -4
- package/dist/barrel/paint.js +4 -4
- package/dist/barrel/paths.js +10 -6
- package/dist/barrel/renderer.js +5 -3
- package/dist/barrel/routing.js +7 -12
- package/dist/barrel/scene.js +9 -5
- package/dist/barrel/text.js +2 -2
- package/dist/barrel/viewport.js +9 -4
- package/dist/canvas/Canvas.js +5 -2
- package/dist/canvas/Canvas.js.map +1 -1
- package/dist/canvas/CanvasView.js +23 -34
- package/dist/canvas/CanvasView.js.map +1 -1
- package/dist/canvas/ModalityHud.js +1 -1
- package/dist/canvas/NodeShape.js +4 -1
- package/dist/canvas/NodeShape.js.map +1 -1
- package/dist/canvas/SceneCanvas/ActionsProviderIfRoot.js +1 -1
- package/dist/canvas/SceneCanvas/DepRegistryProviderIfRoot.js +1 -1
- package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +1 -1
- package/dist/canvas/SceneCanvas/SceneCanvasInput.js +17 -3
- package/dist/canvas/SceneCanvas/SceneCanvasInput.js.map +1 -1
- package/dist/canvas/SceneCanvas/SurfaceDeclarations.js +23 -0
- package/dist/canvas/SceneCanvas/SurfaceDeclarations.js.map +1 -0
- package/dist/canvas/SceneCanvas/builtinToolSets.js +30 -0
- package/dist/canvas/SceneCanvas/builtinToolSets.js.map +1 -0
- package/dist/canvas/SceneCanvas/canvasPassThrough.js +2 -0
- package/dist/canvas/SceneCanvas/canvasPassThrough.js.map +1 -1
- package/dist/canvas/SceneCanvas/coordTrace.js +5 -16
- package/dist/canvas/SceneCanvas/coordTrace.js.map +1 -1
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js +5 -0
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -1
- package/dist/canvas/SceneCanvas/features.js +45 -5
- package/dist/canvas/SceneCanvas/features.js.map +1 -1
- package/dist/canvas/SceneCanvas/props.js +1 -11
- package/dist/canvas/SceneCanvas/props.js.map +1 -1
- package/dist/canvas/SceneCanvas/scenePointQuery.js +7 -3
- package/dist/canvas/SceneCanvas/scenePointQuery.js.map +1 -1
- package/dist/canvas/SceneCanvas/toolRegistry.js +8 -4
- package/dist/canvas/SceneCanvas/toolRegistry.js.map +1 -1
- package/dist/canvas/SceneCanvas/useActionTunings.js +6 -1
- package/dist/canvas/SceneCanvas/useActionTunings.js.map +1 -1
- package/dist/canvas/SceneCanvas/useActionsPropResolver.js +1 -11
- package/dist/canvas/SceneCanvas/useActionsPropResolver.js.map +1 -1
- package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js.map +1 -1
- package/dist/canvas/SceneCanvas/useBuiltinTools.js +2 -9
- package/dist/canvas/SceneCanvas/useBuiltinTools.js.map +1 -1
- package/dist/canvas/SceneCanvas/useCanvasDevtoolsRoot.js +94 -0
- package/dist/canvas/SceneCanvas/useCanvasDevtoolsRoot.js.map +1 -0
- package/dist/canvas/SceneCanvas/useCanvasSelection.js +7 -2
- package/dist/canvas/SceneCanvas/useCanvasSelection.js.map +1 -1
- package/dist/canvas/SceneCanvas/useCanvasTools.js +15 -10
- package/dist/canvas/SceneCanvas/useCanvasTools.js.map +1 -1
- package/dist/canvas/SceneCanvas/useNodeKinds.js +1 -1
- package/dist/canvas/SceneCanvas/useNodeKinds.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneCanvasHandle.js +9 -3
- package/dist/canvas/SceneCanvas/useSceneCanvasHandle.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js +23 -4
- package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneCanvasTools.js +2 -3
- package/dist/canvas/SceneCanvas/useSceneCanvasTools.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneChrome.js +6 -7
- package/dist/canvas/SceneCanvas/useSceneChrome.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneGestureDispatcher.js +24 -7
- package/dist/canvas/SceneCanvas/useSceneGestureDispatcher.js.map +1 -1
- package/dist/canvas/SceneCanvas/useScenePicking.js +2 -3
- package/dist/canvas/SceneCanvas/useScenePicking.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js +2 -1
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneStandardActions.js +5 -5
- package/dist/canvas/SceneCanvas/useSceneStandardActions.js.map +1 -1
- package/dist/canvas/SceneCanvas.js +27 -24
- package/dist/canvas/SceneCanvas.js.map +1 -1
- package/dist/canvas/SurfaceCanvas.js +5 -22
- package/dist/canvas/SurfaceCanvas.js.map +1 -1
- package/dist/canvas/ViewMarker.js +35 -0
- package/dist/canvas/ViewMarker.js.map +1 -0
- package/dist/canvas/canvasRenderer.js +9 -5
- package/dist/canvas/canvasRenderer.js.map +1 -1
- package/dist/canvas/contextAttributes.js +14 -0
- package/dist/canvas/contextAttributes.js.map +1 -0
- package/dist/canvas/defaultDrawOne.js +2 -0
- package/dist/canvas/defaultDrawOne.js.map +1 -1
- package/dist/canvas/deps/booleans.js +2 -1
- package/dist/canvas/deps/booleans.js.map +1 -1
- package/dist/canvas/deps/editAnchors.js +9 -113
- package/dist/canvas/deps/editAnchors.js.map +1 -1
- package/dist/canvas/deps/hitTestArea.js +2 -2
- package/dist/canvas/deps/hitTestArea.js.map +1 -1
- package/dist/canvas/deps/insert.js +10 -4
- package/dist/canvas/deps/insert.js.map +1 -1
- package/dist/canvas/deps/pathEditCommits.js +189 -0
- package/dist/canvas/deps/pathEditCommits.js.map +1 -0
- package/dist/canvas/deps/snap.js +12 -9
- package/dist/canvas/deps/snap.js.map +1 -1
- package/dist/canvas/deps/transformFollowers.js +20 -0
- package/dist/canvas/deps/transformFollowers.js.map +1 -0
- package/dist/canvas/derivedPath.js +20 -1
- package/dist/canvas/derivedPath.js.map +1 -1
- package/dist/canvas/drawnBounds.js +38 -4
- package/dist/canvas/drawnBounds.js.map +1 -1
- package/dist/canvas/inheritedPaints.js +44 -0
- package/dist/canvas/inheritedPaints.js.map +1 -0
- package/dist/canvas/nodeShapes/derivedPainter.js +23 -16
- package/dist/canvas/nodeShapes/derivedPainter.js.map +1 -1
- package/dist/canvas/nodeShapes/nodePaint.js +13 -34
- package/dist/canvas/nodeShapes/nodePaint.js.map +1 -1
- package/dist/canvas/nodeShapes/pathPainter.js +12 -10
- package/dist/canvas/nodeShapes/pathPainter.js.map +1 -1
- package/dist/canvas/nodeShapes/rectFallbackPainter.js +4 -5
- package/dist/canvas/nodeShapes/rectFallbackPainter.js.map +1 -1
- package/dist/canvas/nodeShapes/shapePainter.js +12 -11
- package/dist/canvas/nodeShapes/shapePainter.js.map +1 -1
- package/dist/canvas/nodeShapes/textPainter.js +13 -12
- package/dist/canvas/nodeShapes/textPainter.js.map +1 -1
- package/dist/canvas/overlayRoleStrokes.js +12 -0
- package/dist/canvas/overlayRoleStrokes.js.map +1 -1
- package/dist/canvas/pathOverlay.js +27 -7
- package/dist/canvas/pathOverlay.js.map +1 -1
- package/dist/canvas/pickReach.js +3 -3
- package/dist/canvas/pickReach.js.map +1 -1
- package/dist/canvas/pickWalk.js +3 -1
- package/dist/canvas/pickWalk.js.map +1 -1
- package/dist/canvas/renderDebugSnapshot.js +1 -0
- package/dist/canvas/renderDebugSnapshot.js.map +1 -1
- package/dist/canvas/renderSceneToPixels.js +7 -6
- package/dist/canvas/renderSceneToPixels.js.map +1 -1
- package/dist/canvas/sceneAdapter.js.map +1 -1
- package/dist/canvas/sceneSlotWiring.js +2 -1
- package/dist/canvas/sceneSlotWiring.js.map +1 -1
- package/dist/canvas/sceneViewRender.js +2 -1
- package/dist/canvas/sceneViewRender.js.map +1 -1
- package/dist/canvas/surfaceContribution.js +12 -8
- package/dist/canvas/surfaceContribution.js.map +1 -1
- package/dist/canvas/useCanvasPaint.js +2 -1
- package/dist/canvas/useCanvasPaint.js.map +1 -1
- package/dist/canvas/useCanvasView.js +4 -2
- package/dist/canvas/useCanvasView.js.map +1 -1
- package/dist/canvas/useInFlightBounds.js +52 -0
- package/dist/canvas/useInFlightBounds.js.map +1 -0
- package/dist/canvas/useLayerStack.js +6 -2
- package/dist/canvas/useLayerStack.js.map +1 -1
- package/dist/canvas/useViewAim.js +121 -0
- package/dist/canvas/useViewAim.js.map +1 -0
- package/dist/canvas/useViewHelpers.js +7 -9
- package/dist/canvas/useViewHelpers.js.map +1 -1
- package/dist/canvas/useViewNesting.js +3 -2
- package/dist/canvas/useViewNesting.js.map +1 -1
- package/dist/canvas/useViewRegistrySurface.js +4 -2
- package/dist/canvas/useViewRegistrySurface.js.map +1 -1
- package/dist/canvas/viewMarkers.js +63 -0
- package/dist/canvas/viewMarkers.js.map +1 -0
- package/dist/canvas/viewRegistry.js +27 -1
- package/dist/canvas/viewRegistry.js.map +1 -1
- package/dist/clipboard.d.ts +3 -2
- package/dist/{clone-DZDrfIlU.d.ts → clone-C3e0OTuF.d.ts} +8 -21
- package/dist/clone.d.ts +4 -3
- package/dist/core/geometry/autoPoseDescriptor.js +1 -1
- package/dist/core/ops/setDependsOn.js +37 -0
- package/dist/core/ops/setDependsOn.js.map +1 -0
- package/dist/core/ops/writtenBy.js +53 -0
- package/dist/core/ops/writtenBy.js.map +1 -0
- package/dist/core/pages/fitViewToPage.js +12 -1
- package/dist/core/pages/fitViewToPage.js.map +1 -1
- package/dist/core/pages/pageEdits.js +163 -0
- package/dist/core/pages/pageEdits.js.map +1 -0
- package/dist/core/pages/pages.js +30 -1
- package/dist/core/pages/pages.js.map +1 -1
- package/dist/core/paint/meshKindLazy.js +59 -2
- package/dist/core/paint/meshKindLazy.js.map +1 -1
- package/dist/core/scene/NodeRouting.js +8 -3
- package/dist/core/scene/NodeRouting.js.map +1 -1
- package/dist/core/scene/arrivalWindow.js.map +1 -1
- package/dist/core/scene/carryDescendants.js +51 -0
- package/dist/core/scene/carryDescendants.js.map +1 -0
- package/dist/core/scene/clipNothing.js +13 -0
- package/dist/core/scene/clipNothing.js.map +1 -0
- package/dist/core/scene/depMemo.js +11 -3
- package/dist/core/scene/depMemo.js.map +1 -1
- package/dist/core/scene/dependents.js +7 -1
- package/dist/core/scene/dependents.js.map +1 -1
- package/dist/core/scene/derivedParts.js +10 -11
- package/dist/core/scene/derivedParts.js.map +1 -1
- package/dist/core/scene/docValues.js +57 -0
- package/dist/core/scene/docValues.js.map +1 -0
- package/dist/core/scene/editPass.js +111 -0
- package/dist/core/scene/editPass.js.map +1 -0
- package/dist/core/scene/effectivePose.js +13 -2
- package/dist/core/scene/effectivePose.js.map +1 -1
- package/dist/core/scene/fieldEdits.js +4 -1
- package/dist/core/scene/fieldEdits.js.map +1 -1
- package/dist/core/scene/fontReads.js +37 -0
- package/dist/core/scene/fontReads.js.map +1 -0
- package/dist/core/scene/historyFacade.js +1 -0
- package/dist/core/scene/historyFacade.js.map +1 -1
- package/dist/core/scene/inheritedPaint.js +75 -0
- package/dist/core/scene/inheritedPaint.js.map +1 -0
- package/dist/core/scene/kitRegistry.js +5 -0
- package/dist/core/scene/kitRegistry.js.map +1 -1
- package/dist/core/scene/layoutPass.js +28 -3
- package/dist/core/scene/layoutPass.js.map +1 -1
- package/dist/core/scene/nodeMemo.js +15 -7
- package/dist/core/scene/nodeMemo.js.map +1 -1
- package/dist/core/scene/pathEffects/blend.js.map +1 -1
- package/dist/core/scene/pathEffects/derive.js +7 -2
- package/dist/core/scene/pathEffects/derive.js.map +1 -1
- package/dist/core/scene/pathEffects/effects.js +3 -1
- package/dist/core/scene/pathEffects/effects.js.map +1 -1
- package/dist/core/scene/pathEffects/textAlong.js +95 -0
- package/dist/core/scene/pathEffects/textAlong.js.map +1 -0
- package/dist/core/scene/recorder.js +28 -19
- package/dist/core/scene/recorder.js.map +1 -1
- package/dist/core/scene/scene.js +15 -9
- package/dist/core/scene/scene.js.map +1 -1
- package/dist/core/scene/sceneChanges.js +13 -0
- package/dist/core/scene/sceneChanges.js.map +1 -0
- package/dist/core/scene/sceneEdits.js +8 -1
- package/dist/core/scene/sceneEdits.js.map +1 -1
- package/dist/core/scene/sceneMutators.js +1 -0
- package/dist/core/scene/sceneMutators.js.map +1 -1
- package/dist/core/scene/sceneRecording.js +20 -3
- package/dist/core/scene/sceneRecording.js.map +1 -1
- package/dist/core/scene/sceneSelection.js +4 -1
- package/dist/core/scene/sceneSelection.js.map +1 -1
- package/dist/core/scene/sceneState.js +11 -5
- package/dist/core/scene/sceneState.js.map +1 -1
- package/dist/core/scene/serialization.js +5 -3
- package/dist/core/scene/serialization.js.map +1 -1
- package/dist/core/scene/types.js.map +1 -1
- package/dist/core/scene/unitScopes.js +19 -1
- package/dist/core/scene/unitScopes.js.map +1 -1
- package/dist/core/selection/usePublishSceneSelection.js +6 -12
- package/dist/core/selection/usePublishSceneSelection.js.map +1 -1
- package/dist/core/shapeKinds.js +25 -11
- package/dist/core/shapeKinds.js.map +1 -1
- package/dist/{cornerHandles-Camw_yeu.d.ts → cornerHandles-p8fDIAKt.d.ts} +3 -2
- package/dist/debug/createDebugOverlayLayer.js +16 -111
- package/dist/debug/createDebugOverlayLayer.js.map +1 -1
- package/dist/debug/createDebugSink.js +2 -1
- package/dist/debug/createDebugSink.js.map +1 -1
- package/dist/debug/defaultTheme.js +4 -2
- package/dist/debug/defaultTheme.js.map +1 -1
- package/dist/debug/features.js +17 -0
- package/dist/debug/features.js.map +1 -0
- package/dist/debug/overlayPanels.js +117 -0
- package/dist/debug/overlayPanels.js.map +1 -0
- package/dist/debug/parseDebugFlags.js +4 -13
- package/dist/debug/parseDebugFlags.js.map +1 -1
- package/dist/{depSchema-Cgfu_G9s.d.ts → depSchema-mG19aEdD.d.ts} +174 -904
- package/dist/devtools/handlers.js +112 -0
- package/dist/devtools/handlers.js.map +1 -0
- package/dist/devtools/history.js +71 -0
- package/dist/devtools/history.js.map +1 -0
- package/dist/devtools/hook.js +74 -0
- package/dist/devtools/hook.js.map +1 -0
- package/dist/devtools/label.js +25 -0
- package/dist/devtools/label.js.map +1 -0
- package/dist/devtools/notices.js +58 -0
- package/dist/devtools/notices.js.map +1 -0
- package/dist/devtools/protocol.js +7 -0
- package/dist/devtools/protocol.js.map +1 -0
- package/dist/devtools/registry.js +90 -0
- package/dist/devtools/registry.js.map +1 -0
- package/dist/devtools/root.js +80 -0
- package/dist/devtools/root.js.map +1 -0
- package/dist/devtools/serialize.js +86 -0
- package/dist/devtools/serialize.js.map +1 -0
- package/dist/devtools/session.js +111 -0
- package/dist/devtools/session.js.map +1 -0
- package/dist/devtools/transport.js +67 -0
- package/dist/devtools/transport.js.map +1 -0
- package/dist/devtools/useDevtoolsRoot.js +81 -0
- package/dist/devtools/useDevtoolsRoot.js.map +1 -0
- package/dist/devtools-protocol.d.ts +435 -0
- package/dist/devtools-protocol.js +7 -0
- package/dist/devtools.d.ts +8 -0
- package/dist/devtools.js +12 -0
- package/dist/devtools.js.map +1 -0
- package/dist/features/chrome-caps/useHoverTracking.js +16 -10
- package/dist/features/chrome-caps/useHoverTracking.js.map +1 -1
- package/dist/features/ingestion/contentHandlers.js +25 -2
- package/dist/features/ingestion/contentHandlers.js.map +1 -1
- package/dist/features/measure/measureCommands.js +7 -5
- package/dist/features/measure/measureCommands.js.map +1 -1
- package/dist/features/measure/measureContribution.js +4 -2
- package/dist/features/measure/measureContribution.js.map +1 -1
- package/dist/features/modes/modeTriggers.js +7 -3
- package/dist/features/modes/modeTriggers.js.map +1 -1
- package/dist/features/pathEffects/effectSources.js +60 -0
- package/dist/features/pathEffects/effectSources.js.map +1 -0
- package/dist/features/pathEffects/readSource.js +17 -1
- package/dist/features/pathEffects/readSource.js.map +1 -1
- package/dist/features/pathEffects/textItems.js +53 -0
- package/dist/features/pathEffects/textItems.js.map +1 -0
- package/dist/features/pathEffects/useEffectSourcesLayer.js +57 -0
- package/dist/features/pathEffects/useEffectSourcesLayer.js.map +1 -0
- package/dist/features/paths/index.js +2 -2
- package/dist/features/paths/pathEditExtension.js.map +1 -1
- package/dist/features/paths/pathEditState.js +5 -2
- package/dist/features/paths/pathEditState.js.map +1 -1
- package/dist/features/paths/pathSnap/pathSnapSource.js +5 -5
- package/dist/features/paths/pathSnap/pathSnapSource.js.map +1 -1
- package/dist/features/paths/pathSnap/sceneIndex.js +10 -3
- package/dist/features/paths/pathSnap/sceneIndex.js.map +1 -1
- package/dist/features/selection/selectionPose.js +4 -1
- package/dist/features/selection/selectionPose.js.map +1 -1
- package/dist/features/snap/gather.js +9 -1
- package/dist/features/snap/gather.js.map +1 -1
- package/dist/features/snap/lazySession.js +17 -0
- package/dist/features/snap/lazySession.js.map +1 -0
- package/dist/features/snap/marks.js.map +1 -1
- package/dist/features/snap/probes2d.js +27 -19
- package/dist/features/snap/probes2d.js.map +1 -1
- package/dist/features/snap/readoutLayer.js.map +1 -1
- package/dist/features/snap/roles.js +2 -1
- package/dist/features/snap/roles.js.map +1 -1
- package/dist/features/snap/rotationSource.js +25 -8
- package/dist/features/snap/rotationSource.js.map +1 -1
- package/dist/features/snap/sceneSession2d.js +6 -4
- package/dist/features/snap/sceneSession2d.js.map +1 -1
- package/dist/features/snap/session2d.js +37 -23
- package/dist/features/snap/session2d.js.map +1 -1
- package/dist/features/snap/spanSnap.js +5 -2
- package/dist/features/snap/spanSnap.js.map +1 -1
- package/dist/features/text/sceneTextDrafts.js +65 -0
- package/dist/features/text/sceneTextDrafts.js.map +1 -0
- package/dist/features/text/textHitAt.js +31 -2
- package/dist/features/text/textHitAt.js.map +1 -1
- package/dist/features/text/useSceneTextEdit.js +22 -18
- package/dist/features/text/useSceneTextEdit.js.map +1 -1
- package/dist/features/viewports/aim.js +105 -0
- package/dist/features/viewports/aim.js.map +1 -0
- package/dist/features/viewports/viewMarker.js +82 -0
- package/dist/features/viewports/viewMarker.js.map +1 -0
- package/dist/features/viewports/viewMarkerDrag.js +55 -0
- package/dist/features/viewports/viewMarkerDrag.js.map +1 -0
- package/dist/icons.table.js +1 -1
- package/dist/icons.table.js.map +1 -1
- package/dist/icons.table.json +0 -10
- package/dist/index.d.ts +1198 -894
- package/dist/index.js +55 -38
- package/dist/interactions/actions/align/action.js +6 -4
- package/dist/interactions/actions/align/action.js.map +1 -1
- package/dist/interactions/actions/align/align.js.map +1 -1
- package/dist/interactions/actions/booleans/action.js +7 -1
- package/dist/interactions/actions/booleans/action.js.map +1 -1
- package/dist/interactions/actions/booleans/booleans.js +2 -1
- package/dist/interactions/actions/booleans/booleans.js.map +1 -1
- package/dist/interactions/actions/booleans/operands.js +6 -5
- package/dist/interactions/actions/booleans/operands.js.map +1 -1
- package/dist/interactions/actions/clipboard/action.js +27 -17
- package/dist/interactions/actions/clipboard/action.js.map +1 -1
- package/dist/interactions/actions/clone/action.js +1 -1
- package/dist/interactions/actions/clone/behaviors.js +4 -4
- package/dist/interactions/actions/clone/behaviors.js.map +1 -1
- package/dist/interactions/actions/defaults/anchorEditing.js +44 -23
- package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -1
- package/dist/interactions/actions/defaults/anchorJoin.js +12 -6
- package/dist/interactions/actions/defaults/anchorJoin.js.map +1 -1
- package/dist/interactions/actions/defaults/bendSegment.js +8 -5
- package/dist/interactions/actions/defaults/bendSegment.js.map +1 -1
- package/dist/interactions/actions/defaults/cancelGesture.js +11 -8
- package/dist/interactions/actions/defaults/cancelGesture.js.map +1 -1
- package/dist/interactions/actions/defaults/contextMenu.js +17 -8
- package/dist/interactions/actions/defaults/contextMenu.js.map +1 -1
- package/dist/interactions/actions/defaults/createPaintAction.js +2 -2
- package/dist/interactions/actions/defaults/createPaintAction.js.map +1 -1
- package/dist/interactions/actions/defaults/delete.js +64 -41
- package/dist/interactions/actions/defaults/delete.js.map +1 -1
- package/dist/interactions/actions/defaults/duplicate.js +12 -9
- package/dist/interactions/actions/defaults/duplicate.js.map +1 -1
- package/dist/interactions/actions/defaults/enterPathEdit.js +19 -9
- package/dist/interactions/actions/defaults/enterPathEdit.js.map +1 -1
- package/dist/interactions/actions/defaults/escape.js +11 -8
- package/dist/interactions/actions/defaults/escape.js.map +1 -1
- package/dist/interactions/actions/defaults/exitPathEdit.js +7 -4
- package/dist/interactions/actions/defaults/exitPathEdit.js.map +1 -1
- package/dist/interactions/actions/defaults/group.js +21 -15
- package/dist/interactions/actions/defaults/group.js.map +1 -1
- package/dist/interactions/actions/defaults/ingest.js +17 -9
- package/dist/interactions/actions/defaults/ingest.js.map +1 -1
- package/dist/interactions/actions/defaults/insertPathAnchor.js +7 -4
- package/dist/interactions/actions/defaults/insertPathAnchor.js.map +1 -1
- package/dist/interactions/actions/defaults/nudge.js +21 -40
- package/dist/interactions/actions/defaults/nudge.js.map +1 -1
- package/dist/interactions/actions/defaults/pathEditTools.js +11 -8
- package/dist/interactions/actions/defaults/pathEditTools.js.map +1 -1
- package/dist/interactions/actions/defaults/pinchZoom.js +7 -4
- package/dist/interactions/actions/defaults/pinchZoom.js.map +1 -1
- package/dist/interactions/actions/defaults/reorder.js +24 -6
- package/dist/interactions/actions/defaults/reorder.js.map +1 -1
- package/dist/interactions/actions/defaults/selectAll.js +8 -5
- package/dist/interactions/actions/defaults/selectAll.js.map +1 -1
- package/dist/interactions/actions/defaults/setFill.js +7 -3
- package/dist/interactions/actions/defaults/setFill.js.map +1 -1
- package/dist/interactions/actions/defaults/setFillOpacity.js +1 -1
- package/dist/interactions/actions/defaults/setStroke.js +12 -11
- package/dist/interactions/actions/defaults/setStroke.js.map +1 -1
- package/dist/interactions/actions/defaults/setStrokeOpacity.js +1 -1
- package/dist/interactions/actions/defaults/toolActivate.js +7 -1
- package/dist/interactions/actions/defaults/toolActivate.js.map +1 -1
- package/dist/interactions/actions/defaults/toolResetToDefault.js +7 -4
- package/dist/interactions/actions/defaults/toolResetToDefault.js.map +1 -1
- package/dist/interactions/actions/defaults/undoRedo.js +19 -13
- package/dist/interactions/actions/defaults/undoRedo.js.map +1 -1
- package/dist/interactions/actions/defaults/viewportWheelPan.js +16 -7
- package/dist/interactions/actions/defaults/viewportWheelPan.js.map +1 -1
- package/dist/interactions/actions/defaults/viewportZoom.js +24 -6
- package/dist/interactions/actions/defaults/viewportZoom.js.map +1 -1
- package/dist/interactions/actions/distribute/action.js +6 -4
- package/dist/interactions/actions/distribute/action.js.map +1 -1
- package/dist/interactions/actions/drawnBoxes.js +2 -1
- package/dist/interactions/actions/drawnBoxes.js.map +1 -1
- package/dist/interactions/actions/edit-anchors/action.js +10 -10
- package/dist/interactions/actions/edit-anchors/action.js.map +1 -1
- package/dist/interactions/actions/edit-anchors/preview.js +41 -8
- package/dist/interactions/actions/edit-anchors/preview.js.map +1 -1
- package/dist/interactions/actions/flip/action.js +14 -6
- package/dist/interactions/actions/flip/action.js.map +1 -1
- package/dist/interactions/actions/gestureLifecycle.js +5 -2
- package/dist/interactions/actions/gestureLifecycle.js.map +1 -1
- package/dist/interactions/actions/insert/action.js +1 -2
- package/dist/interactions/actions/insert/action.js.map +1 -1
- package/dist/interactions/actions/insert/commit.js +1 -1
- package/dist/interactions/actions/insert/parent.js +11 -0
- package/dist/interactions/actions/insert/parent.js.map +1 -0
- package/dist/interactions/actions/insert/placeAction.js +7 -2
- package/dist/interactions/actions/insert/placeAction.js.map +1 -1
- package/dist/interactions/actions/insert/repositionAction.js +2 -1
- package/dist/interactions/actions/insert/repositionAction.js.map +1 -1
- package/dist/interactions/actions/insert/session.js +5 -1
- package/dist/interactions/actions/insert/session.js.map +1 -1
- package/dist/interactions/actions/move/action.js +15 -8
- package/dist/interactions/actions/move/action.js.map +1 -1
- package/dist/interactions/actions/move/behaviors/layoutDrop.js +0 -1
- package/dist/interactions/actions/move/behaviors/layoutDrop.js.map +1 -1
- package/dist/interactions/actions/move/behaviors/snapToContainer.js +1 -1
- package/dist/interactions/actions/move/capture.js +1 -1
- package/dist/interactions/actions/move/commit/index.js +0 -2
- package/dist/interactions/actions/move/commit/index.js.map +1 -1
- package/dist/interactions/actions/move/commit/layoutDrop.js +2 -2
- package/dist/interactions/actions/move/commit/layoutRelease.js +2 -2
- package/dist/interactions/actions/move/commit/reparent.js +11 -5
- package/dist/interactions/actions/move/commit/reparent.js.map +1 -1
- package/dist/interactions/actions/move/frame.js +4 -10
- package/dist/interactions/actions/move/frame.js.map +1 -1
- package/dist/interactions/actions/move/landedDescendants.js +20 -17
- package/dist/interactions/actions/move/landedDescendants.js.map +1 -1
- package/dist/interactions/actions/move/layout/container.js +2 -1
- package/dist/interactions/actions/move/layout/container.js.map +1 -1
- package/dist/interactions/actions/move/layout/dragged.js +1 -1
- package/dist/interactions/actions/move/layout/dropPass.js +18 -1
- package/dist/interactions/actions/move/layout/dropPass.js.map +1 -1
- package/dist/interactions/actions/move/layout/exits.js +5 -5
- package/dist/interactions/actions/move/layout/exits.js.map +1 -1
- package/dist/interactions/actions/move/session.js +14 -3
- package/dist/interactions/actions/move/session.js.map +1 -1
- package/dist/interactions/actions/move/translate.js +8 -37
- package/dist/interactions/actions/move/translate.js.map +1 -1
- package/dist/interactions/actions/moveNodes.js +87 -0
- package/dist/interactions/actions/moveNodes.js.map +1 -0
- package/dist/interactions/actions/outlines/createOutlinesAction.js +8 -5
- package/dist/interactions/actions/outlines/createOutlinesAction.js.map +1 -1
- package/dist/interactions/actions/outlines/outlineStroke.js +5 -3
- package/dist/interactions/actions/outlines/outlineStroke.js.map +1 -1
- package/dist/interactions/actions/pathCommands/cutJoin.js +8 -5
- package/dist/interactions/actions/pathCommands/cutJoin.js.map +1 -1
- package/dist/interactions/actions/planeInput.js.map +1 -1
- package/dist/interactions/actions/resize/action.js +83 -72
- package/dist/interactions/actions/resize/action.js.map +1 -1
- package/dist/interactions/actions/resize/commit.js +2 -1
- package/dist/interactions/actions/resize/commit.js.map +1 -1
- package/dist/interactions/actions/resize/cornerHandles.js +2 -1
- package/dist/interactions/actions/resize/cornerHandles.js.map +1 -1
- package/dist/interactions/actions/resize/session.js +2 -0
- package/dist/interactions/actions/resize/session.js.map +1 -1
- package/dist/interactions/actions/resolvePreviews.js +3 -3
- package/dist/interactions/actions/resolvePreviews.js.map +1 -1
- package/dist/interactions/actions/rotate/action.js +7 -4
- package/dist/interactions/actions/rotate/action.js.map +1 -1
- package/dist/interactions/actions/rotate/commit.js +2 -1
- package/dist/interactions/actions/rotate/commit.js.map +1 -1
- package/dist/interactions/actions/rotate/session.js +2 -0
- package/dist/interactions/actions/rotate/session.js.map +1 -1
- package/dist/interactions/actions/selectionSubtree.js +25 -9
- package/dist/interactions/actions/selectionSubtree.js.map +1 -1
- package/dist/interactions/actions/testUtils.js.map +1 -1
- package/dist/interactions/actions/transform-again/action.js +13 -11
- package/dist/interactions/actions/transform-again/action.js.map +1 -1
- package/dist/interactions/actions/transformFinish.js +106 -0
- package/dist/interactions/actions/transformFinish.js.map +1 -0
- package/dist/json.d.ts +4 -0
- package/dist/json.js +3 -0
- package/dist/kitSettingsSchema.js +8 -5
- package/dist/kitSettingsSchema.js.map +1 -1
- package/dist/{math-CrJULaZI.d.ts → math-B56zxVs5.d.ts} +10 -1
- package/dist/math.d.ts +1 -1
- package/dist/math.js +2 -1
- package/dist/move.d.ts +5 -4
- package/dist/{options-p9GZMXbY.d.ts → options-DBxEryYq.d.ts} +1 -1
- package/dist/resize.d.ts +4 -3
- package/dist/routing.d.ts +1 -1
- package/dist/routing.js +2 -2
- package/dist/test-hook/createTestHook.js +1 -1
- package/dist/test-hook/createTestHook.js.map +1 -1
- package/dist/test-hook/useTestHook.js +2 -1
- package/dist/test-hook/useTestHook.js.map +1 -1
- package/dist/test-seams.d.ts +9 -5
- package/dist/tools/builtin/ellipse/useEllipseTool.js +1 -0
- package/dist/tools/builtin/ellipse/useEllipseTool.js.map +1 -1
- package/dist/tools/builtin/eyedropper/useEyedropperTool.js +2 -1
- package/dist/tools/builtin/eyedropper/useEyedropperTool.js.map +1 -1
- package/dist/tools/builtin/hand/dragPanContribution.js +4 -1
- package/dist/tools/builtin/hand/dragPanContribution.js.map +1 -1
- package/dist/tools/builtin/hand/useHandTool.js +7 -4
- package/dist/tools/builtin/hand/useHandTool.js.map +1 -1
- package/dist/tools/builtin/image/useImageTool.js +1 -0
- package/dist/tools/builtin/image/useImageTool.js.map +1 -1
- package/dist/tools/builtin/lasso/useLassoTool.js +1 -0
- package/dist/tools/builtin/lasso/useLassoTool.js.map +1 -1
- package/dist/tools/builtin/line/useLineTool.js +1 -0
- package/dist/tools/builtin/line/useLineTool.js.map +1 -1
- package/dist/tools/builtin/measure/useMeasureTool.js +12 -5
- package/dist/tools/builtin/measure/useMeasureTool.js.map +1 -1
- package/dist/tools/builtin/pen/penHandle.js +3 -5
- package/dist/tools/builtin/pen/penHandle.js.map +1 -1
- package/dist/tools/builtin/pen/usePenTool.js +14 -6
- package/dist/tools/builtin/pen/usePenTool.js.map +1 -1
- package/dist/tools/builtin/pencil/usePencilTool.js +1 -0
- package/dist/tools/builtin/pencil/usePencilTool.js.map +1 -1
- package/dist/tools/builtin/polygon/usePolygonTool.js +13 -4
- package/dist/tools/builtin/polygon/usePolygonTool.js.map +1 -1
- package/dist/tools/builtin/rect/useRectTool.js +1 -0
- package/dist/tools/builtin/rect/useRectTool.js.map +1 -1
- package/dist/tools/builtin/select/adapterPointQuery.js +3 -2
- package/dist/tools/builtin/select/adapterPointQuery.js.map +1 -1
- package/dist/tools/builtin/select/pressDecision.js +32 -0
- package/dist/tools/builtin/select/pressDecision.js.map +1 -0
- package/dist/tools/builtin/select/selectionContributions.js +22 -13
- package/dist/tools/builtin/select/selectionContributions.js.map +1 -1
- package/dist/tools/builtin/select/useSelectTool.js +13 -10
- package/dist/tools/builtin/select/useSelectTool.js.map +1 -1
- package/dist/tools/builtin/slice/useSliceTool.js +22 -8
- package/dist/tools/builtin/slice/useSliceTool.js.map +1 -1
- package/dist/tools/builtin/star/useStarTool.js +13 -4
- package/dist/tools/builtin/star/useStarTool.js.map +1 -1
- package/dist/tools/builtin/sticky/stickyNode.js +4 -1
- package/dist/tools/builtin/sticky/stickyNode.js.map +1 -1
- package/dist/tools/builtin/sticky/useStickyTool.js +10 -5
- package/dist/tools/builtin/sticky/useStickyTool.js.map +1 -1
- package/dist/tools/builtin/text/useTextTool.js +3 -1
- package/dist/tools/builtin/text/useTextTool.js.map +1 -1
- package/dist/tools/index.js +26 -0
- package/dist/{types-CHVXGfYm.d.ts → types-7puAuVD2.d.ts} +3 -262
- package/dist/types-BN9hbdMI.d.ts +184 -0
- package/dist/types-CniVctmk.d.ts +949 -0
- package/dist/types-oFeQ5VjV.d.ts +264 -0
- package/dist/util/paint.js +1 -3
- package/dist/util/paint.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +39 -25
- package/dist/canvas/SceneCanvas/useBuiltinRigTools.js +0 -65
- package/dist/canvas/SceneCanvas/useBuiltinRigTools.js.map +0 -1
- package/dist/tools/builtin/bone/boneActions.js +0 -156
- package/dist/tools/builtin/bone/boneActions.js.map +0 -1
- package/dist/tools/builtin/bone/boneOverlay.js +0 -71
- package/dist/tools/builtin/bone/boneOverlay.js.map +0 -1
- package/dist/tools/builtin/bone/placedRig.js +0 -28
- package/dist/tools/builtin/bone/placedRig.js.map +0 -1
- package/dist/tools/builtin/bone/rigEditState.js +0 -30
- package/dist/tools/builtin/bone/rigEditState.js.map +0 -1
- package/dist/tools/builtin/bone/useBoneTool.js +0 -125
- package/dist/tools/builtin/bone/useBoneTool.js.map +0 -1
- package/dist/tools/builtin/weight/useWeightTool.js +0 -101
- package/dist/tools/builtin/weight/useWeightTool.js.map +0 -1
- package/dist/tools/builtin/weight/weightActions.js +0 -140
- package/dist/tools/builtin/weight/weightActions.js.map +0 -1
- package/dist/tools/builtin/weight/weightOverlay.js +0 -78
- package/dist/tools/builtin/weight/weightOverlay.js.map +0 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { axisAlignedBounds } from "../core/geometry/unionBounds.js";
|
|
1
|
+
import { axisAlignedBounds, unionBounds } from "../core/geometry/unionBounds.js";
|
|
2
2
|
import { framedBounds, poseDescriptorForNode } from "../core/geometry/poseDescriptor.js";
|
|
3
3
|
import { AUTO_POSE_DESCRIPTOR } from "../core/geometry/autoPoseDescriptor.js";
|
|
4
|
+
import { inheritedPaintIn } from "./inheritedPaints.js";
|
|
4
5
|
import { targetCorners, targetTransformOf, worldToLocal } from "../core/geometry/targetFrame.js";
|
|
5
6
|
import { NO_INK_EXTENTS, inkExtentsBetween, outsetBox } from "../core/geometry/inkExtents.js";
|
|
6
7
|
import { findNodeShape } from "./NodeShape.js";
|
|
7
|
-
import { meanScale } from "@weasel-js/geom";
|
|
8
|
+
import { boundsOfPath, meanScale } from "@weasel-js/geom";
|
|
8
9
|
|
|
9
10
|
//#region src/canvas/drawnBounds.ts
|
|
10
11
|
/**
|
|
@@ -18,9 +19,12 @@ import { meanScale } from "@weasel-js/geom";
|
|
|
18
19
|
* drawn in: a turned node's box comes back turned with it. A node with no
|
|
19
20
|
* stroke, a painter that declares no {@link NodeShapeEntry.drawnBounds}, or
|
|
20
21
|
* `includeStroke: false` answers `framedBounds` unchanged. A container's box
|
|
21
|
-
* reaches as far as its members' boxes do.
|
|
22
|
+
* reaches as far as its members' boxes do. A node showing a derived path is
|
|
23
|
+
* boxed around that path, and its placeholder pose plays no part.
|
|
22
24
|
*/
|
|
23
25
|
function drawnBoundsOf(scene, id, pose, opts = {}) {
|
|
26
|
+
const derived = scene.derivedPathOf?.(id) ?? null;
|
|
27
|
+
if (derived !== null) return derivedBoundsOf(scene, id, pose, derived, opts);
|
|
24
28
|
return outsetBox(framedBounds(pose, descriptorFor(scene, id, opts)), inkExtentsOf(scene, id, pose, opts));
|
|
25
29
|
}
|
|
26
30
|
/** How far `id`'s ink at `pose` reaches past its pose box on each side, in
|
|
@@ -38,9 +42,32 @@ function inkExtentsOf(scene, id, pose, opts = {}) {
|
|
|
38
42
|
};
|
|
39
43
|
const members = node.kind === "container" ? scene.childrenOf?.(id) ?? [] : [];
|
|
40
44
|
if (members.length > 0) return membersExtents(scene, members, own, opts);
|
|
41
|
-
const drawn = findShapeDrawnBounds(node, pose, inkCtx(opts.scale, own));
|
|
45
|
+
const drawn = findShapeDrawnBounds(node, pose, withInherited(scene, node, inkCtx(opts.scale, own)));
|
|
42
46
|
return drawn === null ? NO_INK_EXTENTS : inkExtentsBetween(normalized(unframed), drawn);
|
|
43
47
|
}
|
|
48
|
+
/** The box of a node drawn along `path`: the path's own, grown by the stroke
|
|
49
|
+
* its painter reports. */
|
|
50
|
+
function derivedBoundsOf(scene, id, pose, path, opts) {
|
|
51
|
+
const { x, y, width, height } = boundsOfPath(path);
|
|
52
|
+
const own = {
|
|
53
|
+
x,
|
|
54
|
+
y,
|
|
55
|
+
width,
|
|
56
|
+
height
|
|
57
|
+
};
|
|
58
|
+
const node = scene.get(id);
|
|
59
|
+
if (opts.includeStroke === false || !node) return own;
|
|
60
|
+
const drawn = findShapeDrawnBounds(node, pose, {
|
|
61
|
+
...withInherited(scene, node, inkCtx(opts.scale, {
|
|
62
|
+
x: 0,
|
|
63
|
+
y: 0,
|
|
64
|
+
width: 0,
|
|
65
|
+
height: 0
|
|
66
|
+
})),
|
|
67
|
+
derivedPath: path
|
|
68
|
+
});
|
|
69
|
+
return drawn === null ? own : unionBounds([own, drawn]) ?? own;
|
|
70
|
+
}
|
|
44
71
|
/** A container's extents: its members' drawn boxes, taken into its own frame,
|
|
45
72
|
* past its own box. */
|
|
46
73
|
function membersExtents(scene, members, own, opts) {
|
|
@@ -102,6 +129,13 @@ function inkCtx(scale, own) {
|
|
|
102
129
|
]
|
|
103
130
|
};
|
|
104
131
|
}
|
|
132
|
+
function withInherited(scene, node, ctx) {
|
|
133
|
+
const inherited = inheritedPaintIn(scene, node);
|
|
134
|
+
return inherited === void 0 ? ctx : {
|
|
135
|
+
...ctx,
|
|
136
|
+
inherited
|
|
137
|
+
};
|
|
138
|
+
}
|
|
105
139
|
function normalized(b) {
|
|
106
140
|
return {
|
|
107
141
|
x: Math.min(b.x, b.x + b.width),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drawnBounds.js","names":[],"sources":["../../src/canvas/drawnBounds.ts"],"sourcesContent":["/**\n * The box of a node as drawn — its pose box with the stroke included — which\n * is what selection chrome, resize, rotate, and alignment sit on. Places that\n * store geometry (a group's derived pose, booleans, export) keep reading the\n * pose box through `framedBounds`.\n */\nimport { framedBounds, poseDescriptorForNode, type PoseDescriptor } from 'core/geometry/poseDescriptor';\nimport {\n inkExtentsBetween,\n NO_INK_EXTENTS,\n outsetBox,\n type InkExtents,\n} from 'core/geometry/inkExtents';\nimport { targetCorners, targetTransformOf, worldToLocal } from 'core/geometry/targetFrame';\nimport { axisAlignedBounds } from 'core/geometry/unionBounds';\nimport type { Node, NodeId } from 'core/scene/types';\nimport type { Bounds } from 'core/viewport/fitViewToBounds';\nimport { meanScale, type Scale2 } from '@weasel-js/geom';\nimport { AUTO_POSE_DESCRIPTOR } from 'core/geometry/autoPoseDescriptor';\nimport { findNodeShape, type NodeInkCtx } from './NodeShape';\n\n/** The scene reads {@link drawnBoundsOf} makes. `childrenOf` absent: every\n * node is a leaf. */\nexport interface DrawnBoundsScene {\n get(id: NodeId): Node<unknown, string, unknown> | undefined;\n childrenOf?(id: NodeId): readonly NodeId[];\n}\n\n/** How {@link drawnBoundsOf} reads a node. */\nexport interface DrawnBoundsOptions {\n /** How poses are read. Default `AUTO_POSE_DESCRIPTOR`. */\n descriptor?: PoseDescriptor<unknown>;\n /** A member's world pose, for boxing a container around its members.\n * Default: its pose as stored, which is world unless containers compose. */\n worldPoseOf?: (id: NodeId) => unknown;\n /** `false` answers the pose box alone. Default `true`. */\n includeStroke?: boolean;\n /** View scale, which a screen-pixel stroke width is resolved at. Default 1. */\n scale?: number | Scale2;\n}\n\n/**\n * The box of `id` drawn at `pose`, stroke included, in the frame the pose is\n * drawn in: a turned node's box comes back turned with it. A node with no\n * stroke, a painter that declares no {@link NodeShapeEntry.drawnBounds}, or\n * `includeStroke: false` answers `framedBounds` unchanged. A container's box\n * reaches as far as its members' boxes do.\n */\nexport function drawnBoundsOf(\n scene: DrawnBoundsScene,\n id: NodeId,\n pose: unknown,\n opts: DrawnBoundsOptions = {},\n): Bounds {\n return outsetBox(framedBounds(pose, descriptorFor(scene, id, opts)), inkExtentsOf(scene, id, pose, opts));\n}\n\n/** How far `id`'s ink at `pose` reaches past its pose box on each side, in\n * the box's own frame: what {@link drawnBoundsOf} grows the pose box by. */\nexport function inkExtentsOf(\n scene: DrawnBoundsScene,\n id: NodeId,\n pose: unknown,\n opts: DrawnBoundsOptions = {},\n): InkExtents {\n if (opts.includeStroke === false) return NO_INK_EXTENTS;\n const node = scene.get(id);\n if (!node) return NO_INK_EXTENTS;\n const own = framedBounds(pose, descriptorFor(scene, id, opts));\n const unframed = { x: own.x, y: own.y, width: own.width, height: own.height };\n const members = node.kind === 'container' ? scene.childrenOf?.(id) ?? [] : [];\n if (members.length > 0) return membersExtents(scene, members, own, opts);\n const drawn = findShapeDrawnBounds(node, pose, inkCtx(opts.scale, own));\n return drawn === null ? NO_INK_EXTENTS : inkExtentsBetween(normalized(unframed), drawn);\n}\n\n/** A container's extents: its members' drawn boxes, taken into its own frame,\n * past its own box. */\nfunction membersExtents(\n scene: DrawnBoundsScene,\n members: readonly NodeId[],\n own: Bounds,\n opts: DrawnBoundsOptions,\n): InkExtents {\n const xf = targetTransformOf(own);\n const worldPoseOf = opts.worldPoseOf ?? ((m: NodeId) => scene.get(m)?.pose);\n let x0 = Infinity, y0 = Infinity, x1 = -Infinity, y1 = -Infinity;\n for (const m of members) {\n const box = drawnBoundsOf(scene, m, worldPoseOf(m), opts);\n for (const c of targetCorners(box, targetTransformOf(box))) {\n const p = worldToLocal(xf, c.x, c.y);\n if (!p) continue;\n x0 = Math.min(x0, p.x); y0 = Math.min(y0, p.y);\n x1 = Math.max(x1, p.x); y1 = Math.max(y1, p.y);\n }\n }\n if (x0 === Infinity) return NO_INK_EXTENTS;\n return inkExtentsBetween(normalized(own), { x: x0, y: y0, width: x1 - x0, height: y1 - y0 });\n}\n\n/** {@link drawnBoundsOf} as an axis-aligned box: what a turned node covers. */\nexport function drawnAABBOf(\n scene: DrawnBoundsScene,\n id: NodeId,\n pose: unknown,\n opts: DrawnBoundsOptions = {},\n): Bounds {\n return axisAlignedBounds(drawnBoundsOf(scene, id, pose, opts));\n}\n\n/** The painter's {@link NodeShapeEntry.drawnBounds} for `node`, or `null`\n * when no painter matches or the one that does declares none. */\nexport function findShapeDrawnBounds<TData, TPose>(\n node: Node<TData, string, TPose>,\n pose: TPose,\n ctx?: NodeInkCtx,\n): Bounds | null {\n return findNodeShape(node)?.drawnBounds?.(node, pose, ctx) ?? null;\n}\n\nfunction descriptorFor(scene: DrawnBoundsScene, id: NodeId, opts: DrawnBoundsOptions): PoseDescriptor<unknown> {\n const d = opts.descriptor ?? AUTO_POSE_DESCRIPTOR;\n const node = scene.get(id);\n return node ? poseDescriptorForNode(d, node) : d;\n}\n\n/** A per-axis view scale also carries the map from `own`'s frame to screen,\n * so a `{ px }` stroke is measured there rather than at the mean. */\nfunction inkCtx(scale: number | Scale2 | undefined, own: Bounds): NodeInkCtx | undefined {\n if (scale === undefined) return undefined;\n if (typeof scale === 'number') return { scale };\n const xf = targetTransformOf(own);\n const [a, b, c, d] = xf.identity ? [1, 0, 0, 1] : xf.toWorld;\n return { scale: meanScale(scale), screen: [scale.x * a, scale.y * b, scale.x * c, scale.y * d] };\n}\n\nfunction normalized(b: Bounds): Bounds {\n return {\n x: Math.min(b.x, b.x + b.width),\n y: Math.min(b.y, b.y + b.height),\n width: Math.abs(b.width),\n height: Math.abs(b.height),\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"drawnBounds.js","names":[],"sources":["../../src/canvas/drawnBounds.ts"],"sourcesContent":["/**\n * The box of a node as drawn — its pose box with the stroke included — which\n * is what selection chrome, resize, rotate, and alignment sit on. Places that\n * store geometry (a group's derived pose, booleans, export) keep reading the\n * pose box through `framedBounds`.\n */\nimport { inheritedPaintIn } from './inheritedPaints';\nimport { framedBounds, poseDescriptorForNode, type PoseDescriptor } from 'core/geometry/poseDescriptor';\nimport {\n inkExtentsBetween,\n NO_INK_EXTENTS,\n outsetBox,\n type InkExtents,\n} from 'core/geometry/inkExtents';\nimport { targetCorners, targetTransformOf, worldToLocal } from 'core/geometry/targetFrame';\nimport { axisAlignedBounds, unionBounds } from 'core/geometry/unionBounds';\nimport type { Node, NodeId } from 'core/scene/types';\nimport type { Bounds } from 'core/viewport/fitViewToBounds';\nimport { boundsOfPath, meanScale, type Path, type Scale2 } from '@weasel-js/geom';\nimport { AUTO_POSE_DESCRIPTOR } from 'core/geometry/autoPoseDescriptor';\nimport { findNodeShape, type NodeInkCtx } from './NodeShape';\n\n/** The scene reads {@link drawnBoundsOf} makes. `childrenOf` absent: every\n * node is a leaf. `derivedPathOf` absent: every node is measured by its pose,\n * a path-derived one included — `drawnBoundsScene` supplies it for a `Scene`. */\nexport interface DrawnBoundsScene {\n get(id: NodeId): Node<unknown, string, unknown> | undefined;\n childrenOf?(id: NodeId): readonly NodeId[];\n /** The path a node shows in place of its pose's, or `null` for one that shows its own. */\n derivedPathOf?(id: NodeId): Path | null;\n}\n\n/** How {@link drawnBoundsOf} reads a node. */\nexport interface DrawnBoundsOptions {\n /** How poses are read. Default `AUTO_POSE_DESCRIPTOR`. */\n descriptor?: PoseDescriptor<unknown>;\n /** A member's world pose, for boxing a container around its members.\n * Default: its pose as stored, which is world unless containers compose. */\n worldPoseOf?: (id: NodeId) => unknown;\n /** `false` answers the pose box alone. Default `true`. */\n includeStroke?: boolean;\n /** View scale, which a screen-pixel stroke width is resolved at. Default 1. */\n scale?: number | Scale2;\n}\n\n/**\n * The box of `id` drawn at `pose`, stroke included, in the frame the pose is\n * drawn in: a turned node's box comes back turned with it. A node with no\n * stroke, a painter that declares no {@link NodeShapeEntry.drawnBounds}, or\n * `includeStroke: false` answers `framedBounds` unchanged. A container's box\n * reaches as far as its members' boxes do. A node showing a derived path is\n * boxed around that path, and its placeholder pose plays no part.\n */\nexport function drawnBoundsOf(\n scene: DrawnBoundsScene,\n id: NodeId,\n pose: unknown,\n opts: DrawnBoundsOptions = {},\n): Bounds {\n const derived = scene.derivedPathOf?.(id) ?? null;\n if (derived !== null) return derivedBoundsOf(scene, id, pose, derived, opts);\n return outsetBox(framedBounds(pose, descriptorFor(scene, id, opts)), inkExtentsOf(scene, id, pose, opts));\n}\n\n/** How far `id`'s ink at `pose` reaches past its pose box on each side, in\n * the box's own frame: what {@link drawnBoundsOf} grows the pose box by. */\nexport function inkExtentsOf(\n scene: DrawnBoundsScene,\n id: NodeId,\n pose: unknown,\n opts: DrawnBoundsOptions = {},\n): InkExtents {\n if (opts.includeStroke === false) return NO_INK_EXTENTS;\n const node = scene.get(id);\n if (!node) return NO_INK_EXTENTS;\n const own = framedBounds(pose, descriptorFor(scene, id, opts));\n const unframed = { x: own.x, y: own.y, width: own.width, height: own.height };\n const members = node.kind === 'container' ? scene.childrenOf?.(id) ?? [] : [];\n if (members.length > 0) return membersExtents(scene, members, own, opts);\n const drawn = findShapeDrawnBounds(node, pose, withInherited(scene, node, inkCtx(opts.scale, own)));\n return drawn === null ? NO_INK_EXTENTS : inkExtentsBetween(normalized(unframed), drawn);\n}\n\n/** The box of a node drawn along `path`: the path's own, grown by the stroke\n * its painter reports. */\nfunction derivedBoundsOf(scene: DrawnBoundsScene, id: NodeId, pose: unknown, path: Path, opts: DrawnBoundsOptions): Bounds {\n const { x, y, width, height } = boundsOfPath(path);\n const own = { x, y, width, height };\n const node = scene.get(id);\n if (opts.includeStroke === false || !node) return own;\n const ctx = { ...withInherited(scene, node, inkCtx(opts.scale, { x: 0, y: 0, width: 0, height: 0 })), derivedPath: path };\n const drawn = findShapeDrawnBounds(node, pose, ctx);\n return drawn === null ? own : unionBounds([own, drawn]) ?? own;\n}\n\n/** A container's extents: its members' drawn boxes, taken into its own frame,\n * past its own box. */\nfunction membersExtents(\n scene: DrawnBoundsScene,\n members: readonly NodeId[],\n own: Bounds,\n opts: DrawnBoundsOptions,\n): InkExtents {\n const xf = targetTransformOf(own);\n const worldPoseOf = opts.worldPoseOf ?? ((m: NodeId) => scene.get(m)?.pose);\n let x0 = Infinity, y0 = Infinity, x1 = -Infinity, y1 = -Infinity;\n for (const m of members) {\n const box = drawnBoundsOf(scene, m, worldPoseOf(m), opts);\n for (const c of targetCorners(box, targetTransformOf(box))) {\n const p = worldToLocal(xf, c.x, c.y);\n if (!p) continue;\n x0 = Math.min(x0, p.x); y0 = Math.min(y0, p.y);\n x1 = Math.max(x1, p.x); y1 = Math.max(y1, p.y);\n }\n }\n if (x0 === Infinity) return NO_INK_EXTENTS;\n return inkExtentsBetween(normalized(own), { x: x0, y: y0, width: x1 - x0, height: y1 - y0 });\n}\n\n/** {@link drawnBoundsOf} as an axis-aligned box: what a turned node covers. */\nexport function drawnAABBOf(\n scene: DrawnBoundsScene,\n id: NodeId,\n pose: unknown,\n opts: DrawnBoundsOptions = {},\n): Bounds {\n return axisAlignedBounds(drawnBoundsOf(scene, id, pose, opts));\n}\n\n/** The painter's {@link NodeShapeEntry.drawnBounds} for `node`, or `null`\n * when no painter matches or the one that does declares none. */\nexport function findShapeDrawnBounds<TData, TPose>(\n node: Node<TData, string, TPose>,\n pose: TPose,\n ctx?: NodeInkCtx,\n): Bounds | null {\n return findNodeShape(node)?.drawnBounds?.(node, pose, ctx) ?? null;\n}\n\nfunction descriptorFor(scene: DrawnBoundsScene, id: NodeId, opts: DrawnBoundsOptions): PoseDescriptor<unknown> {\n const d = opts.descriptor ?? AUTO_POSE_DESCRIPTOR;\n const node = scene.get(id);\n return node ? poseDescriptorForNode(d, node) : d;\n}\n\n/** A per-axis view scale also carries the map from `own`'s frame to screen,\n * so a `{ px }` stroke is measured there rather than at the mean. */\nfunction inkCtx(scale: number | Scale2 | undefined, own: Bounds): NodeInkCtx | undefined {\n if (scale === undefined) return undefined;\n if (typeof scale === 'number') return { scale };\n const xf = targetTransformOf(own);\n const [a, b, c, d] = xf.identity ? [1, 0, 0, 1] : xf.toWorld;\n return { scale: meanScale(scale), screen: [scale.x * a, scale.y * b, scale.x * c, scale.y * d] };\n}\n\nfunction withInherited(\n scene: DrawnBoundsScene,\n node: Node<unknown, string, unknown>,\n ctx: NodeInkCtx | undefined,\n): NodeInkCtx | undefined {\n const inherited = inheritedPaintIn(scene, node);\n return inherited === undefined ? ctx : { ...ctx, inherited };\n}\n\nfunction normalized(b: Bounds): Bounds {\n return {\n x: Math.min(b.x, b.x + b.width),\n y: Math.min(b.y, b.y + b.height),\n width: Math.abs(b.width),\n height: Math.abs(b.height),\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { inheritedPaintOf, inheritsPaint, sceneAncestors } from "../core/scene/inheritedPaint.js";
|
|
2
|
+
import { INHERIT } from "@weasel-js/paint";
|
|
3
|
+
|
|
4
|
+
//#region src/canvas/inheritedPaints.ts
|
|
5
|
+
/** What `node`'s `'inherit'` fields take from its containers in `scene`, or
|
|
6
|
+
* `undefined` for a node that inherits nothing. */
|
|
7
|
+
function inheritedPaintIn(scene, node) {
|
|
8
|
+
if (!inheritsPaint(node)) return void 0;
|
|
9
|
+
return inheritedPaintOf(node, sceneAncestors((id) => scene.get(id), node));
|
|
10
|
+
}
|
|
11
|
+
var INHERITS_BOTH = { data: {
|
|
12
|
+
fill: INHERIT,
|
|
13
|
+
stroke: INHERIT
|
|
14
|
+
} };
|
|
15
|
+
/** What an `'inherit'` fill and stroke on `node` would take from its
|
|
16
|
+
* containers in `scene`, whatever `node` holds now — what an editor offering
|
|
17
|
+
* the choice shows it would paint. */
|
|
18
|
+
function paintAbove(scene, node) {
|
|
19
|
+
return inheritedPaintOf(INHERITS_BOTH, sceneAncestors((id) => scene.get(id), node));
|
|
20
|
+
}
|
|
21
|
+
/** {@link inheritedPaintIn} bound to `scene`. */
|
|
22
|
+
function sceneInheritedPaintOf(scene) {
|
|
23
|
+
return (node) => inheritedPaintIn(scene, node);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Wrap a `drawOne` so a node whose fill or stroke is `'inherit'` arrives at
|
|
27
|
+
* the painter with its containers' paint on `ctx.inherited`, as
|
|
28
|
+
* `withDerivedPaths` does for a derived path. Every other node passes the
|
|
29
|
+
* caller's `ctx` through untouched.
|
|
30
|
+
*/
|
|
31
|
+
function withInheritedPaints(scene, drawOne) {
|
|
32
|
+
const inheritedOf = sceneInheritedPaintOf(scene);
|
|
33
|
+
return (node, pose, view, ctx) => {
|
|
34
|
+
const inherited = inheritedOf(node);
|
|
35
|
+
return inherited === void 0 ? drawOne(node, pose, view, ctx) : drawOne(node, pose, view, {
|
|
36
|
+
...ctx,
|
|
37
|
+
inherited
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
//#endregion
|
|
43
|
+
export { inheritedPaintIn, paintAbove, sceneInheritedPaintOf, withInheritedPaints };
|
|
44
|
+
//# sourceMappingURL=inheritedPaints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inheritedPaints.js","names":[],"sources":["../../src/canvas/inheritedPaints.ts"],"sourcesContent":["import { INHERIT } from '@weasel-js/paint';\nimport type { Node, NodeId } from 'core/scene/types';\nimport { inheritedPaintOf, inheritsPaint, sceneAncestors, type InheritedPaint } from 'core/scene/inheritedPaint';\nimport type { SceneViewDrawOne } from './nodeShapeTypes';\n\n/** The part of a scene the lookup reads. */\ntype ParentLookup<TNode> = { get(id: NodeId): TNode | undefined };\n\ntype PaintedNode = { data?: unknown; parent?: NodeId | null };\n\n/** What `node`'s `'inherit'` fields take from its containers in `scene`, or\n * `undefined` for a node that inherits nothing. */\nexport function inheritedPaintIn<TNode extends PaintedNode>(\n scene: ParentLookup<TNode>,\n node: TNode,\n): InheritedPaint | undefined {\n if (!inheritsPaint(node)) return undefined;\n return inheritedPaintOf(node, sceneAncestors((id: never) => scene.get(id), node));\n}\n\nconst INHERITS_BOTH = { data: { fill: INHERIT, stroke: INHERIT } };\n\n/** What an `'inherit'` fill and stroke on `node` would take from its\n * containers in `scene`, whatever `node` holds now — what an editor offering\n * the choice shows it would paint. */\nexport function paintAbove<TNode extends PaintedNode>(scene: ParentLookup<TNode>, node: TNode): InheritedPaint {\n return inheritedPaintOf(INHERITS_BOTH, sceneAncestors((id: never) => scene.get(id), node));\n}\n\n/** {@link inheritedPaintIn} bound to `scene`. */\nexport function sceneInheritedPaintOf<TNode extends PaintedNode>(\n scene: ParentLookup<TNode>,\n): (node: TNode) => InheritedPaint | undefined {\n return (node) => inheritedPaintIn(scene, node);\n}\n\n/**\n * Wrap a `drawOne` so a node whose fill or stroke is `'inherit'` arrives at\n * the painter with its containers' paint on `ctx.inherited`, as\n * `withDerivedPaths` does for a derived path. Every other node passes the\n * caller's `ctx` through untouched.\n */\nexport function withInheritedPaints<TData, TLayer extends string, TPose>(\n scene: ParentLookup<Node<TData, TLayer, TPose>>,\n drawOne: SceneViewDrawOne<TData, TLayer, TPose>,\n): SceneViewDrawOne<TData, TLayer, TPose> {\n const inheritedOf = sceneInheritedPaintOf(scene);\n return (node, pose, view, ctx) => {\n const inherited = inheritedOf(node);\n return inherited === undefined ? drawOne(node, pose, view, ctx) : drawOne(node, pose, view, { ...ctx, inherited });\n };\n}\n"],"mappings":";;;;;;AAYA,SAAgB,iBACd,OACA,MAC4B;CAC5B,IAAI,CAAC,cAAc,IAAI,GAAG,OAAO;CACjC,OAAO,iBAAiB,MAAM,gBAAgB,OAAc,MAAM,IAAI,EAAE,GAAG,IAAI,CAAC;AAClF;AAEA,IAAM,gBAAgB,EAAE,MAAM;CAAE,MAAM;CAAS,QAAQ;AAAQ,EAAE;;;;AAKjE,SAAgB,WAAsC,OAA4B,MAA6B;CAC7G,OAAO,iBAAiB,eAAe,gBAAgB,OAAc,MAAM,IAAI,EAAE,GAAG,IAAI,CAAC;AAC3F;;AAGA,SAAgB,sBACd,OAC6C;CAC7C,QAAQ,SAAS,iBAAiB,OAAO,IAAI;AAC/C;;;;;;;AAQA,SAAgB,oBACd,OACA,SACwC;CACxC,MAAM,cAAc,sBAAsB,KAAK;CAC/C,QAAQ,MAAM,MAAM,MAAM,QAAQ;EAChC,MAAM,YAAY,YAAY,IAAI;EAClC,OAAO,cAAc,SAAY,QAAQ,MAAM,MAAM,MAAM,GAAG,IAAI,QAAQ,MAAM,MAAM,MAAM;GAAE,GAAG;GAAK;EAAU,CAAC;CACnH;AACF"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { derivedPartsOf } from "../../core/scene/derivedParts.js";
|
|
2
|
-
import { DEFAULT_SHAPE_FILL } from "../../util/paint.js";
|
|
1
|
+
import { derivedPartsOf, resolvePartPaint } from "../../core/scene/derivedParts.js";
|
|
3
2
|
import { derivesPath } from "./memo.js";
|
|
4
|
-
import { inkReach,
|
|
3
|
+
import { inkReach, withAnimatedVertexColors } from "./nodePaint.js";
|
|
4
|
+
import { strokedBounds } from "./strokedBounds.js";
|
|
5
5
|
import { commandFill, commandStroke } from "@weasel-js/renderer";
|
|
6
6
|
import { boundsOfPath } from "@weasel-js/geom";
|
|
7
|
+
import { resolveFill, resolveStroke } from "@weasel-js/paint";
|
|
7
8
|
|
|
8
9
|
//#region src/canvas/nodeShapes/derivedPainter.ts
|
|
9
10
|
function pathCommand(path, declared, strokeSpec, vertexColors) {
|
|
@@ -18,11 +19,16 @@ function pathCommand(path, declared, strokeSpec, vertexColors) {
|
|
|
18
19
|
...stroke ? { stroke } : {}
|
|
19
20
|
};
|
|
20
21
|
}
|
|
21
|
-
/**
|
|
22
|
-
function
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
return
|
|
22
|
+
/** The stroked box of the path on `ctx`, or `null` with no path or no stroke. */
|
|
23
|
+
function derivedDrawnBounds(node, ctx) {
|
|
24
|
+
const path = ctx?.derivedPath;
|
|
25
|
+
const stroke = resolveStroke(node.data?.stroke, ctx?.inherited?.stroke);
|
|
26
|
+
return path == null || stroke === null ? null : strokedBounds(path, stroke, ctx?.scale ?? 1, ctx?.screen);
|
|
27
|
+
}
|
|
28
|
+
/** One part's command, in its own paint; `INHERIT` takes the node's. */
|
|
29
|
+
function partCommand(part, d, inherited) {
|
|
30
|
+
const { fill, stroke } = resolvePartPaint(part, d, inherited);
|
|
31
|
+
return pathCommand(part.path, fill, stroke, void 0);
|
|
26
32
|
}
|
|
27
33
|
/**
|
|
28
34
|
* Built-in painter for nodes whose geometry is computed from other nodes'
|
|
@@ -42,8 +48,8 @@ function partCommand(part, d) {
|
|
|
42
48
|
* Rotation still comes from the pose — `wrapNodeOutput` turns the output about
|
|
43
49
|
* the pose AABB's center, which for a zero-sized pose is its origin.
|
|
44
50
|
*
|
|
45
|
-
* A path made by `pathFromParts` paints one command per part, each
|
|
46
|
-
* part's own fill and stroke
|
|
51
|
+
* A path made by `pathFromParts` paints one command per part, each in the
|
|
52
|
+
* part's own fill and stroke.
|
|
47
53
|
*/
|
|
48
54
|
var DERIVED_PAINTER = {
|
|
49
55
|
id: "kit:derived",
|
|
@@ -53,22 +59,23 @@ var DERIVED_PAINTER = {
|
|
|
53
59
|
if (path == null) return [];
|
|
54
60
|
const d = node.data;
|
|
55
61
|
const parts = derivedPartsOf(path);
|
|
56
|
-
if (parts !== void 0) return parts.map((part) => partCommand(part, d));
|
|
57
|
-
const strokeSpec =
|
|
58
|
-
const declared =
|
|
62
|
+
if (parts !== void 0) return parts.map((part) => partCommand(part, d, ctx?.inherited));
|
|
63
|
+
const strokeSpec = resolveStroke(d?.stroke, ctx?.inherited?.stroke);
|
|
64
|
+
const declared = resolveFill(d?.fill, ctx?.inherited?.fill);
|
|
59
65
|
return withAnimatedVertexColors([pathCommand(path, declared, strokeSpec, d?.vertexColors)], ctx);
|
|
60
66
|
},
|
|
61
67
|
silhouette: (_node, _pose, ctx) => ctx?.derivedPath ?? null,
|
|
68
|
+
drawnBounds: (node, _pose, ctx) => derivedDrawnBounds(node, ctx),
|
|
62
69
|
ink: (node, _pose, ctx) => {
|
|
63
70
|
const d = node.data;
|
|
64
|
-
const stroke =
|
|
71
|
+
const stroke = resolveStroke(d?.stroke, ctx?.inherited?.stroke);
|
|
65
72
|
return {
|
|
66
|
-
filled:
|
|
73
|
+
filled: resolveFill(d?.fill, ctx?.inherited?.fill) !== null,
|
|
67
74
|
...inkReach(stroke, ctx?.scale)
|
|
68
75
|
};
|
|
69
76
|
}
|
|
70
77
|
};
|
|
71
78
|
|
|
72
79
|
//#endregion
|
|
73
|
-
export { DERIVED_PAINTER };
|
|
80
|
+
export { DERIVED_PAINTER, derivedDrawnBounds };
|
|
74
81
|
//# sourceMappingURL=derivedPainter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derivedPainter.js","names":[],"sources":["../../../src/canvas/nodeShapes/derivedPainter.ts"],"sourcesContent":["import { boundsOfPath, type Path } from '@weasel-js/geom';\nimport type { Stroke, Fill } from '@weasel-js/paint';\nimport type { NodeShapeEntry } from 'canvas/NodeShape';\nimport { commandFill, commandStroke } from '@weasel-js/renderer';\nimport type { DrawCommand } from '@weasel-js/renderer';\nimport {
|
|
1
|
+
{"version":3,"file":"derivedPainter.js","names":[],"sources":["../../../src/canvas/nodeShapes/derivedPainter.ts"],"sourcesContent":["import { boundsOfPath, type Path } from '@weasel-js/geom';\nimport type { Stroke, Fill, Inherit } from '@weasel-js/paint';\nimport type { NodeInkCtx, NodeShapeEntry } from 'canvas/NodeShape';\nimport type { Bounds } from 'core/viewport/fitViewToBounds';\nimport { commandFill, commandStroke } from '@weasel-js/renderer';\nimport type { DrawCommand } from '@weasel-js/renderer';\nimport { derivedPartsOf, resolvePartPaint, type DerivedPart } from 'core/scene/derivedParts';\nimport { derivesPath } from './memo';\nimport type { InheritedPaint } from 'core/scene/inheritedPaint';\nimport { strokedBounds } from './strokedBounds';\nimport { inkReach, withAnimatedVertexColors } from './nodePaint';\nimport { resolveFill, resolveStroke, type PaintedFill, type PaintedStroke } from '@weasel-js/paint';\n\ntype PaintData = { fill?: Fill | Inherit | null; stroke?: Stroke | Inherit | null; vertexColors?: number[] };\n\nfunction pathCommand(\n path: Path,\n declared: PaintedFill | null,\n strokeSpec: PaintedStroke | null,\n vertexColors: number[] | undefined,\n): DrawCommand {\n const box = boundsOfPath(path);\n const fill = declared && commandFill(declared, box);\n const stroke = strokeSpec && commandStroke(strokeSpec, box);\n return {\n kind: 'path',\n path,\n ...(fill ? { fill } : {}),\n ...(fill && vertexColors ? { vertexColors } : {}),\n ...(stroke ? { stroke } : {}),\n };\n}\n\n/** The stroked box of the path on `ctx`, or `null` with no path or no stroke. */\nexport function derivedDrawnBounds(node: { data?: unknown }, ctx: NodeInkCtx | undefined): Bounds | null {\n const path = ctx?.derivedPath;\n const stroke = resolveStroke((node.data as PaintData | null)?.stroke, ctx?.inherited?.stroke);\n return path == null || stroke === null ? null : strokedBounds(path, stroke, ctx?.scale ?? 1, ctx?.screen);\n}\n\n/** One part's command, in its own paint; `INHERIT` takes the node's. */\nfunction partCommand(part: DerivedPart, d: PaintData | null, inherited: InheritedPaint | undefined): DrawCommand {\n const { fill, stroke } = resolvePartPaint(part, d, inherited);\n return pathCommand(part.path, fill, stroke, undefined);\n}\n\n/**\n * Built-in painter for nodes whose geometry is computed from other nodes'\n * poses. The path itself arrives on the paint context — see\n * {@link NodePaintCtx.derivedPath}.\n *\n * Fill and stroke resolve as `kit:path`'s do, but against the **derived path's\n * own bounds**, not the pose. `kit:path` projects its path into the pose frame\n * first, so there the two boxes are the same one; here the path is already\n * absolute and the pose is typically a zero-sized placeholder, which would\n * collapse a box-relative gradient onto a point.\n *\n * Not memoized on {@link PAINT_SLOT} on purpose: that key is `(node, pose,\n * data)` and cannot see `ctx.derivedPath`, so it would serve one caller's\n * commands to a caller that passed a different path.\n *\n * Rotation still comes from the pose — `wrapNodeOutput` turns the output about\n * the pose AABB's center, which for a zero-sized pose is its origin.\n *\n * A path made by `pathFromParts` paints one command per part, each in the\n * part's own fill and stroke.\n */\nexport const DERIVED_PAINTER: NodeShapeEntry = {\n id: 'kit:derived',\n // `dependsOn` alone is not enough: the two fields are independent optionals,\n // and `kit:add` restores a node with its `dependsOn` intact when its\n // `derivePath` key is missing from the registry. Claiming that node would paint\n // nothing where the authored appearance is what the warning promises.\n matches: derivesPath,\n paint: (node, _pose, ctx) => {\n const path = ctx?.derivedPath;\n if (path == null) return [];\n const d = node.data as PaintData | null;\n const parts = derivedPartsOf(path);\n if (parts !== undefined) return parts.map((part) => partCommand(part, d, ctx?.inherited));\n const strokeSpec = resolveStroke(d?.stroke, ctx?.inherited?.stroke);\n const declared = resolveFill(d?.fill, ctx?.inherited?.fill);\n return withAnimatedVertexColors([pathCommand(path, declared, strokeSpec, d?.vertexColors)], ctx);\n },\n // The derived path *is* the silhouette, and it is already absolute — the\n // pose is a placeholder, so nothing here can be recovered from it. Without\n // a `ctx` this reports null, which `shapeCoversPoint` reads as \"no\n // opinion\": picking then falls back to that zero-sized pose.\n silhouette: (_node, _pose, ctx) => ctx?.derivedPath ?? null,\n drawnBounds: (node, _pose, ctx) => derivedDrawnBounds(node, ctx),\n ink: (node, _pose, ctx) => {\n const d = node.data as PaintData | null;\n const stroke = resolveStroke(d?.stroke, ctx?.inherited?.stroke);\n return {\n filled: resolveFill(d?.fill, ctx?.inherited?.fill) !== null,\n ...inkReach(stroke, ctx?.scale),\n };\n },\n};\n"],"mappings":";;;;;;;;;AAeA,SAAS,YACP,MACA,UACA,YACA,cACa;CACb,MAAM,MAAM,aAAa,IAAI;CAC7B,MAAM,OAAO,YAAY,YAAY,UAAU,GAAG;CAClD,MAAM,SAAS,cAAc,cAAc,YAAY,GAAG;CAC1D,OAAO;EACL,MAAM;EACN;EACA,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;EACvB,GAAI,QAAQ,eAAe,EAAE,aAAa,IAAI,CAAC;EAC/C,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;CAC7B;AACF;;AAGA,SAAgB,mBAAmB,MAA0B,KAA4C;CACvG,MAAM,OAAO,KAAK;CAClB,MAAM,SAAS,cAAe,KAAK,MAA2B,QAAQ,KAAK,WAAW,MAAM;CAC5F,OAAO,QAAQ,QAAQ,WAAW,OAAO,OAAO,cAAc,MAAM,QAAQ,KAAK,SAAS,GAAG,KAAK,MAAM;AAC1G;;AAGA,SAAS,YAAY,MAAmB,GAAqB,WAAoD;CAC/G,MAAM,EAAE,MAAM,WAAW,iBAAiB,MAAM,GAAG,SAAS;CAC5D,OAAO,YAAY,KAAK,MAAM,MAAM,QAAQ,MAAS;AACvD;;;;;;;;;;;;;;;;;;;;;;AAuBA,IAAa,kBAAkC;CAC7C,IAAI;CAKJ,SAAS;CACT,QAAQ,MAAM,OAAO,QAAQ;EAC3B,MAAM,OAAO,KAAK;EAClB,IAAI,QAAQ,MAAM,OAAO,CAAC;EAC1B,MAAM,IAAI,KAAK;EACf,MAAM,QAAQ,eAAe,IAAI;EACjC,IAAI,UAAU,QAAW,OAAO,MAAM,KAAK,SAAS,YAAY,MAAM,GAAG,KAAK,SAAS,CAAC;EACxF,MAAM,aAAa,cAAc,GAAG,QAAQ,KAAK,WAAW,MAAM;EAClE,MAAM,WAAW,YAAY,GAAG,MAAM,KAAK,WAAW,IAAI;EAC1D,OAAO,yBAAyB,CAAC,YAAY,MAAM,UAAU,YAAY,GAAG,YAAY,CAAC,GAAG,GAAG;CACjG;CAKA,aAAa,OAAO,OAAO,QAAQ,KAAK,eAAe;CACvD,cAAc,MAAM,OAAO,QAAQ,mBAAmB,MAAM,GAAG;CAC/D,MAAM,MAAM,OAAO,QAAQ;EACzB,MAAM,IAAI,KAAK;EACf,MAAM,SAAS,cAAc,GAAG,QAAQ,KAAK,WAAW,MAAM;EAC9D,OAAO;GACL,QAAQ,YAAY,GAAG,MAAM,KAAK,WAAW,IAAI,MAAM;GACvD,GAAG,SAAS,QAAQ,KAAK,KAAK;EAChC;CACF;AACF"}
|
|
@@ -1,37 +1,17 @@
|
|
|
1
1
|
import { bumpNodeMemoGeneration } from "../../core/scene/nodeMemo.js";
|
|
2
|
-
import { DEFAULT_SHAPE_FILL } from "../../util/paint.js";
|
|
3
2
|
import { paintDrawKindRegistry } from "@weasel-js/renderer";
|
|
4
3
|
import { countPathAnchors } from "@weasel-js/geom";
|
|
4
|
+
import { resolveFill, resolveStroke } from "@weasel-js/paint";
|
|
5
5
|
import { markerReach, resolveStrokeWidth, widestStrokeWidth } from "@weasel-js/stroke";
|
|
6
6
|
|
|
7
7
|
//#region src/canvas/nodeShapes/nodePaint.ts
|
|
8
8
|
paintDrawKindRegistry.subscribe(bumpNodeMemoGeneration);
|
|
9
|
-
/**
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
* `undefined` takes the painter's fallback. Write the paint with
|
|
16
|
-
* {@link solid} rather than by hand when all you have is a color.
|
|
17
|
-
*/
|
|
18
|
-
function resolveNodeFill(fill, fallback) {
|
|
19
|
-
const declared = fill === void 0 ? fallback : fill;
|
|
20
|
-
return declared?.paint == null ? null : declared;
|
|
21
|
-
}
|
|
22
|
-
/** The stroke a built-in painter should emit, or `null` for "no stroke".
|
|
23
|
-
* `data.stroke` is a whole {@link Stroke} — width, cap, join, dash, miter
|
|
24
|
-
* limit, and align all reach the renderer. {@link strokeOf} builds one from a
|
|
25
|
-
* color.
|
|
26
|
-
*
|
|
27
|
-
* A stroke carrying no `paint` reads as no stroke. The type requires `paint`,
|
|
28
|
-
* but a document is data, and a stroke assembled a field at a time arrives
|
|
29
|
-
* here without one; painting it throws out of the painter and takes the whole
|
|
30
|
-
* frame with it. */
|
|
31
|
-
function resolveNodeStroke(stroke) {
|
|
32
|
-
if (stroke?.paint == null) return null;
|
|
33
|
-
return stroke;
|
|
34
|
-
}
|
|
9
|
+
/** How a container's silhouette is inked: not at all, since it paints nothing. */
|
|
10
|
+
var CONTAINER_INK = Object.freeze({
|
|
11
|
+
filled: false,
|
|
12
|
+
outset: 0,
|
|
13
|
+
inset: 0
|
|
14
|
+
});
|
|
35
15
|
/** Per-side grab reach for a resolved stroke: world units for what the
|
|
36
16
|
* renderer builds in world, screen pixels for what it builds on screen — a
|
|
37
17
|
* `{ px }` width, and each head by its own size's units. */
|
|
@@ -130,12 +110,11 @@ function withAnimatedVertexColors(cmds, ctx) {
|
|
|
130
110
|
}, ...cmds.slice(1)];
|
|
131
111
|
}
|
|
132
112
|
/** {@link PathPaint} of a node that keeps its paint in `data.fill` and
|
|
133
|
-
* `data.stroke`, as the built-in path painter draws it: a stroke
|
|
134
|
-
* `paint` is none, and an
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const
|
|
138
|
-
const fill = resolveNodeFill(data.fill, stroke !== null ? null : DEFAULT_SHAPE_FILL);
|
|
113
|
+
* `data.stroke`, as the built-in path painter draws it: a stroke or a fill
|
|
114
|
+
* with no `paint` is none, and an `'inherit'` one is `inherited`'s. */
|
|
115
|
+
function pathPaintOf(data, inherited) {
|
|
116
|
+
const stroke = resolveStroke(data.stroke, inherited?.stroke);
|
|
117
|
+
const fill = resolveFill(data.fill, inherited?.fill);
|
|
139
118
|
return stroke !== null ? {
|
|
140
119
|
fill,
|
|
141
120
|
stroke
|
|
@@ -143,5 +122,5 @@ function pathPaintOf(data) {
|
|
|
143
122
|
}
|
|
144
123
|
|
|
145
124
|
//#endregion
|
|
146
|
-
export { inkReach, pathPaintOf,
|
|
125
|
+
export { CONTAINER_INK, inkReach, pathPaintOf, strokeOutset, strokeOutsetPerAxis, withAnimatedVertexColors };
|
|
147
126
|
//# sourceMappingURL=nodePaint.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodePaint.js","names":[],"sources":["../../../src/canvas/nodeShapes/nodePaint.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"nodePaint.js","names":[],"sources":["../../../src/canvas/nodeShapes/nodePaint.ts"],"sourcesContent":["import type { Stroke, Fill, Inherit } from '@weasel-js/paint';\nimport { resolveFill, resolveStroke } from '@weasel-js/paint';\nimport type { NodeInk, NodeInkCtx, NodePaintCtx } from 'canvas/NodeShape';\nimport { countPathAnchors } from '@weasel-js/geom';\nimport { markerReach } from '@weasel-js/stroke';\nimport { resolveStrokeWidth, widestStrokeWidth } from '@weasel-js/stroke';\nimport type { DrawCommand, PathDrawCommand } from '@weasel-js/renderer';\nimport { paintDrawKindRegistry } from '@weasel-js/renderer';\nimport { bumpNodeMemoGeneration } from 'core/scene/nodeMemo';\nimport type { InheritedPaint } from 'core/scene/inheritedPaint';\n\n// The painters memoize a node's paint and resolve a fill's frame inside the\n// memo, so the kind set is ambient state that memo cannot see change.\npaintDrawKindRegistry.subscribe(bumpNodeMemoGeneration);\n\n/** How a container's silhouette is inked: not at all, since it paints nothing. */\nexport const CONTAINER_INK: Readonly<NodeInk> = Object.freeze({ filled: false, outset: 0, inset: 0 });\n\n/** Per-side grab reach for a resolved stroke: world units for what the\n * renderer builds in world, screen pixels for what it builds on screen — a\n * `{ px }` width, and each head by its own size's units. */\nexport function inkReach(\n stroke: Stroke | null,\n scale: number | undefined,\n): Pick<NodeInk, 'outset' | 'inset' | 'outsetPx' | 'insetPx'> {\n if (stroke === null) return { outset: 0, inset: 0 };\n // A marker paints past the path's own end, and the kit's rule is that\n // visible chrome is hittable — so the reach has to cover it.\n const heads = markerReach(stroke);\n const sides = (width: number, headReach: number) => {\n switch (stroke.align ?? 'center') {\n case 'inner': return { outset: headReach, inset: width };\n case 'outer': return { outset: width + headReach, inset: 0 };\n default: return { outset: width / 2 + headReach, inset: width / 2 };\n }\n };\n const width = stroke.width ?? 1;\n // Per-vertex widths are world units even on a `{ px }` stroke.\n const worldWidth = widestStrokeWidth(typeof width === 'object' ? 0 : resolveStrokeWidth(width, scale ?? 1), stroke.vertexWidths);\n const world = sides(worldWidth, heads.world);\n if (typeof width !== 'object' && !(heads.px > 0)) return world;\n const px = sides(typeof width === 'object' ? width.px : 0, heads.px);\n return { outset: world.outset, inset: world.inset, outsetPx: px.outset, insetPx: px.inset };\n}\n\n/** How far `stroke` reaches outside its outline on every side, world units at\n * `scale`: {@link inkReach}'s outset with its screen part resolved. */\nexport function strokeOutset(stroke: Stroke | null, scale: number): number {\n const r = inkReach(stroke, scale);\n return r.outset + (r.outsetPx ?? 0) / (scale > 0 ? scale : 1);\n}\n\n/** {@link strokeOutset} per axis of the frame `ctx.screen` maps from: `x` past\n * the left and right sides, `y` past the top and bottom. A `{ px }` reach\n * is a disk on screen, and its extent along each axis of that frame is the\n * support of the disk pulled back through the map. */\nexport function strokeOutsetPerAxis(stroke: Stroke | null, ctx: NodeInkCtx | undefined): { x: number; y: number } {\n const scale = ctx?.scale ?? 1;\n const screen = ctx?.screen;\n if (!screen) {\n const r = strokeOutset(stroke, scale);\n return { x: r, y: r };\n }\n const r = inkReach(stroke, scale);\n const px = r.outsetPx ?? 0;\n if (px === 0) return { x: r.outset, y: r.outset };\n const [a, b, c, d] = screen;\n const det = Math.abs(a * d - b * c);\n if (!(det > 0)) return { x: r.outset, y: r.outset };\n return { x: r.outset + (px * Math.hypot(c, d)) / det, y: r.outset + (px * Math.hypot(a, b)) / det };\n}\n\n/** Apply {@link NodePaintCtx.vertexColors} to a path painter's body — its first\n * command. Applied outside the paint memo, whose key\n * cannot see an override: `cmds` comes back as-is when nothing changes, and\n * otherwise as a copy, since a memoized list is not ours to edit. Colors whose\n * length does not match the path's anchors are dropped. */\nexport function withAnimatedVertexColors(cmds: DrawCommand[], ctx: NodePaintCtx | undefined): DrawCommand[] {\n const resolve = ctx?.vertexColors;\n const body = cmds[0];\n if (resolve === undefined || body?.kind !== 'path') return cmds;\n const expected = 4 * countPathAnchors(body.path);\n const fill = body.fill ? resolve('fill', body.vertexColors) : undefined;\n const stroke = body.stroke ? resolve('stroke', body.stroke.vertexColors) : undefined;\n const fillChanged = fill?.length === expected && fill !== body.vertexColors;\n const strokeChanged = stroke?.length === expected && stroke !== body.stroke?.vertexColors;\n if (!fillChanged && !strokeChanged) return cmds;\n const next: PathDrawCommand = {\n ...body,\n ...(fillChanged ? { vertexColors: fill as number[] } : {}),\n ...(strokeChanged ? { stroke: { ...body.stroke!, vertexColors: stroke as number[] } } : {}),\n };\n return [next, ...cmds.slice(1)];\n}\n\n/** The paint a path node wears, resolved: what an action that turns ink into\n * geometry reads from a node and tells a consumer to put on a result. */\nexport interface PathPaint {\n /** `null` is no fill. */\n fill: Fill | null;\n /** Absent for no stroke. */\n stroke?: Stroke;\n}\n\n/** {@link PathPaint} of a node that keeps its paint in `data.fill` and\n * `data.stroke`, as the built-in path painter draws it: a stroke or a fill\n * with no `paint` is none, and an `'inherit'` one is `inherited`'s. */\nexport function pathPaintOf(\n data: { fill?: Fill | Inherit | null; stroke?: Stroke | Inherit | null },\n inherited?: InheritedPaint,\n): PathPaint {\n const stroke = resolveStroke(data.stroke, inherited?.stroke);\n const fill = resolveFill(data.fill, inherited?.fill);\n return stroke !== null ? { fill, stroke } : { fill };\n}\n"],"mappings":"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"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { nodeMemo } from "../../core/scene/nodeMemo.js";
|
|
2
2
|
import { PAINT_SLOT } from "./memo.js";
|
|
3
|
-
import { inkReach, pathPaintOf,
|
|
4
|
-
import { DERIVED_PAINTER } from "./derivedPainter.js";
|
|
5
|
-
import { paintsPose, poseBoxBounds } from "./poseBox.js";
|
|
3
|
+
import { CONTAINER_INK, inkReach, pathPaintOf, withAnimatedVertexColors } from "./nodePaint.js";
|
|
6
4
|
import { strokedPoseBox } from "./strokedBounds.js";
|
|
5
|
+
import { DERIVED_PAINTER, derivedDrawnBounds } from "./derivedPainter.js";
|
|
6
|
+
import { paintsPose, poseBoxBounds } from "./poseBox.js";
|
|
7
7
|
import { commandFill, commandStroke } from "@weasel-js/renderer";
|
|
8
8
|
import { pathInPoseFrame } from "@weasel-js/geom";
|
|
9
|
+
import { resolveStroke } from "@weasel-js/paint";
|
|
9
10
|
|
|
10
11
|
//#region src/canvas/nodeShapes/pathPainter.ts
|
|
11
12
|
var PATH_PAINTER = {
|
|
@@ -14,10 +15,10 @@ var PATH_PAINTER = {
|
|
|
14
15
|
if (!paintsPose(node.pose)) return false;
|
|
15
16
|
return node.data?.path != null;
|
|
16
17
|
},
|
|
17
|
-
paint: (node, pose, ctx) => ctx?.derivedPath != null ? DERIVED_PAINTER.paint(node, pose, ctx) : withAnimatedVertexColors(nodeMemo(node, PAINT_SLOT, pose, () => {
|
|
18
|
+
paint: (node, pose, ctx) => node.kind === "container" ? [] : ctx?.derivedPath != null ? DERIVED_PAINTER.paint(node, pose, ctx) : withAnimatedVertexColors(nodeMemo(node, PAINT_SLOT, pose, () => {
|
|
18
19
|
const d = node.data;
|
|
19
20
|
const projected = pathInPoseFrame(d.path, pose);
|
|
20
|
-
const { fill: declared, stroke: strokeSpec } = pathPaintOf(d);
|
|
21
|
+
const { fill: declared, stroke: strokeSpec } = pathPaintOf(d, ctx?.inherited);
|
|
21
22
|
const fill = declared && commandFill(declared, pose);
|
|
22
23
|
const stroke = strokeSpec && commandStroke(strokeSpec, pose);
|
|
23
24
|
return [{
|
|
@@ -27,24 +28,25 @@ var PATH_PAINTER = {
|
|
|
27
28
|
...fill && d.vertexColors ? { vertexColors: d.vertexColors } : {},
|
|
28
29
|
...stroke ? { stroke } : {}
|
|
29
30
|
}];
|
|
30
|
-
}), ctx),
|
|
31
|
+
}, ctx?.inherited), ctx),
|
|
31
32
|
silhouette: (node, pose, ctx) => {
|
|
32
33
|
if (ctx?.derivedPath != null) return ctx.derivedPath;
|
|
33
34
|
const d = node.data;
|
|
34
35
|
return pathInPoseFrame(d.path, pose);
|
|
35
36
|
},
|
|
36
37
|
ink: (node, _pose, ctx) => {
|
|
37
|
-
|
|
38
|
-
const { fill, stroke } = pathPaintOf(
|
|
38
|
+
if (node.kind === "container") return CONTAINER_INK;
|
|
39
|
+
const { fill, stroke } = pathPaintOf(node.data, ctx?.inherited);
|
|
39
40
|
return {
|
|
40
41
|
filled: fill !== null,
|
|
41
42
|
...inkReach(stroke ?? null, ctx?.scale)
|
|
42
43
|
};
|
|
43
44
|
},
|
|
44
|
-
bounds: (node, pose, ctx) => poseBoxBounds(pose,
|
|
45
|
+
bounds: (node, pose, ctx) => poseBoxBounds(pose, resolveStroke(node.data.stroke, ctx?.inherited?.stroke), ctx),
|
|
45
46
|
drawnBounds: (node, pose, ctx) => {
|
|
47
|
+
if (ctx?.derivedPath != null) return derivedDrawnBounds(node, ctx);
|
|
46
48
|
const d = node.data;
|
|
47
|
-
return strokedPoseBox(node, pose,
|
|
49
|
+
return strokedPoseBox(node, pose, resolveStroke(d.stroke, ctx?.inherited?.stroke), ctx, (at) => pathInPoseFrame(d.path, at));
|
|
48
50
|
}
|
|
49
51
|
};
|
|
50
52
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pathPainter.js","names":[],"sources":["../../../src/canvas/nodeShapes/pathPainter.ts"],"sourcesContent":["import type {\n Path\n} from '@weasel-js/geom';\nimport type { Stroke, Fill } from '@weasel-js/paint';\nimport type { NodeShapeEntry } from 'canvas/NodeShape';\nimport { nodeMemo } from 'core/scene/nodeMemo';\nimport type { RectPose } from 'core/scene/types';\nimport { pathInPoseFrame } from '@weasel-js/geom';\nimport { commandFill, commandStroke } from '@weasel-js/renderer';\nimport type { DrawCommand } from '@weasel-js/renderer';\nimport { DERIVED_PAINTER } from './derivedPainter';\nimport { PAINT_SLOT } from './memo';\nimport { inkReach, pathPaintOf, withAnimatedVertexColors
|
|
1
|
+
{"version":3,"file":"pathPainter.js","names":[],"sources":["../../../src/canvas/nodeShapes/pathPainter.ts"],"sourcesContent":["import type {\n Path\n} from '@weasel-js/geom';\nimport type { Stroke, Fill, Inherit } from '@weasel-js/paint';\nimport type { NodeShapeEntry } from 'canvas/NodeShape';\nimport { nodeMemo } from 'core/scene/nodeMemo';\nimport type { RectPose } from 'core/scene/types';\nimport { pathInPoseFrame } from '@weasel-js/geom';\nimport { commandFill, commandStroke } from '@weasel-js/renderer';\nimport type { DrawCommand } from '@weasel-js/renderer';\nimport { DERIVED_PAINTER, derivedDrawnBounds } from './derivedPainter';\nimport { PAINT_SLOT } from './memo';\nimport { CONTAINER_INK, inkReach, pathPaintOf, withAnimatedVertexColors } from './nodePaint';\nimport { resolveStroke } from '@weasel-js/paint';\nimport { paintsPose, poseBoxBounds } from './poseBox';\nimport { strokedPoseBox } from './strokedBounds';\n\ntype PathData = { fill?: Fill | Inherit | null; stroke?: Stroke | Inherit | null; vertexColors?: number[] };\n\n// ─── Built-in painters ─────────────────────────────────────────────────\nexport const PATH_PAINTER: NodeShapeEntry<unknown, RectPose> = {\n id: 'kit:path',\n matches: (node) => {\n if (!paintsPose(node.pose)) return false;\n const d = node.data as { path?: Path } | null;\n return d?.path != null;\n },\n // Memoized: a pure function of `(data, pose)`, and `pathInPoseFrame`\n // allocates on every call but the identity (`kind: 'rect'`) branch. See\n // PAINT_SLOT.\n // As `kit:shape`, a container paints nothing of its own.\n paint: (node, pose, ctx) => node.kind === 'container' ? [] : ctx?.derivedPath != null\n // A pose override's path stands in for `data.path`, already where it is drawn.\n ? DERIVED_PAINTER.paint(node, pose, ctx)\n : withAnimatedVertexColors(nodeMemo(node, PAINT_SLOT, pose, () => {\n const d = node.data as PathData & { path: Path };\n const projected = pathInPoseFrame(d.path, pose);\n const { fill: declared, stroke: strokeSpec } = pathPaintOf(d, ctx?.inherited);\n // The pose is baked into `projected` rather than emitted as a transform,\n // so a box-relative gradient has to be baked onto the same box here or\n // it would arrive in the renderer referring to a frame that never exists.\n const fill = declared && commandFill(declared, pose);\n const stroke = strokeSpec && commandStroke(strokeSpec, pose);\n const cmd: DrawCommand = {\n kind: 'path',\n path: projected,\n ...(fill ? { fill } : {}),\n ...(fill && d.vertexColors ? { vertexColors: d.vertexColors } : {}),\n ...(stroke ? { stroke } : {}),\n };\n return [cmd];\n }, ctx?.inherited), ctx),\n silhouette: (node, pose, ctx) => {\n if (ctx?.derivedPath != null) return ctx.derivedPath;\n const d = node.data as { path: Path };\n return pathInPoseFrame(d.path, pose);\n },\n ink: (node, _pose, ctx) => {\n if (node.kind === 'container') return CONTAINER_INK;\n const { fill, stroke } = pathPaintOf(node.data as PathData, ctx?.inherited);\n return { filled: fill !== null, ...inkReach(stroke ?? null, ctx?.scale) };\n },\n // `pathInPoseFrame` fits the path's own bounds to the pose box.\n bounds: (node, pose, ctx) =>\n poseBoxBounds(pose, resolveStroke((node.data as PathData).stroke, ctx?.inherited?.stroke), ctx),\n drawnBounds: (node, pose, ctx) => {\n if (ctx?.derivedPath != null) return derivedDrawnBounds(node, ctx);\n const d = node.data as PathData & { path: Path };\n return strokedPoseBox(node, pose, resolveStroke(d.stroke, ctx?.inherited?.stroke), ctx, (at) => pathInPoseFrame(d.path, at));\n },\n};\n"],"mappings":";;;;;;;;;;;AAoBA,IAAa,eAAkD;CAC7D,IAAI;CACJ,UAAU,SAAS;EACjB,IAAI,CAAC,WAAW,KAAK,IAAI,GAAG,OAAO;EAEnC,OADU,KAAK,MACL,QAAQ;CACpB;CAKA,QAAQ,MAAM,MAAM,QAAQ,KAAK,SAAS,cAAc,CAAC,IAAI,KAAK,eAAe,OAE7E,gBAAgB,MAAM,MAAM,MAAM,GAAG,IACrC,yBAAyB,SAAS,MAAM,YAAY,YAAY;EAClE,MAAM,IAAI,KAAK;EACf,MAAM,YAAY,gBAAgB,EAAE,MAAM,IAAI;EAC9C,MAAM,EAAE,MAAM,UAAU,QAAQ,eAAe,YAAY,GAAG,KAAK,SAAS;EAI5E,MAAM,OAAO,YAAY,YAAY,UAAU,IAAI;EACnD,MAAM,SAAS,cAAc,cAAc,YAAY,IAAI;EAQ3D,OAAO,CAAC;GANN,MAAM;GACN,MAAM;GACN,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;GACvB,GAAI,QAAQ,EAAE,eAAe,EAAE,cAAc,EAAE,aAAa,IAAI,CAAC;GACjE,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;EAErB,CAAG;CACb,GAAG,KAAK,SAAS,GAAG,GAAG;CACvB,aAAa,MAAM,MAAM,QAAQ;EAC/B,IAAI,KAAK,eAAe,MAAM,OAAO,IAAI;EACzC,MAAM,IAAI,KAAK;EACf,OAAO,gBAAgB,EAAE,MAAM,IAAI;CACrC;CACA,MAAM,MAAM,OAAO,QAAQ;EACzB,IAAI,KAAK,SAAS,aAAa,OAAO;EACtC,MAAM,EAAE,MAAM,WAAW,YAAY,KAAK,MAAkB,KAAK,SAAS;EAC1E,OAAO;GAAE,QAAQ,SAAS;GAAM,GAAG,SAAS,UAAU,MAAM,KAAK,KAAK;EAAE;CAC1E;CAEA,SAAS,MAAM,MAAM,QACnB,cAAc,MAAM,cAAe,KAAK,KAAkB,QAAQ,KAAK,WAAW,MAAM,GAAG,GAAG;CAChG,cAAc,MAAM,MAAM,QAAQ;EAChC,IAAI,KAAK,eAAe,MAAM,OAAO,mBAAmB,MAAM,GAAG;EACjE,MAAM,IAAI,KAAK;EACf,OAAO,eAAe,MAAM,MAAM,cAAc,EAAE,QAAQ,KAAK,WAAW,MAAM,GAAG,MAAM,OAAO,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC7H;AACF"}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import { DEFAULT_SHAPE_FILL } from "../../util/paint.js";
|
|
2
|
-
import { resolveNodeFill } from "./nodePaint.js";
|
|
3
1
|
import { paintsPose, poseBoxBounds } from "./poseBox.js";
|
|
4
2
|
import { commandFill } from "@weasel-js/renderer";
|
|
3
|
+
import { resolveFill } from "@weasel-js/paint";
|
|
5
4
|
|
|
6
5
|
//#region src/canvas/nodeShapes/rectFallbackPainter.ts
|
|
7
6
|
var RECT_FALLBACK_PAINTER = {
|
|
8
7
|
id: "kit:rect-fallback",
|
|
9
|
-
matches: (node) => paintsPose(node.pose),
|
|
10
|
-
paint: (node, pose) => {
|
|
8
|
+
matches: (node) => node.kind !== "container" && paintsPose(node.pose),
|
|
9
|
+
paint: (node, pose, ctx) => {
|
|
11
10
|
const d = node.data;
|
|
12
11
|
const p = pose;
|
|
13
|
-
const declared =
|
|
12
|
+
const declared = resolveFill(d?.fill, ctx?.inherited?.fill);
|
|
14
13
|
const fill = declared && commandFill(declared, p);
|
|
15
14
|
return [{
|
|
16
15
|
kind: "path",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rectFallbackPainter.js","names":[],"sources":["../../../src/canvas/nodeShapes/rectFallbackPainter.ts"],"sourcesContent":["import type { Fill } from '@weasel-js/paint';\nimport type { NodeShapeEntry } from 'canvas/NodeShape';\nimport type { RectPose } from 'core/scene/types';\nimport { commandFill } from '@weasel-js/renderer';\nimport {
|
|
1
|
+
{"version":3,"file":"rectFallbackPainter.js","names":[],"sources":["../../../src/canvas/nodeShapes/rectFallbackPainter.ts"],"sourcesContent":["import type { Fill, Inherit } from '@weasel-js/paint';\nimport type { NodeShapeEntry } from 'canvas/NodeShape';\nimport type { RectPose } from 'core/scene/types';\nimport { commandFill } from '@weasel-js/renderer';\nimport { resolveFill } from '@weasel-js/paint';\nimport { paintsPose, poseBoxBounds } from './poseBox';\n\n// ─── Built-in painters ─────────────────────────────────────────────────\nexport const RECT_FALLBACK_PAINTER: NodeShapeEntry<unknown, RectPose> = {\n // Last-resort painter — matches any rect-posed leaf, so it must be\n // registered last within `'normal'`. A container is a group, not a box: matching\n // one would also hand it a silhouette, which clips its members. Consumers who want a different\n // fallback should register their own painter at `'high'` priority and let\n // this one never fire (or unregister it explicitly).\n id: 'kit:rect-fallback',\n matches: (node) => node.kind !== 'container' && paintsPose(node.pose),\n paint: (node, pose, ctx) => {\n const d = node.data as { fill?: Fill | Inherit | null } | null;\n const p = pose;\n const declared = resolveFill(d?.fill, ctx?.inherited?.fill);\n const fill = declared && commandFill(declared, p);\n return [{\n kind: 'path',\n path: { kind: 'rect', x: p.x, y: p.y, width: p.width, height: p.height },\n ...(fill ? { fill } : {}),\n }];\n },\n silhouette: (_node, pose) => {\n const p = pose;\n return { kind: 'rect', x: p.x, y: p.y, width: p.width, height: p.height };\n },\n bounds: (_node, pose) => poseBoxBounds(pose, null, undefined),\n};\n"],"mappings":";;;;;AAQA,IAAa,wBAA2D;CAMtE,IAAI;CACJ,UAAU,SAAS,KAAK,SAAS,eAAe,WAAW,KAAK,IAAI;CACpE,QAAQ,MAAM,MAAM,QAAQ;EAC1B,MAAM,IAAI,KAAK;EACf,MAAM,IAAI;EACV,MAAM,WAAW,YAAY,GAAG,MAAM,KAAK,WAAW,IAAI;EAC1D,MAAM,OAAO,YAAY,YAAY,UAAU,CAAC;EAChD,OAAO,CAAC;GACN,MAAM;GACN,MAAM;IAAE,MAAM;IAAQ,GAAG,EAAE;IAAG,GAAG,EAAE;IAAG,OAAO,EAAE;IAAO,QAAQ,EAAE;GAAO;GACvE,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;EACzB,CAAC;CACH;CACA,aAAa,OAAO,SAAS;EAC3B,MAAM,IAAI;EACV,OAAO;GAAE,MAAM;GAAQ,GAAG,EAAE;GAAG,GAAG,EAAE;GAAG,OAAO,EAAE;GAAO,QAAQ,EAAE;EAAO;CAC1E;CACA,SAAS,OAAO,SAAS,cAAc,MAAM,MAAM,MAAS;AAC9D"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { nodeMemo } from "../../core/scene/nodeMemo.js";
|
|
2
|
-
import { DEFAULT_SHAPE_FILL } from "../../util/paint.js";
|
|
3
2
|
import { PAINT_SLOT } from "./memo.js";
|
|
4
|
-
import {
|
|
5
|
-
import { paintsPose, poseBoxBounds } from "./poseBox.js";
|
|
3
|
+
import { CONTAINER_INK, inkReach, withAnimatedVertexColors } from "./nodePaint.js";
|
|
6
4
|
import { outsetPoseBox, strokedPoseBox } from "./strokedBounds.js";
|
|
5
|
+
import { paintsPose, poseBoxBounds } from "./poseBox.js";
|
|
7
6
|
import { commandFill, commandStroke } from "@weasel-js/renderer";
|
|
8
7
|
import { ellipsePath, regularPolygonPath, starPath } from "@weasel-js/geom";
|
|
8
|
+
import { resolveFill, resolveStroke } from "@weasel-js/paint";
|
|
9
9
|
|
|
10
10
|
//#region src/canvas/nodeShapes/shapePainter.ts
|
|
11
11
|
/** Built-in shape dispatcher — matches when `data.shape` names a kit-known
|
|
@@ -19,12 +19,12 @@ var SHAPE_PAINTER = {
|
|
|
19
19
|
const s = node.data?.shape;
|
|
20
20
|
return s != null && SHAPE_KINDS.has(s);
|
|
21
21
|
},
|
|
22
|
-
paint: (node, pose, ctx) => withAnimatedVertexColors(nodeMemo(node, PAINT_SLOT, pose, () => {
|
|
22
|
+
paint: (node, pose, ctx) => node.kind === "container" ? [] : withAnimatedVertexColors(nodeMemo(node, PAINT_SLOT, pose, () => {
|
|
23
23
|
const d = node.data;
|
|
24
24
|
const path = pathForShape(d, pose);
|
|
25
|
-
const declaredFill =
|
|
25
|
+
const declaredFill = resolveFill(d.fill, ctx?.inherited?.fill);
|
|
26
26
|
const shapeFill = declaredFill && commandFill(declaredFill, pose);
|
|
27
|
-
const strokeSpec =
|
|
27
|
+
const strokeSpec = resolveStroke(d.stroke, ctx?.inherited?.stroke);
|
|
28
28
|
const stroke = strokeSpec && commandStroke(strokeSpec, pose);
|
|
29
29
|
return [{
|
|
30
30
|
kind: "path",
|
|
@@ -32,22 +32,23 @@ var SHAPE_PAINTER = {
|
|
|
32
32
|
...shapeFill ? { fill: shapeFill } : {},
|
|
33
33
|
...stroke ? { stroke } : {}
|
|
34
34
|
}];
|
|
35
|
-
}), ctx),
|
|
35
|
+
}, ctx?.inherited), ctx),
|
|
36
36
|
silhouette: (node, pose) => {
|
|
37
37
|
const d = node.data;
|
|
38
38
|
return pathForShape(d, pose);
|
|
39
39
|
},
|
|
40
40
|
ink: (node, _pose, ctx) => {
|
|
41
|
+
if (node.kind === "container") return CONTAINER_INK;
|
|
41
42
|
const d = node.data;
|
|
42
43
|
return {
|
|
43
|
-
filled:
|
|
44
|
-
...inkReach(
|
|
44
|
+
filled: resolveFill(d.fill, ctx?.inherited?.fill) !== null,
|
|
45
|
+
...inkReach(resolveStroke(d.stroke, ctx?.inherited?.stroke), ctx?.scale)
|
|
45
46
|
};
|
|
46
47
|
},
|
|
47
|
-
bounds: (node, pose, ctx) => poseBoxBounds(pose,
|
|
48
|
+
bounds: (node, pose, ctx) => poseBoxBounds(pose, resolveStroke(node.data.stroke, ctx?.inherited?.stroke), ctx),
|
|
48
49
|
drawnBounds: (node, pose, ctx) => {
|
|
49
50
|
const d = node.data;
|
|
50
|
-
const stroke =
|
|
51
|
+
const stroke = resolveStroke(d.stroke, ctx?.inherited?.stroke);
|
|
51
52
|
return d.shape === "polygon" || d.shape === "star" ? strokedPoseBox(node, pose, stroke, ctx, (at) => pathForShape(d, at)) : outsetPoseBox(pose, stroke, ctx);
|
|
52
53
|
}
|
|
53
54
|
};
|