@weasel-js/core 1.10.0 → 1.10.1

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.
Files changed (327) hide show
  1. package/CHANGELOG.md +168 -0
  2. package/README.md +33 -0
  3. package/dist/affordances/composeAffordanceLayer.js +21 -21
  4. package/dist/affordances/composeAffordanceLayer.js.map +1 -1
  5. package/dist/affordances/hitAffordanceRegions.js +48 -32
  6. package/dist/affordances/hitAffordanceRegions.js.map +1 -1
  7. package/dist/affordances/pathAnchors.js +50 -28
  8. package/dist/affordances/pathAnchors.js.map +1 -1
  9. package/dist/affordances/rotateCursor.js +12 -0
  10. package/dist/affordances/rotateCursor.js.map +1 -0
  11. package/dist/affordances/rotationHandle.js +40 -43
  12. package/dist/affordances/rotationHandle.js.map +1 -1
  13. package/dist/animation/rig/rigNode.js +9 -3
  14. package/dist/animation/rig/rigNode.js.map +1 -1
  15. package/dist/animation/rig/rigSeat.js +46 -13
  16. package/dist/animation/rig/rigSeat.js.map +1 -1
  17. package/dist/animation/rig/skinBinding.js +22 -14
  18. package/dist/animation/rig/skinBinding.js.map +1 -1
  19. package/dist/barrel/canvas.js +29 -28
  20. package/dist/barrel/interactions.js +33 -32
  21. package/dist/barrel/paths.js +11 -10
  22. package/dist/barrel/routing.js +49 -48
  23. package/dist/barrel/scene.js +10 -10
  24. package/dist/barrel/viewport.js +24 -21
  25. package/dist/canvas/Canvas.js +6 -17
  26. package/dist/canvas/Canvas.js.map +1 -1
  27. package/dist/canvas/CanvasView.js +34 -37
  28. package/dist/canvas/CanvasView.js.map +1 -1
  29. package/dist/canvas/CursorCoordsHud.js +3 -3
  30. package/dist/canvas/CursorCoordsHud.js.map +1 -1
  31. package/dist/canvas/DrawCanvas.js +3 -3
  32. package/dist/canvas/DrawCanvas.js.map +1 -1
  33. package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +24 -23
  34. package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js.map +1 -1
  35. package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js +40 -49
  36. package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js.map +1 -1
  37. package/dist/canvas/SceneCanvas/defaultNodeProperties.js +297 -259
  38. package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -1
  39. package/dist/canvas/SceneCanvas/features.js +3 -24
  40. package/dist/canvas/SceneCanvas/features.js.map +1 -1
  41. package/dist/canvas/SceneCanvas/insertPreviewCommands.js +97 -0
  42. package/dist/canvas/SceneCanvas/insertPreviewCommands.js.map +1 -0
  43. package/dist/canvas/SceneCanvas/poseGeometry.js.map +1 -1
  44. package/dist/canvas/SceneCanvas/props.js.map +1 -1
  45. package/dist/canvas/SceneCanvas/scenePointQuery.js +50 -0
  46. package/dist/canvas/SceneCanvas/scenePointQuery.js.map +1 -0
  47. package/dist/canvas/SceneCanvas/shapeGeneratorProperties.js +52 -0
  48. package/dist/canvas/SceneCanvas/shapeGeneratorProperties.js.map +1 -0
  49. package/dist/canvas/SceneCanvas/useActionTunings.js +17 -0
  50. package/dist/canvas/SceneCanvas/useActionTunings.js.map +1 -0
  51. package/dist/canvas/SceneCanvas/useCanvasCamera.js +37 -29
  52. package/dist/canvas/SceneCanvas/useCanvasCamera.js.map +1 -1
  53. package/dist/canvas/SceneCanvas/useCanvasDispatcher.js +11 -11
  54. package/dist/canvas/SceneCanvas/useCanvasDispatcher.js.map +1 -1
  55. package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js +45 -109
  56. package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js.map +1 -1
  57. package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +49 -41
  58. package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js.map +1 -1
  59. package/dist/canvas/SceneCanvas/useSceneSelectTool.js +64 -96
  60. package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
  61. package/dist/canvas/SceneCanvas/worldPointAt.js +3 -4
  62. package/dist/canvas/SceneCanvas/worldPointAt.js.map +1 -1
  63. package/dist/canvas/SceneCanvas.js +77 -80
  64. package/dist/canvas/SceneCanvas.js.map +1 -1
  65. package/dist/canvas/SceneViewCanvas.js +3 -3
  66. package/dist/canvas/SceneViewCanvas.js.map +1 -1
  67. package/dist/canvas/SurfaceCanvas.js +40 -0
  68. package/dist/canvas/SurfaceCanvas.js.map +1 -0
  69. package/dist/canvas/adapterDerivedPath.js +13 -13
  70. package/dist/canvas/adapterDerivedPath.js.map +1 -1
  71. package/dist/canvas/adapterPickSource.js +34 -0
  72. package/dist/canvas/adapterPickSource.js.map +1 -0
  73. package/dist/canvas/affordanceAt.js +1 -1
  74. package/dist/canvas/affordanceAt.js.map +1 -1
  75. package/dist/canvas/buildSceneLayer.js.map +1 -1
  76. package/dist/canvas/buildSceneTree.js +56 -34
  77. package/dist/canvas/buildSceneTree.js.map +1 -1
  78. package/dist/canvas/copiesAbove.js +27 -0
  79. package/dist/canvas/copiesAbove.js.map +1 -0
  80. package/dist/canvas/defaultDrawOne.js +24 -23
  81. package/dist/canvas/defaultDrawOne.js.map +1 -1
  82. package/dist/canvas/deps/editAnchors.js +45 -50
  83. package/dist/canvas/deps/editAnchors.js.map +1 -1
  84. package/dist/canvas/deps/hitTestArea.js +30 -15
  85. package/dist/canvas/deps/hitTestArea.js.map +1 -1
  86. package/dist/canvas/deps/insert.js +134 -100
  87. package/dist/canvas/deps/insert.js.map +1 -1
  88. package/dist/canvas/deps/layout.js +9 -15
  89. package/dist/canvas/deps/layout.js.map +1 -1
  90. package/dist/canvas/derivedPath.js +53 -29
  91. package/dist/canvas/derivedPath.js.map +1 -1
  92. package/dist/canvas/insertPreviewExtent.js +33 -31
  93. package/dist/canvas/insertPreviewExtent.js.map +1 -1
  94. package/dist/canvas/overChildren.js +29 -0
  95. package/dist/canvas/overChildren.js.map +1 -0
  96. package/dist/canvas/paintedCursorLayer.js.map +1 -1
  97. package/dist/canvas/pickReach.js +23 -0
  98. package/dist/canvas/pickReach.js.map +1 -0
  99. package/dist/canvas/pickWalk.js +51 -80
  100. package/dist/canvas/pickWalk.js.map +1 -1
  101. package/dist/canvas/sceneAdapter.js +14 -35
  102. package/dist/canvas/sceneAdapter.js.map +1 -1
  103. package/dist/canvas/sceneSlotWiring.js +11 -10
  104. package/dist/canvas/sceneSlotWiring.js.map +1 -1
  105. package/dist/canvas/sceneViewRender.js +38 -44
  106. package/dist/canvas/sceneViewRender.js.map +1 -1
  107. package/dist/canvas/useCanvasView.js +42 -44
  108. package/dist/canvas/useCanvasView.js.map +1 -1
  109. package/dist/canvas/useSceneAdapter.js +22 -0
  110. package/dist/canvas/useSceneAdapter.js.map +1 -0
  111. package/dist/canvas/useSurfaceInput.js +13 -16
  112. package/dist/canvas/useSurfaceInput.js.map +1 -1
  113. package/dist/canvas/viewRegistry.js +31 -23
  114. package/dist/canvas/viewRegistry.js.map +1 -1
  115. package/dist/canvas/wrapNodeOutput.js +7 -2
  116. package/dist/canvas/wrapNodeOutput.js.map +1 -1
  117. package/dist/clipboard.d.ts +1 -1
  118. package/dist/{clone-2a5hVbBd.d.ts → clone-C0eADtS0.d.ts} +13 -13
  119. package/dist/clone.d.ts +2 -2
  120. package/dist/core/geometry/poseDescriptor.js +49 -23
  121. package/dist/core/geometry/poseDescriptor.js.map +1 -1
  122. package/dist/core/geometry/regionHit.js +2 -2
  123. package/dist/core/geometry/regionHit.js.map +1 -1
  124. package/dist/core/geometry/targetFrame.js.map +1 -1
  125. package/dist/core/layers/children.js +1 -3
  126. package/dist/core/layers/children.js.map +1 -1
  127. package/dist/core/ops/create.js +2 -2
  128. package/dist/core/ops/create.js.map +1 -1
  129. package/dist/core/ops/delete.js +19 -23
  130. package/dist/core/ops/delete.js.map +1 -1
  131. package/dist/core/ops/reorder/index.js +3 -7
  132. package/dist/core/ops/reorder/index.js.map +1 -1
  133. package/dist/core/ops/reorder/setChildOrder.js +2 -4
  134. package/dist/core/ops/reorder/setChildOrder.js.map +1 -1
  135. package/dist/core/ops/reparent.js +0 -1
  136. package/dist/core/ops/reparent.js.map +1 -1
  137. package/dist/core/ops/slot.js +3 -6
  138. package/dist/core/ops/slot.js.map +1 -1
  139. package/dist/core/pages/fitViewToPage.js +15 -0
  140. package/dist/core/pages/fitViewToPage.js.map +1 -0
  141. package/dist/core/pages/pages.js +65 -0
  142. package/dist/core/pages/pages.js.map +1 -0
  143. package/dist/core/pages/pagesLayer.js +27 -0
  144. package/dist/core/pages/pagesLayer.js.map +1 -0
  145. package/dist/core/paint/meshKindLazy.js +2 -2
  146. package/dist/core/paint/meshKindLazy.js.map +1 -1
  147. package/dist/core/scene/NodeProperties.js.map +1 -1
  148. package/dist/core/scene/composeFrame.js.map +1 -1
  149. package/dist/core/scene/composePose.js +58 -20
  150. package/dist/core/scene/composePose.js.map +1 -1
  151. package/dist/core/scene/effectivePose.js +5 -1
  152. package/dist/core/scene/effectivePose.js.map +1 -1
  153. package/dist/core/scene/historyFacade.js +19 -13
  154. package/dist/core/scene/historyFacade.js.map +1 -1
  155. package/dist/core/scene/nodeFnFields.js +7 -0
  156. package/dist/core/scene/nodeFnFields.js.map +1 -1
  157. package/dist/core/scene/outerOps.js +2 -1
  158. package/dist/core/scene/outerOps.js.map +1 -1
  159. package/dist/core/scene/reconcileSpecs.js +1 -1
  160. package/dist/core/scene/reconcileSpecs.js.map +1 -1
  161. package/dist/core/scene/sceneRecording.js +2 -1
  162. package/dist/core/scene/sceneRecording.js.map +1 -1
  163. package/dist/core/scene/types.js.map +1 -1
  164. package/dist/core/viewport/screenSlop.js.map +1 -1
  165. package/dist/core/viewport/useDecayLoop.js +28 -30
  166. package/dist/core/viewport/useDecayLoop.js.map +1 -1
  167. package/dist/core/viewport/useNodeOverlayFrame.js.map +1 -1
  168. package/dist/core/viewport/useViewAnimation.js +70 -69
  169. package/dist/core/viewport/useViewAnimation.js.map +1 -1
  170. package/dist/core/viewport/view.js +8 -5
  171. package/dist/core/viewport/view.js.map +1 -1
  172. package/dist/core/viewport/zoomAt.js +11 -2
  173. package/dist/core/viewport/zoomAt.js.map +1 -1
  174. package/dist/{cornerHandles-BEshc4z3.d.ts → cornerHandles-BSKbyuvQ.d.ts} +1 -1
  175. package/dist/features/paths/editablePath.js +24 -8
  176. package/dist/features/paths/editablePath.js.map +1 -1
  177. package/dist/features/paths/index.js +4 -4
  178. package/dist/features/paths/shapeGenerator.js +89 -0
  179. package/dist/features/paths/shapeGenerator.js.map +1 -0
  180. package/dist/features/paths/usePathEdit.js +13 -13
  181. package/dist/features/poseRun/usePoseRun.js +25 -25
  182. package/dist/features/poseRun/usePoseRun.js.map +1 -1
  183. package/dist/features/text/useSceneTextEdit.js +82 -64
  184. package/dist/features/text/useSceneTextEdit.js.map +1 -1
  185. package/dist/features/viewports/viewResolver.js +28 -24
  186. package/dist/features/viewports/viewResolver.js.map +1 -1
  187. package/dist/icons/SliceIcon.js +24 -0
  188. package/dist/icons/SliceIcon.js.map +1 -0
  189. package/dist/index.d.ts +956 -581
  190. package/dist/index.js +260 -251
  191. package/dist/interactions/actions/align/align.js +9 -9
  192. package/dist/interactions/actions/align/align.js.map +1 -1
  193. package/dist/interactions/actions/booleans/booleans.js +18 -18
  194. package/dist/interactions/actions/booleans/booleans.js.map +1 -1
  195. package/dist/interactions/actions/booleans/operands.js.map +1 -1
  196. package/dist/interactions/actions/clone/action.js +35 -30
  197. package/dist/interactions/actions/clone/action.js.map +1 -1
  198. package/dist/interactions/actions/defaults/anchorEditing.js +56 -59
  199. package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -1
  200. package/dist/interactions/actions/defaults/anchorHandles.js +42 -0
  201. package/dist/interactions/actions/defaults/anchorHandles.js.map +1 -0
  202. package/dist/interactions/actions/defaults/anchorJoin.js +92 -0
  203. package/dist/interactions/actions/defaults/anchorJoin.js.map +1 -0
  204. package/dist/interactions/actions/defaults/bendSegment.js +46 -0
  205. package/dist/interactions/actions/defaults/bendSegment.js.map +1 -0
  206. package/dist/interactions/actions/defaults/copySubtree.js +1 -1
  207. package/dist/interactions/actions/defaults/copySubtree.js.map +1 -1
  208. package/dist/interactions/actions/defaults/duplicate.js +32 -17
  209. package/dist/interactions/actions/defaults/duplicate.js.map +1 -1
  210. package/dist/interactions/actions/defaults/enterPathEdit.js +19 -7
  211. package/dist/interactions/actions/defaults/enterPathEdit.js.map +1 -1
  212. package/dist/interactions/actions/defaults/icons/anchorIcons.js +75 -0
  213. package/dist/interactions/actions/defaults/icons/anchorIcons.js.map +1 -0
  214. package/dist/interactions/actions/defaults/icons/editIcons.js +35 -8
  215. package/dist/interactions/actions/defaults/icons/editIcons.js.map +1 -1
  216. package/dist/interactions/actions/defaults/insertPathAnchor.js +16 -31
  217. package/dist/interactions/actions/defaults/insertPathAnchor.js.map +1 -1
  218. package/dist/interactions/actions/defaults/nudge.js +28 -23
  219. package/dist/interactions/actions/defaults/nudge.js.map +1 -1
  220. package/dist/interactions/actions/defaults/pinchZoom.js +29 -29
  221. package/dist/interactions/actions/defaults/pinchZoom.js.map +1 -1
  222. package/dist/interactions/actions/defaults/segmentUnder.js +22 -0
  223. package/dist/interactions/actions/defaults/segmentUnder.js.map +1 -0
  224. package/dist/interactions/actions/defaults/viewportZoom.js +82 -79
  225. package/dist/interactions/actions/defaults/viewportZoom.js.map +1 -1
  226. package/dist/interactions/actions/distribute/distribute.js +8 -8
  227. package/dist/interactions/actions/distribute/distribute.js.map +1 -1
  228. package/dist/interactions/actions/edit-anchors/action.js +58 -55
  229. package/dist/interactions/actions/edit-anchors/action.js.map +1 -1
  230. package/dist/interactions/actions/edit-anchors/preview.js +26 -0
  231. package/dist/interactions/actions/edit-anchors/preview.js.map +1 -0
  232. package/dist/interactions/actions/edit-anchors/symmetry.js +11 -0
  233. package/dist/interactions/actions/edit-anchors/symmetry.js.map +1 -0
  234. package/dist/interactions/actions/flip/action.js.map +1 -1
  235. package/dist/interactions/actions/geometryProjection.js.map +1 -1
  236. package/dist/interactions/actions/insert/action.js +37 -30
  237. package/dist/interactions/actions/insert/action.js.map +1 -1
  238. package/dist/interactions/actions/insert/frame.js +9 -2
  239. package/dist/interactions/actions/insert/frame.js.map +1 -1
  240. package/dist/interactions/actions/insert/repositionAction.js +31 -0
  241. package/dist/interactions/actions/insert/repositionAction.js.map +1 -0
  242. package/dist/interactions/actions/lasso-select/action.js +32 -32
  243. package/dist/interactions/actions/move/action.js +29 -25
  244. package/dist/interactions/actions/move/action.js.map +1 -1
  245. package/dist/interactions/actions/move/behaviors/snapToContainer.js +12 -6
  246. package/dist/interactions/actions/move/behaviors/snapToContainer.js.map +1 -1
  247. package/dist/interactions/actions/move/capture.js +32 -23
  248. package/dist/interactions/actions/move/capture.js.map +1 -1
  249. package/dist/interactions/actions/move/frame.js +2 -14
  250. package/dist/interactions/actions/move/frame.js.map +1 -1
  251. package/dist/interactions/actions/move/session.js +1 -1
  252. package/dist/interactions/actions/move/session.js.map +1 -1
  253. package/dist/interactions/actions/move/translate.js.map +1 -1
  254. package/dist/interactions/actions/outlines/createOutlines.js.map +1 -1
  255. package/dist/interactions/actions/outlines/replaceWithPaths.js +13 -13
  256. package/dist/interactions/actions/outlines/replaceWithPaths.js.map +1 -1
  257. package/dist/interactions/actions/outlines/strokeRegion.js.map +1 -1
  258. package/dist/interactions/actions/pathCommands/cutJoin.js +102 -0
  259. package/dist/interactions/actions/pathCommands/cutJoin.js.map +1 -0
  260. package/dist/interactions/actions/pathCommands/livePathEdit.js +64 -0
  261. package/dist/interactions/actions/pathCommands/livePathEdit.js.map +1 -0
  262. package/dist/interactions/actions/pathCommands/pathNodes.js +99 -0
  263. package/dist/interactions/actions/pathCommands/pathNodes.js.map +1 -0
  264. package/dist/interactions/actions/pathCommands/simplifyOffset.js +42 -0
  265. package/dist/interactions/actions/pathCommands/simplifyOffset.js.map +1 -0
  266. package/dist/interactions/actions/resize/action.js +31 -20
  267. package/dist/interactions/actions/resize/action.js.map +1 -1
  268. package/dist/interactions/actions/resize/commit.js.map +1 -1
  269. package/dist/interactions/actions/resize/frame.js +29 -15
  270. package/dist/interactions/actions/resize/frame.js.map +1 -1
  271. package/dist/interactions/actions/resize/replay.js +47 -0
  272. package/dist/interactions/actions/resize/replay.js.map +1 -0
  273. package/dist/interactions/actions/resize/session.js +49 -35
  274. package/dist/interactions/actions/resize/session.js.map +1 -1
  275. package/dist/interactions/actions/resolveOverlays.js +2 -1
  276. package/dist/interactions/actions/resolveOverlays.js.map +1 -1
  277. package/dist/interactions/actions/rotate/action.js +40 -25
  278. package/dist/interactions/actions/rotate/action.js.map +1 -1
  279. package/dist/interactions/actions/rotate/frame.js +1 -1
  280. package/dist/interactions/actions/rotate/frame.js.map +1 -1
  281. package/dist/interactions/actions/rotate/replay.js +22 -0
  282. package/dist/interactions/actions/rotate/replay.js.map +1 -0
  283. package/dist/interactions/actions/rotate/session.js +42 -32
  284. package/dist/interactions/actions/rotate/session.js.map +1 -1
  285. package/dist/interactions/actions/transform-again/action.js +63 -0
  286. package/dist/interactions/actions/transform-again/action.js.map +1 -0
  287. package/dist/interactions/actions/transform-again/memory.js +35 -0
  288. package/dist/interactions/actions/transform-again/memory.js.map +1 -0
  289. package/dist/interactions/actions/useStandardActions.js +101 -83
  290. package/dist/interactions/actions/useStandardActions.js.map +1 -1
  291. package/dist/move.d.ts +4 -4
  292. package/dist/{originProjection-PPT88jZv.d.ts → originProjection-CoNVpITV.d.ts} +1 -1
  293. package/dist/resize.d.ts +3 -3
  294. package/dist/style.css +1 -1
  295. package/dist/tools/builtin/ellipse/useEllipseTool.js +16 -15
  296. package/dist/tools/builtin/ellipse/useEllipseTool.js.map +1 -1
  297. package/dist/tools/builtin/line/useLineTool.js +16 -15
  298. package/dist/tools/builtin/line/useLineTool.js.map +1 -1
  299. package/dist/tools/builtin/pen/usePenTool.js +111 -111
  300. package/dist/tools/builtin/pen/usePenTool.js.map +1 -1
  301. package/dist/tools/builtin/pickTopMostHit.js +11 -14
  302. package/dist/tools/builtin/pickTopMostHit.js.map +1 -1
  303. package/dist/tools/builtin/polygon/usePolygonTool.js +17 -15
  304. package/dist/tools/builtin/polygon/usePolygonTool.js.map +1 -1
  305. package/dist/tools/builtin/rect/useRectTool.js +15 -14
  306. package/dist/tools/builtin/rect/useRectTool.js.map +1 -1
  307. package/dist/tools/builtin/select/adapterPointQuery.js +22 -18
  308. package/dist/tools/builtin/select/adapterPointQuery.js.map +1 -1
  309. package/dist/tools/builtin/select/selectionContributions.js +1 -1
  310. package/dist/tools/builtin/select/selectionContributions.js.map +1 -1
  311. package/dist/tools/builtin/select/useSelectTool.js +2 -1
  312. package/dist/tools/builtin/select/useSelectTool.js.map +1 -1
  313. package/dist/tools/builtin/slice/useSliceTool.js +42 -40
  314. package/dist/tools/builtin/slice/useSliceTool.js.map +1 -1
  315. package/dist/tools/builtin/star/useStarTool.js +18 -16
  316. package/dist/tools/builtin/star/useStarTool.js.map +1 -1
  317. package/dist/tools/builtin/text/useTextTool.js +2 -2
  318. package/dist/tools/builtin/text/useTextTool.js.map +1 -1
  319. package/dist/{types-CIKDwlsP.d.ts → types-DBbbCy0i.d.ts} +22 -15
  320. package/dist/version.js +1 -1
  321. package/package.json +22 -22
  322. package/dist/canvas/surface.module.js +0 -6
  323. package/dist/canvas/surface.module.js.map +0 -1
  324. package/dist/canvas/surfaceBox.js +0 -16
  325. package/dist/canvas/surfaceBox.js.map +0 -1
  326. package/dist/layout/arrivals.js +0 -33
  327. package/dist/layout/arrivals.js.map +0 -1
@@ -1,82 +1,77 @@
1
1
  import { createTransformOp as e } from "../../core/ops/transform.js";
2
2
  import { createSetDataOp as t } from "../../core/ops/setData.js";
3
- import { createPathEditState as n, isSelectedNode as r } from "../../features/paths/pathEditState.js";
4
- import { classifyPathStorage as i, resolveEditablePathOf as a } from "../../features/paths/editablePath.js";
5
- import { worldEditToStorage as o } from "@weasel-js/geom";
6
- import { useState as s } from "react";
7
- import { useLatest as c } from "@weasel-js/react";
8
- import { recordModeSwitch as l } from "@weasel-js/routing";
9
- import { useDepSource as u } from "@weasel-js/routing/react";
3
+ import { classifyPathStorage as n, resolveEditablePathOf as r, storeEditablePath as i } from "../../features/paths/editablePath.js";
4
+ import { withoutShapeGenerator as a } from "../../features/paths/shapeGenerator.js";
5
+ import { remapSkin as o } from "../../animation/rig/skinBinding.js";
6
+ import { createPathEditState as s, isSelectedNode as c } from "../../features/paths/pathEditState.js";
7
+ import { useState as l } from "react";
8
+ import { useLatest as u } from "@weasel-js/react";
9
+ import { recordModeSwitch as d } from "@weasel-js/routing";
10
+ import { useDepSource as f } from "@weasel-js/routing/react";
10
11
  //#region src/canvas/deps/editAnchors.ts
11
- var d = /* @__PURE__ */ new Set();
12
- function f(f, p, m, h) {
13
- let g = c(f), _ = c(p), v = c(m), [y] = s(() => n({ isSelectedNode: (e) => r(g.current, _.current, e) })), b = c(h ?? y);
14
- u("editAnchors", () => {
15
- let n = g.current, r = v.current, s = b.current, c = s.getEditingId(), u = c ? s.getSelectedAnchors() : d, f = c ? s.getMarquee() : null, p = (r, a, s) => {
16
- let c = a, l = n.get(r);
17
- if (!l) return [];
18
- let u = i(l);
19
- if (!u) return [];
20
- if (u.kind === "pose") return [e({
21
- id: r,
22
- from: l.pose,
23
- to: c,
24
- label: s
25
- })];
26
- let { pose: d, path: f } = o(u.pose, c);
27
- return [e({
28
- id: r,
29
- from: l.pose,
30
- to: d,
31
- label: s
32
- }), t({
33
- id: r,
34
- from: l.data,
12
+ var p = /* @__PURE__ */ new Set();
13
+ function m(m, h, g, _) {
14
+ let v = u(m), y = u(h), b = u(g), [x] = l(() => s({ isSelectedNode: (e) => c(v.current, y.current, e) })), S = u(_ ?? x);
15
+ f("editAnchors", () => {
16
+ let s = v.current, c = b.current, l = S.current, u = l.getEditingId(), f = u ? l.getSelectedAnchors() : p, m = u ? l.getMarquee() : null, h = (n, r, c, l) => {
17
+ let u = r, d = s.get(n);
18
+ if (!d) return [];
19
+ let f = i(d, u);
20
+ if (!f) return [];
21
+ let p = d.data?.skin, m = p && l ? { skin: o(p, l) } : null, h = e({
22
+ id: n,
23
+ from: d.pose,
24
+ to: f.pose,
25
+ label: c
26
+ }), g = f.data === d.data ? d.data : a(f.data);
27
+ return g === d.data && !m ? [h] : [h, t({
28
+ id: n,
29
+ from: d.data,
35
30
  to: {
36
- ...l.data,
37
- path: f
31
+ ...g,
32
+ ...m
38
33
  },
39
- label: s
34
+ label: c
40
35
  })];
41
36
  };
42
37
  return {
43
- editingId: c,
38
+ editingId: u,
44
39
  setEditingId(e) {
45
40
  let t = e ?? "";
46
- c !== t && (l("editAnchors.editingId", c || null, t || null, t ? "enter" : "exit"), s.setSelectedAnchors(d), s.setMarquee(null)), b.current.setEditingId(e);
41
+ u !== t && (d("editAnchors.editingId", u || null, t || null, t ? "enter" : "exit"), l.setSelectedAnchors(p), l.setMarquee(null)), S.current.setEditingId(e);
47
42
  },
48
- selectedAnchors: u,
43
+ selectedAnchors: f,
49
44
  setSelectedAnchors(e) {
50
- c && s.setSelectedAnchors(new Set(e));
45
+ u && l.setSelectedAnchors(new Set(e));
51
46
  },
52
- marquee: f,
47
+ marquee: m,
53
48
  setMarquee(e) {
54
- c && s.setMarquee(e);
49
+ u && l.setMarquee(e);
55
50
  },
56
51
  getEditablePath(e) {
57
- let t = n.get(e);
58
- return a(t);
52
+ let t = s.get(e);
53
+ return r(t);
59
54
  },
60
55
  getStorageKind(e) {
61
- let t = n.get(e);
62
- return i(t)?.kind ?? null;
56
+ let t = s.get(e);
57
+ return n(t)?.kind ?? null;
63
58
  },
64
59
  getNodeShape(e) {
65
- let t = n.get(e);
60
+ let t = s.get(e);
66
61
  return t ? {
67
62
  pose: t.pose,
68
63
  data: t.data
69
64
  } : null;
70
65
  },
71
- applyEdit(e, t, n) {
72
- let i = p(e, t, n);
73
- i.length > 0 && r.applyOps(i, n);
66
+ applyEdit(e, t, n, r) {
67
+ let i = h(e, t, n, r);
68
+ i.length > 0 && c.applyOps(i, n);
74
69
  },
75
- editOps: p
70
+ editOps: h
76
71
  };
77
72
  });
78
73
  }
79
74
  //#endregion
80
- export { a as resolveEditablePathOf, f as useEditAnchorsDepSource };
75
+ export { r as resolveEditablePathOf, m as useEditAnchorsDepSource };
81
76
 
82
77
  //# sourceMappingURL=editAnchors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"editAnchors.js","names":["EMPTY_ANCHOR_SELECTION","useEditAnchorsDepSource","sceneRef","useLatest","scene","selectionRef","selection","adapterRef","adapter","ownState","useState","createPathEditState","isSelectedNode","id","stateRef","externalState","sc","ad","state","effectiveId","selectedAnchors","marquee","editOps","wp","worldPath","node","storage","classifyPathStorage","createTransformOp","newPose","aligned","worldEditToStorage","createSetDataOp","next","recordModeSwitch","rect","resolveEditablePathOf","ops","label"],"sources":["../../../src/canvas/deps/editAnchors.ts"],"sourcesContent":["/**\n * `useEditAnchorsDepSource` — wires the `editAnchors` dep.\n *\n * A node's editable polygon lives in one of two places: the pose itself\n * (`pose.kind === 'polygon'`), or `data.path` with a rect pose, stored pose-local.\n * `getEditablePath` returns it in **world coords** either way, and `applyEdit` commits in the\n * correct storage shape as one undoable batch, preserving the render invariant\n * `pathInWorld(stored, pose) === world`. Live previews ride the standard\n * `OngoingHandle.previewIds/Pose/Data` triple — this dep doesn't own preview state.\n */\nimport { useState } from 'react';\nimport { useDepSource } from '@weasel-js/routing/react';\nimport { useLatest } from '@weasel-js/react';\nimport type { EditAnchorsDep } from 'interactions/actions/depSchema';\nimport type { Scene, NodeId } from 'core/scene/types';\nimport type { SelectionApi } from 'core/selection/useSelection';\nimport type { PolygonPath } from '@weasel-js/geom';\nimport { worldEditToStorage } from '@weasel-js/geom';\nimport { classifyPathStorage, resolveEditablePathOf } from 'features/paths/editablePath';\nimport { createPathEditState, isSelectedNode, type PathEditState } from 'features/paths/pathEditState';\nimport { recordModeSwitch } from '@weasel-js/routing';\nimport type { Op } from 'core/ops/types';\nimport { createTransformOp } from 'core/ops/transform';\nimport { createSetDataOp } from 'core/ops/setData';\n\ninterface OpsApplier {\n applyOps(ops: Op[], label?: string): void;\n}\n\n/** The part of a `PathEditState` the dep reads and writes. */\nexport type EditAnchorsStateRef = Omit<PathEditState, 'subscribe' | 'getEditingIds'>;\n\nexport { resolveEditablePathOf };\n\nconst EMPTY_ANCHOR_SELECTION: ReadonlySet<number> = new Set<number>();\n\nexport function useEditAnchorsDepSource(\n scene: Scene<unknown, string, unknown>,\n selection: SelectionApi,\n adapter: OpsApplier,\n externalState?: EditAnchorsStateRef,\n): void {\n const sceneRef = useLatest(scene);\n const selectionRef = useLatest(selection);\n const adapterRef = useLatest(adapter);\n\n // A caller that shares the state with nothing else gets one of its own.\n const [ownState] = useState(() => createPathEditState({\n isSelectedNode: (id) => isSelectedNode(sceneRef.current, selectionRef.current, id),\n }));\n const stateRef = useLatest(externalState ?? ownState);\n\n useDepSource('editAnchors', (): EditAnchorsDep => {\n const sc = sceneRef.current;\n const ad = adapterRef.current;\n const state = stateRef.current;\n const effectiveId = state.getEditingId();\n // Anchor selection and the marquee belong to one specific edited node, so never\n // hand them out alongside an empty id.\n const selectedAnchors = effectiveId ? state.getSelectedAnchors() : EMPTY_ANCHOR_SELECTION;\n const marquee = effectiveId ? state.getMarquee() : null;\n const editOps = (id: string, worldPath: unknown, label: string): Op[] => {\n const wp = worldPath as PolygonPath;\n const node = sc.get(id as NodeId);\n if (!node) return [];\n const storage = classifyPathStorage(node as { pose: unknown; data: unknown });\n if (!storage) return [];\n if (storage.kind === 'pose') return [createTransformOp({ id, from: node.pose, to: wp, label })];\n // The edited path arrives in world coords; invert it back to the unrotated stored\n // shape so `pose.rotation` is preserved and edits round-trip.\n const { pose: newPose, path: aligned } = worldEditToStorage(storage.pose, wp);\n return [\n createTransformOp({ id, from: node.pose, to: newPose, label }),\n createSetDataOp({ id, from: node.data, to: { ...(node.data as object), path: aligned }, label }),\n ];\n };\n return {\n editingId: effectiveId,\n setEditingId(id: string | null) {\n const next = id ?? '';\n if (effectiveId !== next) {\n recordModeSwitch(\n 'editAnchors.editingId',\n effectiveId || null,\n next || null,\n next ? 'enter' : 'exit',\n );\n // Anchor indices only mean something relative to one path.\n state.setSelectedAnchors(EMPTY_ANCHOR_SELECTION);\n state.setMarquee(null);\n }\n stateRef.current.setEditingId(id);\n },\n selectedAnchors,\n setSelectedAnchors(next: Iterable<number>) {\n if (!effectiveId) return;\n state.setSelectedAnchors(new Set(next));\n },\n marquee,\n setMarquee(rect) {\n if (!effectiveId) return;\n state.setMarquee(rect);\n },\n getEditablePath(id: string): PolygonPath | null {\n const node = sc.get(id as NodeId);\n return resolveEditablePathOf(node as { pose: unknown; data: unknown });\n },\n getStorageKind(id: string): 'pose' | 'data' | null {\n const node = sc.get(id as NodeId);\n const storage = classifyPathStorage(node as { pose: unknown; data: unknown });\n return storage?.kind ?? null;\n },\n getNodeShape(id: string): { pose: unknown; data: unknown } | null {\n const node = sc.get(id as NodeId);\n if (!node) return null;\n return { pose: node.pose, data: node.data };\n },\n applyEdit(id: string, worldPath: unknown, label: string) {\n const ops = editOps(id, worldPath, label);\n if (ops.length > 0) ad.applyOps(ops, label);\n },\n editOps,\n };\n });\n}\n"],"mappings":";;;;;;;;;;AAkCA,IAAMA,oBAA8C,IAAI,IAAY;AAEpE,SAAgBC,EACd,GACA,GACA,GACA,GACM;CACN,IAAMC,IAAWC,EAAUC,CAAK,GAC1BC,IAAeF,EAAUG,CAAS,GAClCC,IAAaJ,EAAUK,CAAO,GAG9B,CAACC,KAAYC,QAAeC,EAAoB,EACpD,iBAAiB,MAAOC,EAAeV,EAAS,SAASG,EAAa,SAASQ,CAAE,EACnF,CAAC,CAAC,GACIC,IAAWX,EAAUY,KAAiBN,CAAQ;CAEpD,EAAa,qBAAqC;EAChD,IAAMO,IAAKd,EAAS,SACde,IAAKV,EAAW,SAChBW,IAAQJ,EAAS,SACjBK,IAAcD,EAAM,aAAa,GAGjCE,IAAkBD,IAAcD,EAAM,mBAAmB,IAAIlB,GAC7DqB,IAAUF,IAAcD,EAAM,WAAW,IAAI,MAC7CI,KAAW,GAAY,GAAoB,MAAwB;GACvE,IAAMC,IAAKC,GACLC,IAAOT,EAAG,IAAIH,CAAY;GAChC,IAAI,CAACY,GAAM,OAAO,CAAC;GACnB,IAAMC,IAAUC,EAAoBF,CAAwC;GAC5E,IAAI,CAACC,GAAS,OAAO,CAAC;GACtB,IAAIA,EAAQ,SAAS,QAAQ,OAAO,CAACE,EAAkB;IAAE;IAAI,MAAMH,EAAK;IAAM,IAAIF;IAAI;GAAM,CAAC,CAAC;GAG9F,IAAM,EAAE,MAAMM,GAAS,MAAMC,MAAYC,EAAmBL,EAAQ,MAAMH,CAAE;GAC5E,OAAO,CACLK,EAAkB;IAAE;IAAI,MAAMH,EAAK;IAAM,IAAII;IAAS;GAAM,CAAC,GAC7DG,EAAgB;IAAE;IAAI,MAAMP,EAAK;IAAM,IAAI;KAAE,GAAIA,EAAK;KAAiB,MAAMK;IAAQ;IAAG;GAAM,CAAC,CACjG;EACF;EACA,OAAO;GACL,WAAWX;GACX,aAAa,GAAmB;IAC9B,IAAMc,IAAOpB,KAAM;IAYnB,AAXIM,MAAgBc,MAClBC,EACE,yBACAf,KAAe,MACfc,KAAQ,MACRA,IAAO,UAAU,MACnB,GAEAf,EAAM,mBAAmBlB,CAAsB,GAC/CkB,EAAM,WAAW,IAAI,IAEvBJ,EAAS,QAAQ,aAAaD,CAAE;GAClC;GACA;GACA,mBAAmB,GAAwB;IACzC,AAAKM,KACLD,EAAM,mBAAmB,IAAI,IAAIe,CAAI,CAAC;GACxC;GACA;GACA,WAAW,GAAM;IACf,AAAKd,KACLD,EAAM,WAAWiB,CAAI;GACvB;GACA,gBAAgB,GAAgC;IAC9C,IAAMV,IAAOT,EAAG,IAAIH,CAAY;IAChC,OAAOuB,EAAsBX,CAAwC;GACvE;GACA,eAAe,GAAoC;IACjD,IAAMA,IAAOT,EAAG,IAAIH,CAAY;IAEhC,OADgBc,EAAoBF,CAC7B,CAAA,EAAS,QAAQ;GAC1B;GACA,aAAa,GAAqD;IAChE,IAAMA,IAAOT,EAAG,IAAIH,CAAY;IAEhC,OADKY,IACE;KAAE,MAAMA,EAAK;KAAM,MAAMA,EAAK;IAAK,IADxB;GAEpB;GACA,UAAU,GAAY,GAAoB,GAAe;IACvD,IAAMY,IAAMf,EAAQT,GAAIW,GAAWc,CAAK;IACxC,AAAID,EAAI,SAAS,KAAGpB,EAAG,SAASoB,GAAKC,CAAK;GAC5C;GACA;EACF;CACF,CAAC;AACH"}
1
+ {"version":3,"file":"editAnchors.js","names":["EMPTY_ANCHOR_SELECTION","useEditAnchorsDepSource","sceneRef","useLatest","scene","selectionRef","selection","adapterRef","adapter","ownState","useState","createPathEditState","isSelectedNode","id","stateRef","externalState","sc","ad","state","effectiveId","selectedAnchors","marquee","editOps","wp","worldPath","node","next","storeEditablePath","skin","reskinned","origins","remapSkin","reshape","createTransformOp","data","withoutShapeGenerator","createSetDataOp","recordModeSwitch","rect","resolveEditablePathOf","classifyPathStorage","ops","label"],"sources":["../../../src/canvas/deps/editAnchors.ts"],"sourcesContent":["/**\n * `useEditAnchorsDepSource` — wires the `editAnchors` dep.\n *\n * A node's editable polygon lives in one of two places: the pose itself\n * (`pose.kind === 'polygon'`), or `data.path` with a rect pose, stored pose-local.\n * `getEditablePath` returns it in **world coords** either way, and `applyEdit` commits in the\n * correct storage shape as one undoable batch, preserving the render invariant\n * `pathInWorld(stored, pose) === world`. A node with a `data.skin` has it renumbered in that\n * batch when the caller says where the points came from. Live previews ride the standard\n * `OngoingHandle.previewIds/Pose/Data` triple — this dep doesn't own preview state.\n */\nimport { useState } from 'react';\nimport { useDepSource } from '@weasel-js/routing/react';\nimport { useLatest } from '@weasel-js/react';\nimport type { EditAnchorsDep } from 'interactions/actions/depSchema';\nimport type { Scene, NodeId } from 'core/scene/types';\nimport type { SelectionApi } from 'core/selection/useSelection';\nimport type { PointOrigin, PolygonPath } from '@weasel-js/geom';\nimport type { Skin } from '@weasel-js/animator';\nimport { remapSkin } from '../../animation/rig/skinBinding';\nimport { classifyPathStorage, resolveEditablePathOf, storeEditablePath } from 'features/paths/editablePath';\nimport { withoutShapeGenerator } from 'features/paths/shapeGenerator';\nimport { createPathEditState, isSelectedNode, type PathEditState } from 'features/paths/pathEditState';\nimport { recordModeSwitch } from '@weasel-js/routing';\nimport type { Op } from 'core/ops/types';\nimport { createTransformOp } from 'core/ops/transform';\nimport { createSetDataOp } from 'core/ops/setData';\n\ninterface OpsApplier {\n applyOps(ops: Op[], label?: string): void;\n}\n\n/** The part of a `PathEditState` the dep reads and writes. */\nexport type EditAnchorsStateRef = Omit<PathEditState, 'subscribe' | 'getEditingIds'>;\n\nexport { resolveEditablePathOf };\n\nconst EMPTY_ANCHOR_SELECTION: ReadonlySet<number> = new Set<number>();\n\nexport function useEditAnchorsDepSource(\n scene: Scene<unknown, string, unknown>,\n selection: SelectionApi,\n adapter: OpsApplier,\n externalState?: EditAnchorsStateRef,\n): void {\n const sceneRef = useLatest(scene);\n const selectionRef = useLatest(selection);\n const adapterRef = useLatest(adapter);\n\n // A caller that shares the state with nothing else gets one of its own.\n const [ownState] = useState(() => createPathEditState({\n isSelectedNode: (id) => isSelectedNode(sceneRef.current, selectionRef.current, id),\n }));\n const stateRef = useLatest(externalState ?? ownState);\n\n useDepSource('editAnchors', (): EditAnchorsDep => {\n const sc = sceneRef.current;\n const ad = adapterRef.current;\n const state = stateRef.current;\n const effectiveId = state.getEditingId();\n // Anchor selection and the marquee belong to one specific edited node, so never\n // hand them out alongside an empty id.\n const selectedAnchors = effectiveId ? state.getSelectedAnchors() : EMPTY_ANCHOR_SELECTION;\n const marquee = effectiveId ? state.getMarquee() : null;\n const editOps = (id: string, worldPath: unknown, label: string, origins?: readonly (PointOrigin | null)[]): Op[] => {\n const wp = worldPath as PolygonPath;\n const node = sc.get(id as NodeId);\n if (!node) return [];\n const next = storeEditablePath(node as { pose: unknown; data: unknown }, wp);\n if (!next) return [];\n const skin = (node.data as { skin?: Skin } | null)?.skin;\n const reskinned = skin && origins ? { skin: remapSkin(skin, origins) } : null;\n const reshape = createTransformOp({ id, from: node.pose, to: next.pose, label });\n // A path edited by hand is no longer what its generator makes: it becomes plain geometry.\n const data = next.data === node.data ? node.data : withoutShapeGenerator(next.data);\n if (data === node.data && !reskinned) return [reshape];\n return [reshape, createSetDataOp({ id, from: node.data, to: { ...(data as object), ...reskinned }, label })];\n };\n return {\n editingId: effectiveId,\n setEditingId(id: string | null) {\n const next = id ?? '';\n if (effectiveId !== next) {\n recordModeSwitch(\n 'editAnchors.editingId',\n effectiveId || null,\n next || null,\n next ? 'enter' : 'exit',\n );\n // Anchor indices only mean something relative to one path.\n state.setSelectedAnchors(EMPTY_ANCHOR_SELECTION);\n state.setMarquee(null);\n }\n stateRef.current.setEditingId(id);\n },\n selectedAnchors,\n setSelectedAnchors(next: Iterable<number>) {\n if (!effectiveId) return;\n state.setSelectedAnchors(new Set(next));\n },\n marquee,\n setMarquee(rect) {\n if (!effectiveId) return;\n state.setMarquee(rect);\n },\n getEditablePath(id: string): PolygonPath | null {\n const node = sc.get(id as NodeId);\n return resolveEditablePathOf(node as { pose: unknown; data: unknown });\n },\n getStorageKind(id: string): 'pose' | 'data' | null {\n const node = sc.get(id as NodeId);\n const storage = classifyPathStorage(node as { pose: unknown; data: unknown });\n return storage?.kind ?? null;\n },\n getNodeShape(id: string): { pose: unknown; data: unknown } | null {\n const node = sc.get(id as NodeId);\n if (!node) return null;\n return { pose: node.pose, data: node.data };\n },\n applyEdit(id: string, worldPath: unknown, label: string, origins?: readonly (PointOrigin | null)[]) {\n const ops = editOps(id, worldPath, label, origins);\n if (ops.length > 0) ad.applyOps(ops, label);\n },\n editOps,\n };\n });\n}\n"],"mappings":";;;;;;;;;;;AAqCA,IAAMA,oBAA8C,IAAI,IAAY;AAEpE,SAAgBC,EACd,GACA,GACA,GACA,GACM;CACN,IAAMC,IAAWC,EAAUC,CAAK,GAC1BC,IAAeF,EAAUG,CAAS,GAClCC,IAAaJ,EAAUK,CAAO,GAG9B,CAACC,KAAYC,QAAeC,EAAoB,EACpD,iBAAiB,MAAOC,EAAeV,EAAS,SAASG,EAAa,SAASQ,CAAE,EACnF,CAAC,CAAC,GACIC,IAAWX,EAAUY,KAAiBN,CAAQ;CAEpD,EAAa,qBAAqC;EAChD,IAAMO,IAAKd,EAAS,SACde,IAAKV,EAAW,SAChBW,IAAQJ,EAAS,SACjBK,IAAcD,EAAM,aAAa,GAGjCE,IAAkBD,IAAcD,EAAM,mBAAmB,IAAIlB,GAC7DqB,IAAUF,IAAcD,EAAM,WAAW,IAAI,MAC7CI,KAAW,GAAY,GAAoB,GAAe,MAAoD;GAClH,IAAMC,IAAKC,GACLC,IAAOT,EAAG,IAAIH,CAAY;GAChC,IAAI,CAACY,GAAM,OAAO,CAAC;GACnB,IAAMC,IAAOC,EAAkBF,GAA0CF,CAAE;GAC3E,IAAI,CAACG,GAAM,OAAO,CAAC;GACnB,IAAME,IAAQH,EAAK,MAAiC,MAC9CI,IAAYD,KAAQE,IAAU,EAAE,MAAMC,EAAUH,GAAME,CAAO,EAAE,IAAI,MACnEE,IAAUC,EAAkB;IAAE;IAAI,MAAMR,EAAK;IAAM,IAAIC,EAAK;IAAM;GAAM,CAAC,GAEzEQ,IAAOR,EAAK,SAASD,EAAK,OAAOA,EAAK,OAAOU,EAAsBT,EAAK,IAAI;GAElF,OADIQ,MAAST,EAAK,QAAQ,CAACI,IAAkB,CAACG,CAAO,IAC9C,CAACA,GAASI,EAAgB;IAAE;IAAI,MAAMX,EAAK;IAAM,IAAI;KAAE,GAAIS;KAAiB,GAAGL;IAAU;IAAG;GAAM,CAAC,CAAC;EAC7G;EACA,OAAO;GACL,WAAWV;GACX,aAAa,GAAmB;IAC9B,IAAMO,IAAOb,KAAM;IAYnB,AAXIM,MAAgBO,MAClBW,EACE,yBACAlB,KAAe,MACfO,KAAQ,MACRA,IAAO,UAAU,MACnB,GAEAR,EAAM,mBAAmBlB,CAAsB,GAC/CkB,EAAM,WAAW,IAAI,IAEvBJ,EAAS,QAAQ,aAAaD,CAAE;GAClC;GACA;GACA,mBAAmB,GAAwB;IACzC,AAAKM,KACLD,EAAM,mBAAmB,IAAI,IAAIQ,CAAI,CAAC;GACxC;GACA;GACA,WAAW,GAAM;IACf,AAAKP,KACLD,EAAM,WAAWoB,CAAI;GACvB;GACA,gBAAgB,GAAgC;IAC9C,IAAMb,IAAOT,EAAG,IAAIH,CAAY;IAChC,OAAO0B,EAAsBd,CAAwC;GACvE;GACA,eAAe,GAAoC;IACjD,IAAMA,IAAOT,EAAG,IAAIH,CAAY;IAEhC,OADgB2B,EAAoBf,CAC7B,CAAA,EAAS,QAAQ;GAC1B;GACA,aAAa,GAAqD;IAChE,IAAMA,IAAOT,EAAG,IAAIH,CAAY;IAEhC,OADKY,IACE;KAAE,MAAMA,EAAK;KAAM,MAAMA,EAAK;IAAK,IADxB;GAEpB;GACA,UAAU,GAAY,GAAoB,GAAe,GAA2C;IAClG,IAAMgB,IAAMnB,EAAQT,GAAIW,GAAWkB,GAAOZ,CAAO;IACjD,AAAIW,EAAI,SAAS,KAAGxB,EAAG,SAASwB,GAAKC,CAAK;GAC5C;GACA;EACF;CACF,CAAC;AACH"}
@@ -4,9 +4,9 @@ import { AUTO_POSE_DESCRIPTOR as i } from "../../core/geometry/autoPoseDescripto
4
4
  import { findShapeInk as a, findShapeSilhouette as o } from "../NodeShape.js";
5
5
  import { pickWalk as s, scenePickSource as c } from "../pickWalk.js";
6
6
  import { polygonRegion as l, poseOutline as u, rectRegion as d, regionBoundsOf as f, regionOf as p, regionTakes as m } from "../../core/geometry/regionHit.js";
7
- import { pathIntersectsRect as h } from "@weasel-js/geom";
7
+ import { applyToPoint as h, pathIntersectsRect as g } from "@weasel-js/geom";
8
8
  //#region src/canvas/deps/hitTestArea.ts
9
- function g(e, t) {
9
+ function _(e, t) {
10
10
  let n = e?.get?.();
11
11
  return {
12
12
  ...t ? { alphaOf: t } : {},
@@ -14,35 +14,36 @@ function g(e, t) {
14
14
  ...n ? { camera: n } : {}
15
15
  };
16
16
  }
17
- function _(e, t, n, r = i, a = {}) {
18
- return b(e, d(t), "intersect", n, r, a);
17
+ function v(e, t, n, r = i, a = {}) {
18
+ return x(e, d(t), "intersect", n, r, a);
19
19
  }
20
- function v(e, t, n, r, a = i, o = {}) {
20
+ function y(e, t, n, r, a = i, o = {}) {
21
21
  let s = l(t);
22
- return s ? b(e, s, n, r, a, o) : [];
22
+ return s ? x(e, s, n, r, a, o) : [];
23
23
  }
24
- function y(e, t) {
24
+ function b(e, t) {
25
25
  return t?.kind === "polygon" ? e() ? t : {
26
26
  ...t,
27
27
  openFill: "none"
28
28
  } : t;
29
29
  }
30
- function b(e, t, i, l, d, p) {
31
- let g = (e) => ({
30
+ function x(e, t, i, l, d, p) {
31
+ let h = (e) => ({
32
32
  includeContainers: p.includeContainers === !0,
33
33
  clipAdmits: (t, i, a) => {
34
34
  let o = n(d, i);
35
- return h(t, r(a, o)) && h(t, e.bounds);
35
+ return g(t, r(a, o)) && g(t, e.bounds);
36
36
  },
37
37
  hits: (t, r) => {
38
38
  let s = n(d, t), c = f(t, r, s), l, p = () => l ??= a(t, r)?.filled !== !1;
39
- return m(e, i, y(p, r), c, () => y(p, o(t, r) ?? u(r, c)), p);
39
+ return m(e, i, b(p, r), c, () => b(p, o(t, r) ?? u(r, c)), p);
40
40
  },
41
- inPlane: (t) => g(x(e, t))
41
+ inPlane: (t) => h(S(e, t)),
42
+ inCopy: (t) => h(C(e, t))
42
43
  });
43
- return s(c(e, l), g(t));
44
+ return s(c(e, l), h(t));
44
45
  }
45
- function x(n, r) {
46
+ function S(n, r) {
46
47
  let i = [];
47
48
  for (let e of n.verts) {
48
49
  let n = t(r, e);
@@ -50,7 +51,21 @@ function x(n, r) {
50
51
  }
51
52
  return p(i, e(r, n.bounds), n.isRect);
52
53
  }
54
+ function C(e, t) {
55
+ let n = [], r = Infinity, i = Infinity, a = -Infinity, o = -Infinity;
56
+ for (let s of e.verts) {
57
+ let [e, c] = h(t, s.x, s.y);
58
+ n.push(e, c), r = Math.min(r, e), i = Math.min(i, c), a = Math.max(a, e), o = Math.max(o, c);
59
+ }
60
+ let s = t[1] === 0 && t[2] === 0 || t[0] === 0 && t[3] === 0;
61
+ return p(n, {
62
+ x: r,
63
+ y: i,
64
+ width: a - r,
65
+ height: o - i
66
+ }, e.isRect && s);
67
+ }
53
68
  //#endregion
54
- export { _ as hitTestArea, v as hitTestLassoPolygon, g as regionPickOptions };
69
+ export { v as hitTestArea, y as hitTestLassoPolygon, _ as regionPickOptions };
55
70
 
56
71
  //# sourceMappingURL=hitTestArea.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hitTestArea.js","names":["regionPickOptions","camera","view","alphaOf","layer","hitTestArea","AUTO_POSE_DESCRIPTOR","walkArea","scene","rectRegion","bounds","opts","descriptor","query","hitTestLassoPolygon","region","polygonRegion","polygon","mode","asInked","shape","filled","regionQuery","g","poseDescriptorForNode","node","pathIntersectsRect","clip","visualBoundsViaDescriptor","pose","r","b","regionBoundsOf","ink","findShapeInk","regionTakes","findShapeSilhouette","poseOutline","regionInPlane","m","pickWalk","scenePickSource","coords","v","p","toPlane","regionOf","rectToPlane"],"sources":["../../../src/canvas/deps/hitTestArea.ts"],"sourcesContent":["/**\n * Silhouette-aware area hit-test for marquee and lasso selection.\n *\n * The per-node decision is `regionTakes` (`core/geometry/regionHit`). This\n * module supplies the scene walk and the node's drawn outline: the painter's\n * world-frame silhouette (`findShapeSilhouette`), or with no painter the pose\n * rect, rotated if the pose is.\n */\nimport type { Scene, NodeId } from 'core/scene/types';\nimport { pathIntersectsRect } from '@weasel-js/geom';\nimport type { LassoHitMode } from 'core/adapters/types';\nimport {\n poseDescriptorForNode,\n visualBoundsViaDescriptor,\n type PoseDescriptor,\n} from 'interactions/actions/resize/geometry';\nimport { AUTO_POSE_DESCRIPTOR } from 'core/geometry/autoPoseDescriptor';\nimport {\n pickWalk,\n scenePickSource,\n type PickQuery,\n type ScenePickSourceOptions,\n} from 'canvas/pickWalk';\nimport { rectToPlane, toPlane, type PlaneMap } from 'core/viewport/parallax';\n\nexport { hiddenLayerIds } from 'canvas/pickWalk';\nimport type { HitTestView } from 'interactions/actions/depSchema';\nimport { findShapeInk, findShapeSilhouette } from 'canvas/NodeShape';\nimport {\n polygonRegion,\n poseOutline,\n rectRegion,\n regionBoundsOf,\n regionOf,\n regionTakes,\n type SelectRegion,\n} from 'core/geometry/regionHit';\n\nexport interface AABBBounds {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/** What a region query takes back beyond leaves. */\nexport interface RegionQueryOptions {\n /** Default `false`: a region that takes a container and its children\n * selects the same ink twice. A bare-adapter consumer, which has nothing\n * to fold children back into their container, asks for them. */\n includeContainers?: boolean;\n}\n\n\n/** The pick options a region dep hands the shared walk: the asking view's\n * layer gate and camera, and the surface's alpha. */\nexport function regionPickOptions(\n view: HitTestView | undefined,\n alphaOf: ((id: string) => number) | undefined,\n): ScenePickSourceOptions<unknown> {\n const camera = view?.get?.();\n return {\n ...(alphaOf ? { alphaOf } : {}),\n ...(view?.layerIsPainted ? { layerIsPainted: (layer: string) => view.layerIsPainted!(layer) } : {}),\n ...(camera ? { camera } : {}),\n };\n}\n\n/** Marquee entry point: every node the rect `bounds` meets. */\nexport function hitTestArea(\n scene: Scene<unknown, string, unknown>,\n bounds: AABBBounds,\n opts?: ScenePickSourceOptions<unknown>,\n descriptor: PoseDescriptor<unknown> = AUTO_POSE_DESCRIPTOR,\n query: RegionQueryOptions = {},\n): NodeId[] {\n return walkArea(scene, rectRegion(bounds), 'intersect', opts, descriptor, query);\n}\n\n/**\n * Every node an arbitrary closed area polygon meets. `area` is interleaved\n * `[x0,y0,x1,y1,…]`; `areaBounds` is its AABB, derived when omitted.\n */\nexport function hitTestAreaPolygon(\n scene: Scene<unknown, string, unknown>,\n area: ArrayLike<number>,\n areaBounds?: AABBBounds,\n /** True when `area` IS its own bounding rect, so `areaBounds` containment\n * implies containment in the area proper. Never pass this for a lasso\n * polygon — a node inside the hull's box can miss the hull. */\n areaIsRect = false,\n /** The asking view's alpha and layer accessors. A bare scene answers for\n * itself; a view that dims or reorders layers has to supply its own. */\n opts?: ScenePickSourceOptions<unknown>,\n /** How to read this scene's poses. Default `AUTO_POSE_DESCRIPTOR`. */\n descriptor: PoseDescriptor<unknown> = AUTO_POSE_DESCRIPTOR,\n query: RegionQueryOptions = {},\n): NodeId[] {\n const region = regionOf(area, areaBounds, areaIsRect);\n return region ? walkArea(scene, region, 'intersect', opts, descriptor, query) : [];\n}\n\n/**\n * Lasso entry point: which nodes a closed lasso polygon picks under `mode`\n * (see `regionTakes`).\n */\nexport function hitTestLassoPolygon(\n scene: Scene<unknown, string, unknown>,\n polygon: ReadonlyArray<{ x: number; y: number }>,\n mode: LassoHitMode,\n opts?: ScenePickSourceOptions<unknown>,\n descriptor: PoseDescriptor<unknown> = AUTO_POSE_DESCRIPTOR,\n query: RegionQueryOptions = {},\n): NodeId[] {\n const region = polygonRegion(polygon);\n return region ? walkArea(scene, region, mode, opts, descriptor, query) : [];\n}\n\n/** `shape` as a region reads it: a polygon path's open subpaths enclose\n * nothing when the node's painter lays down no fill. */\nfunction asInked<T>(filled: () => boolean, shape: T): T {\n if ((shape as { kind?: unknown } | null)?.kind !== 'polygon') return shape;\n return filled() ? shape : { ...shape, openFill: 'none' };\n}\n\n/** The walk every region query shares: skip containers unless asked, gate on\n * the clip, and let `regionTakes` decide each node. */\nfunction walkArea(\n scene: Scene<unknown, string, unknown>,\n region: SelectRegion,\n mode: LassoHitMode,\n opts: ScenePickSourceOptions<unknown> | undefined,\n descriptor: PoseDescriptor<unknown>,\n query: RegionQueryOptions,\n): NodeId[] {\n const regionQuery = (r: SelectRegion): PickQuery<unknown> => ({\n includeContainers: query.includeContainers === true,\n clipAdmits: (clip, node, pose) => {\n const g = poseDescriptorForNode(descriptor, node);\n return pathIntersectsRect(clip, visualBoundsViaDescriptor(pose, g))\n && pathIntersectsRect(clip, r.bounds);\n },\n hits: (node, pose) => {\n // The descriptor sees the node here, so a pose shape whose extent\n // depends on `node.data` bounds itself rather than its pose's default.\n const g = poseDescriptorForNode(descriptor, node);\n const b = regionBoundsOf(node as object, pose, g);\n let ink: boolean | undefined;\n const filled = (): boolean => ink ??= findShapeInk(node as never, pose)?.filled !== false;\n return regionTakes(r, mode, asInked(filled, pose), b, () =>\n asInked(filled, findShapeSilhouette(node as never, pose) ?? poseOutline(pose, b)), filled);\n },\n inPlane: (m) => regionQuery(regionInPlane(r, m)),\n });\n return pickWalk<unknown>(scenePickSource(scene, opts), regionQuery(region)) as NodeId[];\n}\n\n/** `r` carried into a plane's world. The map is axis-aligned, so a rect stays\n * one; a flipped axis reverses the winding, which no region test reads. */\nfunction regionInPlane(r: SelectRegion, m: PlaneMap): SelectRegion {\n const coords: number[] = [];\n for (const v of r.verts) {\n const p = toPlane(m, v);\n coords.push(p.x, p.y);\n }\n return regionOf(coords, rectToPlane(m, r.bounds), r.isRect)!;\n}\n"],"mappings":";;;;;;;;AAwDA,SAAgBA,EACd,GACA,GACiC;CACjC,IAAMC,IAASC,GAAM,MAAM;CAC3B,OAAO;EACL,GAAIC,IAAU,EAAE,WAAQ,IAAI,CAAC;EAC7B,GAAID,GAAM,iBAAiB,EAAE,iBAAiB,MAAkBA,EAAK,eAAgBE,CAAK,EAAE,IAAI,CAAC;EACjG,GAAIH,IAAS,EAAE,UAAO,IAAI,CAAC;CAC7B;AACF;AAGA,SAAgBI,EACd,GACA,GACA,GACA,IAAsCC,GACtC,IAA4B,CAAC,GACnB;CACV,OAAOC,EAASC,GAAOC,EAAWC,CAAM,GAAG,aAAaC,GAAMC,GAAYC,CAAK;AACjF;AA6BA,SAAgBC,EACd,GACA,GACA,GACA,GACA,IAAsCR,GACtC,IAA4B,CAAC,GACnB;CACV,IAAMS,IAASC,EAAcC,CAAO;CACpC,OAAOF,IAASR,EAASC,GAAOO,GAAQG,GAAMP,GAAMC,GAAYC,CAAK,IAAI,CAAC;AAC5E;AAIA,SAASM,EAAW,GAAuB,GAAa;CAEtD,OADKC,GAAqC,SAAS,YAC5CC,EAAO,IAAID,IAAQ;EAAE,GAAGA;EAAO,UAAU;CAAO,IADcA;AAEvE;AAIA,SAASb,EACP,GACA,GACA,GACA,GACA,GACA,GACU;CACV,IAAMe,KAAe,OAAyC;EAC5D,mBAAmBT,EAAM,sBAAsB;EAC/C,aAAa,GAAM,GAAM,MAAS;GAChC,IAAMU,IAAIC,EAAsBZ,GAAYa,CAAI;GAChD,OAAOC,EAAmBC,GAAMC,EAA0BC,GAAMN,CAAC,CAAC,KAC7DG,EAAmBC,GAAMG,EAAE,MAAM;EACxC;EACA,OAAO,GAAM,MAAS;GAGpB,IAAMP,IAAIC,EAAsBZ,GAAYa,CAAI,GAC1CM,IAAIC,EAAeP,GAAgBI,GAAMN,CAAC,GAC5CU,GACEZ,UAAwB,MAAQa,EAAaT,GAAeI,CAAI,CAAC,EAAE,WAAW;GACpF,OAAOM,EAAYL,GAAGZ,GAAMC,EAAQE,GAAQQ,CAAI,GAAGE,SACjDZ,EAAQE,GAAQe,EAAoBX,GAAeI,CAAI,KAAKQ,EAAYR,GAAME,CAAC,CAAC,GAAGV,CAAM;EAC7F;EACA,UAAU,MAAMC,EAAYgB,EAAcR,GAAGS,CAAC,CAAC;CACjD;CACA,OAAOC,EAAkBC,EAAgBjC,GAAOG,CAAI,GAAGW,EAAYP,CAAM,CAAC;AAC5E;AAIA,SAASuB,EAAc,GAAiB,GAA2B;CACjE,IAAMI,IAAmB,CAAC;CAC1B,KAAK,IAAMC,KAAKb,EAAE,OAAO;EACvB,IAAMc,IAAIC,EAAQN,GAAGI,CAAC;EACtB,EAAO,KAAKC,EAAE,GAAGA,EAAE,CAAC;CACtB;CACA,OAAOE,EAASJ,GAAQK,EAAYR,GAAGT,EAAE,MAAM,GAAGA,EAAE,MAAM;AAC5D"}
1
+ {"version":3,"file":"hitTestArea.js","names":["regionPickOptions","camera","view","alphaOf","layer","hitTestArea","AUTO_POSE_DESCRIPTOR","walkArea","scene","rectRegion","bounds","opts","descriptor","query","hitTestLassoPolygon","region","polygonRegion","polygon","mode","asInked","shape","filled","regionQuery","g","poseDescriptorForNode","node","pathIntersectsRect","clip","visualBoundsViaDescriptor","pose","r","b","regionBoundsOf","ink","findShapeInk","regionTakes","findShapeSilhouette","poseOutline","regionInPlane","m","regionInCopy","pickWalk","scenePickSource","coords","v","p","toPlane","regionOf","rectToPlane","x0","y0","x1","y1","x","y","applyToPoint","keepsAxes"],"sources":["../../../src/canvas/deps/hitTestArea.ts"],"sourcesContent":["/**\n * Silhouette-aware area hit-test for marquee and lasso selection.\n *\n * The per-node decision is `regionTakes` (`core/geometry/regionHit`). This\n * module supplies the scene walk and the node's drawn outline: the painter's\n * world-frame silhouette (`findShapeSilhouette`), or with no painter the pose\n * rect, rotated if the pose is.\n */\nimport type { Scene, NodeId } from 'core/scene/types';\nimport { applyToPoint, pathIntersectsRect, type Affine } from '@weasel-js/geom';\nimport type { LassoHitMode } from 'core/adapters/types';\nimport {\n poseDescriptorForNode,\n visualBoundsViaDescriptor,\n type PoseDescriptor,\n} from 'interactions/actions/resize/geometry';\nimport { AUTO_POSE_DESCRIPTOR } from 'core/geometry/autoPoseDescriptor';\nimport {\n pickWalk,\n scenePickSource,\n type PickQuery,\n type ScenePickSourceOptions,\n} from 'canvas/pickWalk';\nimport { rectToPlane, toPlane, type PlaneMap } from 'core/viewport/parallax';\n\nexport { hiddenLayerIds } from 'canvas/pickWalk';\nimport type { HitTestView } from 'interactions/actions/depSchema';\nimport { findShapeInk, findShapeSilhouette } from 'canvas/NodeShape';\nimport {\n polygonRegion,\n poseOutline,\n rectRegion,\n regionBoundsOf,\n regionOf,\n regionTakes,\n type SelectRegion,\n} from 'core/geometry/regionHit';\n\nexport interface AABBBounds {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/** What a region query takes back beyond leaves. */\nexport interface RegionQueryOptions {\n /** Default `false`: a region that takes a container and its children\n * selects the same ink twice. A bare-adapter consumer, which has nothing\n * to fold children back into their container, asks for them. */\n includeContainers?: boolean;\n}\n\n\n/** The pick options a region dep hands the shared walk: the asking view's\n * layer gate and camera, and the surface's alpha. */\nexport function regionPickOptions(\n view: HitTestView | undefined,\n alphaOf: ((id: string) => number) | undefined,\n): ScenePickSourceOptions<unknown> {\n const camera = view?.get?.();\n return {\n ...(alphaOf ? { alphaOf } : {}),\n ...(view?.layerIsPainted ? { layerIsPainted: (layer: string) => view.layerIsPainted!(layer) } : {}),\n ...(camera ? { camera } : {}),\n };\n}\n\n/** Marquee entry point: every node the rect `bounds` meets. */\nexport function hitTestArea(\n scene: Scene<unknown, string, unknown>,\n bounds: AABBBounds,\n opts?: ScenePickSourceOptions<unknown>,\n descriptor: PoseDescriptor<unknown> = AUTO_POSE_DESCRIPTOR,\n query: RegionQueryOptions = {},\n): NodeId[] {\n return walkArea(scene, rectRegion(bounds), 'intersect', opts, descriptor, query);\n}\n\n/**\n * Every node an arbitrary closed area polygon meets. `area` is interleaved\n * `[x0,y0,x1,y1,…]`; `areaBounds` is its AABB, derived when omitted.\n */\nexport function hitTestAreaPolygon(\n scene: Scene<unknown, string, unknown>,\n area: ArrayLike<number>,\n areaBounds?: AABBBounds,\n /** True when `area` IS its own bounding rect, so `areaBounds` containment\n * implies containment in the area proper. Never pass this for a lasso\n * polygon — a node inside the hull's box can miss the hull. */\n areaIsRect = false,\n /** The asking view's alpha and layer accessors. A bare scene answers for\n * itself; a view that dims or reorders layers has to supply its own. */\n opts?: ScenePickSourceOptions<unknown>,\n /** How to read this scene's poses. Default `AUTO_POSE_DESCRIPTOR`. */\n descriptor: PoseDescriptor<unknown> = AUTO_POSE_DESCRIPTOR,\n query: RegionQueryOptions = {},\n): NodeId[] {\n const region = regionOf(area, areaBounds, areaIsRect);\n return region ? walkArea(scene, region, 'intersect', opts, descriptor, query) : [];\n}\n\n/**\n * Lasso entry point: which nodes a closed lasso polygon picks under `mode`\n * (see `regionTakes`).\n */\nexport function hitTestLassoPolygon(\n scene: Scene<unknown, string, unknown>,\n polygon: ReadonlyArray<{ x: number; y: number }>,\n mode: LassoHitMode,\n opts?: ScenePickSourceOptions<unknown>,\n descriptor: PoseDescriptor<unknown> = AUTO_POSE_DESCRIPTOR,\n query: RegionQueryOptions = {},\n): NodeId[] {\n const region = polygonRegion(polygon);\n return region ? walkArea(scene, region, mode, opts, descriptor, query) : [];\n}\n\n/** `shape` as a region reads it: a polygon path's open subpaths enclose\n * nothing when the node's painter lays down no fill. */\nfunction asInked<T>(filled: () => boolean, shape: T): T {\n if ((shape as { kind?: unknown } | null)?.kind !== 'polygon') return shape;\n return filled() ? shape : { ...shape, openFill: 'none' };\n}\n\n/** The walk every region query shares: skip containers unless asked, gate on\n * the clip, and let `regionTakes` decide each node. */\nfunction walkArea(\n scene: Scene<unknown, string, unknown>,\n region: SelectRegion,\n mode: LassoHitMode,\n opts: ScenePickSourceOptions<unknown> | undefined,\n descriptor: PoseDescriptor<unknown>,\n query: RegionQueryOptions,\n): NodeId[] {\n const regionQuery = (r: SelectRegion): PickQuery<unknown> => ({\n includeContainers: query.includeContainers === true,\n clipAdmits: (clip, node, pose) => {\n const g = poseDescriptorForNode(descriptor, node);\n return pathIntersectsRect(clip, visualBoundsViaDescriptor(pose, g))\n && pathIntersectsRect(clip, r.bounds);\n },\n hits: (node, pose) => {\n // The descriptor sees the node here, so a pose shape whose extent\n // depends on `node.data` bounds itself rather than its pose's default.\n const g = poseDescriptorForNode(descriptor, node);\n const b = regionBoundsOf(node as object, pose, g);\n let ink: boolean | undefined;\n const filled = (): boolean => ink ??= findShapeInk(node as never, pose)?.filled !== false;\n return regionTakes(r, mode, asInked(filled, pose), b, () =>\n asInked(filled, findShapeSilhouette(node as never, pose) ?? poseOutline(pose, b)), filled);\n },\n inPlane: (m) => regionQuery(regionInPlane(r, m)),\n inCopy: (m) => regionQuery(regionInCopy(r, m)),\n });\n return pickWalk<unknown>(scenePickSource(scene, opts), regionQuery(region)) as NodeId[];\n}\n\n/** `r` carried into a plane's world. The map is axis-aligned, so a rect stays\n * one; a flipped axis reverses the winding, which no region test reads. */\nfunction regionInPlane(r: SelectRegion, m: PlaneMap): SelectRegion {\n const coords: number[] = [];\n for (const v of r.verts) {\n const p = toPlane(m, v);\n coords.push(p.x, p.y);\n }\n return regionOf(coords, rectToPlane(m, r.bounds), r.isRect)!;\n}\n\n/** `r` carried by an affine into a copy's source frame. A rect stays one only\n * while the map keeps the axes; a turn makes it a polygon. */\nfunction regionInCopy(r: SelectRegion, m: Affine): SelectRegion {\n const coords: number[] = [];\n let x0 = Infinity, y0 = Infinity, x1 = -Infinity, y1 = -Infinity;\n for (const v of r.verts) {\n const [x, y] = applyToPoint(m, v.x, v.y);\n coords.push(x, y);\n x0 = Math.min(x0, x); y0 = Math.min(y0, y); x1 = Math.max(x1, x); y1 = Math.max(y1, y);\n }\n const keepsAxes = (m[1] === 0 && m[2] === 0) || (m[0] === 0 && m[3] === 0);\n return regionOf(coords, { x: x0, y: y0, width: x1 - x0, height: y1 - y0 }, r.isRect && keepsAxes)!;\n}\n"],"mappings":";;;;;;;;AAwDA,SAAgBA,EACd,GACA,GACiC;CACjC,IAAMC,IAASC,GAAM,MAAM;CAC3B,OAAO;EACL,GAAIC,IAAU,EAAE,WAAQ,IAAI,CAAC;EAC7B,GAAID,GAAM,iBAAiB,EAAE,iBAAiB,MAAkBA,EAAK,eAAgBE,CAAK,EAAE,IAAI,CAAC;EACjG,GAAIH,IAAS,EAAE,UAAO,IAAI,CAAC;CAC7B;AACF;AAGA,SAAgBI,EACd,GACA,GACA,GACA,IAAsCC,GACtC,IAA4B,CAAC,GACnB;CACV,OAAOC,EAASC,GAAOC,EAAWC,CAAM,GAAG,aAAaC,GAAMC,GAAYC,CAAK;AACjF;AA6BA,SAAgBC,EACd,GACA,GACA,GACA,GACA,IAAsCR,GACtC,IAA4B,CAAC,GACnB;CACV,IAAMS,IAASC,EAAcC,CAAO;CACpC,OAAOF,IAASR,EAASC,GAAOO,GAAQG,GAAMP,GAAMC,GAAYC,CAAK,IAAI,CAAC;AAC5E;AAIA,SAASM,EAAW,GAAuB,GAAa;CAEtD,OADKC,GAAqC,SAAS,YAC5CC,EAAO,IAAID,IAAQ;EAAE,GAAGA;EAAO,UAAU;CAAO,IADcA;AAEvE;AAIA,SAASb,EACP,GACA,GACA,GACA,GACA,GACA,GACU;CACV,IAAMe,KAAe,OAAyC;EAC5D,mBAAmBT,EAAM,sBAAsB;EAC/C,aAAa,GAAM,GAAM,MAAS;GAChC,IAAMU,IAAIC,EAAsBZ,GAAYa,CAAI;GAChD,OAAOC,EAAmBC,GAAMC,EAA0BC,GAAMN,CAAC,CAAC,KAC7DG,EAAmBC,GAAMG,EAAE,MAAM;EACxC;EACA,OAAO,GAAM,MAAS;GAGpB,IAAMP,IAAIC,EAAsBZ,GAAYa,CAAI,GAC1CM,IAAIC,EAAeP,GAAgBI,GAAMN,CAAC,GAC5CU,GACEZ,UAAwB,MAAQa,EAAaT,GAAeI,CAAI,CAAC,EAAE,WAAW;GACpF,OAAOM,EAAYL,GAAGZ,GAAMC,EAAQE,GAAQQ,CAAI,GAAGE,SACjDZ,EAAQE,GAAQe,EAAoBX,GAAeI,CAAI,KAAKQ,EAAYR,GAAME,CAAC,CAAC,GAAGV,CAAM;EAC7F;EACA,UAAU,MAAMC,EAAYgB,EAAcR,GAAGS,CAAC,CAAC;EAC/C,SAAS,MAAMjB,EAAYkB,EAAaV,GAAGS,CAAC,CAAC;CAC/C;CACA,OAAOE,EAAkBC,EAAgBlC,GAAOG,CAAI,GAAGW,EAAYP,CAAM,CAAC;AAC5E;AAIA,SAASuB,EAAc,GAAiB,GAA2B;CACjE,IAAMK,IAAmB,CAAC;CAC1B,KAAK,IAAMC,KAAKd,EAAE,OAAO;EACvB,IAAMe,IAAIC,EAAQP,GAAGK,CAAC;EACtB,EAAO,KAAKC,EAAE,GAAGA,EAAE,CAAC;CACtB;CACA,OAAOE,EAASJ,GAAQK,EAAYT,GAAGT,EAAE,MAAM,GAAGA,EAAE,MAAM;AAC5D;AAIA,SAASU,EAAa,GAAiB,GAAyB;CAC9D,IAAMG,IAAmB,CAAC,GACtBM,IAAK,UAAUC,IAAK,UAAUC,IAAK,WAAWC,IAAK;CACvD,KAAK,IAAMR,KAAKd,EAAE,OAAO;EACvB,IAAM,CAACuB,GAAGC,KAAKC,EAAahB,GAAGK,EAAE,GAAGA,EAAE,CAAC;EAE2B,AADlED,EAAO,KAAKU,GAAGC,CAAC,GAChB,IAAK,KAAK,IAAIL,GAAII,CAAC,GAAG,IAAK,KAAK,IAAIH,GAAII,CAAC,GAAG,IAAK,KAAK,IAAIH,GAAIE,CAAC,GAAG,IAAK,KAAK,IAAID,GAAIE,CAAC;CACvF;CACA,IAAME,IAAajB,EAAE,OAAO,KAAKA,EAAE,OAAO,KAAOA,EAAE,OAAO,KAAKA,EAAE,OAAO;CACxE,OAAOQ,EAASJ,GAAQ;EAAE,GAAGM;EAAI,GAAGC;EAAI,OAAOC,IAAKF;EAAI,QAAQG,IAAKF;CAAG,GAAGpB,EAAE,UAAU0B,CAAS;AAClG"}
@@ -1,18 +1,20 @@
1
- import { insertPreviewExtent as e } from "../insertPreviewExtent.js";
2
- import { cycleFill as t, solid as n, strokeOf as r } from "../../util/paint.js";
3
- import { createInsertOp as i } from "../../core/ops/create.js";
4
- import { ellipsePath as a, linePath as o, polygonFromPoints as s, rectPath as c, regularPolygonPath as l, schneiderFit as u, starPath as d } from "@weasel-js/geom";
5
- import { useRef as f } from "react";
6
- import { useLatest as p } from "@weasel-js/react";
7
- import { useDepSource as m } from "@weasel-js/routing/react";
1
+ import { composeWorldPose as e, composesFrames as t } from "../../core/scene/composeFrame.js";
2
+ import { definesFrame as n } from "../../core/scene/effectivePose.js";
3
+ import { insertPreviewExtent as r } from "../insertPreviewExtent.js";
4
+ import { cycleFill as i, solid as a, strokeOf as o } from "../../util/paint.js";
5
+ import { createInsertOp as s } from "../../core/ops/create.js";
6
+ import { ellipsePath as c, linePath as l, polygonFromPoints as u, rectPath as d, regularPolygonPath as f, schneiderFit as p, starPath as m } from "@weasel-js/geom";
7
+ import { useRef as h } from "react";
8
+ import { useLatest as g } from "@weasel-js/react";
9
+ import { useDepRegistry as _, useDepSource as v } from "@weasel-js/routing/react";
8
10
  //#region src/canvas/deps/insert.ts
9
- function h({ fill: e, stroke: t }) {
11
+ function y({ fill: e, stroke: t }) {
10
12
  return {
11
13
  ...e === void 0 ? {} : { fill: e },
12
14
  ...t === void 0 ? {} : { stroke: t }
13
15
  };
14
16
  }
15
- function g(e, t) {
17
+ function b(e, t) {
16
18
  let n = e?.path;
17
19
  return t === void 0 || n === void 0 || !("fillRule" in n) ? e : {
18
20
  ...e,
@@ -22,134 +24,166 @@ function g(e, t) {
22
24
  }
23
25
  };
24
26
  }
25
- var _ = (e, i) => {
26
- let a = t(i);
27
- return e === "line" || e === "pencil" ? { stroke: r(a, 2) } : e === "path" ? {
28
- fill: { paint: n(a) },
29
- stroke: r(a, 2)
30
- } : { fill: { paint: n(a) } };
27
+ var x = (e, t) => {
28
+ let n = i(t);
29
+ return e === "line" || e === "pencil" ? { stroke: o(n, 2) } : e === "path" ? {
30
+ fill: { paint: a(n) },
31
+ stroke: o(n, 2)
32
+ } : { fill: { paint: a(n) } };
31
33
  };
32
- function v(t, n, r, v = _) {
33
- let y = p(t), b = p(n), x = p(r), S = p(v), C = f(0), w = f({ gesture: null });
34
- m("insertLive", () => w.current), m("insert", () => {
35
- let t = y.current, n = b.current, r = t.layers[0]?.id ?? "default", f = (n, f) => {
36
- let p = f.kind, m = ++C.current, _ = t.mintId(), v, y = (e = p) => h(v = S.current(e, m)), b = e({
37
- shape: p,
38
- bounds: n,
39
- extras: f
40
- }), w = b.bounds, T = x.current?.[p];
41
- if (T) {
42
- let e = T(n, f);
34
+ function S(e, t, n, r) {
35
+ switch (e) {
36
+ case "rect": return {
37
+ path: d(0, 0, t.width, t.height),
38
+ ...r()
39
+ };
40
+ case "ellipse": return {
41
+ path: c(t),
42
+ ...r()
43
+ };
44
+ case "path": {
45
+ let e = n;
46
+ return {
47
+ path: e.path,
48
+ ...r(),
49
+ ...e.closed ? {} : { fill: null }
50
+ };
51
+ }
52
+ case "text": return { text: n.text ?? "" };
53
+ case "image": {
54
+ let e = n;
55
+ return { image: {
56
+ src: e.src ?? "",
57
+ ...e.opacity === void 0 ? {} : { opacity: e.opacity }
58
+ } };
59
+ }
60
+ default: return null;
61
+ }
62
+ }
63
+ function C(r, i) {
64
+ let a = i == null ? void 0 : r.get(i);
65
+ if (a === void 0 || a.kind !== "container") return {
66
+ parent: null,
67
+ layer: r.layers[0]?.id ?? "default",
68
+ local: (e) => e
69
+ };
70
+ let o = r.composition;
71
+ if (o === void 0 || !t(o)) return {
72
+ parent: a.id,
73
+ layer: a.layer,
74
+ local: (e) => e
75
+ };
76
+ let s = e({
77
+ getPose: (e) => r.get(e).pose,
78
+ getParent: (e) => r.get(e)?.parent ?? null,
79
+ definesFrame: (e) => n(r.get(e) ?? {})
80
+ }, a.id, o.compose);
81
+ return {
82
+ parent: a.id,
83
+ layer: a.layer,
84
+ local: (e) => o.decompose(s, e)
85
+ };
86
+ }
87
+ function w(e, t, n, i = x) {
88
+ let a = g(e), o = g(t), c = g(n), w = g(i), T = _(), E = h(0), D = h({ gesture: null });
89
+ v("insertLive", () => D.current), v("insert", () => {
90
+ let e = a.current, t = o.current, n = () => C(e, T.get("insertInto")?.get()), i = (t, i) => {
91
+ let a = i.kind, { parent: o, layer: h, local: g } = n(), _ = ++E.current, v = e.mintId(), x, C = (e = a) => y(x = w.current(e, _)), T = r({
92
+ shape: a,
93
+ bounds: t,
94
+ extras: i
95
+ }), D = T.bounds, O = c.current?.[a];
96
+ if (O) {
97
+ let e = O(t, i);
43
98
  return e === null ? null : {
44
- id: _,
45
- ops: [i({
99
+ id: v,
100
+ ops: [s({
46
101
  node: {
47
- id: _,
102
+ id: v,
48
103
  kind: "leaf",
49
- layer: r,
50
- pose: e.pose ?? w,
104
+ layer: h,
105
+ parent: o,
106
+ pose: g(e.pose ?? D),
51
107
  data: e.data
52
108
  },
53
- label: `Insert ${p}`
109
+ label: `Insert ${a}`
54
110
  })]
55
111
  };
56
112
  }
57
- let E = b.geometry, D;
58
- switch (E.kind) {
113
+ let k = T.geometry, A;
114
+ switch (k.kind) {
59
115
  case "line":
60
- D = {
61
- path: o(E.a, E.b),
62
- ...y(),
116
+ A = {
117
+ path: l(k.a, k.b),
118
+ ...C(),
63
119
  fill: null
64
120
  };
65
121
  break;
66
122
  case "polygon":
67
- D = {
68
- path: l(E.center, E.radius, E.sides, E.rotation),
69
- ...y()
123
+ A = {
124
+ path: f(k.center, k.radius, k.sides, k.rotation),
125
+ generator: {
126
+ kind: "polygon",
127
+ sides: k.sides,
128
+ rotation: k.rotation
129
+ },
130
+ ...C()
70
131
  };
71
132
  break;
72
133
  case "star":
73
- D = {
74
- path: d(E.center, E.outerRadius, E.points, E.innerRadius, E.rotation),
75
- ...y()
134
+ A = {
135
+ path: m(k.center, k.outerRadius, k.points, k.innerRadius, k.rotation),
136
+ generator: {
137
+ kind: "star",
138
+ points: k.points,
139
+ innerRadiusRatio: k.outerRadius === 0 ? .5 : k.innerRadius / k.outerRadius,
140
+ rotation: k.rotation
141
+ },
142
+ ...C()
76
143
  };
77
144
  break;
78
145
  case "pencil": {
79
- let e = E.samples;
80
- D = e.length >= 4 ? {
81
- path: u(e, 2),
82
- ...y()
146
+ let e = k.samples;
147
+ A = e.length >= 4 ? {
148
+ path: p(e, 2),
149
+ ...C()
83
150
  } : e.length >= 2 ? {
84
- path: s(e),
85
- ...y()
151
+ path: u(e),
152
+ ...C()
86
153
  } : {
87
- path: c(0, 0, b.bounds.width, b.bounds.height),
88
- ...y("rect")
154
+ path: d(0, 0, T.bounds.width, T.bounds.height),
155
+ ...C("rect")
89
156
  };
90
157
  break;
91
158
  }
92
- case "box": switch (p) {
93
- case "rect":
94
- D = {
95
- path: c(0, 0, b.bounds.width, b.bounds.height),
96
- ...y()
97
- };
98
- break;
99
- case "ellipse":
100
- D = {
101
- path: a(b.bounds),
102
- ...y()
103
- };
104
- break;
105
- case "path": {
106
- let e = f;
107
- D = {
108
- path: e.path,
109
- ...y(),
110
- ...e.closed ? {} : { fill: null }
111
- };
112
- break;
113
- }
114
- case "text":
115
- D = { text: f.text ?? "" };
116
- break;
117
- case "image": {
118
- let e = f;
119
- D = { image: {
120
- src: e.src ?? "",
121
- ...e.opacity === void 0 ? {} : { opacity: e.opacity }
122
- } };
123
- break;
124
- }
125
- default: return console.warn(`weasel insertDep: no factory for kind="${p}". Skipping insert.`), null;
126
- }
159
+ case "box": if (A = S(a, T.bounds, i, C), A === null) return console.warn(`weasel insertDep: no factory for kind="${a}". Skipping insert.`), null;
127
160
  }
128
- return D = g(D, v?.fillRule), {
129
- id: _,
130
- ops: [i({
161
+ return A = b(A, x?.fillRule), {
162
+ id: v,
163
+ ops: [s({
131
164
  node: {
132
- id: _,
165
+ id: v,
133
166
  kind: "leaf",
134
- layer: r,
135
- pose: w,
136
- data: D
167
+ layer: h,
168
+ parent: o,
169
+ pose: g(D),
170
+ data: A
137
171
  },
138
- label: `Insert ${p}`
172
+ label: `Insert ${a}`
139
173
  })]
140
174
  };
141
175
  };
142
176
  return {
143
- layer: () => r,
144
- build: f,
145
- commit(e, t) {
146
- let r = f(e, t);
147
- return r === null ? null : (n.applyOps(r.ops, `Insert ${t.kind}`), r.id);
177
+ layer: () => n().layer,
178
+ build: i,
179
+ commit(e, n) {
180
+ let r = i(e, n);
181
+ return r === null ? null : (t.applyOps(r.ops, `Insert ${n.kind}`), r.id);
148
182
  }
149
183
  };
150
184
  });
151
185
  }
152
186
  //#endregion
153
- export { _ as paletteInsertPaint, v as useInsertDepSource };
187
+ export { x as paletteInsertPaint, w as useInsertDepSource };
154
188
 
155
189
  //# sourceMappingURL=insert.js.map