@weasel-js/core 1.12.0 → 1.13.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 +199 -0
- package/dist/animation/poseTarget.js +46 -15
- package/dist/animation/poseTarget.js.map +1 -1
- package/dist/animation/poseTransition.js +3 -3
- package/dist/animation/poseTransition.js.map +1 -1
- package/dist/animation/reflow.js +3 -6
- package/dist/animation/reflow.js.map +1 -1
- package/dist/animation/rig/bindRig.js +2 -2
- package/dist/animation/rig/bindRig.js.map +1 -1
- package/dist/animation/rig/skinBinding.js +2 -2
- package/dist/animation/rig/skinBinding.js.map +1 -1
- package/dist/barrel/canvas.js +5 -3
- package/dist/barrel/chrome.js +3 -1
- package/dist/barrel/paths.js +3 -2
- package/dist/barrel/routing.js +2 -2
- package/dist/barrel/scene.js +6 -1
- package/dist/barrel/text.js +2 -2
- package/dist/canvas/NodeShape.js +1 -0
- package/dist/canvas/NodeShape.js.map +1 -1
- package/dist/canvas/SceneCanvas/SceneCanvasInput.js +2 -0
- package/dist/canvas/SceneCanvas/SceneCanvasInput.js.map +1 -1
- package/dist/canvas/SceneCanvas/canvasPassThrough.js +1 -1
- package/dist/canvas/SceneCanvas/canvasPassThrough.js.map +1 -1
- package/dist/canvas/SceneCanvas/defaultNodeRouting.js +2 -2
- package/dist/canvas/SceneCanvas/defaultNodeRouting.js.map +1 -1
- package/dist/canvas/SceneCanvas/scenePointQuery.js +20 -2
- package/dist/canvas/SceneCanvas/scenePointQuery.js.map +1 -1
- package/dist/canvas/SceneCanvas/useCanvasTools.js +3 -0
- package/dist/canvas/SceneCanvas/useCanvasTools.js.map +1 -1
- package/dist/canvas/SceneCanvas/useContributionRoles.js +2 -0
- package/dist/canvas/SceneCanvas/useContributionRoles.js.map +1 -1
- package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +25 -19
- package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js +7 -0
- package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneCanvasTools.js +1 -0
- package/dist/canvas/SceneCanvas/useSceneCanvasTools.js.map +1 -1
- package/dist/canvas/SceneCanvas/useScenePicking.js +31 -6
- package/dist/canvas/SceneCanvas/useScenePicking.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js +4 -5
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneStandardActions.js +5 -3
- package/dist/canvas/SceneCanvas/useSceneStandardActions.js.map +1 -1
- package/dist/canvas/SceneCanvas.js +19 -2
- package/dist/canvas/SceneCanvas.js.map +1 -1
- package/dist/canvas/accentColor.js +26 -3
- package/dist/canvas/accentColor.js.map +1 -1
- package/dist/canvas/buildSceneLayer.js +1 -1
- package/dist/canvas/buildSceneLayer.js.map +1 -1
- package/dist/canvas/buildSceneTree.js +14 -20
- package/dist/canvas/buildSceneTree.js.map +1 -1
- package/dist/canvas/canvasRenderer.js +6 -2
- package/dist/canvas/canvasRenderer.js.map +1 -1
- package/dist/canvas/copiesAbove.js +1 -1
- package/dist/canvas/copiesAbove.js.map +1 -1
- package/dist/canvas/defaultDrawOne.js +10 -7
- package/dist/canvas/defaultDrawOne.js.map +1 -1
- package/dist/canvas/deps/areaSelect.js +5 -2
- package/dist/canvas/deps/areaSelect.js.map +1 -1
- package/dist/canvas/deps/booleans.js +1 -1
- package/dist/canvas/deps/booleans.js.map +1 -1
- package/dist/canvas/deps/enteredGroup.js +81 -0
- package/dist/canvas/deps/enteredGroup.js.map +1 -0
- package/dist/canvas/deps/hitTestArea.js +27 -15
- package/dist/canvas/deps/hitTestArea.js.map +1 -1
- package/dist/canvas/deps/insert.js +4 -36
- package/dist/canvas/deps/insert.js.map +1 -1
- package/dist/canvas/deps/insertSite.js +39 -0
- package/dist/canvas/deps/insertSite.js.map +1 -0
- package/dist/canvas/deps/lassoSelect.js +6 -3
- package/dist/canvas/deps/lassoSelect.js.map +1 -1
- package/dist/canvas/deps/pathLeaf.js +1 -1
- package/dist/canvas/deps/pathLeaf.js.map +1 -1
- package/dist/canvas/deps/slice.js +2 -1
- package/dist/canvas/deps/slice.js.map +1 -1
- package/dist/canvas/derivedPath.js +14 -6
- package/dist/canvas/derivedPath.js.map +1 -1
- package/dist/canvas/doubleClickTarget.js +9 -11
- package/dist/canvas/doubleClickTarget.js.map +1 -1
- package/dist/canvas/drawnBounds.js +16 -7
- package/dist/canvas/drawnBounds.js.map +1 -1
- package/dist/canvas/inheritedPaints.js +22 -11
- package/dist/canvas/inheritedPaints.js.map +1 -1
- package/dist/canvas/nodeShapes/nodePaint.js +1 -7
- package/dist/canvas/nodeShapes/nodePaint.js.map +1 -1
- package/dist/canvas/nodeShapes/pathPainter.js +2 -3
- package/dist/canvas/nodeShapes/pathPainter.js.map +1 -1
- package/dist/canvas/nodeShapes/rectFallbackPainter.js +1 -1
- package/dist/canvas/nodeShapes/rectFallbackPainter.js.map +1 -1
- package/dist/canvas/nodeShapes/shapePainter.js +2 -3
- package/dist/canvas/nodeShapes/shapePainter.js.map +1 -1
- package/dist/canvas/ownClip.js +24 -0
- package/dist/canvas/ownClip.js.map +1 -0
- package/dist/canvas/paintCull.js.map +1 -1
- package/dist/canvas/pickIndex/nodeBroadBox.js +86 -0
- package/dist/canvas/pickIndex/nodeBroadBox.js.map +1 -0
- package/dist/canvas/pickIndex/scenePickIndex.js +208 -0
- package/dist/canvas/pickIndex/scenePickIndex.js.map +1 -0
- package/dist/canvas/pickWalk.js +14 -90
- package/dist/canvas/pickWalk.js.map +1 -1
- package/dist/canvas/poseCascade.js +1 -1
- package/dist/canvas/poseCascade.js.map +1 -1
- package/dist/canvas/publishPreviews.js +97 -0
- package/dist/canvas/publishPreviews.js.map +1 -0
- package/dist/canvas/sceneAdapter.js +7 -5
- package/dist/canvas/sceneAdapter.js.map +1 -1
- package/dist/canvas/sceneClipboard.js +17 -10
- package/dist/canvas/sceneClipboard.js.map +1 -1
- package/dist/canvas/scenePickReads.js +37 -0
- package/dist/canvas/scenePickReads.js.map +1 -0
- package/dist/canvas/scenePickSource.js +74 -0
- package/dist/canvas/scenePickSource.js.map +1 -0
- package/dist/canvas/sceneSlotWiring.js +9 -4
- package/dist/canvas/sceneSlotWiring.js.map +1 -1
- package/dist/canvas/sceneViewRender.js +13 -8
- package/dist/canvas/sceneViewRender.js.map +1 -1
- package/dist/canvas/shownNodes.js +15 -0
- package/dist/canvas/shownNodes.js.map +1 -0
- package/dist/canvas/useCanvasPaint.js +3 -1
- package/dist/canvas/useCanvasPaint.js.map +1 -1
- package/dist/canvas/useSceneAdapter.js +5 -3
- package/dist/canvas/useSceneAdapter.js.map +1 -1
- package/dist/clipboard.d.ts +2 -2
- package/dist/{clone-C3e0OTuF.d.ts → clone-qb2e1F5p.d.ts} +2 -2
- package/dist/clone.d.ts +3 -3
- package/dist/core/isPlainObject.js +2 -2
- package/dist/core/layers/layerGroup.js.map +1 -1
- package/dist/core/layers/render.js.map +1 -1
- package/dist/core/scene/NodeRouting.js.map +1 -1
- package/dist/core/scene/arrivalWindow.js +1 -1
- package/dist/core/scene/arrivalWindow.js.map +1 -1
- package/dist/core/scene/clipNothing.js +2 -5
- package/dist/core/scene/clipNothing.js.map +1 -1
- package/dist/core/scene/declaredFieldSetters.js +44 -0
- package/dist/core/scene/declaredFieldSetters.js.map +1 -0
- package/dist/core/scene/depMemo.js +3 -0
- package/dist/core/scene/depMemo.js.map +1 -1
- package/dist/core/scene/dependents.js +3 -1
- package/dist/core/scene/dependents.js.map +1 -1
- package/dist/core/scene/documentOf.js +43 -0
- package/dist/core/scene/documentOf.js.map +1 -0
- package/dist/core/scene/effectivePose.js +37 -13
- package/dist/core/scene/effectivePose.js.map +1 -1
- package/dist/core/scene/fieldEdits.js +17 -14
- package/dist/core/scene/fieldEdits.js.map +1 -1
- package/dist/core/scene/historyForm.js +4 -4
- package/dist/core/scene/historyForm.js.map +1 -1
- package/dist/core/scene/inheritedPaint.js +27 -5
- package/dist/core/scene/inheritedPaint.js.map +1 -1
- package/dist/core/scene/kitOps.js +3 -23
- package/dist/core/scene/kitOps.js.map +1 -1
- package/dist/core/scene/layoutPass.js +1 -2
- package/dist/core/scene/layoutPass.js.map +1 -1
- package/dist/core/scene/nodeAsShown.js +72 -0
- package/dist/core/scene/nodeAsShown.js.map +1 -0
- package/dist/core/scene/nodeFnFields.js +2 -10
- package/dist/core/scene/nodeFnFields.js.map +1 -1
- package/dist/core/scene/nodeMemo.js +6 -1
- package/dist/core/scene/nodeMemo.js.map +1 -1
- package/dist/core/scene/nodeStore.js +2 -4
- package/dist/core/scene/nodeStore.js.map +1 -1
- package/dist/core/scene/pathEffects/derive.js +3 -2
- package/dist/core/scene/pathEffects/derive.js.map +1 -1
- package/dist/core/scene/pathEffects/foundHidden.js +35 -0
- package/dist/core/scene/pathEffects/foundHidden.js.map +1 -0
- package/dist/core/scene/plyStacks.js +89 -0
- package/dist/core/scene/plyStacks.js.map +1 -0
- package/dist/core/scene/poseHold.js +42 -24
- package/dist/core/scene/poseHold.js.map +1 -1
- package/dist/core/scene/poseOverrides.js +35 -38
- package/dist/core/scene/poseOverrides.js.map +1 -1
- package/dist/core/scene/posePlies.js +59 -0
- package/dist/core/scene/posePlies.js.map +1 -0
- package/dist/core/scene/reconcileSpecs.js +6 -15
- package/dist/core/scene/reconcileSpecs.js.map +1 -1
- package/dist/core/scene/renderOrder.js +10 -4
- package/dist/core/scene/renderOrder.js.map +1 -1
- package/dist/core/scene/sameValue.js +17 -0
- package/dist/core/scene/sameValue.js.map +1 -0
- package/dist/core/scene/scene.js +3 -3
- package/dist/core/scene/scene.js.map +1 -1
- package/dist/core/scene/sceneEdits.js +8 -0
- package/dist/core/scene/sceneEdits.js.map +1 -1
- package/dist/core/scene/sceneState.js +1 -2
- package/dist/core/scene/sceneState.js.map +1 -1
- package/dist/core/scene/serialization.js +45 -9
- package/dist/core/scene/serialization.js.map +1 -1
- package/dist/core/scene/staleReplay.js +5 -2
- package/dist/core/scene/staleReplay.js.map +1 -1
- package/dist/core/scene/statedFields.js +4 -2
- package/dist/core/scene/statedFields.js.map +1 -1
- package/dist/core/scene/treeEdits.js +2 -4
- package/dist/core/scene/treeEdits.js.map +1 -1
- package/dist/core/scene/treeOrder.js +3 -1
- package/dist/core/scene/treeOrder.js.map +1 -1
- package/dist/core/scene/treeReads.js +1 -2
- package/dist/core/scene/treeReads.js.map +1 -1
- package/dist/core/scene/treeShape.js +13 -0
- package/dist/core/scene/treeShape.js.map +1 -0
- package/dist/core/scene/types.js.map +1 -1
- package/dist/core/scene/useScene.js +1 -1
- package/dist/core/scene/useScene.js.map +1 -1
- package/dist/{cornerHandles-p8fDIAKt.d.ts → cornerHandles-CNCb7aTY.d.ts} +1 -1
- package/dist/{depSchema-mG19aEdD.d.ts → depSchema-CpIQzKWQ.d.ts} +38 -59
- package/dist/devtools/handlers.js +1 -1
- package/dist/devtools/handlers.js.map +1 -1
- package/dist/devtools/protocol.js.map +1 -1
- package/dist/devtools-protocol.d.ts +4 -3
- package/dist/devtools.d.ts +3 -2
- package/dist/features/measure/measureHit.js +5 -3
- package/dist/features/measure/measureHit.js.map +1 -1
- package/dist/features/measure/measurement.js +1 -1
- package/dist/features/measure/measurement.js.map +1 -1
- package/dist/features/modes/modeLayers.js +14 -7
- package/dist/features/modes/modeLayers.js.map +1 -1
- package/dist/features/modes/modeTriggers.js +3 -3
- package/dist/features/modes/modeTriggers.js.map +1 -1
- package/dist/features/pathEffects/effectSources.js +25 -16
- package/dist/features/pathEffects/effectSources.js.map +1 -1
- package/dist/features/pathEffects/readSource.js +1 -1
- package/dist/features/pathEffects/readSource.js.map +1 -1
- package/dist/features/pathEffects/useEffectSourcesLayer.js +15 -19
- package/dist/features/pathEffects/useEffectSourcesLayer.js.map +1 -1
- package/dist/features/paths/editablePath.js +1 -1
- package/dist/features/paths/editablePath.js.map +1 -1
- package/dist/features/paths/pathSnap/sceneIndex.js +1 -1
- package/dist/features/paths/pathSnap/sceneIndex.js.map +1 -1
- package/dist/features/selection/enteredGroupFrame.js +65 -0
- package/dist/features/selection/enteredGroupFrame.js.map +1 -0
- package/dist/features/selection/enteredGroupScope.js +44 -0
- package/dist/features/selection/enteredGroupScope.js.map +1 -0
- package/dist/features/text/sceneTextDrafts.js +26 -27
- package/dist/features/text/sceneTextDrafts.js.map +1 -1
- package/dist/features/text/textHitAt.js +4 -2
- package/dist/features/text/textHitAt.js.map +1 -1
- package/dist/features/text/useSceneTextEdit.js +3 -3
- package/dist/features/text/useSceneTextEdit.js.map +1 -1
- package/dist/features/viewports/viewportLayer.js +2 -1
- package/dist/features/viewports/viewportLayer.js.map +1 -1
- package/dist/index.d.ts +230 -77
- package/dist/index.js +16 -6
- package/dist/interactions/actions/admitsChild.js +11 -0
- package/dist/interactions/actions/admitsChild.js.map +1 -0
- package/dist/interactions/actions/defaults/contextMenu.js +16 -3
- package/dist/interactions/actions/defaults/contextMenu.js.map +1 -1
- package/dist/interactions/actions/defaults/createPaintAction.js +4 -1
- package/dist/interactions/actions/defaults/createPaintAction.js.map +1 -1
- package/dist/interactions/actions/defaults/enterGroup.js +88 -0
- package/dist/interactions/actions/defaults/enterGroup.js.map +1 -0
- package/dist/interactions/actions/defaults/enterPathEdit.js +1 -1
- package/dist/interactions/actions/defaults/enterPathEdit.js.map +1 -1
- package/dist/interactions/actions/defaults/enterTextEdit.js +1 -1
- package/dist/interactions/actions/defaults/enterTextEdit.js.map +1 -1
- package/dist/interactions/actions/defaults/group.js +7 -7
- package/dist/interactions/actions/defaults/group.js.map +1 -1
- package/dist/interactions/actions/defaults/selectAll.js +7 -3
- package/dist/interactions/actions/defaults/selectAll.js.map +1 -1
- package/dist/interactions/actions/defaults/selectDeep.js +35 -0
- package/dist/interactions/actions/defaults/selectDeep.js.map +1 -0
- package/dist/interactions/actions/drawnBoxes.js +2 -1
- package/dist/interactions/actions/drawnBoxes.js.map +1 -1
- package/dist/interactions/actions/insert/action.js +1 -0
- package/dist/interactions/actions/insert/action.js.map +1 -1
- package/dist/interactions/actions/insert/parent.js +7 -5
- package/dist/interactions/actions/insert/parent.js.map +1 -1
- package/dist/interactions/actions/insert/placeAction.js +3 -2
- package/dist/interactions/actions/insert/placeAction.js.map +1 -1
- package/dist/interactions/actions/insert/session.js +2 -2
- package/dist/interactions/actions/insert/session.js.map +1 -1
- package/dist/interactions/actions/move/commit/reparent.js +1 -1
- package/dist/interactions/actions/move/commit/reparent.js.map +1 -1
- package/dist/interactions/actions/move/gestureAdapter.js +6 -7
- package/dist/interactions/actions/move/gestureAdapter.js.map +1 -1
- package/dist/interactions/actions/move/layout/exits.js +1 -1
- package/dist/interactions/actions/move/layout/exits.js.map +1 -1
- package/dist/interactions/actions/move/session.js +4 -4
- package/dist/interactions/actions/move/session.js.map +1 -1
- package/dist/interactions/actions/pathCommands/pathNodes.js +14 -5
- package/dist/interactions/actions/pathCommands/pathNodes.js.map +1 -1
- package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js +14 -2
- package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js.map +1 -1
- package/dist/{math-B56zxVs5.d.ts → math-C_elShP_.d.ts} +2 -5
- package/dist/math.d.ts +1 -1
- package/dist/move.d.ts +4 -4
- package/dist/{options-DBxEryYq.d.ts → options-ClEm3SEl.d.ts} +1 -1
- package/dist/resize.d.ts +4 -4
- package/dist/test-seams.d.ts +6 -6
- package/dist/tools/builtin/pressTarget.js +22 -0
- package/dist/tools/builtin/pressTarget.js.map +1 -0
- package/dist/tools/builtin/select/adapterPointQuery.js +3 -3
- package/dist/tools/builtin/select/adapterPointQuery.js.map +1 -1
- package/dist/tools/builtin/select/collapseDeferred.js +40 -0
- package/dist/tools/builtin/select/collapseDeferred.js.map +1 -0
- package/dist/tools/builtin/select/groupEntry.js +82 -0
- package/dist/tools/builtin/select/groupEntry.js.map +1 -0
- package/dist/tools/builtin/select/pressDecision.js +1 -1
- package/dist/tools/builtin/select/pressDecision.js.map +1 -1
- package/dist/tools/builtin/select/useSelectTool.js +61 -45
- package/dist/tools/builtin/select/useSelectTool.js.map +1 -1
- package/dist/{types-7puAuVD2.d.ts → types-49uYJN3j.d.ts} +1 -1
- package/dist/{types-CniVctmk.d.ts → types-BEdRIhNc.d.ts} +272 -109
- package/dist/{types-oFeQ5VjV.d.ts → types-p2alu-R1.d.ts} +1 -1
- package/dist/version.js +1 -1
- package/package.json +25 -25
|
@@ -84,7 +84,7 @@ function bindRigOn(options, seat) {
|
|
|
84
84
|
const drop = () => {
|
|
85
85
|
if (!installed) return;
|
|
86
86
|
installed = false;
|
|
87
|
-
for (const b of bound) scene.overrides.clear(b.node);
|
|
87
|
+
for (const b of bound) scene.overrides.clear(b.node, b.entry);
|
|
88
88
|
skins.release();
|
|
89
89
|
};
|
|
90
90
|
const release = () => {
|
|
@@ -114,7 +114,7 @@ function bindRigOn(options, seat) {
|
|
|
114
114
|
restWorld: b.restWorld,
|
|
115
115
|
fromRest: motionOf(b.joint)
|
|
116
116
|
});
|
|
117
|
-
if (!
|
|
117
|
+
if (!scene.overrides.has(b.node, b.entry)) scene.overrides.set(b.node, b.entry);
|
|
118
118
|
}
|
|
119
119
|
skins.joints.forEach(motionOf);
|
|
120
120
|
skins.show(fromRest);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bindRig.js","names":[],"sources":["../../../src/animation/rig/bindRig.ts"],"sourcesContent":["import type { PoseDescriptor } from '../../core/geometry/poseDescriptor';\nimport type { NodeId, PoseOverride } from '../../core/scene/types';\nimport { AUTO_POSE_DESCRIPTOR } from 'core/geometry/autoPoseDescriptor';\nimport { mat3, type GlMat3 } from '@weasel-js/geom';\nimport type { Target } from '@weasel-js/animator';\nimport { resolveSkeleton } from '@weasel-js/animator';\nimport type { Pose, Skeleton } from '@weasel-js/animator';\nimport type { Skin } from '@weasel-js/animator';\nimport { createRigSeat, type RigBinding, type RigSeat } from './rigSeat';\nimport { bindSkins, dataRestPath, type RestPath, type SkinScene } from './skinBinding';\n\n/** The part of a scene a rig writes to. */\nexport interface RigScene<TPose> extends SkinScene<TPose> {\n batch<T>(label: string, fn: () => T): T;\n}\n\n/** What a `RigApply` knows about the node it is posing. */\nexport interface RigApplyContext<TPose> {\n /** The joint the node rides. */\n joint: string;\n node: NodeId;\n /** The node's document pose when the rig was bound — where it sits at the\n * bind pose. */\n rest: TPose;\n /** The joint's world transform at the bind pose. */\n restWorld: GlMat3;\n /** `world * inverse(restWorld)`: the motion since the bind pose, in world\n * space. Carrying `rest` by it is what welding the node to the joint means. */\n fromRest: GlMat3;\n}\n\n/** Turns a joint's world transform into a pose for one bound node. The only\n * part of a rig that knows the scene's pose shape. */\nexport type RigApply<TPose> = (world: GlMat3, ctx: RigApplyContext<TPose>) => TPose;\n\n/** Options for `bindRig`. */\nexport interface BindRigOptions<TPose> {\n scene: RigScene<TPose>;\n skeleton: Skeleton;\n /** Joint name → the node or nodes that ride it. Each node keeps the offset\n * from its joint that it has at the bind pose. */\n bindings?: Readonly<Record<string, NodeId | readonly NodeId[]>>;\n /** Node id → the weights its path bends by. Where a bound node moves whole with one joint,\n * a skinned node's points each follow their own joints, and the rig shows the bent path\n * through the node's pose override, posed at the path's bounds. */\n skins?: Readonly<Record<NodeId, Skin>>;\n /** Where a skinned node's path is drawn when the rig is bound. Default\n * {@link dataRestPath}: the node's `data.path`, through its pose. */\n restPath?: RestPath<TPose>;\n /** Default: {@link rigidRigApply} over `descriptor`. */\n apply?: RigApply<TPose>;\n /** The descriptor the default `apply` reads and writes poses through.\n * Default `AUTO_POSE_DESCRIPTOR`. */\n descriptor?: PoseDescriptor<TPose>;\n}\n\n/** A skeleton bound to scene nodes, as `bindRig` returns it. */\nexport interface Rig {\n readonly skeleton: Skeleton;\n /**\n * The rig's pose as a value an animator moves. Its committed value starts as `{}`, the bind\n * pose, and each frame the rig is posed with what the target shows. A clip is a\n * `SampledTrack<Pose>` given this as its `target`: clips on one rig crossfade by their\n * `weight`s, weights short of 1 leave the rest to the committed pose, and a `spring` or\n * `tween` from a pose away from the committed one adds on top. `animator.hold` shows a pose made elsewhere the same way, an\n * IK solve included.\n */\n readonly target: Target<Pose>;\n /**\n * Commit `pose` and move every bound node to what the target now shows, which is `pose`\n * unless something is animating the target; a hold on it weighs the new pose in when it is\n * next read, at the animator's next frame or the hold's `touch()`. Writes go through the scene's pose overrides —\n * no history entry, no document write, no version bump — and are committed. `root`, where\n * given, replaces the placement, as {@link Rig.place}.\n */\n pose(pose: Pose, root?: GlMat3): void;\n /** Place the rig in the world by `root`, which may mirror it, and pose it there. It stays\n * until placed again; with no `root`, the rig goes back to where its skeleton puts it. */\n place(root?: GlMat3): void;\n /** The joint world transforms as the rig was last posed, root applied. */\n world(): ReadonlyMap<string, GlMat3>;\n /** Write the current frame into the bound nodes' document poses as one\n * undo entry, and drop the overrides. A skinned node's bent path goes into\n * its `data.path`. Later frames stay relative to the bind-time rest, so\n * baking does not compound. */\n bake(label?: string): void;\n /** Drop the overrides; the nodes show their document poses again until the\n * rig is next posed. */\n release(): void;\n}\n\n/**\n * Carries a node rigidly with its joint: the rest pose's center moves by\n * `fromRest`, and its rotation turns with the rest pose's x-axis. Scale in the\n * joint chain moves positions but not sizes — the pose model holds no shear,\n * and a sized pose under anisotropic scale would need one. Write an `apply`\n * that reads `world` to size nodes from joint scale.\n */\nexport function rigidRigApply<TPose>(descriptor: PoseDescriptor<TPose>): RigApply<TPose> {\n return (_world, { rest, fromRest }) => {\n const b = descriptor.getBounds(rest);\n const cx = b.x + b.width / 2;\n const cy = b.y + b.height / 2;\n const [nx, ny] = mat3.apply(fromRest, cx, cy);\n const moved = descriptor.translate\n ? descriptor.translate(rest, nx - cx, ny - cy)\n : descriptor.remapBounds(rest, b, { ...b, x: b.x + nx - cx, y: b.y + ny - cy });\n if (!descriptor.withRotation) return moved;\n const r0 = descriptor.getRotation?.(rest) ?? 0;\n const ux = Math.cos(r0);\n const uy = Math.sin(r0);\n return descriptor.withRotation(\n moved,\n Math.atan2(fromRest[1] * ux + fromRest[4] * uy, fromRest[0] * ux + fromRest[3] * uy),\n );\n };\n}\n\ninterface Bound<TPose> {\n node: NodeId;\n joint: string;\n rest: TPose;\n restWorld: GlMat3;\n entry: PoseOverride<TPose>;\n}\n\n/**\n * Bind a skeleton's joints to scene nodes. Nodes are written in world space\n * and the rig resolves its own hierarchy, so bound nodes are best left\n * unparented, or under containers whose pose does not compose into theirs;\n * the scene's tree stays free to order and group them for drawing.\n */\nexport function bindRig<TPose>(options: BindRigOptions<TPose>): Rig {\n const seat = createRigSeat(options.skeleton);\n const { rig, binding } = bindRigOn(options, seat);\n seat.binding = binding;\n return rig;\n}\n\n/** {@link bindRig} on a seat the caller keeps. The rig shows the seat's target once its\n * `binding` is the seat's. */\nexport function bindRigOn<TPose>(\n options: BindRigOptions<TPose>,\n seat: RigSeat,\n): { rig: Rig; binding: RigBinding } {\n const { scene, skeleton } = options;\n const descriptor = options.descriptor ?? (AUTO_POSE_DESCRIPTOR as PoseDescriptor<TPose>);\n const apply = options.apply ?? rigidRigApply(descriptor);\n const restWorlds = resolveSkeleton(skeleton, {});\n const restInverses = new Map<string, GlMat3>();\n const restInverseOf = (joint: string): GlMat3 => {\n let inverse = restInverses.get(joint);\n if (inverse) return inverse;\n const restWorld = restWorlds.get(joint);\n if (!restWorld) throw new Error(`bindRig: the skeleton has no joint \"${joint}\".`);\n inverse = mat3.invert(restWorld) ?? undefined;\n if (!inverse) throw new Error(`bindRig: joint \"${joint}\" is singular at the bind pose.`);\n restInverses.set(joint, inverse);\n return inverse;\n };\n\n const skins = bindSkins(scene, options.skins ?? {}, options.restPath ?? dataRestPath, descriptor);\n skins.joints.forEach(restInverseOf);\n\n const bound: Bound<TPose>[] = [];\n for (const [joint, ids] of Object.entries(options.bindings ?? {})) {\n restInverseOf(joint);\n const restWorld = restWorlds.get(joint)!;\n for (const node of typeof ids === 'string' ? [ids] : (ids as readonly NodeId[])) {\n if (options.skins && node in options.skins) {\n throw new Error(`bindRig: node \"${node}\" is both bound to joint \"${joint}\" and skinned.`);\n }\n const n = scene.get(node);\n if (!n) throw new Error(`bindRig: joint \"${joint}\" is bound to node \"${node}\", which the scene lacks.`);\n bound.push({ node, joint, rest: n.pose, restWorld, entry: { pose: n.pose } });\n }\n }\n\n let world: ReadonlyMap<string, GlMat3> = restWorlds;\n let installed = false;\n\n const drop = () => {\n if (!installed) return;\n installed = false;\n for (const b of bound) scene.overrides.clear(b.node);\n skins.release();\n };\n const release = () => {\n seat.shown = false;\n drop();\n };\n\n const show = (pose: Pose): void => {\n const local = resolveSkeleton(skeleton, pose);\n const { root } = seat;\n if (root) for (const [name, m] of local) local.set(name, mat3.multiply(root, m));\n world = local;\n const fromRest = new Map<string, GlMat3>();\n const motionOf = (joint: string): GlMat3 => {\n let delta = fromRest.get(joint);\n if (!delta) {\n delta = mat3.multiply(local.get(joint)!, restInverseOf(joint));\n fromRest.set(joint, delta);\n }\n return delta;\n };\n for (const b of bound) {\n const w = local.get(b.joint)!;\n b.entry.pose = apply(w, { joint: b.joint, node: b.node, rest: b.rest, restWorld: b.restWorld, fromRest: motionOf(b.joint) });\n if (!installed) scene.overrides.set(b.node, b.entry);\n }\n skins.joints.forEach(motionOf);\n skins.show(fromRest);\n installed = true;\n seat.shown = true;\n scene.overrides.commit();\n };\n\n const { target } = seat;\n const rig: Rig = {\n skeleton,\n target,\n pose(pose, at) {\n seat.committed = pose;\n if (at) seat.root = at;\n show(target.read());\n },\n place(at) {\n seat.root = at;\n show(target.read());\n },\n world: () => world,\n bake(label = 'Bake rig pose') {\n if (!installed) return;\n scene.batch(label, () => {\n for (const b of bound) if (b.entry.pose !== undefined) scene.setPose(b.node, b.entry.pose);\n skins.write();\n });\n release();\n },\n release,\n };\n return { rig, binding: { show, drop } };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bindRig.js","names":[],"sources":["../../../src/animation/rig/bindRig.ts"],"sourcesContent":["import type { PoseDescriptor } from '../../core/geometry/poseDescriptor';\nimport type { NodeId, PoseOverride } from '../../core/scene/types';\nimport { AUTO_POSE_DESCRIPTOR } from 'core/geometry/autoPoseDescriptor';\nimport { mat3, type GlMat3 } from '@weasel-js/geom';\nimport type { Target } from '@weasel-js/animator';\nimport { resolveSkeleton } from '@weasel-js/animator';\nimport type { Pose, Skeleton } from '@weasel-js/animator';\nimport type { Skin } from '@weasel-js/animator';\nimport { createRigSeat, type RigBinding, type RigSeat } from './rigSeat';\nimport { bindSkins, dataRestPath, type RestPath, type SkinScene } from './skinBinding';\n\n/** The part of a scene a rig writes to. */\nexport interface RigScene<TPose> extends SkinScene<TPose> {\n batch<T>(label: string, fn: () => T): T;\n}\n\n/** What a `RigApply` knows about the node it is posing. */\nexport interface RigApplyContext<TPose> {\n /** The joint the node rides. */\n joint: string;\n node: NodeId;\n /** The node's document pose when the rig was bound — where it sits at the\n * bind pose. */\n rest: TPose;\n /** The joint's world transform at the bind pose. */\n restWorld: GlMat3;\n /** `world * inverse(restWorld)`: the motion since the bind pose, in world\n * space. Carrying `rest` by it is what welding the node to the joint means. */\n fromRest: GlMat3;\n}\n\n/** Turns a joint's world transform into a pose for one bound node. The only\n * part of a rig that knows the scene's pose shape. */\nexport type RigApply<TPose> = (world: GlMat3, ctx: RigApplyContext<TPose>) => TPose;\n\n/** Options for `bindRig`. */\nexport interface BindRigOptions<TPose> {\n scene: RigScene<TPose>;\n skeleton: Skeleton;\n /** Joint name → the node or nodes that ride it. Each node keeps the offset\n * from its joint that it has at the bind pose. */\n bindings?: Readonly<Record<string, NodeId | readonly NodeId[]>>;\n /** Node id → the weights its path bends by. Where a bound node moves whole with one joint,\n * a skinned node's points each follow their own joints, and the rig shows the bent path\n * through the node's pose override, posed at the path's bounds. */\n skins?: Readonly<Record<NodeId, Skin>>;\n /** Where a skinned node's path is drawn when the rig is bound. Default\n * {@link dataRestPath}: the node's `data.path`, through its pose. */\n restPath?: RestPath<TPose>;\n /** Default: {@link rigidRigApply} over `descriptor`. */\n apply?: RigApply<TPose>;\n /** The descriptor the default `apply` reads and writes poses through.\n * Default `AUTO_POSE_DESCRIPTOR`. */\n descriptor?: PoseDescriptor<TPose>;\n}\n\n/** A skeleton bound to scene nodes, as `bindRig` returns it. */\nexport interface Rig {\n readonly skeleton: Skeleton;\n /**\n * The rig's pose as a value an animator moves. Its committed value starts as `{}`, the bind\n * pose, and each frame the rig is posed with what the target shows. A clip is a\n * `SampledTrack<Pose>` given this as its `target`: clips on one rig crossfade by their\n * `weight`s, weights short of 1 leave the rest to the committed pose, and a `spring` or\n * `tween` from a pose away from the committed one adds on top. `animator.hold` shows a pose made elsewhere the same way, an\n * IK solve included.\n */\n readonly target: Target<Pose>;\n /**\n * Commit `pose` and move every bound node to what the target now shows, which is `pose`\n * unless something is animating the target; a hold on it weighs the new pose in when it is\n * next read, at the animator's next frame or the hold's `touch()`. Writes go through the scene's pose overrides —\n * no history entry, no document write, no version bump — and are committed. `root`, where\n * given, replaces the placement, as {@link Rig.place}.\n */\n pose(pose: Pose, root?: GlMat3): void;\n /** Place the rig in the world by `root`, which may mirror it, and pose it there. It stays\n * until placed again; with no `root`, the rig goes back to where its skeleton puts it. */\n place(root?: GlMat3): void;\n /** The joint world transforms as the rig was last posed, root applied. */\n world(): ReadonlyMap<string, GlMat3>;\n /** Write the current frame into the bound nodes' document poses as one\n * undo entry, and drop the overrides. A skinned node's bent path goes into\n * its `data.path`. Later frames stay relative to the bind-time rest, so\n * baking does not compound. */\n bake(label?: string): void;\n /** Drop the overrides; the nodes show their document poses again until the\n * rig is next posed. */\n release(): void;\n}\n\n/**\n * Carries a node rigidly with its joint: the rest pose's center moves by\n * `fromRest`, and its rotation turns with the rest pose's x-axis. Scale in the\n * joint chain moves positions but not sizes — the pose model holds no shear,\n * and a sized pose under anisotropic scale would need one. Write an `apply`\n * that reads `world` to size nodes from joint scale.\n */\nexport function rigidRigApply<TPose>(descriptor: PoseDescriptor<TPose>): RigApply<TPose> {\n return (_world, { rest, fromRest }) => {\n const b = descriptor.getBounds(rest);\n const cx = b.x + b.width / 2;\n const cy = b.y + b.height / 2;\n const [nx, ny] = mat3.apply(fromRest, cx, cy);\n const moved = descriptor.translate\n ? descriptor.translate(rest, nx - cx, ny - cy)\n : descriptor.remapBounds(rest, b, { ...b, x: b.x + nx - cx, y: b.y + ny - cy });\n if (!descriptor.withRotation) return moved;\n const r0 = descriptor.getRotation?.(rest) ?? 0;\n const ux = Math.cos(r0);\n const uy = Math.sin(r0);\n return descriptor.withRotation(\n moved,\n Math.atan2(fromRest[1] * ux + fromRest[4] * uy, fromRest[0] * ux + fromRest[3] * uy),\n );\n };\n}\n\ninterface Bound<TPose> {\n node: NodeId;\n joint: string;\n rest: TPose;\n restWorld: GlMat3;\n entry: PoseOverride<TPose>;\n}\n\n/**\n * Bind a skeleton's joints to scene nodes. Nodes are written in world space\n * and the rig resolves its own hierarchy, so bound nodes are best left\n * unparented, or under containers whose pose does not compose into theirs;\n * the scene's tree stays free to order and group them for drawing.\n */\nexport function bindRig<TPose>(options: BindRigOptions<TPose>): Rig {\n const seat = createRigSeat(options.skeleton);\n const { rig, binding } = bindRigOn(options, seat);\n seat.binding = binding;\n return rig;\n}\n\n/** {@link bindRig} on a seat the caller keeps. The rig shows the seat's target once its\n * `binding` is the seat's. */\nexport function bindRigOn<TPose>(\n options: BindRigOptions<TPose>,\n seat: RigSeat,\n): { rig: Rig; binding: RigBinding } {\n const { scene, skeleton } = options;\n const descriptor = options.descriptor ?? (AUTO_POSE_DESCRIPTOR as PoseDescriptor<TPose>);\n const apply = options.apply ?? rigidRigApply(descriptor);\n const restWorlds = resolveSkeleton(skeleton, {});\n const restInverses = new Map<string, GlMat3>();\n const restInverseOf = (joint: string): GlMat3 => {\n let inverse = restInverses.get(joint);\n if (inverse) return inverse;\n const restWorld = restWorlds.get(joint);\n if (!restWorld) throw new Error(`bindRig: the skeleton has no joint \"${joint}\".`);\n inverse = mat3.invert(restWorld) ?? undefined;\n if (!inverse) throw new Error(`bindRig: joint \"${joint}\" is singular at the bind pose.`);\n restInverses.set(joint, inverse);\n return inverse;\n };\n\n const skins = bindSkins(scene, options.skins ?? {}, options.restPath ?? dataRestPath, descriptor);\n skins.joints.forEach(restInverseOf);\n\n const bound: Bound<TPose>[] = [];\n for (const [joint, ids] of Object.entries(options.bindings ?? {})) {\n restInverseOf(joint);\n const restWorld = restWorlds.get(joint)!;\n for (const node of typeof ids === 'string' ? [ids] : (ids as readonly NodeId[])) {\n if (options.skins && node in options.skins) {\n throw new Error(`bindRig: node \"${node}\" is both bound to joint \"${joint}\" and skinned.`);\n }\n const n = scene.get(node);\n if (!n) throw new Error(`bindRig: joint \"${joint}\" is bound to node \"${node}\", which the scene lacks.`);\n bound.push({ node, joint, rest: n.pose, restWorld, entry: { pose: n.pose } });\n }\n }\n\n let world: ReadonlyMap<string, GlMat3> = restWorlds;\n let installed = false;\n\n const drop = () => {\n if (!installed) return;\n installed = false;\n for (const b of bound) scene.overrides.clear(b.node, b.entry);\n skins.release();\n };\n const release = () => {\n seat.shown = false;\n drop();\n };\n\n const show = (pose: Pose): void => {\n const local = resolveSkeleton(skeleton, pose);\n const { root } = seat;\n if (root) for (const [name, m] of local) local.set(name, mat3.multiply(root, m));\n world = local;\n const fromRest = new Map<string, GlMat3>();\n const motionOf = (joint: string): GlMat3 => {\n let delta = fromRest.get(joint);\n if (!delta) {\n delta = mat3.multiply(local.get(joint)!, restInverseOf(joint));\n fromRest.set(joint, delta);\n }\n return delta;\n };\n for (const b of bound) {\n const w = local.get(b.joint)!;\n b.entry.pose = apply(w, { joint: b.joint, node: b.node, rest: b.rest, restWorld: b.restWorld, fromRest: motionOf(b.joint) });\n // Checked every frame: the table drops a node's overrides when the node goes.\n if (!scene.overrides.has(b.node, b.entry)) scene.overrides.set(b.node, b.entry);\n }\n skins.joints.forEach(motionOf);\n skins.show(fromRest);\n installed = true;\n seat.shown = true;\n scene.overrides.commit();\n };\n\n const { target } = seat;\n const rig: Rig = {\n skeleton,\n target,\n pose(pose, at) {\n seat.committed = pose;\n if (at) seat.root = at;\n show(target.read());\n },\n place(at) {\n seat.root = at;\n show(target.read());\n },\n world: () => world,\n bake(label = 'Bake rig pose') {\n if (!installed) return;\n scene.batch(label, () => {\n for (const b of bound) if (b.entry.pose !== undefined) scene.setPose(b.node, b.entry.pose);\n skins.write();\n });\n release();\n },\n release,\n };\n return { rig, binding: { show, drop } };\n}\n"],"mappings":"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"}
|
|
@@ -47,7 +47,7 @@ function bindSkins(scene, skins, restPath, descriptor) {
|
|
|
47
47
|
const path = skinPath(s.rest, s.skin, motions);
|
|
48
48
|
s.entry.path = path;
|
|
49
49
|
s.entry.pose = descriptor.fromBounds(boundsOfPath(path), s.restPose);
|
|
50
|
-
if (!
|
|
50
|
+
if (!scene.overrides.has(s.node, s.entry)) scene.overrides.set(s.node, s.entry);
|
|
51
51
|
}
|
|
52
52
|
installed = true;
|
|
53
53
|
},
|
|
@@ -66,7 +66,7 @@ function bindSkins(scene, skins, restPath, descriptor) {
|
|
|
66
66
|
release() {
|
|
67
67
|
if (!installed) return;
|
|
68
68
|
installed = false;
|
|
69
|
-
for (const s of skinned) scene.overrides.clear(s.node);
|
|
69
|
+
for (const s of skinned) scene.overrides.clear(s.node, s.entry);
|
|
70
70
|
}
|
|
71
71
|
};
|
|
72
72
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skinBinding.js","names":[],"sources":["../../../src/animation/rig/skinBinding.ts"],"sourcesContent":["import {\n boundsOfPath, pathInWorld, remapPointValues,\n type GlMat3, type Path, type PathInWorldPose, type PointOrigin,\n} from '@weasel-js/geom';\nimport type { PoseDescriptor } from '../../core/geometry/poseDescriptor';\nimport type { NodeId, PoseOverride, PoseOverrides } from '../../core/scene/types';\nimport { skinPath, type Skin } from '@weasel-js/animator';\n\n/** The part of a scene a rig's skins read and write. */\nexport interface SkinScene<TPose> {\n get(id: NodeId): { pose: TPose; data?: unknown } | undefined;\n readonly overrides: PoseOverrides<TPose>;\n setPose(id: NodeId, pose: TPose): void;\n update(id: NodeId, patch: { data: never }): void;\n}\n\n/** Where a node's path is drawn, for a skin to bend: `null` for a node with none. */\nexport type RestPath<TPose> = (node: { pose: TPose; data?: unknown }) => Path | null;\n\n/** The path in a node's `data.path`, carried through its pose as `kit:path` paints it. */\nexport function dataRestPath<TPose>(node: { pose: TPose; data?: unknown }): Path | null {\n const path = (node.data as { path?: Path } | null | undefined)?.path;\n return path ? pathInWorld(path, node.pose as PathInWorldPose) : null;\n}\n\n/**\n * `skin` after an edit to the points of the path it weighs: `origins` says where each point\n * of the new path came from, as `editAnchorSetTracked` answers. A point the edit made takes\n * weights between those of the points it lies between, and a joint left weighing nothing is\n * dropped.\n */\nexport function remapSkin(skin: Skin, origins: readonly (PointOrigin | null)[]): Skin {\n const next: Record<string, number[]> = {};\n for (const joint in skin) {\n const weights = remapPointValues(skin[joint], origins);\n if (weights.some((w) => w > 0)) next[joint] = weights;\n }\n return next;\n}\n\ninterface Skinned<TPose> {\n node: NodeId;\n skin: Skin;\n rest: Path;\n restPose: TPose;\n entry: PoseOverride<TPose>;\n}\n\n/** A rig's skinned nodes, as `bindSkins` returns them. */\nexport interface SkinBinding {\n /** Every joint a skin weighs. */\n readonly joints: readonly string[];\n /** Bend each skinned path by `motions`, which holds every one of `joints`, into its node's\n * pose override. The caller commits the overrides. */\n show(motions: ReadonlyMap<string, GlMat3>): void;\n /** Write each bent path and its bounds into the document. */\n write(): void;\n release(): void;\n}\n\n/** Read each skinned node's rest path and ready an override for it. */\nexport function bindSkins<TPose>(\n scene: SkinScene<TPose>,\n skins: Readonly<Record<NodeId, Skin>>,\n restPath: RestPath<TPose>,\n descriptor: PoseDescriptor<TPose>,\n): SkinBinding {\n const skinned: Skinned<TPose>[] = [];\n const joints = new Set<string>();\n for (const [id, skin] of Object.entries(skins) as [NodeId, Skin][]) {\n const node = scene.get(id);\n if (!node) throw new Error(`bindRig: a skin names node \"${id}\", which the scene lacks.`);\n const rest = restPath(node);\n if (!rest) throw new Error(`bindRig: node \"${id}\" has no path to skin.`);\n for (const joint in skin) joints.add(joint);\n skinned.push({ node: id, skin, rest, restPose: node.pose, entry: {} });\n }\n let installed = false;\n return {\n joints: [...joints],\n show(motions) {\n for (const s of skinned) {\n const path = skinPath(s.rest, s.skin, motions);\n s.entry.path = path;\n s.entry.pose = descriptor.fromBounds(boundsOfPath(path), s.restPose);\n if (!
|
|
1
|
+
{"version":3,"file":"skinBinding.js","names":[],"sources":["../../../src/animation/rig/skinBinding.ts"],"sourcesContent":["import {\n boundsOfPath, pathInWorld, remapPointValues,\n type GlMat3, type Path, type PathInWorldPose, type PointOrigin,\n} from '@weasel-js/geom';\nimport type { PoseDescriptor } from '../../core/geometry/poseDescriptor';\nimport type { NodeId, PoseOverride, PoseOverrides } from '../../core/scene/types';\nimport { skinPath, type Skin } from '@weasel-js/animator';\n\n/** The part of a scene a rig's skins read and write. */\nexport interface SkinScene<TPose> {\n get(id: NodeId): { pose: TPose; data?: unknown } | undefined;\n readonly overrides: PoseOverrides<TPose>;\n setPose(id: NodeId, pose: TPose): void;\n update(id: NodeId, patch: { data: never }): void;\n}\n\n/** Where a node's path is drawn, for a skin to bend: `null` for a node with none. */\nexport type RestPath<TPose> = (node: { pose: TPose; data?: unknown }) => Path | null;\n\n/** The path in a node's `data.path`, carried through its pose as `kit:path` paints it. */\nexport function dataRestPath<TPose>(node: { pose: TPose; data?: unknown }): Path | null {\n const path = (node.data as { path?: Path } | null | undefined)?.path;\n return path ? pathInWorld(path, node.pose as PathInWorldPose) : null;\n}\n\n/**\n * `skin` after an edit to the points of the path it weighs: `origins` says where each point\n * of the new path came from, as `editAnchorSetTracked` answers. A point the edit made takes\n * weights between those of the points it lies between, and a joint left weighing nothing is\n * dropped.\n */\nexport function remapSkin(skin: Skin, origins: readonly (PointOrigin | null)[]): Skin {\n const next: Record<string, number[]> = {};\n for (const joint in skin) {\n const weights = remapPointValues(skin[joint], origins);\n if (weights.some((w) => w > 0)) next[joint] = weights;\n }\n return next;\n}\n\ninterface Skinned<TPose> {\n node: NodeId;\n skin: Skin;\n rest: Path;\n restPose: TPose;\n entry: PoseOverride<TPose>;\n}\n\n/** A rig's skinned nodes, as `bindSkins` returns them. */\nexport interface SkinBinding {\n /** Every joint a skin weighs. */\n readonly joints: readonly string[];\n /** Bend each skinned path by `motions`, which holds every one of `joints`, into its node's\n * pose override. The caller commits the overrides. */\n show(motions: ReadonlyMap<string, GlMat3>): void;\n /** Write each bent path and its bounds into the document. */\n write(): void;\n release(): void;\n}\n\n/** Read each skinned node's rest path and ready an override for it. */\nexport function bindSkins<TPose>(\n scene: SkinScene<TPose>,\n skins: Readonly<Record<NodeId, Skin>>,\n restPath: RestPath<TPose>,\n descriptor: PoseDescriptor<TPose>,\n): SkinBinding {\n const skinned: Skinned<TPose>[] = [];\n const joints = new Set<string>();\n for (const [id, skin] of Object.entries(skins) as [NodeId, Skin][]) {\n const node = scene.get(id);\n if (!node) throw new Error(`bindRig: a skin names node \"${id}\", which the scene lacks.`);\n const rest = restPath(node);\n if (!rest) throw new Error(`bindRig: node \"${id}\" has no path to skin.`);\n for (const joint in skin) joints.add(joint);\n skinned.push({ node: id, skin, rest, restPose: node.pose, entry: {} });\n }\n let installed = false;\n return {\n joints: [...joints],\n show(motions) {\n for (const s of skinned) {\n const path = skinPath(s.rest, s.skin, motions);\n s.entry.path = path;\n s.entry.pose = descriptor.fromBounds(boundsOfPath(path), s.restPose);\n if (!scene.overrides.has(s.node, s.entry)) scene.overrides.set(s.node, s.entry);\n }\n installed = true;\n },\n write() {\n for (const s of skinned) {\n const { path, pose } = s.entry;\n if (path === undefined || pose === undefined) continue;\n const data = scene.get(s.node)?.data;\n scene.update(s.node, { data: { ...(data as object), path } as never });\n scene.setPose(s.node, pose);\n }\n },\n release() {\n if (!installed) return;\n installed = false;\n for (const s of skinned) scene.overrides.clear(s.node, s.entry);\n },\n };\n}\n"],"mappings":";;;;;AAoBA,SAAgB,aAAoB,MAAoD;CACtF,MAAM,OAAQ,KAAK,MAA6C;CAChE,OAAO,OAAO,YAAY,MAAM,KAAK,IAAuB,IAAI;AAClE;;;;;;;AAQA,SAAgB,UAAU,MAAY,SAAgD;CACpF,MAAM,OAAiC,CAAC;CACxC,KAAK,MAAM,SAAS,MAAM;EACxB,MAAM,UAAU,iBAAiB,KAAK,QAAQ,OAAO;EACrD,IAAI,QAAQ,MAAM,MAAM,IAAI,CAAC,GAAG,KAAK,SAAS;CAChD;CACA,OAAO;AACT;;AAuBA,SAAgB,UACd,OACA,OACA,UACA,YACa;CACb,MAAM,UAA4B,CAAC;CACnC,MAAM,yBAAS,IAAI,IAAY;CAC/B,KAAK,MAAM,CAAC,IAAI,SAAS,OAAO,QAAQ,KAAK,GAAuB;EAClE,MAAM,OAAO,MAAM,IAAI,EAAE;EACzB,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,+BAA+B,GAAG,0BAA0B;EACvF,MAAM,OAAO,SAAS,IAAI;EAC1B,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,kBAAkB,GAAG,uBAAuB;EACvE,KAAK,MAAM,SAAS,MAAM,OAAO,IAAI,KAAK;EAC1C,QAAQ,KAAK;GAAE,MAAM;GAAI;GAAM;GAAM,UAAU,KAAK;GAAM,OAAO,CAAC;EAAE,CAAC;CACvE;CACA,IAAI,YAAY;CAChB,OAAO;EACL,QAAQ,CAAC,GAAG,MAAM;EAClB,KAAK,SAAS;GACZ,KAAK,MAAM,KAAK,SAAS;IACvB,MAAM,OAAO,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO;IAC7C,EAAE,MAAM,OAAO;IACf,EAAE,MAAM,OAAO,WAAW,WAAW,aAAa,IAAI,GAAG,EAAE,QAAQ;IACnE,IAAI,CAAC,MAAM,UAAU,IAAI,EAAE,MAAM,EAAE,KAAK,GAAG,MAAM,UAAU,IAAI,EAAE,MAAM,EAAE,KAAK;GAChF;GACA,YAAY;EACd;EACA,QAAQ;GACN,KAAK,MAAM,KAAK,SAAS;IACvB,MAAM,EAAE,MAAM,SAAS,EAAE;IACzB,IAAI,SAAS,UAAa,SAAS,QAAW;IAC9C,MAAM,OAAO,MAAM,IAAI,EAAE,IAAI,CAAC,EAAE;IAChC,MAAM,OAAO,EAAE,MAAM,EAAE,MAAM;KAAE,GAAI;KAAiB;IAAK,EAAW,CAAC;IACrE,MAAM,QAAQ,EAAE,MAAM,IAAI;GAC5B;EACF;EACA,UAAU;GACR,IAAI,CAAC,WAAW;GAChB,YAAY;GACZ,KAAK,MAAM,KAAK,SAAS,MAAM,UAAU,MAAM,EAAE,MAAM,EAAE,KAAK;EAChE;CACF;AACF"}
|
package/dist/barrel/canvas.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { DEFAULT_LAYER_RETAIN } from "../core/layers/retain.js";
|
|
2
2
|
import { subscribeToSources } from "../core/layers/redrawSource.js";
|
|
3
3
|
import { depsUnchanged, drawLayers, drawOneLayer, isLayerPainted, isLayerVisible, paintedLayers } from "../core/layers/render.js";
|
|
4
|
+
import { inheritedPaintIn, inheritedPaintOf, inheritsPaint, withInheritedPaint } from "../core/scene/inheritedPaint.js";
|
|
4
5
|
import { dlog, dwarn, isDebugEnabled } from "../debug/flag.js";
|
|
5
|
-
import {
|
|
6
|
-
import { inheritedPaintIn, paintAbove, withInheritedPaints } from "../canvas/inheritedPaints.js";
|
|
6
|
+
import { paintAbove, withInheritedPaintBounds, withInheritedPaints } from "../canvas/inheritedPaints.js";
|
|
7
7
|
import { OVERLAY_ROLE_STROKES } from "../canvas/overlayRoleStrokes.js";
|
|
8
8
|
import { DEFAULT_INK, findNodeShape, findShapeBounds, findShapeInk, findShapeSilhouette, getNodeShapes, registerNodeShape, shapeCoversPoint } from "../canvas/NodeShape.js";
|
|
9
9
|
import { drawnAABBOf, drawnBoundsOf, findShapeDrawnBounds, inkExtentsOf } from "../canvas/drawnBounds.js";
|
|
10
10
|
import { insertPreviewExtent } from "../canvas/insertPreviewExtent.js";
|
|
11
11
|
import { CANVAS_CONTEXT_ATTRIBUTES } from "../canvas/contextAttributes.js";
|
|
12
12
|
import { isOverChildren, overChildren, splitOverChildren } from "../canvas/overChildren.js";
|
|
13
|
+
import { clipOutline } from "../canvas/ownClip.js";
|
|
13
14
|
import { drawnBoundsScene } from "../canvas/derivedPath.js";
|
|
14
15
|
import { sceneToAdapter } from "../canvas/sceneAdapter.js";
|
|
15
16
|
import { defaultDrawOne, defaultPaintBounds } from "../canvas/defaultDrawOne.js";
|
|
@@ -27,6 +28,7 @@ import { PickHud } from "../canvas/PickHud.js";
|
|
|
27
28
|
import { PATH_OVERLAY_ROLES, createPathOverlay } from "../canvas/pathOverlay.js";
|
|
28
29
|
import { DevtoolsLabel, useDevtoolsLabel } from "../devtools/label.js";
|
|
29
30
|
import { defaultNodeRouting, groupNodeRouting, inferredNodeRouting } from "../canvas/SceneCanvas/defaultNodeRouting.js";
|
|
31
|
+
import { publishPreviews } from "../canvas/publishPreviews.js";
|
|
30
32
|
import { DEFAULT_HANDLE_SIZE } from "../canvas/SceneCanvas/props.js";
|
|
31
33
|
import { resolveOverlays } from "../interactions/actions/resolveOverlays.js";
|
|
32
34
|
import { flattenPreviews, resolvePreviews } from "../interactions/actions/resolvePreviews.js";
|
|
@@ -44,4 +46,4 @@ import { modeTriggers } from "../features/modes/modeTriggers.js";
|
|
|
44
46
|
import { createChildrenLayer } from "../core/layers/children.js";
|
|
45
47
|
import { bitmapSrc, getImageBitmap as getImageBitmap$1, imageStatus as imageStatus$1, isVectorImageSrc, releaseImage, retryImage, setImageCacheBudget, subscribeImageReady as subscribeImageReady$1 } from "@weasel-js/renderer";
|
|
46
48
|
|
|
47
|
-
export { CANVAS_CONTEXT_ATTRIBUTES, CursorCoordsHud, DEBUG_FEATURES, DEFAULT_DEBUG_STROKES, DEFAULT_DEBUG_THEME, DEFAULT_HANDLE_SIZE, DEFAULT_INK, DEFAULT_LAYER_RETAIN, DevtoolsLabel, LeanSceneCanvas, OVERLAY_ROLE_STROKES, PATH_OVERLAY_ROLES, PickHud, SceneCanvas, WeaselProvider, bitmapSrc, buildDebugOverlayCommands, createChildrenLayer, createDebugOverlayLayer, createDebugSink, createNodeProperties, createNodeRouting, createPathOverlay, defaultDrawOne, defaultNodeProperties, defaultNodeRouting, defaultPaintBounds, depsUnchanged, dlog, drawLayers, drawOneLayer, drawnAABBOf, drawnBoundsOf, drawnBoundsScene, dwarn, findNodeShape, findShapeBounds, findShapeDrawnBounds, findShapeInk, findShapeSilhouette, flattenPreviews, getImageBitmap$1 as getImageBitmap, getNodeShapes, groupNodeRouting, hostAnchorCss, hostAnchorRect, imageStatus$1 as imageStatus, inferredNodeProperties, inferredNodeRouting, inheritedPaintIn, inheritedPaintOf, inheritsPaint, inkExtentsOf, insertPreviewExtent, isDebugEnabled, isLayerPainted, isLayerVisible, isOverChildren, isVectorImageSrc, kitTextHandler, minSizeOf, modeDecorationLayer, modeTriggers, openFilePicker, overChildren, paintAbove, paintedLayers, parseDebugFlags, registerContentHandler, registerNodeShape, releaseImage, resolveOverlays, resolvePreviews, retryImage, rotationDegreesUnit, routeKind, sceneToAdapter, setImageCacheBudget, shapeCoversPoint, splitOverChildren, subscribeImageReady$1 as subscribeImageReady, subscribeToSources, useDevtoolsLabel, useHostAnchor, useSceneAdapter, withInheritedPaint, withInheritedPaints, workspaceTintLayer };
|
|
49
|
+
export { CANVAS_CONTEXT_ATTRIBUTES, CursorCoordsHud, DEBUG_FEATURES, DEFAULT_DEBUG_STROKES, DEFAULT_DEBUG_THEME, DEFAULT_HANDLE_SIZE, DEFAULT_INK, DEFAULT_LAYER_RETAIN, DevtoolsLabel, LeanSceneCanvas, OVERLAY_ROLE_STROKES, PATH_OVERLAY_ROLES, PickHud, SceneCanvas, WeaselProvider, bitmapSrc, buildDebugOverlayCommands, clipOutline, createChildrenLayer, createDebugOverlayLayer, createDebugSink, createNodeProperties, createNodeRouting, createPathOverlay, defaultDrawOne, defaultNodeProperties, defaultNodeRouting, defaultPaintBounds, depsUnchanged, dlog, drawLayers, drawOneLayer, drawnAABBOf, drawnBoundsOf, drawnBoundsScene, dwarn, findNodeShape, findShapeBounds, findShapeDrawnBounds, findShapeInk, findShapeSilhouette, flattenPreviews, getImageBitmap$1 as getImageBitmap, getNodeShapes, groupNodeRouting, hostAnchorCss, hostAnchorRect, imageStatus$1 as imageStatus, inferredNodeProperties, inferredNodeRouting, inheritedPaintIn, inheritedPaintOf, inheritsPaint, inkExtentsOf, insertPreviewExtent, isDebugEnabled, isLayerPainted, isLayerVisible, isOverChildren, isVectorImageSrc, kitTextHandler, minSizeOf, modeDecorationLayer, modeTriggers, openFilePicker, overChildren, paintAbove, paintedLayers, parseDebugFlags, publishPreviews, registerContentHandler, registerNodeShape, releaseImage, resolveOverlays, resolvePreviews, retryImage, rotationDegreesUnit, routeKind, sceneToAdapter, setImageCacheBudget, shapeCoversPoint, splitOverChildren, subscribeImageReady$1 as subscribeImageReady, subscribeToSources, useDevtoolsLabel, useHostAnchor, useSceneAdapter, withInheritedPaint, withInheritedPaintBounds, withInheritedPaints, workspaceTintLayer };
|
package/dist/barrel/chrome.js
CHANGED
|
@@ -4,6 +4,7 @@ import { annulusSemiAxes, hitAffordanceRegions, pointRegionFrame } from "../affo
|
|
|
4
4
|
import { createCornerResizeAffordance } from "../affordances/cornerResize.js";
|
|
5
5
|
import { createRotationAffordance } from "../affordances/rotationHandle.js";
|
|
6
6
|
import { PATH_ANCHOR_CHROME_ID, createPathAnchorAffordances } from "../affordances/pathAnchors.js";
|
|
7
|
+
import { createEnteredGroup, useEnteredGroup } from "../canvas/deps/enteredGroup.js";
|
|
7
8
|
import { actionIs, always, and, canHover, capabilityAll, capabilityIn, capabilityIs, capabilityNot, coarsePointer, cond, editingAnchors, focused, gesturing, hovering, hoveringSelected, modeIn, modeIs, modeNot, modifierHeld, multiActive, never, not, or, selectionAtLeast, selectionEmpty, selectionIs, when, zoomAtLeast } from "../features/chrome-caps/conditions.js";
|
|
8
9
|
import { composeSelectionPose } from "../features/selection/selectionPose.js";
|
|
9
10
|
import { createSelectionHandlesLayer, createSelectionOutlineLayer, createSelectionOverlayLayer } from "../features/selection/overlay.js";
|
|
@@ -12,8 +13,9 @@ import { resolveVisibility } from "../features/chrome-caps/resolve.js";
|
|
|
12
13
|
import { buildChromeCtx } from "../features/chrome-caps/buildChromeCtx.js";
|
|
13
14
|
import { useHoverTracking } from "../features/chrome-caps/useHoverTracking.js";
|
|
14
15
|
import { ALWAYS, DEFAULT_ALLOWED_CAPABILITIES, NEVER, buildRuleCtx, describeRule, evaluate } from "../features/chrome-caps/index.js";
|
|
16
|
+
import { createEnteredGroupScope } from "../features/selection/enteredGroupScope.js";
|
|
15
17
|
import { composeAffordanceLayer } from "../affordances/composeAffordanceLayer.js";
|
|
16
18
|
import { SelectionContextProvider as SelectionContextProvider$1, SelectionContextProviderIfRoot as SelectionContextProviderIfRoot$1, usePublishSelection as usePublishSelection$1, useSelectionContext } from "@weasel-js/routing/react";
|
|
17
19
|
import { ANGLE_RADIANS as ANGLE_RADIANS$1, IMPERIAL_INCHES, METRIC_MM, PIXELS, axisUnits, formatAxes, formatScoped, formatUnit, fromRoot, parseUnitExpr, resolveAxes, resolveScoped, resolveUnit, resolveUnitExpr, scopesOf as scopesOf$1, toRoot, unitScale } from "@weasel-js/quantity";
|
|
18
20
|
|
|
19
|
-
export { ALWAYS, ANGLE_RADIANS$1 as ANGLE_RADIANS, DEFAULT_ALLOWED_CAPABILITIES, IMPERIAL_INCHES, METRIC_MM, NEVER, PATH_ANCHOR_CHROME_ID, PIXELS, SelectionContextProvider$1 as SelectionContextProvider, SelectionContextProviderIfRoot$1 as SelectionContextProviderIfRoot, actionIs, always, and, annulusSemiAxes, axisUnits, buildChromeCtx, buildRuleCtx, canHover, capabilityAll, capabilityIn, capabilityIs, capabilityNot, coarsePointer, composeAffordanceLayer, composeSelectionPose, cond, createCornerResizeAffordance, createPathAnchorAffordances, createRotationAffordance, createSelectionHandlesLayer, createSelectionOutlineLayer, createSelectionOverlayLayer, defaultVisibilityRules, describeRule, editingAnchors, evaluate, focused, formatAxes, formatScoped, formatUnit, fromRoot, gesturing, hitAffordanceRegions, hovering, hoveringSelected, modeIn, modeIs, modeNot, modifierHeld, multiActive, never, not, or, paintsLayer, parseUnitExpr, pointRegionFrame, resolveAxes, resolveScoped, resolveUnit, resolveUnitExpr, resolveVisibility, scopesOf$1 as scopesOf, selectionAtLeast, selectionEmpty, selectionIs, toRoot, unitScale, useHoverTracking, usePublishSelection$1 as usePublishSelection, useSelection, useSelectionContext, when, zoomAtLeast };
|
|
21
|
+
export { ALWAYS, ANGLE_RADIANS$1 as ANGLE_RADIANS, DEFAULT_ALLOWED_CAPABILITIES, IMPERIAL_INCHES, METRIC_MM, NEVER, PATH_ANCHOR_CHROME_ID, PIXELS, SelectionContextProvider$1 as SelectionContextProvider, SelectionContextProviderIfRoot$1 as SelectionContextProviderIfRoot, actionIs, always, and, annulusSemiAxes, axisUnits, buildChromeCtx, buildRuleCtx, canHover, capabilityAll, capabilityIn, capabilityIs, capabilityNot, coarsePointer, composeAffordanceLayer, composeSelectionPose, cond, createCornerResizeAffordance, createEnteredGroup, createEnteredGroupScope, createPathAnchorAffordances, createRotationAffordance, createSelectionHandlesLayer, createSelectionOutlineLayer, createSelectionOverlayLayer, defaultVisibilityRules, describeRule, editingAnchors, evaluate, focused, formatAxes, formatScoped, formatUnit, fromRoot, gesturing, hitAffordanceRegions, hovering, hoveringSelected, modeIn, modeIs, modeNot, modifierHeld, multiActive, never, not, or, paintsLayer, parseUnitExpr, pointRegionFrame, resolveAxes, resolveScoped, resolveUnit, resolveUnitExpr, resolveVisibility, scopesOf$1 as scopesOf, selectionAtLeast, selectionEmpty, selectionIs, toRoot, unitScale, useEnteredGroup, useHoverTracking, usePublishSelection$1 as usePublishSelection, useSelection, useSelectionContext, when, zoomAtLeast };
|
package/dist/barrel/paths.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { noteFontRead } from "../core/scene/fontReads.js";
|
|
2
2
|
import { derivedPartsOf, pathFromParts, resolvePartPaint } from "../core/scene/derivedParts.js";
|
|
3
|
+
import { sourcesOf } from "../core/scene/dependents.js";
|
|
3
4
|
import { pathPoseDescriptor } from "../core/geometry/pathPoseDescriptor.js";
|
|
4
5
|
import { commitOps } from "../interactions/actions/defaultCommitAdapter.js";
|
|
5
6
|
import { HANDLE_LOCK_ROLES, locksInForce } from "../interactions/actions/edit-anchors/handleDrag.js";
|
|
@@ -10,7 +11,7 @@ import { deleteSelectedMark, editTargetOf, markUnder } from "../interactions/act
|
|
|
10
11
|
import { anchorEditWouldChange, commitAnchorEdit, depOf, requiresAnchorSelection } from "../interactions/actions/defaults/anchorEditing.js";
|
|
11
12
|
import { textAlongParts } from "../core/scene/pathEffects/textAlong.js";
|
|
12
13
|
import { PATH_EFFECT, createPathEffectDerivations, pathEffectNode, pathEffectOf, pathEffectParts, registeredPathEffects } from "../core/scene/pathEffects/derive.js";
|
|
13
|
-
import { effectSourceFor, hiddenSourcesTakenWith } from "../features/pathEffects/effectSources.js";
|
|
14
|
+
import { effectSourceFor, hiddenSourcesTakenWith, sourcesHiddenBy } from "../features/pathEffects/effectSources.js";
|
|
14
15
|
import { makeHandleCommand } from "../interactions/actions/defaults/anchorHandles.js";
|
|
15
16
|
import { joinSelectedAnchors } from "../interactions/actions/defaults/anchorJoin.js";
|
|
16
17
|
import { segmentUnder } from "../interactions/actions/defaults/segmentUnder.js";
|
|
@@ -40,4 +41,4 @@ import { commitBooleanPieces, resolveBooleanOperands } from "../interactions/act
|
|
|
40
41
|
import { CONSTRAINT_TOLERANCE, constrainPathEdit, constraintAnchors, pathAnchorPoints, solveConstraints, solvePathConstraints, unsatisfiedConstraints } from "@weasel-js/geom";
|
|
41
42
|
import { CURVE_REPS, bezierCubic, bezierQuadratic, nurbs, spiro } from "@weasel-js/geom/curves";
|
|
42
43
|
|
|
43
|
-
export { CONSTRAINT_TOLERANCE, CORNER_FIT_TOLERANCE, CORNER_KEYWORDS, CURVE_REPS, DEFAULT_FLATTEN_TOLERANCE, DEFAULT_OVERLAY_STYLE, DEFAULT_SIMPLIFY_TOLERANCE, GEOMETRY_BOUND_DATA, HANDLE_LOCK_ROLES, PATHFINDER_STROKES, PATH_C$1 as PATH_C, PATH_CMD_LENGTHS, PATH_EFFECT, PATH_EFFECT_DERIVATIONS, PATH_L$1 as PATH_L, PATH_M$1 as PATH_M, PATH_Q$1 as PATH_Q, PATH_SNAP_KINDS$1 as PATH_SNAP_KINDS, PATH_SNAP_LABELS, PATH_Z$1 as PATH_Z, PathBuilder, SHAPE_COUNT_RANGE, STAR_RATIO_RANGE, anchorEditWouldChange, applyBooleanOp, asPolygonPath$1 as asPolygonPath, averageAnchorsAt$1 as averageAnchorsAt, bendAlongPath$1 as bendAlongPath, bezierCubic, bezierQuadratic, blendPaths, boundsOfPath$1 as boundsOfPath, circlePath$1 as circlePath, clampShapeGenerator, classifyPathStorage, commitAnchorEdit, commitBooleanPieces, commitOps, composePath, constrainPathEdit, constraintAnchors, cornerAt, cornerFrameAt, cornerFrames, cornerKeywordOf, cornerShapeK, cornerShapePieces, cornerSpecAt, countPathAnchors$1 as countPathAnchors, createPathEditingOverlayLayer, createPathEffectDerivations, createPathLayer, createPathSnapIndex$1 as createPathSnapIndex, createPenPreviewLayer, decomposePath, deleteNode, deleteSelectedMark, depOf, derivedPartsOf, editTargetOf, editedPathSymmetries, effectSourceFor, ellipsePath$1 as ellipsePath, extendToMeet, findPathSnap$1 as findPathSnap, finishPathEditFrame, flattenCubic, flattenCubicWithArcLen, flattenQuadratic, flattenQuadraticWithArcLen, hasCorners, hasEditablePath, hasOpenSubpath$1 as hasOpenSubpath, hiddenSourcesTakenWith, insertAt, intersectSegments, isCornerShape, isShapeGenerator, joinAnchorsAt$1 as joinAnchorsAt, joinPathsCommand, joinSelectedAnchors, lengthenOpenEnd, linePath$1 as linePath, livePathEdit, locksInForce, makeHandleCommand, markUnder, measurePath$1 as measurePath, nextCornerShape, nodeOutline, noteFontRead, nurbs, offsetPath, openEndRay, openPathEnds, pathAnchorPoints, pathCommandCoordCount, pathContainsPoint$1 as pathContainsPoint, pathContainsPolygon, pathContainsRect, pathCopy, pathCrossings, pathDistanceToPoint, pathDivide, pathEditPathOf, pathEditPreview, pathEffectNode, pathEffectOf, pathEffectParts, pathExclude, pathFromD$1 as pathFromD, pathFromParts, pathInPoseFrame$1 as pathInPoseFrame, pathInWorld$1 as pathInWorld, pathIntersect, pathIntersectsPolygon, pathIntersectsRect$1 as pathIntersectsRect, pathNodesOf, pathOriginProjection, pathPoseDescriptor, pathSegments, pathSignedArea, pathSnapGlyph, pathSubtract, pathThroughPoseFrame$1 as pathThroughPoseFrame, pathToAnchors$1 as pathToAnchors, pathToD, pathUnion, planJoin, pointAlongPath, pointInPath$1 as pointInPath, polygonFromPoints$1 as polygonFromPoints, polylineFromPoints$1 as polylineFromPoints, poseFrameInverseOf$1 as poseFrameInverseOf, poseFrameOf$1 as poseFrameOf, poseLinearOf$1 as poseLinearOf, poseRotationOf, prepareBlend$1 as prepareBlend, previewBooleanOp, readEffectSource, rectMarkerPath$1 as rectMarkerPath, rectPath$1 as rectPath, regenerateShape, registeredPathEffects, regularPolygonPath$1 as regularPolygonPath, remapPerAnchor, repeatAlongPath$1 as repeatAlongPath, requiresAnchorSelection, reshapeOps, reshapeTo, resolveBooleanOperands, resolveCorners$1 as resolveCorners, resolveCornersWithSources, resolveEditablePathOf, resolvePartPaint, reversePath, rotatePathAround$1 as rotatePathAround, roundRectPath, scalePathToBounds, segmentUnder, selectedPathNodes, settleShapeGenerator, shapeGeneratorOf, shapeGeneratorPath, simplifyAnchorsAt, simplifyPath$1 as simplifyPath, slotOf, smudgePath, snipPathByPolyline, snipPathsAtCrossings, solveConstraints, solvePathConstraints, spiro, splitByClosure, splitPathByPolyline, splitPathBySegment, splitSubpaths, squarePath$1 as squarePath, starPath$1 as starPath, stationsAlongPath, storeEditablePath, strokeToPath, textAlongParts, transformPath$1 as transformPath, translatePath$1 as translatePath, trianglesToPath, trimPathAt, unionBoundsPath, unsatisfiedConstraints, useAnchorFields, useBooleans, useBooleansAdapter, useEffectSourcesLayer, withCorner, withPath, withPathEffectsRegistry, withoutCorners, withoutGeometryBoundData, withoutShapeGenerator, worldEditToStorage$1 as worldEditToStorage };
|
|
44
|
+
export { CONSTRAINT_TOLERANCE, CORNER_FIT_TOLERANCE, CORNER_KEYWORDS, CURVE_REPS, DEFAULT_FLATTEN_TOLERANCE, DEFAULT_OVERLAY_STYLE, DEFAULT_SIMPLIFY_TOLERANCE, GEOMETRY_BOUND_DATA, HANDLE_LOCK_ROLES, PATHFINDER_STROKES, PATH_C$1 as PATH_C, PATH_CMD_LENGTHS, PATH_EFFECT, PATH_EFFECT_DERIVATIONS, PATH_L$1 as PATH_L, PATH_M$1 as PATH_M, PATH_Q$1 as PATH_Q, PATH_SNAP_KINDS$1 as PATH_SNAP_KINDS, PATH_SNAP_LABELS, PATH_Z$1 as PATH_Z, PathBuilder, SHAPE_COUNT_RANGE, STAR_RATIO_RANGE, anchorEditWouldChange, applyBooleanOp, asPolygonPath$1 as asPolygonPath, averageAnchorsAt$1 as averageAnchorsAt, bendAlongPath$1 as bendAlongPath, bezierCubic, bezierQuadratic, blendPaths, boundsOfPath$1 as boundsOfPath, circlePath$1 as circlePath, clampShapeGenerator, classifyPathStorage, commitAnchorEdit, commitBooleanPieces, commitOps, composePath, constrainPathEdit, constraintAnchors, cornerAt, cornerFrameAt, cornerFrames, cornerKeywordOf, cornerShapeK, cornerShapePieces, cornerSpecAt, countPathAnchors$1 as countPathAnchors, createPathEditingOverlayLayer, createPathEffectDerivations, createPathLayer, createPathSnapIndex$1 as createPathSnapIndex, createPenPreviewLayer, decomposePath, deleteNode, deleteSelectedMark, depOf, derivedPartsOf, editTargetOf, editedPathSymmetries, effectSourceFor, ellipsePath$1 as ellipsePath, extendToMeet, findPathSnap$1 as findPathSnap, finishPathEditFrame, flattenCubic, flattenCubicWithArcLen, flattenQuadratic, flattenQuadraticWithArcLen, hasCorners, hasEditablePath, hasOpenSubpath$1 as hasOpenSubpath, hiddenSourcesTakenWith, insertAt, intersectSegments, isCornerShape, isShapeGenerator, joinAnchorsAt$1 as joinAnchorsAt, joinPathsCommand, joinSelectedAnchors, lengthenOpenEnd, linePath$1 as linePath, livePathEdit, locksInForce, makeHandleCommand, markUnder, measurePath$1 as measurePath, nextCornerShape, nodeOutline, noteFontRead, nurbs, offsetPath, openEndRay, openPathEnds, pathAnchorPoints, pathCommandCoordCount, pathContainsPoint$1 as pathContainsPoint, pathContainsPolygon, pathContainsRect, pathCopy, pathCrossings, pathDistanceToPoint, pathDivide, pathEditPathOf, pathEditPreview, pathEffectNode, pathEffectOf, pathEffectParts, pathExclude, pathFromD$1 as pathFromD, pathFromParts, pathInPoseFrame$1 as pathInPoseFrame, pathInWorld$1 as pathInWorld, pathIntersect, pathIntersectsPolygon, pathIntersectsRect$1 as pathIntersectsRect, pathNodesOf, pathOriginProjection, pathPoseDescriptor, pathSegments, pathSignedArea, pathSnapGlyph, pathSubtract, pathThroughPoseFrame$1 as pathThroughPoseFrame, pathToAnchors$1 as pathToAnchors, pathToD, pathUnion, planJoin, pointAlongPath, pointInPath$1 as pointInPath, polygonFromPoints$1 as polygonFromPoints, polylineFromPoints$1 as polylineFromPoints, poseFrameInverseOf$1 as poseFrameInverseOf, poseFrameOf$1 as poseFrameOf, poseLinearOf$1 as poseLinearOf, poseRotationOf, prepareBlend$1 as prepareBlend, previewBooleanOp, readEffectSource, rectMarkerPath$1 as rectMarkerPath, rectPath$1 as rectPath, regenerateShape, registeredPathEffects, regularPolygonPath$1 as regularPolygonPath, remapPerAnchor, repeatAlongPath$1 as repeatAlongPath, requiresAnchorSelection, reshapeOps, reshapeTo, resolveBooleanOperands, resolveCorners$1 as resolveCorners, resolveCornersWithSources, resolveEditablePathOf, resolvePartPaint, reversePath, rotatePathAround$1 as rotatePathAround, roundRectPath, scalePathToBounds, segmentUnder, selectedPathNodes, settleShapeGenerator, shapeGeneratorOf, shapeGeneratorPath, simplifyAnchorsAt, simplifyPath$1 as simplifyPath, slotOf, smudgePath, snipPathByPolyline, snipPathsAtCrossings, solveConstraints, solvePathConstraints, sourcesHiddenBy, sourcesOf, spiro, splitByClosure, splitPathByPolyline, splitPathBySegment, splitSubpaths, squarePath$1 as squarePath, starPath$1 as starPath, stationsAlongPath, storeEditablePath, strokeToPath, textAlongParts, transformPath$1 as transformPath, translatePath$1 as translatePath, trianglesToPath, trimPathAt, unionBoundsPath, unsatisfiedConstraints, useAnchorFields, useBooleans, useBooleansAdapter, useEffectSourcesLayer, withCorner, withPath, withPathEffectsRegistry, withoutCorners, withoutGeometryBoundData, withoutShapeGenerator, worldEditToStorage$1 as worldEditToStorage };
|
package/dist/barrel/routing.js
CHANGED
|
@@ -57,8 +57,8 @@ import { useSliceTool } from "../tools/builtin/slice/useSliceTool.js";
|
|
|
57
57
|
import { useMeasureTool } from "../tools/builtin/measure/useMeasureTool.js";
|
|
58
58
|
import { isToolSet, toolIdsOf as toolIdsOf$1, toolSet as toolSet$1, toolSetHas, withoutTools } from "../tools/index.js";
|
|
59
59
|
import { useLatest as useLatest$1 } from "@weasel-js/react";
|
|
60
|
-
import { ActionDisabledReason as ActionDisabledReason$1, actionBindings as actionBindings$1, actionCursor, actionItemTitle, actionItems, actionSettingsParams, actionShortcuts, actionsTagged, bindingId, buildDepsFromRequires as buildDepsFromRequires$1, createDepRegistry, createDispatcher as createDispatcher$1, deleteScratch, evaluateActive as evaluateActive$1, evaluateEnabled as evaluateEnabled$1, getScratch as getScratch$1, heldKeySpec as heldKeySpec$1, keySpecShortcut, keysHeld, matchActionItem, overlaysOf as overlaysOf$1, readActionSettings, resolveBindingOverrides, resolveParams as resolveParams$1, resolveSchemaMenu, roleReader as roleReader$1, scratchKey as scratchKey$1, setScratch as setScratch$1, specificity, taggedActionItems, tuneAction } from "@weasel-js/routing";
|
|
60
|
+
import { ActionDisabledReason as ActionDisabledReason$1, actionBindings as actionBindings$1, actionCursor, actionItemTitle, actionItems, actionSettingsParams, actionShortcuts, actionsTagged, bindingId, buildDepsFromRequires as buildDepsFromRequires$1, createDepRegistry, createDispatcher as createDispatcher$1, deleteScratch, evaluateActive as evaluateActive$1, evaluateEnabled as evaluateEnabled$1, getScratch as getScratch$1, heldKeySpec as heldKeySpec$1, keySpecShortcut, keysHeld, matchActionItem, modifierStateOf, overlaysOf as overlaysOf$1, readActionSettings, resolveBindingOverrides, resolveParams as resolveParams$1, resolveSchemaMenu, roleReader as roleReader$1, scratchKey as scratchKey$1, setScratch as setScratch$1, specificity, taggedActionItems, tuneAction } from "@weasel-js/routing";
|
|
61
61
|
import { bodyPredicate, hitPredicate as hitPredicate$1 } from "@weasel-js/gestures";
|
|
62
62
|
import { ActionsProvider as ActionsProvider$1, ActiveToolContextProvider as ActiveToolContextProvider$1, ActiveToolContextProviderIfRoot as ActiveToolContextProviderIfRoot$1, DepRegistryProvider as DepRegistryProvider$1, InputScope as InputScope$1, Yoke, useAction, useActionsRegistry as useActionsRegistry$1, useActiveToolContext, useCommand, useDepRegistry as useDepRegistry$1, useDepSource as useDepSource$1, useGestureDispatcher as useGestureDispatcher$1, useMenuHost as useMenuHost$1, useMenus, useOngoingAction, useOpenKeymap, useOptionalActiveToolContext as useOptionalActiveToolContext$1, useOptionalDepRegistry as useOptionalDepRegistry$1, useYoke } from "@weasel-js/routing/react";
|
|
63
63
|
|
|
64
|
-
export { AREA_SELECT_ID, ActionDisabledReason$1 as ActionDisabledReason, ActionsProvider$1 as ActionsProvider, ActiveToolContextProvider$1 as ActiveToolContextProvider, ActiveToolContextProviderIfRoot$1 as ActiveToolContextProviderIfRoot, CORNER_ANCHORS, DRAG_PAN_ID, DepRegistryProvider$1 as DepRegistryProvider, EDGE_HANDLE_MIN_RADII, INSERT_REPOSITION_BINDING, InputScope$1 as InputScope, KIT_STANDARD_ACTION_IDS, PATH_GESTURE_TAGS, RESIZE_HANDLE_ANCHORS, SELECTION_MOVE_ID, SELECTION_RESIZE_ID, SELECTION_ROTATE_ID, SELECTION_TRANSFORM_ID, STICKY_DEFAULTS, Yoke, actionBindings$1 as actionBindings, actionCursor, actionItemTitle, actionItems, actionSettingsParams, actionShortcuts, actionsTagged, areaSelectAction, areaSelectContribution, bindingId, bodyPredicate, buildDepsFromRequires$1 as buildDepsFromRequires, clearSelectionAction, clipboardCopyAction, clipboardCutAction, clipboardPasteAction, clipboardPasteEventAction, cloneAction, commitDeleteToScene, computeSliceOps, contextMenuAction, cornerPoint, createDeleteAction, createDepRegistry, createDispatcher$1 as createDispatcher, createPointerFollower, createResizeAction, defaultCommitAdapter, defineTool, deleteAction, deleteAnchorsAction, deleteScratch, dragPanContribution, editAnchorsAction, editingLayer, enterTextEditAction, evaluateActive$1 as evaluateActive, evaluateEnabled$1 as evaluateEnabled, exitPathEditToolAction, flipAction, getScratch$1 as getScratch, handlePoint, heldKeySpec$1 as heldKeySpec, hiddenSourceDeleteOps, hitPredicate$1 as hitPredicate, inPlane, insertAction, insertLayer, insertRepositionAction, isCornerHandle, isToolSet, keySpecShortcut, keysHeld, lassoSelectAction, makePinchZoomAction, makeViewportWheelPanAction, makeViewportZoomAction, matchActionItem, moveAction, nudgeAnchorsDownAction, nudgeAnchorsLeftAction, nudgeAnchorsRightAction, nudgeAnchorsUpAction, onEmptyCanvas, openContextMenu, overlaysOf$1 as overlaysOf, pathEditToolAction, pathEditToolActive, pathOperationTags, pickTopMostHit, pinchZoomAction, placeAction, readActionSettings, resizeAction, resizeHandlesFor, resolveBindingOverrides, resolveParams$1 as resolveParams, resolveSchemaMenu, roleReader$1 as roleReader, rotateAction, scratchKey$1 as scratchKey, selectAnchorAction, selectFromLasso, selectionLayer, selectionMoveBindings, selectionMoveContribution, selectionResizeBindings, selectionResizeContribution, selectionRotateBindings, selectionRotateContribution, selectionTransformBindings, selectionTransformContribution, setScratch$1 as setScratch, sliceAction, specificity, stickyData, stickyNodeFactory, taggedActionItems, toolIdsOf$1 as toolIdsOf, toolSet$1 as toolSet, toolSetHas, tuneAction, useAction, useActionsRegistry$1 as useActionsRegistry, useActiveToolContext, useBooleansAdapterSource, useCommand, useDepRegistry$1 as useDepRegistry, useDepSource$1 as useDepSource, useEllipseTool, useEyedropperTool, useGestureDispatcher$1 as useGestureDispatcher, useHandTool, useImageTool, useKeybindings, useLassoTool, useLatest$1 as useLatest, useLineTool, useMeasureTool, useMenuHost$1 as useMenuHost, useMenus, useOngoingAction, useOpenKeymap, useOptionalActiveToolContext$1 as useOptionalActiveToolContext, useOptionalDepRegistry$1 as useOptionalDepRegistry, usePenTool, usePencilTool, usePolygonTool, usePoseDescriptorDepSource, useRectTool, useResizePolicy, useSelectTool, useSliceDep, useSliceDepSource, useSliceTool, useStandardActions, useStarTool, useStickyTool, useTextTool, useTools$1 as useTools, useYoke, viewportDragPanAction, viewportWheelPanAction, viewportZoomAction, withoutTools };
|
|
64
|
+
export { AREA_SELECT_ID, ActionDisabledReason$1 as ActionDisabledReason, ActionsProvider$1 as ActionsProvider, ActiveToolContextProvider$1 as ActiveToolContextProvider, ActiveToolContextProviderIfRoot$1 as ActiveToolContextProviderIfRoot, CORNER_ANCHORS, DRAG_PAN_ID, DepRegistryProvider$1 as DepRegistryProvider, EDGE_HANDLE_MIN_RADII, INSERT_REPOSITION_BINDING, InputScope$1 as InputScope, KIT_STANDARD_ACTION_IDS, PATH_GESTURE_TAGS, RESIZE_HANDLE_ANCHORS, SELECTION_MOVE_ID, SELECTION_RESIZE_ID, SELECTION_ROTATE_ID, SELECTION_TRANSFORM_ID, STICKY_DEFAULTS, Yoke, actionBindings$1 as actionBindings, actionCursor, actionItemTitle, actionItems, actionSettingsParams, actionShortcuts, actionsTagged, areaSelectAction, areaSelectContribution, bindingId, bodyPredicate, buildDepsFromRequires$1 as buildDepsFromRequires, clearSelectionAction, clipboardCopyAction, clipboardCutAction, clipboardPasteAction, clipboardPasteEventAction, cloneAction, commitDeleteToScene, computeSliceOps, contextMenuAction, cornerPoint, createDeleteAction, createDepRegistry, createDispatcher$1 as createDispatcher, createPointerFollower, createResizeAction, defaultCommitAdapter, defineTool, deleteAction, deleteAnchorsAction, deleteScratch, dragPanContribution, editAnchorsAction, editingLayer, enterTextEditAction, evaluateActive$1 as evaluateActive, evaluateEnabled$1 as evaluateEnabled, exitPathEditToolAction, flipAction, getScratch$1 as getScratch, handlePoint, heldKeySpec$1 as heldKeySpec, hiddenSourceDeleteOps, hitPredicate$1 as hitPredicate, inPlane, insertAction, insertLayer, insertRepositionAction, isCornerHandle, isToolSet, keySpecShortcut, keysHeld, lassoSelectAction, makePinchZoomAction, makeViewportWheelPanAction, makeViewportZoomAction, matchActionItem, modifierStateOf, moveAction, nudgeAnchorsDownAction, nudgeAnchorsLeftAction, nudgeAnchorsRightAction, nudgeAnchorsUpAction, onEmptyCanvas, openContextMenu, overlaysOf$1 as overlaysOf, pathEditToolAction, pathEditToolActive, pathOperationTags, pickTopMostHit, pinchZoomAction, placeAction, readActionSettings, resizeAction, resizeHandlesFor, resolveBindingOverrides, resolveParams$1 as resolveParams, resolveSchemaMenu, roleReader$1 as roleReader, rotateAction, scratchKey$1 as scratchKey, selectAnchorAction, selectFromLasso, selectionLayer, selectionMoveBindings, selectionMoveContribution, selectionResizeBindings, selectionResizeContribution, selectionRotateBindings, selectionRotateContribution, selectionTransformBindings, selectionTransformContribution, setScratch$1 as setScratch, sliceAction, specificity, stickyData, stickyNodeFactory, taggedActionItems, toolIdsOf$1 as toolIdsOf, toolSet$1 as toolSet, toolSetHas, tuneAction, useAction, useActionsRegistry$1 as useActionsRegistry, useActiveToolContext, useBooleansAdapterSource, useCommand, useDepRegistry$1 as useDepRegistry, useDepSource$1 as useDepSource, useEllipseTool, useEyedropperTool, useGestureDispatcher$1 as useGestureDispatcher, useHandTool, useImageTool, useKeybindings, useLassoTool, useLatest$1 as useLatest, useLineTool, useMeasureTool, useMenuHost$1 as useMenuHost, useMenus, useOngoingAction, useOpenKeymap, useOptionalActiveToolContext$1 as useOptionalActiveToolContext, useOptionalDepRegistry$1 as useOptionalDepRegistry, usePenTool, usePencilTool, usePolygonTool, usePoseDescriptorDepSource, useRectTool, useResizePolicy, useSelectTool, useSliceDep, useSliceDepSource, useSliceTool, useStandardActions, useStarTool, useStickyTool, useTextTool, useTools$1 as useTools, useYoke, viewportDragPanAction, viewportWheelPanAction, viewportZoomAction, withoutTools };
|
package/dist/barrel/scene.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { IDENTITY_POSE_COMPOSITION, composeWorldPose, composesFrames, rebaseLocalPose } from "../core/scene/composeFrame.js";
|
|
2
2
|
import { RECT_POSE_COMPOSITION, RIGID_POSE_COMPOSITION, composeRectPose, composeRigidPose, decomposeRectPose, decomposeRigidPose, translateRectPose, worldPoseLookup } from "../core/scene/composePose.js";
|
|
3
|
+
import { documentOf } from "../core/scene/documentOf.js";
|
|
4
|
+
import { nodeAsShown } from "../core/scene/nodeAsShown.js";
|
|
3
5
|
import { definesFrame, derivedDepOf, derivedPose, documentDepOf, documentPose, effectivePose } from "../core/scene/effectivePose.js";
|
|
4
6
|
import { axisAlignedBounds, unionAABB, unionBounds } from "../core/geometry/unionBounds.js";
|
|
5
7
|
import { scenePoseAdapter } from "../core/scene/scenePoseAdapter.js";
|
|
@@ -8,7 +10,9 @@ import { measureBetween, measureEndsOf, measureNode, measurePose, measurementOf
|
|
|
8
10
|
import { asNodeId } from "../core/scene/types.js";
|
|
9
11
|
import { annotationLayerIds, isAnnotationLayer, isAnnotationNode } from "../core/scene/annotation.js";
|
|
10
12
|
import { hidesSubtree, isNodeHidden, isNodeLocked, nodeGates } from "../core/scene/nodeGates.js";
|
|
13
|
+
import { statedFields } from "../core/scene/statedFields.js";
|
|
11
14
|
import { applyOpsTo, dispatchApplyBatch } from "../core/applyOps.js";
|
|
15
|
+
import { hasChildren, isLeaf } from "../core/scene/treeShape.js";
|
|
12
16
|
import { SceneArrivalRefused } from "../core/scene/arrivals.js";
|
|
13
17
|
import { opFactoryRegistry, rebuildOp, registerOpFactory, registeredOpNames } from "../core/ops/registry.js";
|
|
14
18
|
import { createTransformOp } from "../core/ops/transform.js";
|
|
@@ -32,6 +36,7 @@ import { createArrangeOp } from "../core/ops/arrange.js";
|
|
|
32
36
|
import { createHistory as createHistory$1 } from "../core/ops/createHistory.js";
|
|
33
37
|
import { SCENE_HISTORY_FORM } from "../core/scene/historyForm.js";
|
|
34
38
|
import { sceneSelectionStore } from "../core/scene/sceneSelection.js";
|
|
39
|
+
import { nodeKindOf, specsFromSerialized } from "../core/scene/serialization.js";
|
|
35
40
|
import { createScene, sceneFromJSON } from "../core/scene/scene.js";
|
|
36
41
|
import { createSetTextOp } from "../core/ops/setText.js";
|
|
37
42
|
import { createSetDependsOnOp } from "../core/ops/setDependsOn.js";
|
|
@@ -49,4 +54,4 @@ import { measurementsContribution } from "../features/measure/measureContributio
|
|
|
49
54
|
import { MIXED } from "@weasel-js/registry";
|
|
50
55
|
import { swapOp } from "@weasel-js/history";
|
|
51
56
|
|
|
52
|
-
export { CLIP_NOTHING, IDENTITY_POSE_COMPOSITION, MEASURE_ACTION_IDS, MEASURE_AFFORDANCE_KIND, MEASURE_LAYER_ID, MIXED, RECT_POSE_COMPOSITION, RIGID_POSE_COMPOSITION, SCENE_HISTORY_FORM, SceneArrivalRefused, UNION_OF_CHILDREN, annotationLayerIds, applyOpsTo, asNodeId, axisAlignedBounds, canBringForward, canSendBackward, carriedDescendants, clipNothing, composeRectPose, composeRigidPose, composeWorldPose, composesFrames, createArrangeOp, createDeleteOp, createHistory$1 as createHistory, createInsertOp, createMeasurements, createMoveToIndexOp, createPoseFeed, createPoseOverrides, createReorderOp, createReparentOp, createScene, createSetChildOrderOp, createSetDataOp, createSetDependsOnOp, createSetHiddenOp, createSetLayerOp, createSetLayoutOp, createSetLockedOp, createSetPathOp, createSetSelectionOp, createSetTextOp, createTransformOp, currentMeasureId, decomposeRectPose, decomposeRigidPose, definesFrame, derivedDepOf, derivedPose, dispatchApplyBatch, documentDepOf, documentPose, effectivePose, hidesSubtree, isAnnotationLayer, isAnnotationNode, isNodeHidden, isNodeLocked, measureAt, measureBetween, measureEndSource, measureEndsOf, measureIds, measureNode, measurePose, measurementOf, measurementsContribution, nestedHitTester, nodeGates, opFactoryRegistry, rebaseLocalPose, rebuildOp, reconcileSpecs, registerOpFactory, registeredOpNames, sceneCarrySource, sceneFromJSON, scenePoseAdapter, sceneSelectionStore, sceneSharedUnitScopes, sceneUnitScopes, swapOp, translateRectPose, unionAABB, unionBounds, unionOfChildren, unionOfChildrenVia, useScene, worldPoseLookup, writtenBy };
|
|
57
|
+
export { CLIP_NOTHING, IDENTITY_POSE_COMPOSITION, MEASURE_ACTION_IDS, MEASURE_AFFORDANCE_KIND, MEASURE_LAYER_ID, MIXED, RECT_POSE_COMPOSITION, RIGID_POSE_COMPOSITION, SCENE_HISTORY_FORM, SceneArrivalRefused, UNION_OF_CHILDREN, annotationLayerIds, applyOpsTo, asNodeId, axisAlignedBounds, canBringForward, canSendBackward, carriedDescendants, clipNothing, composeRectPose, composeRigidPose, composeWorldPose, composesFrames, createArrangeOp, createDeleteOp, createHistory$1 as createHistory, createInsertOp, createMeasurements, createMoveToIndexOp, createPoseFeed, createPoseOverrides, createReorderOp, createReparentOp, createScene, createSetChildOrderOp, createSetDataOp, createSetDependsOnOp, createSetHiddenOp, createSetLayerOp, createSetLayoutOp, createSetLockedOp, createSetPathOp, createSetSelectionOp, createSetTextOp, createTransformOp, currentMeasureId, decomposeRectPose, decomposeRigidPose, definesFrame, derivedDepOf, derivedPose, dispatchApplyBatch, documentDepOf, documentOf, documentPose, effectivePose, hasChildren, hidesSubtree, isAnnotationLayer, isAnnotationNode, isLeaf, isNodeHidden, isNodeLocked, measureAt, measureBetween, measureEndSource, measureEndsOf, measureIds, measureNode, measurePose, measurementOf, measurementsContribution, nestedHitTester, nodeAsShown, nodeGates, nodeKindOf, opFactoryRegistry, rebaseLocalPose, rebuildOp, reconcileSpecs, registerOpFactory, registeredOpNames, sceneCarrySource, sceneFromJSON, scenePoseAdapter, sceneSelectionStore, sceneSharedUnitScopes, sceneUnitScopes, specsFromSerialized, statedFields, swapOp, translateRectPose, unionAABB, unionBounds, unionOfChildren, unionOfChildrenVia, useScene, worldPoseLookup, writtenBy };
|
package/dist/barrel/text.js
CHANGED
|
@@ -5,6 +5,6 @@ import { createTextLayer } from "../features/text/textLayer.js";
|
|
|
5
5
|
import { useSceneTextEdit } from "../features/text/useSceneTextEdit.js";
|
|
6
6
|
import { TEXT_EDIT_FONT_HOLD, TextOutlinesError as TextOutlinesError$1, charOffsetToDomPosition, domPositionToCharOffset, domToRuns, loadTextOutlines as loadTextOutlines$1, runsToDom, textCommand, textCommandFromPose, textCommandFromRuns, textToPath as textToPath$1, textToPathsByPaint as textToPathsByPaint$1, useTextEdit } from "../features/text/index.js";
|
|
7
7
|
import { useCreateOutlinesAdapter } from "../interactions/actions/outlines/useCreateOutlinesAdapter.js";
|
|
8
|
-
import { DEFAULT_DECORATION_METRICS, DEFAULT_TEXT_FILL as DEFAULT_TEXT_FILL$1, DEFAULT_TEXT_STYLE, MARKDOWN_RUN_GRAMMAR, SCRIPT_METRICS, SMALL_CAPS_SCALE, applyStyleToRange, cachedLayoutRuns, cachedPaintRuns, caretIndexAt as caretIndexAt$1, createMarkdownRenderer, decorationMetrics, defaultLabelTextRenderer, effectiveRangeStyle, fitTextPose, fontString, isBoldWeight, isSmallCapsLetter, isTextData as isTextData$1, layoutMarkdown, layoutRuns, layoutTextPose, markdownToRuns, measureText, measureTextBounds as measureTextBounds$1, measuredWidth, nodeHasFlag, numericWeight, paintRuns, paragraphDirection, patchRangeStyle, pointInTextPose as pointInTextPose$1, rangeWeight, registerBidi, renderLabel, resolveAlign as resolveAlign$1, resolveRunFace, resolveRuns, resolveTextStyle, runsToMarkdown, runsToPlainText as runsToPlainText$1, scriptMetrics, scriptMetricsFor, setFlagOverRange, smallCapsScale, smallCapsScaleFor, smallCapsText, styleAtRange, textLineBoxes as textLineBoxes$1, textPoseLayoutInput, toRuns, transformRunTexts, unboldPatch, verticalAlignOffset } from "@weasel-js/text";
|
|
8
|
+
import { DEFAULT_DECORATION_METRICS, DEFAULT_TEXT_FILL as DEFAULT_TEXT_FILL$1, DEFAULT_TEXT_STYLE, MARKDOWN_RUN_GRAMMAR, QUAD_STRIDE, SCRIPT_METRICS, SMALL_CAPS_SCALE, applyStyleToRange, cachedLayoutRuns, cachedPaintRuns, caretIndexAt as caretIndexAt$1, createMarkdownRenderer, decorationMetrics, defaultLabelTextRenderer, effectiveRangeStyle, fitTextPose, fontString, isBoldWeight, isSmallCapsLetter, isTextData as isTextData$1, layoutMarkdown, layoutRuns, layoutTextPose, markdownToRuns, measureText, measureTextBounds as measureTextBounds$1, measuredWidth, nodeHasFlag, numericWeight, paintRuns, paragraphDirection, patchRangeStyle, pointInTextPose as pointInTextPose$1, rangeWeight, registerBidi, renderLabel, resolveAlign as resolveAlign$1, resolveRunFace, resolveRuns, resolveTextStyle, runsToMarkdown, runsToPlainText as runsToPlainText$1, scriptMetrics, scriptMetricsFor, setFlagOverRange, smallCapsScale, smallCapsScaleFor, smallCapsText, styleAtRange, textLineBoxes as textLineBoxes$1, textPoseLayoutInput, toRuns, transformRunTexts, unboldPatch, verticalAlignOffset } from "@weasel-js/text";
|
|
9
9
|
|
|
10
|
-
export { DEFAULT_DECORATION_METRICS, DEFAULT_TEXT_FILL$1 as DEFAULT_TEXT_FILL, DEFAULT_TEXT_STYLE, MARKDOWN_RUN_GRAMMAR, SCRIPT_METRICS, SMALL_CAPS_SCALE, TEXT_EDIT_FONT_HOLD, TextOutlinesError$1 as TextOutlinesError, applyCreateOutlines, applyOutlineStroke, applyStyleToRange, cachedLayoutRuns, cachedPaintRuns, caretIndexAt$1 as caretIndexAt, charOffsetToDomPosition, createMarkdownRenderer, createTextLayer, decorationMetrics, defaultLabelTextRenderer, domPositionToCharOffset, domToRuns, effectiveRangeStyle, fitTextPose, fontString, isBoldWeight, isSmallCapsLetter, isTextData$1 as isTextData, layoutMarkdown, layoutRuns, layoutTextPose, loadTextOutlines$1 as loadTextOutlines, markdownToRuns, measureText, measureTextBounds$1 as measureTextBounds, measuredWidth, nodeHasFlag, numericWeight, paintRuns, paragraphDirection, patchRangeStyle, pointInTextPose$1 as pointInTextPose, rangeWeight, registerBidi, renderLabel, resolveAlign$1 as resolveAlign, resolveRunFace, resolveRuns, resolveTextStyle, runsToDom, runsToMarkdown, runsToPlainText$1 as runsToPlainText, scriptMetrics, scriptMetricsFor, setFlagOverRange, smallCapsScale, smallCapsScaleFor, smallCapsText, strokeRegion, styleAtRange, textCommand, textCommandFromPose, textCommandFromRuns, textLineBoxes$1 as textLineBoxes, textPoseLayoutInput, textToPath$1 as textToPath, textToPathsByPaint$1 as textToPathsByPaint, toRuns, transformRunTexts, unboldPatch, useCreateOutlinesAdapter, useSceneTextEdit, useTextEdit, verticalAlignOffset };
|
|
10
|
+
export { DEFAULT_DECORATION_METRICS, DEFAULT_TEXT_FILL$1 as DEFAULT_TEXT_FILL, DEFAULT_TEXT_STYLE, MARKDOWN_RUN_GRAMMAR, QUAD_STRIDE, SCRIPT_METRICS, SMALL_CAPS_SCALE, TEXT_EDIT_FONT_HOLD, TextOutlinesError$1 as TextOutlinesError, applyCreateOutlines, applyOutlineStroke, applyStyleToRange, cachedLayoutRuns, cachedPaintRuns, caretIndexAt$1 as caretIndexAt, charOffsetToDomPosition, createMarkdownRenderer, createTextLayer, decorationMetrics, defaultLabelTextRenderer, domPositionToCharOffset, domToRuns, effectiveRangeStyle, fitTextPose, fontString, isBoldWeight, isSmallCapsLetter, isTextData$1 as isTextData, layoutMarkdown, layoutRuns, layoutTextPose, loadTextOutlines$1 as loadTextOutlines, markdownToRuns, measureText, measureTextBounds$1 as measureTextBounds, measuredWidth, nodeHasFlag, numericWeight, paintRuns, paragraphDirection, patchRangeStyle, pointInTextPose$1 as pointInTextPose, rangeWeight, registerBidi, renderLabel, resolveAlign$1 as resolveAlign, resolveRunFace, resolveRuns, resolveTextStyle, runsToDom, runsToMarkdown, runsToPlainText$1 as runsToPlainText, scriptMetrics, scriptMetricsFor, setFlagOverRange, smallCapsScale, smallCapsScaleFor, smallCapsText, strokeRegion, styleAtRange, textCommand, textCommandFromPose, textCommandFromRuns, textLineBoxes$1 as textLineBoxes, textPoseLayoutInput, textToPath$1 as textToPath, textToPathsByPaint$1 as textToPathsByPaint, toRuns, transformRunTexts, unboldPatch, useCreateOutlinesAdapter, useSceneTextEdit, useTextEdit, verticalAlignOffset };
|
package/dist/canvas/NodeShape.js
CHANGED
|
@@ -128,6 +128,7 @@ function findShapeBounds(node, pose, ctx) {
|
|
|
128
128
|
* "no opinion" — so callers should keep their own AABB test as a pre-filter.
|
|
129
129
|
*/
|
|
130
130
|
function shapeCoversPoint(node, pose, x, y, opts = {}) {
|
|
131
|
+
if (node.kind === "group") return true;
|
|
131
132
|
const sil = findShapeSilhouette(node, pose, { derivedPath: opts.derivedPath });
|
|
132
133
|
if (sil === null) return true;
|
|
133
134
|
const ink = findShapeInk(node, pose, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeShape.js","names":[],"sources":["../../src/canvas/NodeShape.ts"],"sourcesContent":["/**\n * NodeShape — the **shape trait's** registry: the per-kind `paint` + `silhouette` used by\n * `defaultDrawOne`, clipping, non-rect hit-testing, and lasso/area-select. Teaching the kit\n * about a new kind of shape goes through this registry rather than by overriding `drawOne`.\n *\n * The first entry whose `matches` predicate returns true paints the node: `'high'` entries\n * first, then the built-ins, then `'normal'` ones, in registration order within a tier. Every\n * built-in but `kit:derived` additionally requires a rect-shaped pose — a scene whose poses are\n * some other shape matches none of them, and paints through a consumer painter or not at all.\n */\nimport { glyphGeneration } from '@weasel-js/font';\nimport {\n pathContainsPoint,\n strokeHitTest,\n type Path\n} from '@weasel-js/geom';\nimport { pathThroughPoseFrame } from '@weasel-js/geom';\nimport { bumpNodeMemoGeneration, nodeMemo } from 'core/scene/nodeMemo';\nimport type { Node } from 'core/scene/types';\nimport type { Bounds } from 'core/viewport/fitViewToBounds';\nimport { hasSlop, slopForStrokeHit, widenSlop, type PickSlop } from 'core/viewport/screenSlop';\nimport { DERIVED_PAINTER } from './nodeShapes/derivedPainter';\nimport { IMAGE_PAINTER } from './nodeShapes/imagePainter';\nimport { MEASURE_PAINTER } from './nodeShapes/measurePainter';\nimport { derivesPath } from './nodeShapes/memo';\nimport { PATH_PAINTER } from './nodeShapes/pathPainter';\nimport { paintsPose } from './nodeShapes/poseBox';\nimport { RECT_FALLBACK_PAINTER } from './nodeShapes/rectFallbackPainter';\nimport { SHAPE_PAINTER } from './nodeShapes/shapePainter';\nimport { TEXT_PAINTER } from './nodeShapes/textPainter';\nimport type { NodeShapeEntry, NodeInk, NodeSilhouetteCtx, NodeInkCtx } from './nodeShapeTypes';\nexport type { NodePaintCtx, SceneViewDrawOne, NodeShapeEntry, NodeInk, NodeSilhouetteCtx, NodeInkCtx } from './nodeShapeTypes';\nexport type { InheritedPaint } from 'core/scene/inheritedPaint';\n\n/** What a painter that declares no `ink` is assumed to do. */\nexport const DEFAULT_INK: Readonly<NodeInk> = Object.freeze({ filled: true, outset: 0, inset: 0 });\n\n/** Options for `registerNodeShape`. */\nexport interface RegisterNodeShapeOptions {\n /** `'high'` puts the painter ahead of all normally-registered ones (so\n * it can win over a kit built-in). `'normal'` appends at the end. */\n priority?: 'high' | 'normal';\n}\n\nconst PAINTERS: { high: NodeShapeEntry[]; normal: NodeShapeEntry[] } = {\n high: [],\n normal: [],\n};\n\n// The built-ins go in on first use, not at module load: a bundler may drop an\n// import kept only for its side effect, and the registry would come up empty.\nlet builtInsRegistered = false;\nfunction ensureBuiltIns(): void {\n if (builtInsRegistered) return;\n builtInsRegistered = true;\n registerBuiltInShapePainters();\n}\n\n/** Register a shape painter. Returns a disposer that removes it. */\nexport function registerNodeShape<TData, TPose>(\n painter: NodeShapeEntry<TData, TPose>,\n opts: RegisterNodeShapeOptions = {},\n): () => void {\n ensureBuiltIns();\n const list = opts.priority === 'high' ? PAINTERS.high : PAINTERS.normal;\n list.push(painter as NodeShapeEntry);\n // The painter set is exactly the ambient state `findNodeShape` reads, and a\n // memo keyed on the node alone cannot see it change. See `nodeMemo`.\n bumpNodeMemoGeneration();\n return () => {\n const i = list.indexOf(painter as NodeShapeEntry);\n if (i >= 0) list.splice(i, 1);\n bumpNodeMemoGeneration();\n };\n}\n\n/**\n * Slot names for what picking asks per node per pointer move: which painter matches, and that\n * painter's silhouette path. Both go through {@link nodeMemo}, so they invalidate on `data`\n * (and, for the silhouette, `pose`) reference changes and on a painter registration.\n *\n * Separate slots rather than one entry: they mostly invalidate together, but not always, and a\n * shared entry would force the stricter key on both.\n */\nconst PAINTER_SLOT = 'shape:painter';\nconst PAINTER_SLOT_NONRECT = 'shape:painter:nonrect';\nconst PAINTER_SLOT_DERIVED = 'shape:painter:derived';\nconst PAINTER_SLOT_DERIVED_NONRECT = 'shape:painter:derived:nonrect';\nconst SILHOUETTE_SLOT = 'shape:silhouette';\nconst TEXT_SILHOUETTE_SLOT = 'shape:silhouette:text';\n\n/** The painter that will render `node` — first match in priority order — or undefined if\n * none accepts it. */\nexport function findNodeShape<TData, TPose>(\n node: Node<TData, string, TPose>,\n): NodeShapeEntry<TData, TPose> | undefined {\n // Built-in painters also gate on pose shape and on whether the node derives\n // its path, neither of which shows in `data`, so the key carries both.\n const rect = paintsPose(node.pose);\n const slot = derivesPath(node)\n ? (rect ? PAINTER_SLOT_DERIVED : PAINTER_SLOT_DERIVED_NONRECT)\n : (rect ? PAINTER_SLOT : PAINTER_SLOT_NONRECT);\n return nodeMemo(node as { data?: unknown }, slot, undefined, () =>\n matchNodeShape(node),\n );\n}\n\nfunction matchNodeShape<TData, TPose>(\n node: Node<TData, string, TPose>,\n): NodeShapeEntry<TData, TPose> | undefined {\n ensureBuiltIns();\n for (const p of PAINTERS.high) {\n if (p.matches(node as Node<unknown, string, unknown>)) {\n return p as NodeShapeEntry<TData, TPose>;\n }\n }\n for (const p of PAINTERS.normal) {\n if (p.matches(node as Node<unknown, string, unknown>)) {\n return p as NodeShapeEntry<TData, TPose>;\n }\n }\n return undefined;\n}\n\n/** The silhouette path of `node`, in **world** coords, or null if no painter matches or the\n * matching painter has none.\n *\n * Painters return their silhouette in the pose's local (unrotated) frame;\n * this bakes the pose's frame (`poseFrameOf`: its rotation and `transform`)\n * on top, so clips/area-select of a turned or skewed node use the boundary\n * the renderer draws. */\nexport function findShapeSilhouette<TData, TPose>(\n node: Node<TData, string, TPose>,\n pose: TPose,\n ctx?: NodeSilhouetteCtx,\n): Path | null {\n const build = (): Path | null => {\n const sil = findNodeShape(node)?.silhouette?.(node, pose, ctx) ?? null;\n return sil && pathThroughPoseFrame(sil, pose);\n };\n // `SILHOUETTE_SLOT`'s key is (node, pose, data) and cannot see\n // `ctx.derivedPath` — the same reason `kit:derived` skips `PAINT_SLOT`.\n // Memoizing here would serve one caller's silhouette to a caller that\n // passed a different path. Only an actual path skips it: a scene-backed\n // source answers `null` for every ordinary node, and treating that as a\n // reason to bypass would retire the memo for the whole scene.\n if (ctx?.derivedPath != null) return build();\n // Line boxes follow font metrics, and a face landing changes those with no\n // change to the node, so the text entry is checked against the glyph epoch.\n if (findNodeShape(node) === (TEXT_PAINTER as NodeShapeEntry<unknown, unknown>)) {\n const epoch = glyphGeneration();\n const held = nodeMemo(node as { data?: unknown }, TEXT_SILHOUETTE_SLOT, pose,\n (): { epoch: number; path: Path | null } => ({ epoch, path: build() }));\n if (held.epoch !== epoch) {\n held.epoch = epoch;\n held.path = build();\n }\n return held.path;\n }\n return nodeMemo(node as { data?: unknown }, SILHOUETTE_SLOT, pose, build);\n}\n\n/** Find the painter for `node` and ask how it inks its silhouette. Returns\n * the painter's declared {@link NodeInk}, or `null` when no painter matches\n * or it declares none — callers substitute {@link DEFAULT_INK}. */\nexport function findShapeInk<TData, TPose>(\n node: Node<TData, string, TPose>,\n pose: TPose,\n ctx?: NodeInkCtx,\n): NodeInk | null {\n return findNodeShape(node)?.ink?.(node, pose, ctx) ?? null;\n}\n\n/** Find the painter for `node` and ask for the box its paint fits in. `null`\n * when no painter matches, or the one that does cannot say — see\n * {@link NodeShapeEntry.bounds}. */\nexport function findShapeBounds<TData, TPose>(\n node: Node<TData, string, TPose>,\n pose: TPose,\n ctx?: NodeInkCtx,\n): Bounds | null {\n return findNodeShape(node)?.bounds?.(node, pose, ctx) ?? null;\n}\n\n/** Options for {@link shapeCoversPoint}. */\nexport interface ShapeCoversPointOptions {\n /** Extra grab distance around the outline: **world** units as a number,\n * or screen pixels under a view scale (`{ px, scale }`), which is measured\n * on screen and so stays exact under non-uniform zoom. Defaults to `0`,\n * where a hairline is too thin a target to hit. */\n tolerance?: PickSlop;\n /** View scale, passed to the painter's `ink`, and what a screen reach is\n * read at under a world `tolerance`. Defaults to 1. */\n scale?: number;\n /** The node's derived path — see {@link NodeSilhouetteCtx.derivedPath}.\n * Without it a derived node reports no silhouette and this answers `true`\n * everywhere, which degrades picking to the caller's AABB: for an edge,\n * a zero-sized pose. */\n derivedPath?: Path | null;\n /** See {@link NodeInkCtx.inherited}. Without it an `'inherit'` field is\n * read as none. */\n inherited?: NodeInkCtx['inherited'];\n}\n\n/**\n * Does the shape `node` actually paints cover the world point? Asks the painter's silhouette,\n * the same boundary used for clipping and area-select, rather than the pose rect.\n *\n * The ink counts too: a shape whose interior isn't filled is grabbable along its outline and\n * not through its empty middle. The outline's grab width is the stroke's half-width plus\n * `tolerance`.\n *\n * A painter with no `silhouette`, or one that returns `null` for this node, reports `true` —\n * \"no opinion\" — so callers should keep their own AABB test as a pre-filter.\n */\nexport function shapeCoversPoint<TData, TPose>(\n node: Node<TData, string, TPose>,\n pose: TPose,\n x: number,\n y: number,\n opts: ShapeCoversPointOptions = {},\n): boolean {\n const sil = findShapeSilhouette(node, pose, { derivedPath: opts.derivedPath });\n if (sil === null) return true;\n const ink = findShapeInk(node, pose, { scale: opts.scale, inherited: opts.inherited }) ?? DEFAULT_INK;\n const inside = pathContainsPoint(sil, x, y);\n if (ink.filled && inside) return true;\n // The stroke reaches a different distance on each side, so which side the point is on\n // picks the reach. `tolerance` also makes a filled shape grabbable a few pixels outside\n // its edge.\n const slop = widenSlop(opts.tolerance, (inside ? ink.insetPx : ink.outsetPx) ?? 0, opts.scale);\n const { extra, opts: hit } = slopForStrokeHit(slop);\n const reach = (inside ? ink.inset : ink.outset) + extra;\n return (reach > 0 || hasSlop(slop)) && strokeHitTest(sil, x, y, reach, hit);\n}\n\n/** The current painters in evaluation order — `'high'` tier first, then `'normal'`. */\nexport function getNodeShapes(): readonly NodeShapeEntry[] {\n ensureBuiltIns();\n return [...PAINTERS.high, ...PAINTERS.normal];\n}\n\n/** Test-only: clear the registry and re-register the built-ins. */\nexport function _resetShapePaintersForTests(): void {\n PAINTERS.high.length = 0;\n PAINTERS.normal.length = 0;\n builtInsRegistered = false;\n ensureBuiltIns();\n // `registerNodeShape` already bumps, but the clearing above happens without one.\n bumpNodeMemoGeneration();\n}\n\nfunction registerBuiltInShapePainters(): void {\n registerNodeShape(TEXT_PAINTER);\n registerNodeShape(MEASURE_PAINTER);\n // Ahead of path/shape/image: a derived node whose `data` also carries a\n // `path`, `shape` or `image` means the derived path, and those three match\n // on the presence of the field alone.\n registerNodeShape(DERIVED_PAINTER);\n registerNodeShape(PATH_PAINTER);\n registerNodeShape(SHAPE_PAINTER);\n registerNodeShape(IMAGE_PAINTER);\n registerNodeShape(RECT_FALLBACK_PAINTER);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"NodeShape.js","names":[],"sources":["../../src/canvas/NodeShape.ts"],"sourcesContent":["/**\n * NodeShape — the **shape trait's** registry: the per-kind `paint` + `silhouette` used by\n * `defaultDrawOne`, clipping, non-rect hit-testing, and lasso/area-select. Teaching the kit\n * about a new kind of shape goes through this registry rather than by overriding `drawOne`.\n *\n * The first entry whose `matches` predicate returns true paints the node: `'high'` entries\n * first, then the built-ins, then `'normal'` ones, in registration order within a tier. Every\n * built-in but `kit:derived` additionally requires a rect-shaped pose — a scene whose poses are\n * some other shape matches none of them, and paints through a consumer painter or not at all.\n */\nimport { glyphGeneration } from '@weasel-js/font';\nimport {\n pathContainsPoint,\n strokeHitTest,\n type Path\n} from '@weasel-js/geom';\nimport { pathThroughPoseFrame } from '@weasel-js/geom';\nimport { bumpNodeMemoGeneration, nodeMemo } from 'core/scene/nodeMemo';\nimport type { Node } from 'core/scene/types';\nimport type { Bounds } from 'core/viewport/fitViewToBounds';\nimport { hasSlop, slopForStrokeHit, widenSlop, type PickSlop } from 'core/viewport/screenSlop';\nimport { DERIVED_PAINTER } from './nodeShapes/derivedPainter';\nimport { IMAGE_PAINTER } from './nodeShapes/imagePainter';\nimport { MEASURE_PAINTER } from './nodeShapes/measurePainter';\nimport { derivesPath } from './nodeShapes/memo';\nimport { PATH_PAINTER } from './nodeShapes/pathPainter';\nimport { paintsPose } from './nodeShapes/poseBox';\nimport { RECT_FALLBACK_PAINTER } from './nodeShapes/rectFallbackPainter';\nimport { SHAPE_PAINTER } from './nodeShapes/shapePainter';\nimport { TEXT_PAINTER } from './nodeShapes/textPainter';\nimport type { NodeShapeEntry, NodeInk, NodeSilhouetteCtx, NodeInkCtx } from './nodeShapeTypes';\nexport type { NodePaintCtx, SceneViewDrawOne, NodeShapeEntry, NodeInk, NodeSilhouetteCtx, NodeInkCtx } from './nodeShapeTypes';\nexport type { InheritedPaint } from 'core/scene/inheritedPaint';\n\n/** What a painter that declares no `ink` is assumed to do. */\nexport const DEFAULT_INK: Readonly<NodeInk> = Object.freeze({ filled: true, outset: 0, inset: 0 });\n\n/** Options for `registerNodeShape`. */\nexport interface RegisterNodeShapeOptions {\n /** `'high'` puts the painter ahead of all normally-registered ones (so\n * it can win over a kit built-in). `'normal'` appends at the end. */\n priority?: 'high' | 'normal';\n}\n\nconst PAINTERS: { high: NodeShapeEntry[]; normal: NodeShapeEntry[] } = {\n high: [],\n normal: [],\n};\n\n// The built-ins go in on first use, not at module load: a bundler may drop an\n// import kept only for its side effect, and the registry would come up empty.\nlet builtInsRegistered = false;\nfunction ensureBuiltIns(): void {\n if (builtInsRegistered) return;\n builtInsRegistered = true;\n registerBuiltInShapePainters();\n}\n\n/** Register a shape painter. Returns a disposer that removes it. */\nexport function registerNodeShape<TData, TPose>(\n painter: NodeShapeEntry<TData, TPose>,\n opts: RegisterNodeShapeOptions = {},\n): () => void {\n ensureBuiltIns();\n const list = opts.priority === 'high' ? PAINTERS.high : PAINTERS.normal;\n list.push(painter as NodeShapeEntry);\n // The painter set is exactly the ambient state `findNodeShape` reads, and a\n // memo keyed on the node alone cannot see it change. See `nodeMemo`.\n bumpNodeMemoGeneration();\n return () => {\n const i = list.indexOf(painter as NodeShapeEntry);\n if (i >= 0) list.splice(i, 1);\n bumpNodeMemoGeneration();\n };\n}\n\n/**\n * Slot names for what picking asks per node per pointer move: which painter matches, and that\n * painter's silhouette path. Both go through {@link nodeMemo}, so they invalidate on `data`\n * (and, for the silhouette, `pose`) reference changes and on a painter registration.\n *\n * Separate slots rather than one entry: they mostly invalidate together, but not always, and a\n * shared entry would force the stricter key on both.\n */\nconst PAINTER_SLOT = 'shape:painter';\nconst PAINTER_SLOT_NONRECT = 'shape:painter:nonrect';\nconst PAINTER_SLOT_DERIVED = 'shape:painter:derived';\nconst PAINTER_SLOT_DERIVED_NONRECT = 'shape:painter:derived:nonrect';\nconst SILHOUETTE_SLOT = 'shape:silhouette';\nconst TEXT_SILHOUETTE_SLOT = 'shape:silhouette:text';\n\n/** The painter that will render `node` — first match in priority order — or undefined if\n * none accepts it. */\nexport function findNodeShape<TData, TPose>(\n node: Node<TData, string, TPose>,\n): NodeShapeEntry<TData, TPose> | undefined {\n // Built-in painters also gate on pose shape and on whether the node derives\n // its path, neither of which shows in `data`, so the key carries both.\n const rect = paintsPose(node.pose);\n const slot = derivesPath(node)\n ? (rect ? PAINTER_SLOT_DERIVED : PAINTER_SLOT_DERIVED_NONRECT)\n : (rect ? PAINTER_SLOT : PAINTER_SLOT_NONRECT);\n return nodeMemo(node as { data?: unknown }, slot, undefined, () =>\n matchNodeShape(node),\n );\n}\n\nfunction matchNodeShape<TData, TPose>(\n node: Node<TData, string, TPose>,\n): NodeShapeEntry<TData, TPose> | undefined {\n ensureBuiltIns();\n for (const p of PAINTERS.high) {\n if (p.matches(node as Node<unknown, string, unknown>)) {\n return p as NodeShapeEntry<TData, TPose>;\n }\n }\n for (const p of PAINTERS.normal) {\n if (p.matches(node as Node<unknown, string, unknown>)) {\n return p as NodeShapeEntry<TData, TPose>;\n }\n }\n return undefined;\n}\n\n/** The silhouette path of `node`, in **world** coords, or null if no painter matches or the\n * matching painter has none.\n *\n * Painters return their silhouette in the pose's local (unrotated) frame;\n * this bakes the pose's frame (`poseFrameOf`: its rotation and `transform`)\n * on top, so clips/area-select of a turned or skewed node use the boundary\n * the renderer draws. */\nexport function findShapeSilhouette<TData, TPose>(\n node: Node<TData, string, TPose>,\n pose: TPose,\n ctx?: NodeSilhouetteCtx,\n): Path | null {\n const build = (): Path | null => {\n const sil = findNodeShape(node)?.silhouette?.(node, pose, ctx) ?? null;\n return sil && pathThroughPoseFrame(sil, pose);\n };\n // `SILHOUETTE_SLOT`'s key is (node, pose, data) and cannot see\n // `ctx.derivedPath` — the same reason `kit:derived` skips `PAINT_SLOT`.\n // Memoizing here would serve one caller's silhouette to a caller that\n // passed a different path. Only an actual path skips it: a scene-backed\n // source answers `null` for every ordinary node, and treating that as a\n // reason to bypass would retire the memo for the whole scene.\n if (ctx?.derivedPath != null) return build();\n // Line boxes follow font metrics, and a face landing changes those with no\n // change to the node, so the text entry is checked against the glyph epoch.\n if (findNodeShape(node) === (TEXT_PAINTER as NodeShapeEntry<unknown, unknown>)) {\n const epoch = glyphGeneration();\n const held = nodeMemo(node as { data?: unknown }, TEXT_SILHOUETTE_SLOT, pose,\n (): { epoch: number; path: Path | null } => ({ epoch, path: build() }));\n if (held.epoch !== epoch) {\n held.epoch = epoch;\n held.path = build();\n }\n return held.path;\n }\n return nodeMemo(node as { data?: unknown }, SILHOUETTE_SLOT, pose, build);\n}\n\n/** Find the painter for `node` and ask how it inks its silhouette. Returns\n * the painter's declared {@link NodeInk}, or `null` when no painter matches\n * or it declares none — callers substitute {@link DEFAULT_INK}. */\nexport function findShapeInk<TData, TPose>(\n node: Node<TData, string, TPose>,\n pose: TPose,\n ctx?: NodeInkCtx,\n): NodeInk | null {\n return findNodeShape(node)?.ink?.(node, pose, ctx) ?? null;\n}\n\n/** Find the painter for `node` and ask for the box its paint fits in. `null`\n * when no painter matches, or the one that does cannot say — see\n * {@link NodeShapeEntry.bounds}. */\nexport function findShapeBounds<TData, TPose>(\n node: Node<TData, string, TPose>,\n pose: TPose,\n ctx?: NodeInkCtx,\n): Bounds | null {\n return findNodeShape(node)?.bounds?.(node, pose, ctx) ?? null;\n}\n\n/** Options for {@link shapeCoversPoint}. */\nexport interface ShapeCoversPointOptions {\n /** Extra grab distance around the outline: **world** units as a number,\n * or screen pixels under a view scale (`{ px, scale }`), which is measured\n * on screen and so stays exact under non-uniform zoom. Defaults to `0`,\n * where a hairline is too thin a target to hit. */\n tolerance?: PickSlop;\n /** View scale, passed to the painter's `ink`, and what a screen reach is\n * read at under a world `tolerance`. Defaults to 1. */\n scale?: number;\n /** The node's derived path — see {@link NodeSilhouetteCtx.derivedPath}.\n * Without it a derived node reports no silhouette and this answers `true`\n * everywhere, which degrades picking to the caller's AABB: for an edge,\n * a zero-sized pose. */\n derivedPath?: Path | null;\n /** See {@link NodeInkCtx.inherited}. Without it an `'inherit'` field is\n * read as none. */\n inherited?: NodeInkCtx['inherited'];\n}\n\n/**\n * Does the shape `node` actually paints cover the world point? Asks the painter's silhouette,\n * the same boundary used for clipping and area-select, rather than the pose rect.\n *\n * The ink counts too: a shape whose interior isn't filled is grabbable along its outline and\n * not through its empty middle. The outline's grab width is the stroke's half-width plus\n * `tolerance`.\n *\n * A painter with no `silhouette`, or one that returns `null` for this node, reports `true` —\n * \"no opinion\" — so callers should keep their own AABB test as a pre-filter.\n */\nexport function shapeCoversPoint<TData, TPose>(\n node: Node<TData, string, TPose>,\n pose: TPose,\n x: number,\n y: number,\n opts: ShapeCoversPointOptions = {},\n): boolean {\n // A group paints nothing, so its interior is its box, which the caller's pre-filter tested.\n if (node.kind === 'group') return true;\n const sil = findShapeSilhouette(node, pose, { derivedPath: opts.derivedPath });\n if (sil === null) return true;\n const ink = findShapeInk(node, pose, { scale: opts.scale, inherited: opts.inherited }) ?? DEFAULT_INK;\n const inside = pathContainsPoint(sil, x, y);\n if (ink.filled && inside) return true;\n // The stroke reaches a different distance on each side, so which side the point is on\n // picks the reach. `tolerance` also makes a filled shape grabbable a few pixels outside\n // its edge.\n const slop = widenSlop(opts.tolerance, (inside ? ink.insetPx : ink.outsetPx) ?? 0, opts.scale);\n const { extra, opts: hit } = slopForStrokeHit(slop);\n const reach = (inside ? ink.inset : ink.outset) + extra;\n return (reach > 0 || hasSlop(slop)) && strokeHitTest(sil, x, y, reach, hit);\n}\n\n/** The current painters in evaluation order — `'high'` tier first, then `'normal'`. */\nexport function getNodeShapes(): readonly NodeShapeEntry[] {\n ensureBuiltIns();\n return [...PAINTERS.high, ...PAINTERS.normal];\n}\n\n/** Test-only: clear the registry and re-register the built-ins. */\nexport function _resetShapePaintersForTests(): void {\n PAINTERS.high.length = 0;\n PAINTERS.normal.length = 0;\n builtInsRegistered = false;\n ensureBuiltIns();\n // `registerNodeShape` already bumps, but the clearing above happens without one.\n bumpNodeMemoGeneration();\n}\n\nfunction registerBuiltInShapePainters(): void {\n registerNodeShape(TEXT_PAINTER);\n registerNodeShape(MEASURE_PAINTER);\n // Ahead of path/shape/image: a derived node whose `data` also carries a\n // `path`, `shape` or `image` means the derived path, and those three match\n // on the presence of the field alone.\n registerNodeShape(DERIVED_PAINTER);\n registerNodeShape(PATH_PAINTER);\n registerNodeShape(SHAPE_PAINTER);\n registerNodeShape(IMAGE_PAINTER);\n registerNodeShape(RECT_FALLBACK_PAINTER);\n}\n"],"mappings":"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"}
|
|
@@ -36,6 +36,7 @@ function SceneCanvasInput(p) {
|
|
|
36
36
|
props,
|
|
37
37
|
viewOn: p.viewOn,
|
|
38
38
|
selection,
|
|
39
|
+
enteredGroup: picking.enteredGroup,
|
|
39
40
|
scene,
|
|
40
41
|
adapter: picking.adapter,
|
|
41
42
|
standardActions: p.tools.standardActions,
|
|
@@ -46,6 +47,7 @@ function SceneCanvasInput(p) {
|
|
|
46
47
|
pickEvery: picking.pickEvery,
|
|
47
48
|
layerIsPainted: picking.viewLayerGate,
|
|
48
49
|
alphaOf: picking.alphaOf,
|
|
50
|
+
reachable: picking.reachable,
|
|
49
51
|
viewAnimation: p.camera.viewAnimation,
|
|
50
52
|
editAnchorsExternalState: p.pathEdit.state,
|
|
51
53
|
canvasRef: canvas.elementRef,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SceneCanvasInput.js","names":["_Fragment"],"sources":["../../../src/canvas/SceneCanvas/SceneCanvasInput.tsx"],"sourcesContent":["import type { ResizeHandleLayout } from 'interactions/actions/resize/cornerHandles';\nimport { useLatest } from '@weasel-js/react';\nimport type { Dispatcher } from '@weasel-js/routing';\nimport type { Scene } from 'core/scene/types';\nimport type { SelectionApi } from 'core/selection/useSelection';\nimport type { RuleCtx } from 'features/chrome-caps';\nimport type { Affordance } from 'affordances/types';\nimport type { PoseDescriptor } from 'interactions/actions/resize/geometry';\nimport type { UseResizeOptions } from 'interactions/actions/resize/options';\nimport { useContext, useEffect, type MutableRefObject, type RefObject } from 'react';\nimport { SnapSourceRegistryContext } from 'features/snap/registry';\nimport type { SnapOutcomeStore } from 'features/snap/outcomeStore';\nimport type { SnapSource } from 'features/snap/types';\nimport { dlog } from '../../debug/flag';\nimport { useDeviceProfile } from '../../core/device/useDeviceProfile';\nimport { useTestHook } from '../../test-hook/useTestHook';\nimport type { CanvasExtensionApi } from '../canvasExtension';\nimport { useHitObserver } from '../useHitObserver';\nimport type { CanvasViewState } from '../useCanvasView';\nimport { GeometryProjectionRegistrar, ResizePolicyRegistrar } from './poseRegistrars';\nimport { usePointerPublisher } from './PointerProviderIfRoot';\nimport type { BridgeAdapter, SceneCanvasProps } from './props';\nimport type { NodeAtPoint } from './useNodeAtPoint';\nimport type { useSceneCanvasTools } from './useSceneCanvasTools';\nimport { useSceneGestureDispatcher } from './useSceneGestureDispatcher';\nimport { useCanvasDevtoolsRoot, type CanvasDevtools } from './useCanvasDevtoolsRoot';\nimport type { useScenePicking } from './useScenePicking';\nimport {\n useSceneStandardActions, type SceneStandardActionsInputs, type StandardActionsProps,\n} from './useSceneStandardActions';\nimport { useToolKeybindings } from './useToolKeybindings';\n\ntype Props = SceneCanvasProps<unknown, string, unknown>;\ntype Picking = ReturnType<typeof useScenePicking<unknown, string, unknown>>;\n\n/** The `<SceneCanvas>` props its input wiring reads. */\nexport type SceneCanvasInputOptions = StandardActionsProps & Pick<\n Props,\n | 'selectTool' | 'geometryProjection' | 'enableGestureDispatcher' | 'enableKeybindings'\n | 'claimKeys' | 'longPress' | 'modes' | 'versionCheck' | 'onClick' | 'onDoubleClick' | 'routing'\n>;\n\n/** What `<SceneCanvas>` hands {@link SceneCanvasInput}. */\nexport interface SceneCanvasInputProps {\n props: SceneCanvasInputOptions;\n scene: Scene<unknown, string, unknown>;\n selection: SelectionApi;\n descriptor: PoseDescriptor<unknown>;\n picking: Pick<\n Picking, 'pickEvery' | 'pickBest' | 'boundsOf' | 'planeOfNode' | 'kindOfNode' | 'doubleClickNames' | 'viewLayerGate' | 'alphaOf'\n > & { adapter: BridgeAdapter };\n /** The node a hit resolves to, for the `onClick` / `onDoubleClick` observers. */\n nodeAtPointRef: MutableRefObject<NodeAtPoint | undefined>;\n tools: ReturnType<typeof useSceneCanvasTools>;\n viewOn: boolean;\n camera: { viewState: CanvasViewState; viewAnimation: SceneStandardActionsInputs['viewAnimation'] };\n dispatcher: Dispatcher;\n pathEdit: {\n state: SceneStandardActionsInputs['editAnchorsExternalState'];\n };\n chrome: { getIsVisible: () => (id: string) => boolean; getRuleCtx: () => RuleCtx | undefined };\n /** The selection overlay's rotate badge, and where the dispatcher reports the affordances\n * it hit-tests, for the slops overlay. */\n overlay: {\n rotationBadge: { distancePx: number; sizePx: number } | null | undefined;\n /** The resize-handle layout the overlay paints, so the hit-test grabs exactly those. */\n resizeHandles: ResizeHandleLayout;\n chromeAffordancesRef: MutableRefObject<readonly Affordance[]>;\n };\n canvas: {\n elementRef: MutableRefObject<HTMLElement | null>;\n apiRef: RefObject<CanvasExtensionApi | null>;\n ready: boolean;\n };\n ingestionClipboard: SceneStandardActionsInputs['ingestionClipboard'];\n /** The enabled presets' snap sources. */\n snapSources: readonly SnapSource[];\n /** The outcome store the canvas's readout layer draws. */\n snapStore: SnapOutcomeStore;\n devtools: CanvasDevtools;\n}\n\n/**\n * The canvas's input wiring: the pointer publisher, the standard actions and their deps, the\n * gesture dispatcher, and the tool keybindings, in that order, then the test hook.\n *\n * A component of its own, mounted ahead of `<SceneCanvas>`'s children, rather than hooks in the\n * canvas's body: dep sources and actions stack newest-live in effect order, and a parent's\n * effects run after its children's, so a child overriding a kit dep would lose to it.\n */\nexport function SceneCanvasInput(p: SceneCanvasInputProps) {\n const { props, scene, selection, picking, chrome, overlay, canvas } = p;\n const { viewState } = p.camera;\n const { selectTool, enableKeybindings = true } = props;\n const snapRegistry = useContext(SnapSourceRegistryContext);\n useEffect(() => {\n dlog('scene-canvas', 'mount');\n return () => dlog('scene-canvas', 'unmount');\n }, []);\n usePointerPublisher(canvas.elementRef, canvas.apiRef);\n useSceneStandardActions({\n props, viewOn: p.viewOn,\n selection, scene, adapter: picking.adapter, standardActions: p.tools.standardActions,\n currentViewRef: viewState.viewRef, onViewChange: viewState.setViewFromInput,\n poseDescriptor: p.descriptor, dispatcher: p.dispatcher,\n pickEvery: picking.pickEvery, layerIsPainted: picking.viewLayerGate, alphaOf: picking.alphaOf,\n viewAnimation: p.camera.viewAnimation, editAnchorsExternalState: p.pathEdit.state,\n canvasRef: canvas.elementRef, canvasApiRef: canvas.apiRef, ingestionClipboard: p.ingestionClipboard,\n snap: { sources: [...(props.snap?.sources ?? []), ...p.snapSources], registry: snapRegistry, store: p.snapStore },\n });\n\n // Rides the gesture dispatcher as an OBSERVER rather than an Action binding because the\n // prop is a notification, not a behavior: as a binding it would lose first-match-wins to\n // `enterPathEdit` on every body hit and silently stop firing.\n const onDoubleClick = useHitObserver(props.onDoubleClick, p.nodeAtPointRef);\n const onClick = useHitObserver(props.onClick, p.nodeAtPointRef);\n const selectionRef = useLatest(selection);\n const { targetScale } = useDeviceProfile();\n const { root, traces } = useCanvasDevtoolsRoot({\n scene, selection, viewState, tools: p.tools.tools, contributions: p.tools.contributions, routing: props.routing,\n element: canvas.elementRef, api: canvas.apiRef, devtools: p.devtools,\n });\n useSceneGestureDispatcher({\n canvasRef: canvas.elementRef, canvasApiRef: canvas.apiRef,\n tools: p.tools.tools, contributions: p.tools.contributions,\n enabled: props.enableGestureDispatcher ?? true, keyboard: enableKeybindings,\n claimKeys: props.claimKeys ?? false,\n selectionRef,\n boundsOf: picking.boundsOf, planeOfNode: picking.planeOfNode,\n pickEvery: picking.pickEvery, pickBest: picking.pickBest, kindOfNode: picking.kindOfNode,\n doubleClickNames: picking.doubleClickNames,\n viewRef: viewState.viewRef, dispatcher: p.dispatcher, traces,\n getIsVisibleForCanvas: chrome.getIsVisible, getRuleCtx: chrome.getRuleCtx,\n targetScale, handleHitRadius: overlay.resizeHandles.hitRadiusPx,\n edgeHandles: overlay.resizeHandles.edges,\n rotationBadge: overlay.rotationBadge, chromeAffordancesRef: overlay.chromeAffordancesRef,\n onDoubleClick, onClick, longPress: props.longPress,\n });\n useToolKeybindings({\n internalTools: p.tools.internal,\n toolsTakeover: p.tools.takeover ?? undefined,\n enableKeybindings,\n modes: props.modes,\n canvasApi: canvas.ready ? canvas.apiRef.current : null,\n versionCheck: props.versionCheck,\n });\n useTestHook({\n getScene: () => scene as never,\n getSelectionIds: () => (selection.current as readonly string[] | undefined) ?? [],\n getView: () => viewState.viewRef.current,\n getActiveToolId: () => p.tools.tools.active ?? null,\n probes: root.probes,\n });\n\n // Mounted only when passed: an empty default registered with the deps above would land\n // after, and over, a dep one of these registered (child effects run first). Absent\n // `geometryProjection` leaves the dep undefined.\n return (\n <>\n {selectTool?.resize\n ? <ResizePolicyRegistrar options={selectTool.resize as UseResizeOptions<unknown>} />\n : null}\n {props.geometryProjection ? <GeometryProjectionRegistrar projection={props.geometryProjection} /> : null}\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA0FA,SAAgB,iBAAiB,GAA0B;CACzD,MAAM,EAAE,OAAO,OAAO,WAAW,SAAS,QAAQ,SAAS,WAAW;CACtE,MAAM,EAAE,cAAc,EAAE;CACxB,MAAM,EAAE,YAAY,oBAAoB,SAAS;CACjD,MAAM,eAAe,WAAW,yBAAyB;CACzD,gBAAgB;EACd,KAAK,gBAAgB,OAAO;EAC5B,aAAa,KAAK,gBAAgB,SAAS;CAC7C,GAAG,CAAC,CAAC;CACL,oBAAoB,OAAO,YAAY,OAAO,MAAM;CACpD,wBAAwB;EACtB;EAAO,QAAQ,EAAE;EACjB;EAAW;EAAO,SAAS,QAAQ;EAAS,iBAAiB,EAAE,MAAM;EACrE,gBAAgB,UAAU;EAAS,cAAc,UAAU;EAC3D,gBAAgB,EAAE;EAAY,YAAY,EAAE;EAC5C,WAAW,QAAQ;EAAW,gBAAgB,QAAQ;EAAe,SAAS,QAAQ;EACtF,eAAe,EAAE,OAAO;EAAe,0BAA0B,EAAE,SAAS;EAC5E,WAAW,OAAO;EAAY,cAAc,OAAO;EAAQ,oBAAoB,EAAE;EACjF,MAAM;GAAE,SAAS,CAAC,GAAI,MAAM,MAAM,WAAW,CAAC,GAAI,GAAG,EAAE,WAAW;GAAG,UAAU;GAAc,OAAO,EAAE;EAAU;CAClH,CAAC;CAKD,MAAM,gBAAgB,eAAe,MAAM,eAAe,EAAE,cAAc;CAC1E,MAAM,UAAU,eAAe,MAAM,SAAS,EAAE,cAAc;CAC9D,MAAM,eAAe,UAAU,SAAS;CACxC,MAAM,EAAE,gBAAgB,iBAAiB;CACzC,MAAM,EAAE,MAAM,WAAW,sBAAsB;EAC7C;EAAO;EAAW;EAAW,OAAO,EAAE,MAAM;EAAO,eAAe,EAAE,MAAM;EAAe,SAAS,MAAM;EACxG,SAAS,OAAO;EAAY,KAAK,OAAO;EAAQ,UAAU,EAAE;CAC9D,CAAC;CACD,0BAA0B;EACxB,WAAW,OAAO;EAAY,cAAc,OAAO;EACnD,OAAO,EAAE,MAAM;EAAO,eAAe,EAAE,MAAM;EAC7C,SAAS,MAAM,2BAA2B;EAAM,UAAU;EAC1D,WAAW,MAAM,aAAa;EAC9B;EACA,UAAU,QAAQ;EAAU,aAAa,QAAQ;EACjD,WAAW,QAAQ;EAAW,UAAU,QAAQ;EAAU,YAAY,QAAQ;EAC9E,kBAAkB,QAAQ;EAC1B,SAAS,UAAU;EAAS,YAAY,EAAE;EAAY;EACtD,uBAAuB,OAAO;EAAc,YAAY,OAAO;EAC/D;EAAa,iBAAiB,QAAQ,cAAc;EACpD,aAAa,QAAQ,cAAc;EACnC,eAAe,QAAQ;EAAe,sBAAsB,QAAQ;EACpE;EAAe;EAAS,WAAW,MAAM;CAC3C,CAAC;CACD,mBAAmB;EACjB,eAAe,EAAE,MAAM;EACvB,eAAe,EAAE,MAAM,YAAY;EACnC;EACA,OAAO,MAAM;EACb,WAAW,OAAO,QAAQ,OAAO,OAAO,UAAU;EAClD,cAAc,MAAM;CACtB,CAAC;CACD,YAAY;EACV,gBAAgB;EAChB,uBAAwB,UAAU,WAA6C,CAAC;EAChF,eAAe,UAAU,QAAQ;EACjC,uBAAuB,EAAE,MAAM,MAAM,UAAU;EAC/C,QAAQ,KAAK;CACf,CAAC;CAKD,OACE,qBAAAA,UAAA,EAAA,UAAA,CACG,YAAY,SACT,oBAAC,uBAAD,EAAuB,SAAS,WAAW,OAAsC,CAAA,IACjF,MACH,MAAM,qBAAqB,oBAAC,6BAAD,EAA6B,YAAY,MAAM,mBAAqB,CAAA,IAAI,IACpG,EAAA,CAAA;AAEN"}
|
|
1
|
+
{"version":3,"file":"SceneCanvasInput.js","names":["_Fragment"],"sources":["../../../src/canvas/SceneCanvas/SceneCanvasInput.tsx"],"sourcesContent":["import type { ResizeHandleLayout } from 'interactions/actions/resize/cornerHandles';\nimport { useLatest } from '@weasel-js/react';\nimport type { Dispatcher } from '@weasel-js/routing';\nimport type { Scene } from 'core/scene/types';\nimport type { SelectionApi } from 'core/selection/useSelection';\nimport type { RuleCtx } from 'features/chrome-caps';\nimport type { Affordance } from 'affordances/types';\nimport type { PoseDescriptor } from 'interactions/actions/resize/geometry';\nimport type { UseResizeOptions } from 'interactions/actions/resize/options';\nimport { useContext, useEffect, type MutableRefObject, type RefObject } from 'react';\nimport { SnapSourceRegistryContext } from 'features/snap/registry';\nimport type { SnapOutcomeStore } from 'features/snap/outcomeStore';\nimport type { SnapSource } from 'features/snap/types';\nimport { dlog } from '../../debug/flag';\nimport { useDeviceProfile } from '../../core/device/useDeviceProfile';\nimport { useTestHook } from '../../test-hook/useTestHook';\nimport type { CanvasExtensionApi } from '../canvasExtension';\nimport { useHitObserver } from '../useHitObserver';\nimport type { CanvasViewState } from '../useCanvasView';\nimport { GeometryProjectionRegistrar, ResizePolicyRegistrar } from './poseRegistrars';\nimport { usePointerPublisher } from './PointerProviderIfRoot';\nimport type { BridgeAdapter, SceneCanvasProps } from './props';\nimport type { NodeAtPoint } from './useNodeAtPoint';\nimport type { useSceneCanvasTools } from './useSceneCanvasTools';\nimport { useSceneGestureDispatcher } from './useSceneGestureDispatcher';\nimport { useCanvasDevtoolsRoot, type CanvasDevtools } from './useCanvasDevtoolsRoot';\nimport type { useScenePicking } from './useScenePicking';\nimport {\n useSceneStandardActions, type SceneStandardActionsInputs, type StandardActionsProps,\n} from './useSceneStandardActions';\nimport { useToolKeybindings } from './useToolKeybindings';\n\ntype Props = SceneCanvasProps<unknown, string, unknown>;\ntype Picking = ReturnType<typeof useScenePicking<unknown, string, unknown>>;\n\n/** The `<SceneCanvas>` props its input wiring reads. */\nexport type SceneCanvasInputOptions = StandardActionsProps & Pick<\n Props,\n | 'selectTool' | 'geometryProjection' | 'enableGestureDispatcher' | 'enableKeybindings'\n | 'claimKeys' | 'longPress' | 'modes' | 'versionCheck' | 'onClick' | 'onDoubleClick' | 'routing'\n>;\n\n/** What `<SceneCanvas>` hands {@link SceneCanvasInput}. */\nexport interface SceneCanvasInputProps {\n props: SceneCanvasInputOptions;\n scene: Scene<unknown, string, unknown>;\n selection: SelectionApi;\n descriptor: PoseDescriptor<unknown>;\n picking: Pick<\n Picking, 'pickEvery' | 'pickBest' | 'boundsOf' | 'planeOfNode' | 'kindOfNode' | 'doubleClickNames' | 'viewLayerGate' | 'alphaOf' | 'enteredGroup' | 'reachable'\n > & { adapter: BridgeAdapter };\n /** The node a hit resolves to, for the `onClick` / `onDoubleClick` observers. */\n nodeAtPointRef: MutableRefObject<NodeAtPoint | undefined>;\n tools: ReturnType<typeof useSceneCanvasTools>;\n viewOn: boolean;\n camera: { viewState: CanvasViewState; viewAnimation: SceneStandardActionsInputs['viewAnimation'] };\n dispatcher: Dispatcher;\n pathEdit: {\n state: SceneStandardActionsInputs['editAnchorsExternalState'];\n };\n chrome: { getIsVisible: () => (id: string) => boolean; getRuleCtx: () => RuleCtx | undefined };\n /** The selection overlay's rotate badge, and where the dispatcher reports the affordances\n * it hit-tests, for the slops overlay. */\n overlay: {\n rotationBadge: { distancePx: number; sizePx: number } | null | undefined;\n /** The resize-handle layout the overlay paints, so the hit-test grabs exactly those. */\n resizeHandles: ResizeHandleLayout;\n chromeAffordancesRef: MutableRefObject<readonly Affordance[]>;\n };\n canvas: {\n elementRef: MutableRefObject<HTMLElement | null>;\n apiRef: RefObject<CanvasExtensionApi | null>;\n ready: boolean;\n };\n ingestionClipboard: SceneStandardActionsInputs['ingestionClipboard'];\n /** The enabled presets' snap sources. */\n snapSources: readonly SnapSource[];\n /** The outcome store the canvas's readout layer draws. */\n snapStore: SnapOutcomeStore;\n devtools: CanvasDevtools;\n}\n\n/**\n * The canvas's input wiring: the pointer publisher, the standard actions and their deps, the\n * gesture dispatcher, and the tool keybindings, in that order, then the test hook.\n *\n * A component of its own, mounted ahead of `<SceneCanvas>`'s children, rather than hooks in the\n * canvas's body: dep sources and actions stack newest-live in effect order, and a parent's\n * effects run after its children's, so a child overriding a kit dep would lose to it.\n */\nexport function SceneCanvasInput(p: SceneCanvasInputProps) {\n const { props, scene, selection, picking, chrome, overlay, canvas } = p;\n const { viewState } = p.camera;\n const { selectTool, enableKeybindings = true } = props;\n const snapRegistry = useContext(SnapSourceRegistryContext);\n useEffect(() => {\n dlog('scene-canvas', 'mount');\n return () => dlog('scene-canvas', 'unmount');\n }, []);\n usePointerPublisher(canvas.elementRef, canvas.apiRef);\n useSceneStandardActions({\n props, viewOn: p.viewOn,\n selection, enteredGroup: picking.enteredGroup, scene, adapter: picking.adapter, standardActions: p.tools.standardActions,\n currentViewRef: viewState.viewRef, onViewChange: viewState.setViewFromInput,\n poseDescriptor: p.descriptor, dispatcher: p.dispatcher,\n pickEvery: picking.pickEvery, layerIsPainted: picking.viewLayerGate, alphaOf: picking.alphaOf, reachable: picking.reachable,\n viewAnimation: p.camera.viewAnimation, editAnchorsExternalState: p.pathEdit.state,\n canvasRef: canvas.elementRef, canvasApiRef: canvas.apiRef, ingestionClipboard: p.ingestionClipboard,\n snap: { sources: [...(props.snap?.sources ?? []), ...p.snapSources], registry: snapRegistry, store: p.snapStore },\n });\n\n // Rides the gesture dispatcher as an OBSERVER rather than an Action binding because the\n // prop is a notification, not a behavior: as a binding it would lose first-match-wins to\n // `enterPathEdit` on every body hit and silently stop firing.\n const onDoubleClick = useHitObserver(props.onDoubleClick, p.nodeAtPointRef);\n const onClick = useHitObserver(props.onClick, p.nodeAtPointRef);\n const selectionRef = useLatest(selection);\n const { targetScale } = useDeviceProfile();\n const { root, traces } = useCanvasDevtoolsRoot({\n scene, selection, viewState, tools: p.tools.tools, contributions: p.tools.contributions, routing: props.routing,\n element: canvas.elementRef, api: canvas.apiRef, devtools: p.devtools,\n });\n useSceneGestureDispatcher({\n canvasRef: canvas.elementRef, canvasApiRef: canvas.apiRef,\n tools: p.tools.tools, contributions: p.tools.contributions,\n enabled: props.enableGestureDispatcher ?? true, keyboard: enableKeybindings,\n claimKeys: props.claimKeys ?? false,\n selectionRef,\n boundsOf: picking.boundsOf, planeOfNode: picking.planeOfNode,\n pickEvery: picking.pickEvery, pickBest: picking.pickBest, kindOfNode: picking.kindOfNode,\n doubleClickNames: picking.doubleClickNames,\n viewRef: viewState.viewRef, dispatcher: p.dispatcher, traces,\n getIsVisibleForCanvas: chrome.getIsVisible, getRuleCtx: chrome.getRuleCtx,\n targetScale, handleHitRadius: overlay.resizeHandles.hitRadiusPx,\n edgeHandles: overlay.resizeHandles.edges,\n rotationBadge: overlay.rotationBadge, chromeAffordancesRef: overlay.chromeAffordancesRef,\n onDoubleClick, onClick, longPress: props.longPress,\n });\n useToolKeybindings({\n internalTools: p.tools.internal,\n toolsTakeover: p.tools.takeover ?? undefined,\n enableKeybindings,\n modes: props.modes,\n canvasApi: canvas.ready ? canvas.apiRef.current : null,\n versionCheck: props.versionCheck,\n });\n useTestHook({\n getScene: () => scene as never,\n getSelectionIds: () => (selection.current as readonly string[] | undefined) ?? [],\n getView: () => viewState.viewRef.current,\n getActiveToolId: () => p.tools.tools.active ?? null,\n probes: root.probes,\n });\n\n // Mounted only when passed: an empty default registered with the deps above would land\n // after, and over, a dep one of these registered (child effects run first). Absent\n // `geometryProjection` leaves the dep undefined.\n return (\n <>\n {selectTool?.resize\n ? <ResizePolicyRegistrar options={selectTool.resize as UseResizeOptions<unknown>} />\n : null}\n {props.geometryProjection ? <GeometryProjectionRegistrar projection={props.geometryProjection} /> : null}\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA0FA,SAAgB,iBAAiB,GAA0B;CACzD,MAAM,EAAE,OAAO,OAAO,WAAW,SAAS,QAAQ,SAAS,WAAW;CACtE,MAAM,EAAE,cAAc,EAAE;CACxB,MAAM,EAAE,YAAY,oBAAoB,SAAS;CACjD,MAAM,eAAe,WAAW,yBAAyB;CACzD,gBAAgB;EACd,KAAK,gBAAgB,OAAO;EAC5B,aAAa,KAAK,gBAAgB,SAAS;CAC7C,GAAG,CAAC,CAAC;CACL,oBAAoB,OAAO,YAAY,OAAO,MAAM;CACpD,wBAAwB;EACtB;EAAO,QAAQ,EAAE;EACjB;EAAW,cAAc,QAAQ;EAAc;EAAO,SAAS,QAAQ;EAAS,iBAAiB,EAAE,MAAM;EACzG,gBAAgB,UAAU;EAAS,cAAc,UAAU;EAC3D,gBAAgB,EAAE;EAAY,YAAY,EAAE;EAC5C,WAAW,QAAQ;EAAW,gBAAgB,QAAQ;EAAe,SAAS,QAAQ;EAAS,WAAW,QAAQ;EAClH,eAAe,EAAE,OAAO;EAAe,0BAA0B,EAAE,SAAS;EAC5E,WAAW,OAAO;EAAY,cAAc,OAAO;EAAQ,oBAAoB,EAAE;EACjF,MAAM;GAAE,SAAS,CAAC,GAAI,MAAM,MAAM,WAAW,CAAC,GAAI,GAAG,EAAE,WAAW;GAAG,UAAU;GAAc,OAAO,EAAE;EAAU;CAClH,CAAC;CAKD,MAAM,gBAAgB,eAAe,MAAM,eAAe,EAAE,cAAc;CAC1E,MAAM,UAAU,eAAe,MAAM,SAAS,EAAE,cAAc;CAC9D,MAAM,eAAe,UAAU,SAAS;CACxC,MAAM,EAAE,gBAAgB,iBAAiB;CACzC,MAAM,EAAE,MAAM,WAAW,sBAAsB;EAC7C;EAAO;EAAW;EAAW,OAAO,EAAE,MAAM;EAAO,eAAe,EAAE,MAAM;EAAe,SAAS,MAAM;EACxG,SAAS,OAAO;EAAY,KAAK,OAAO;EAAQ,UAAU,EAAE;CAC9D,CAAC;CACD,0BAA0B;EACxB,WAAW,OAAO;EAAY,cAAc,OAAO;EACnD,OAAO,EAAE,MAAM;EAAO,eAAe,EAAE,MAAM;EAC7C,SAAS,MAAM,2BAA2B;EAAM,UAAU;EAC1D,WAAW,MAAM,aAAa;EAC9B;EACA,UAAU,QAAQ;EAAU,aAAa,QAAQ;EACjD,WAAW,QAAQ;EAAW,UAAU,QAAQ;EAAU,YAAY,QAAQ;EAC9E,kBAAkB,QAAQ;EAC1B,SAAS,UAAU;EAAS,YAAY,EAAE;EAAY;EACtD,uBAAuB,OAAO;EAAc,YAAY,OAAO;EAC/D;EAAa,iBAAiB,QAAQ,cAAc;EACpD,aAAa,QAAQ,cAAc;EACnC,eAAe,QAAQ;EAAe,sBAAsB,QAAQ;EACpE;EAAe;EAAS,WAAW,MAAM;CAC3C,CAAC;CACD,mBAAmB;EACjB,eAAe,EAAE,MAAM;EACvB,eAAe,EAAE,MAAM,YAAY;EACnC;EACA,OAAO,MAAM;EACb,WAAW,OAAO,QAAQ,OAAO,OAAO,UAAU;EAClD,cAAc,MAAM;CACtB,CAAC;CACD,YAAY;EACV,gBAAgB;EAChB,uBAAwB,UAAU,WAA6C,CAAC;EAChF,eAAe,UAAU,QAAQ;EACjC,uBAAuB,EAAE,MAAM,MAAM,UAAU;EAC/C,QAAQ,KAAK;CACf,CAAC;CAKD,OACE,qBAAAA,UAAA,EAAA,UAAA,CACG,YAAY,SACT,oBAAC,uBAAD,EAAuB,SAAS,WAAW,OAAsC,CAAA,IACjF,MACH,MAAM,qBAAqB,oBAAC,6BAAD,EAA6B,YAAY,MAAM,mBAAqB,CAAA,IAAI,IACpG,EAAA,CAAA;AAEN"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvasPassThrough.js","names":[],"sources":["../../../src/canvas/SceneCanvas/canvasPassThrough.ts"],"sourcesContent":["import type { SceneCanvasProps } from './props';\n\ntype Props = SceneCanvasProps<unknown, string, unknown>;\n\n/** Every prop `<SceneCanvas>` reads itself instead of handing to `<Canvas>`. */\nconst OWN_PROPS = [\n 'scene', 'geometry', 'poseDescriptor', 'selectTool', 'insertNodeFactories', 'insertPaint',\n 'ingestion', 'layoutDropTarget', 'reflowTransition', 'poseTransition', 'geometryProjection', 'routing',\n 'selection', 'selectionOptions', 'selectable', 'tools', 'features', 'enableKeybindings',\n 'claimKeys', 'enableGestureDispatcher', 'onToolsCreated', 'defaultTools', 'toolOptions',\n 'initialActiveTool', 'ambient', 'versionCheck', 'longPress', 'viewport', 'layers', 'actions',\n 'tune', 'bindingOverrides', 'describeKind', 'animator', 'views', 'children', 'debug', 'alphaFor', 'layerVisibility',\n 'layerOrder', 'isPointerInteractive', '
|
|
1
|
+
{"version":3,"file":"canvasPassThrough.js","names":[],"sources":["../../../src/canvas/SceneCanvas/canvasPassThrough.ts"],"sourcesContent":["import type { SceneCanvasProps } from './props';\n\ntype Props = SceneCanvasProps<unknown, string, unknown>;\n\n/** Every prop `<SceneCanvas>` reads itself instead of handing to `<Canvas>`. */\nconst OWN_PROPS = [\n 'scene', 'geometry', 'poseDescriptor', 'selectTool', 'insertNodeFactories', 'insertPaint',\n 'ingestion', 'layoutDropTarget', 'reflowTransition', 'poseTransition', 'geometryProjection', 'routing',\n 'selection', 'selectionOptions', 'selectable', 'tools', 'features', 'enableKeybindings',\n 'claimKeys', 'enableGestureDispatcher', 'onToolsCreated', 'defaultTools', 'toolOptions',\n 'initialActiveTool', 'ambient', 'versionCheck', 'longPress', 'viewport', 'layers', 'actions',\n 'tune', 'bindingOverrides', 'describeKind', 'animator', 'views', 'children', 'debug', 'alphaFor', 'layerVisibility',\n 'layerOrder', 'isPointerInteractive', 'enteredGroup', 'onDoubleClick', 'onClick', 'onHover', 'chromeVisibility', 'modes',\n 'pathEdit', 'defaultPathEdit', 'getFocused', 'cursorCoordsHud', 'pickHud', 'modalityHud', 'view',\n 'onViewChange', 'defaultView', 'viewBounds', 'redrawOn', 'snap',\n] as const satisfies readonly (keyof Props)[];\n\n/** The props `<SceneCanvas>` passes through to its `<Canvas>`: all but its own. */\nexport function canvasPassThrough<P extends object>(props: P): Omit<P, (typeof OWN_PROPS)[number] | 'presetSource'> {\n const rest = { ...props } as Record<string, unknown>;\n for (const key of OWN_PROPS) delete rest[key];\n delete rest.presetSource;\n return rest as Omit<P, (typeof OWN_PROPS)[number] | 'presetSource'>;\n}\n"],"mappings":";;AAKA,IAAM,YAAY;CAChB;CAAS;CAAY;CAAkB;CAAc;CAAuB;CAC5E;CAAa;CAAoB;CAAoB;CAAkB;CAAsB;CAC7F;CAAa;CAAoB;CAAc;CAAS;CAAY;CACpE;CAAa;CAA2B;CAAkB;CAAgB;CAC1E;CAAqB;CAAW;CAAgB;CAAa;CAAY;CAAU;CACnF;CAAQ;CAAoB;CAAgB;CAAY;CAAS;CAAY;CAAS;CAAY;CAClG;CAAc;CAAwB;CAAgB;CAAiB;CAAW;CAAW;CAAoB;CACjH;CAAY;CAAmB;CAAc;CAAmB;CAAW;CAAe;CAC1F;CAAgB;CAAe;CAAc;CAAY;AAC3D;;AAGA,SAAgB,kBAAoC,OAAgE;CAClH,MAAM,OAAO,EAAE,GAAG,MAAM;CACxB,KAAK,MAAM,OAAO,WAAW,OAAO,KAAK;CACzC,OAAO,KAAK;CACZ,OAAO;AACT"}
|
|
@@ -5,11 +5,11 @@ import { isTextData } from "@weasel-js/text";
|
|
|
5
5
|
function isObj(d) {
|
|
6
6
|
return typeof d === "object" && d !== null;
|
|
7
7
|
}
|
|
8
|
-
/** Routes a
|
|
8
|
+
/** Routes a group node as `'group'`, whatever its data holds. `inferredNodeRouting` leads
|
|
9
9
|
* with it; spread it ahead of `defaultNodeRouting`, which is the shape-kind table alone. */
|
|
10
10
|
var groupNodeRouting = {
|
|
11
11
|
name: "group",
|
|
12
|
-
matches: (_data, node) => node?.kind === "
|
|
12
|
+
matches: (_data, node) => node?.kind === "group"
|
|
13
13
|
};
|
|
14
14
|
/**
|
|
15
15
|
* Routing classifiers for the kit's built-in shape kinds
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaultNodeRouting.js","names":[],"sources":["../../../src/canvas/SceneCanvas/defaultNodeRouting.ts"],"sourcesContent":["import { KIT_SHAPE_KINDS } from 'core/shapeKinds';\nimport type { NodeRoutingEntry } from 'core/scene/NodeRouting';\nimport { isTextData } from '@weasel-js/text';\n\nfunction isObj(d: unknown): d is Record<string, unknown> {\n return typeof d === 'object' && d !== null;\n}\n\n/** Routes a
|
|
1
|
+
{"version":3,"file":"defaultNodeRouting.js","names":[],"sources":["../../../src/canvas/SceneCanvas/defaultNodeRouting.ts"],"sourcesContent":["import { KIT_SHAPE_KINDS } from 'core/shapeKinds';\nimport type { NodeRoutingEntry } from 'core/scene/NodeRouting';\nimport { isTextData } from '@weasel-js/text';\n\nfunction isObj(d: unknown): d is Record<string, unknown> {\n return typeof d === 'object' && d !== null;\n}\n\n/** Routes a group node as `'group'`, whatever its data holds. `inferredNodeRouting` leads\n * with it; spread it ahead of `defaultNodeRouting`, which is the shape-kind table alone. */\nexport const groupNodeRouting: NodeRoutingEntry = {\n name: 'group',\n matches: (_data, node) => node?.kind === 'group',\n};\n\n/**\n * Routing classifiers for the kit's built-in shape kinds\n * (`KIT_SHAPE_KINDS`): each entry matches `data.kind === '<name>'`. Routing\n * kinds and shape kinds are independent — `'group'` has no shape painter.\n *\n * Spread it into `<SceneCanvas routing={...}>` when scene data carries a\n * `kind` tag. Data with no `kind` that follows the kit's common shapes\n * (`{ path }`, `{ text }`, `{ image }`) wants `inferredNodeRouting`, which\n * SceneCanvas applies when `routing` is unset.\n */\nexport const defaultNodeRouting: readonly NodeRoutingEntry[] = KIT_SHAPE_KINDS.map(\n (name) => ({\n name,\n matches: (data) =>\n isObj(data) &&\n (data as { kind?: unknown }).kind === name,\n }),\n);\n\n/**\n * Routing classifiers used when a consumer doesn't pass `routing` to\n * `<SceneCanvas>`, keyed on the data's shape rather than a `data.kind` tag.\n *\n * Order matters: `'text'` beats `'path'` so an SVG-imported text node\n * carrying a fallback `path` routes to text-edit.\n */\nexport const inferredNodeRouting: readonly NodeRoutingEntry[] = [\n groupNodeRouting,\n { name: 'text', matches: isTextData },\n { name: 'path', matches: (d) => isObj(d) && d.path != null },\n { name: 'image', matches: (d) => isObj(d) && d.image != null },\n];\n"],"mappings":";;;;AAIA,SAAS,MAAM,GAA0C;CACvD,OAAO,OAAO,MAAM,YAAY,MAAM;AACxC;;;AAIA,IAAa,mBAAqC;CAChD,MAAM;CACN,UAAU,OAAO,SAAS,MAAM,SAAS;AAC3C;;;;;;;;;;;AAYA,IAAa,qBAAkD,gBAAgB,KAC5E,UAAU;CACT;CACA,UAAU,SACR,MAAM,IAAI,KACT,KAA4B,SAAS;AAC1C,EACF;;;;;;;;AASA,IAAa,sBAAmD;CAC9D;CACA;EAAE,MAAM;EAAQ,SAAS;CAAW;CACpC;EAAE,MAAM;EAAQ,UAAU,MAAM,MAAM,CAAC,KAAK,EAAE,QAAQ;CAAK;CAC3D;EAAE,MAAM;EAAS,UAAU,MAAM,MAAM,CAAC,KAAK,EAAE,SAAS;CAAK;AAC/D"}
|