@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
@@ -0,0 +1,50 @@
1
+ import { toPlane as e } from "../../core/viewport/parallax.js";
2
+ import { findShapeInk as t, shapeCoversPoint as n } from "../NodeShape.js";
3
+ import { poseContains as r, poseContainsRotated as i } from "./poseGeometry.js";
4
+ import { applyToPoint as a, meanScale as o, pathContainsPoint as s } from "@weasel-js/geom";
5
+ //#region src/canvas/SceneCanvas/scenePointQuery.ts
6
+ function c(c, l, u) {
7
+ let d = (f, p, m) => {
8
+ let h = o(m), g = {
9
+ px: u,
10
+ scale: m
11
+ };
12
+ return {
13
+ hits: (e, a, o) => {
14
+ let s = l ? t(e, a, { scale: h }) : null, u = {
15
+ ...g,
16
+ px: g.px + (s?.outsetPx ?? 0),
17
+ reach: s?.outset ?? 0
18
+ };
19
+ return (o ? r(o, f, p, u, c) : i(a, f, p, u, c)) ? !l || n(e, a, f, p, {
20
+ tolerance: g,
21
+ scale: h,
22
+ derivedPath: o
23
+ }) : !1;
24
+ },
25
+ clipAdmits: (e) => s(e, f, p),
26
+ inPlane: (t) => {
27
+ let n = e(t, {
28
+ x: f,
29
+ y: p
30
+ });
31
+ return d(n.x, n.y, {
32
+ x: m.x / t.scale.x,
33
+ y: m.y / t.scale.y
34
+ });
35
+ },
36
+ inCopy: (e) => {
37
+ let [t, n] = a(e, f, p), r = Math.sqrt(Math.abs(e[0] * e[3] - e[1] * e[2]));
38
+ return d(t, n, {
39
+ x: m.x / r,
40
+ y: m.y / r
41
+ });
42
+ }
43
+ };
44
+ };
45
+ return d;
46
+ }
47
+ //#endregion
48
+ export { c as scenePointQuery };
49
+
50
+ //# sourceMappingURL=scenePointQuery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scenePointQuery.js","names":["scenePointQuery","pointQuery","scale","meanScale","s","tolerance","pickTolerancePx","ink","shapePicking","findShapeInk","n","pose","slop","derived","poseContains","px","py","d","poseContainsRotated","shapeCoversPoint","pathContainsPoint","clip","p","toPlane","m","x","y","applyToPoint","k"],"sources":["../../../src/canvas/SceneCanvas/scenePointQuery.ts"],"sourcesContent":["import { applyToPoint, meanScale, pathContainsPoint } from '@weasel-js/geom';\nimport type { PickQuery } from 'canvas/pickWalk';\nimport { findShapeInk, shapeCoversPoint } from 'canvas/NodeShape';\nimport { toPlane } from 'core/viewport/parallax';\nimport type { PoseDescriptor } from 'interactions/actions/resize/geometry';\nimport { poseContains, poseContainsRotated } from './poseGeometry';\n\n/** The point query `<SceneCanvas>`'s default pick asks: a world point with\n * `pickTolerancePx` of screen slop, refined to the painter's ink when\n * `shapePicking` is on. */\nexport function scenePointQuery<TPose>(\n d: PoseDescriptor<unknown>,\n shapePicking: boolean,\n pickTolerancePx: number,\n): (px: number, py: number, s: { x: number; y: number }) => PickQuery<TPose> {\n // `s` makes the slop a screen distance, so the grab zone stays the same\n // apparent thickness at any zoom and on every axis. A `{ px }` stroke's\n // reach is on screen too, and joins the slop there.\n const pointQuery = (px: number, py: number, s: { x: number; y: number }): PickQuery<TPose> => {\n const scale = meanScale(s);\n const tolerance = { px: pickTolerancePx, scale: s };\n return {\n hits: (n, pose, derived) => {\n // The pre-filter has to be at least as generous as the refinement\n // that follows it, or it rejects points the refinement would have\n // claimed. A stroke reaches past the pose box by `outset` — a whole\n // stroke width for an outer align — on top of the pointer slop.\n const ink = shapePicking ? findShapeInk(n as never, pose, { scale }) : null;\n // A derived node's pose is a placeholder — typically zero-sized at\n // the origin — so its own box rejects every point the path covers.\n // The path is the region to test instead, and `poseContains` already\n // reads a path-like pose as one.\n const slop = { ...tolerance, px: tolerance.px + (ink?.outsetPx ?? 0), reach: ink?.outset ?? 0 };\n const admitted = derived\n ? poseContains(derived as never, px, py, slop, d as PoseDescriptor<unknown>)\n : poseContainsRotated(pose, px, py, slop, d as PoseDescriptor<unknown>);\n if (!admitted) return false;\n // `shapeCoversPoint` narrows the rect to the ink the painter actually\n // lays down (and answers `true` for painters that have no silhouette,\n // so nothing becomes unpickable).\n return !shapePicking\n || shapeCoversPoint(n as never, pose, px, py, {\n tolerance, scale, derivedPath: derived,\n });\n },\n clipAdmits: (clip) => pathContainsPoint(clip, px, py),\n inPlane: (m) => {\n const p = toPlane(m, { x: px, y: py });\n return pointQuery(p.x, p.y, { x: s.x / m.scale.x, y: s.y / m.scale.y });\n },\n inCopy: (m) => {\n const [x, y] = applyToPoint(m, px, py);\n const k = Math.sqrt(Math.abs(m[0] * m[3] - m[1] * m[2]));\n return pointQuery(x, y, { x: s.x / k, y: s.y / k });\n },\n };\n };\n return pointQuery;\n}\n"],"mappings":";;;;;AAUA,SAAgBA,EACd,GACA,GACA,GAC2E;CAI3E,IAAMC,KAAc,GAAY,GAAY,MAAkD;EAC5F,IAAMC,IAAQC,EAAUC,CAAC,GACnBC,IAAY;GAAE,IAAIC;GAAiB,OAAOF;EAAE;EAClD,OAAO;GACL,OAAO,GAAG,GAAM,MAAY;IAK1B,IAAMG,IAAMC,IAAeC,EAAaC,GAAYC,GAAM,EAAE,SAAM,CAAC,IAAI,MAKjEC,IAAO;KAAE,GAAGP;KAAW,IAAIA,EAAU,MAAME,GAAK,YAAY;KAAI,OAAOA,GAAK,UAAU;IAAE;IAQ9F,QAPiBM,IACbC,EAAaD,GAAkBE,GAAIC,GAAIJ,GAAMK,CAA4B,IACzEC,EAAoBP,GAAMI,GAAIC,GAAIJ,GAAMK,CAA4B,KAKjE,CAACT,KACHW,EAAiBT,GAAYC,GAAMI,GAAIC,GAAI;KAC5C;KAAW;KAAO,aAAaH;IACjC,CAAC,IAPmB;GAQxB;GACA,aAAa,MAASO,EAAkBC,GAAMN,GAAIC,CAAE;GACpD,UAAU,MAAM;IACd,IAAMM,IAAIC,EAAQC,GAAG;KAAE,GAAGT;KAAI,GAAGC;IAAG,CAAC;IACrC,OAAOf,EAAWqB,EAAE,GAAGA,EAAE,GAAG;KAAE,GAAGlB,EAAE,IAAIoB,EAAE,MAAM;KAAG,GAAGpB,EAAE,IAAIoB,EAAE,MAAM;IAAE,CAAC;GACxE;GACA,SAAS,MAAM;IACb,IAAM,CAACC,GAAGC,KAAKC,EAAaH,GAAGT,GAAIC,CAAE,GAC/BY,IAAI,KAAK,KAAK,KAAK,IAAIJ,EAAE,KAAKA,EAAE,KAAKA,EAAE,KAAKA,EAAE,EAAE,CAAC;IACvD,OAAOvB,EAAWwB,GAAGC,GAAG;KAAE,GAAGtB,EAAE,IAAIwB;KAAG,GAAGxB,EAAE,IAAIwB;IAAE,CAAC;GACpD;EACF;CACF;CACA,OAAO3B;AACT"}
@@ -0,0 +1,52 @@
1
+ import { SHAPE_COUNT_RANGE as e, STAR_RATIO_RANGE as t } from "../../features/paths/shapeGenerator.js";
2
+ import { decimal as n } from "@weasel-js/quantity";
3
+ //#region src/canvas/SceneCanvas/shapeGeneratorProperties.ts
4
+ var r = n({
5
+ maxPlaces: 2,
6
+ grouping: !1
7
+ }), i = {
8
+ polygon: {
9
+ name: "Polygon",
10
+ showIf: { path: "data.generator.sides" },
11
+ members: { "data.generator.sides": {
12
+ kind: "number",
13
+ display: r,
14
+ name: "Sides",
15
+ description: "Number of sides.",
16
+ default: 6,
17
+ min: e.min,
18
+ max: e.max,
19
+ step: 1
20
+ } }
21
+ },
22
+ star: {
23
+ name: "Star",
24
+ showIf: { path: "data.generator.points" },
25
+ members: {
26
+ "data.generator.points": {
27
+ kind: "number",
28
+ display: r,
29
+ name: "Points",
30
+ description: "Number of points.",
31
+ default: 5,
32
+ min: e.min,
33
+ max: e.max,
34
+ step: 1
35
+ },
36
+ "data.generator.innerRadiusRatio": {
37
+ kind: "number",
38
+ name: "Inner",
39
+ description: "Inner radius as a fraction of the outer one.",
40
+ default: .5,
41
+ min: t.min,
42
+ max: t.max,
43
+ step: .01,
44
+ control: "slider"
45
+ }
46
+ }
47
+ }
48
+ };
49
+ //#endregion
50
+ export { i as SHAPE_GENERATOR_SECTIONS };
51
+
52
+ //# sourceMappingURL=shapeGeneratorProperties.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shapeGeneratorProperties.js","names":["WHOLE","decimal","SHAPE_GENERATOR_SECTIONS","SHAPE_COUNT_RANGE","STAR_RATIO_RANGE"],"sources":["../../../src/canvas/SceneCanvas/shapeGeneratorProperties.ts"],"sourcesContent":["import type { PrefSection } from '@weasel-js/prefs';\nimport { decimal } from '@weasel-js/quantity';\nimport { SHAPE_COUNT_RANGE, STAR_RATIO_RANGE } from 'features/paths/shapeGenerator';\n\nconst WHOLE = decimal({ maxPlaces: 2, grouping: false });\n\n/**\n * The rows that edit a polygon's or a star's `data.generator`, each shown only\n * on a node holding that kind's generator. A write to one regenerates the\n * shape through the entry's `settle` (`settleShapeGenerator`).\n */\nexport const SHAPE_GENERATOR_SECTIONS: Record<string, PrefSection> = {\n polygon: {\n name: 'Polygon',\n showIf: { path: 'data.generator.sides' },\n members: {\n 'data.generator.sides': {\n kind: 'number', display: WHOLE, name: 'Sides', description: 'Number of sides.',\n default: 6, min: SHAPE_COUNT_RANGE.min, max: SHAPE_COUNT_RANGE.max, step: 1,\n },\n },\n },\n star: {\n name: 'Star',\n showIf: { path: 'data.generator.points' },\n members: {\n 'data.generator.points': {\n kind: 'number', display: WHOLE, name: 'Points', description: 'Number of points.',\n default: 5, min: SHAPE_COUNT_RANGE.min, max: SHAPE_COUNT_RANGE.max, step: 1,\n },\n 'data.generator.innerRadiusRatio': {\n kind: 'number', name: 'Inner', description: 'Inner radius as a fraction of the outer one.',\n default: 0.5, min: STAR_RATIO_RANGE.min, max: STAR_RATIO_RANGE.max, step: 0.01, control: 'slider',\n },\n },\n },\n};\n"],"mappings":";;;AAIA,IAAMA,IAAQC,EAAQ;CAAE,WAAW;CAAG,UAAU;AAAM,CAAC,GAO1CC,IAAwD;CACnE,SAAS;EACP,MAAM;EACN,QAAQ,EAAE,MAAM,uBAAuB;EACvC,SAAS,EACP,wBAAwB;GACtB,MAAM;GAAU,SAASF;GAAO,MAAM;GAAS,aAAa;GAC5D,SAAS;GAAG,KAAKG,EAAkB;GAAK,KAAKA,EAAkB;GAAK,MAAM;EAC5E,EACF;CACF;CACA,MAAM;EACJ,MAAM;EACN,QAAQ,EAAE,MAAM,wBAAwB;EACxC,SAAS;GACP,yBAAyB;IACvB,MAAM;IAAU,SAASH;IAAO,MAAM;IAAU,aAAa;IAC7D,SAAS;IAAG,KAAKG,EAAkB;IAAK,KAAKA,EAAkB;IAAK,MAAM;GAC5E;GACA,mCAAmC;IACjC,MAAM;IAAU,MAAM;IAAS,aAAa;IAC5C,SAAS;IAAK,KAAKC,EAAiB;IAAK,KAAKA,EAAiB;IAAK,MAAM;IAAM,SAAS;GAC3F;EACF;CACF;AACF"}
@@ -0,0 +1,17 @@
1
+ import { useEffect as e } from "react";
2
+ import { useActionsRegistry as t } from "@weasel-js/routing/react";
3
+ //#region src/canvas/SceneCanvas/useActionTunings.ts
4
+ function n(n) {
5
+ let r = t();
6
+ e(() => {
7
+ if (!r || !n) return;
8
+ let e = Object.entries(n).flatMap(([e, t]) => t ? [r.tune(e, t)] : []);
9
+ return () => {
10
+ for (let t of e) t();
11
+ };
12
+ }, [r, n]);
13
+ }
14
+ //#endregion
15
+ export { n as useActionTunings };
16
+
17
+ //# sourceMappingURL=useActionTunings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useActionTunings.js","names":["useActionTunings","reg","useActionsRegistry","tune","releases","id","release"],"sources":["../../../src/canvas/SceneCanvas/useActionTunings.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport type { ActionTuning, ActionTunings } from '@weasel-js/routing';\nimport { useActionsRegistry } from '@weasel-js/routing/react';\n\n/** Hold `tune`'s tunings on the registry in scope for as long as the object\n * is the same one. */\nexport function useActionTunings(tune: ActionTunings | undefined): void {\n const reg = useActionsRegistry();\n useEffect(() => {\n if (!reg || !tune) return;\n const releases = Object.entries(tune).flatMap(([id, t]) => (t ? [reg.tune(id, t as ActionTuning)] : []));\n return () => { for (const release of releases) release(); };\n }, [reg, tune]);\n}\n"],"mappings":";;;AAMA,SAAgBA,EAAiB,GAAuC;CACtE,IAAMC,IAAMC,EAAmB;CAC/B,QAAgB;EACd,IAAI,CAACD,KAAO,CAACE,GAAM;EACnB,IAAMC,IAAW,OAAO,QAAQD,CAAI,CAAC,CAAC,SAAS,CAACE,GAAI,OAAQ,IAAI,CAACJ,EAAI,KAAKI,GAAI,CAAiB,CAAC,IAAI,CAAC,CAAE;EACvG,aAAa;GAAE,KAAK,IAAMC,KAAWF,GAAU,EAAQ;EAAG;CAC5D,GAAG,CAACH,GAAKE,CAAI,CAAC;AAChB"}
@@ -1,38 +1,46 @@
1
- import { useViewAnimationOn as e } from "../../core/viewport/useViewAnimation.js";
2
- import { useCanvasView as t } from "../useCanvasView.js";
3
- import { useInsertionEffect as n, useMemo as r, useRef as i } from "react";
4
- import { useLatest as a } from "@weasel-js/react";
5
- import { useAnimator as o } from "@weasel-js/animator";
1
+ import { sameView as e } from "../../core/viewport/view.js";
2
+ import { useViewAnimationOn as t } from "../../core/viewport/useViewAnimation.js";
3
+ import { useCanvasView as n } from "../useCanvasView.js";
4
+ import { useInsertionEffect as r, useMemo as i, useRef as a } from "react";
5
+ import { useLatest as o } from "@weasel-js/react";
6
+ import { useAnimator as s } from "@weasel-js/animator";
6
7
  //#region src/canvas/SceneCanvas/useCanvasCamera.ts
7
- function s(s) {
8
- let { view: c, defaultView: l, onViewChange: u, viewBounds: d, width: f, height: p, requestRedraw: m } = s, h = a({
9
- width: f,
10
- height: p
11
- }), g = i(null), _ = t({
12
- view: c,
13
- defaultView: l,
8
+ function c(c) {
9
+ let { view: l, defaultView: u, onViewChange: d, viewBounds: f, width: p, height: m, requestRedraw: h } = c, g = o({
10
+ width: p,
11
+ height: m
12
+ }), _ = a(null), v = a(!1), y = n({
13
+ view: l,
14
+ defaultView: u,
14
15
  onViewChange: (e) => {
15
- g.current?.stopIfExternal(), u?.(e);
16
+ _.current?.stopIfExternal(), d?.(e);
16
17
  },
17
- viewBounds: d,
18
- dims: () => h.current,
19
- requestRedraw: m
20
- }), v = o(), { viewRef: y, setViewFromInput: b } = _, x = r(() => ({
21
- get: () => y.current,
22
- set: b
23
- }), [y, b]), S = e(x, v);
24
- return n(() => {
25
- g.current = S;
18
+ viewBounds: f,
19
+ dims: () => g.current,
20
+ requestRedraw: h
21
+ }), b = s(), { viewRef: x, setViewFromInput: S, controlled: C } = y, w = i(() => ({
22
+ get: () => x.current,
23
+ set: (e) => {
24
+ v.current = !0, S(e);
25
+ }
26
+ }), [x, S]), T = t(w, b);
27
+ r(() => {
28
+ _.current = T;
29
+ });
30
+ let E = a(C);
31
+ return r(() => {
32
+ let t = E.current;
33
+ E.current = C, C && t && !e(t, C) && (v.current ? v.current = !1 : T.stopIfExternal());
26
34
  }), {
27
- viewState: _,
28
- viewAnimation: S,
29
- camera: r(() => ({
30
- target: S.viewTarget,
31
- animator: v
32
- }), [S, v])
35
+ viewState: y,
36
+ viewAnimation: T,
37
+ camera: i(() => ({
38
+ target: T.viewTarget,
39
+ animator: b
40
+ }), [T, b])
33
41
  };
34
42
  }
35
43
  //#endregion
36
- export { s as useCanvasCamera };
44
+ export { c as useCanvasCamera };
37
45
 
38
46
  //# sourceMappingURL=useCanvasCamera.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useCanvasCamera.js","names":["useCanvasCamera","opts","size","useLatest","animationRef","useRef","viewState","useCanvasView","onViewChange","next","animator","useAnimator","channel","useMemo","viewRef","setViewFromInput","viewAnimation","useViewAnimationOn","useInsertionEffect"],"sources":["../../../src/canvas/SceneCanvas/useCanvasCamera.ts"],"sourcesContent":["import { useInsertionEffect, useMemo, useRef } from 'react';\nimport { useAnimator } from '@weasel-js/animator';\nimport { useLatest } from '@weasel-js/react';\nimport { useViewAnimationOn, type ViewAnimationApi } from 'core/viewport/useViewAnimation';\nimport type { SceneCanvasApi } from '../canvasExtension';\nimport { useCanvasView, type CameraProps, type CanvasViewState } from '../useCanvasView';\n\n/**\n * The canvas's camera: the view `<Canvas>` looks through, the runner behind\n * `animateView`, and the target and animator it runs on.\n */\nexport function useCanvasCamera(opts: CameraProps & {\n /** The size the camera looks through, which `viewBounds` clamps against. */\n width: number;\n height: number;\n requestRedraw: () => void;\n}): {\n viewState: CanvasViewState;\n viewAnimation: ViewAnimationApi;\n camera: SceneCanvasApi['camera'];\n} {\n const { view, defaultView, onViewChange, viewBounds, width, height, requestRedraw } = opts;\n const size = useLatest({ width, height });\n const animationRef = useRef<ViewAnimationApi | null>(null);\n const viewState = useCanvasView({\n view,\n defaultView,\n // Every write to the view is reported here, so it is the runner's one\n // interrupt feed.\n onViewChange: (next) => {\n animationRef.current?.stopIfExternal();\n onViewChange?.(next);\n },\n viewBounds,\n dims: () => size.current,\n requestRedraw,\n });\n\n // The camera runs on its own animator, never the `animator` prop's: that prop\n // is the consumer's scene animator, and their `cancelAll()` or `pause()` must\n // not strand a zoom half-finished or freeze the camera.\n const animator = useAnimator();\n const { viewRef, setViewFromInput } = viewState;\n const channel = useMemo(\n () => ({ get: () => viewRef.current, set: setViewFromInput }),\n [viewRef, setViewFromInput],\n );\n const viewAnimation = useViewAnimationOn(channel, animator);\n useInsertionEffect(() => { animationRef.current = viewAnimation; });\n const camera = useMemo(() => ({ target: viewAnimation.viewTarget, animator }), [viewAnimation, animator]);\n return { viewState, viewAnimation, camera };\n}\n"],"mappings":";;;;;;AAWA,SAAgBA,EAAgB,GAS9B;CACA,IAAM,EAAE,SAAM,gBAAa,iBAAc,eAAY,UAAO,WAAQ,qBAAkBC,GAChFC,IAAOC,EAAU;EAAE;EAAO;CAAO,CAAC,GAClCC,IAAeC,EAAgC,IAAI,GACnDC,IAAYC,EAAc;EAC9B;EACA;EAGA,eAAe,MAAS;GAEtB,AADAH,EAAa,SAAS,eAAe,GACrCI,IAAeC,CAAI;EACrB;EACA;EACA,YAAYP,EAAK;EACjB;CACF,CAAC,GAKKQ,IAAWC,EAAY,GACvB,EAAE,YAAS,wBAAqBL,GAChCM,IAAUC,SACP;EAAE,WAAWC,EAAQ;EAAS,KAAKC;CAAiB,IAC3D,CAACD,GAASC,CAAgB,CAC5B,GACMC,IAAgBC,EAAmBL,GAASF,CAAQ;CAG1D,OAFAQ,QAAyB;EAAE,EAAa,UAAUF;CAAe,CAAC,GAE3D;EAAE;EAAW;EAAe,QADpBH,SAAe;GAAE,QAAQG,EAAc;GAAY;EAAS,IAAI,CAACA,GAAeN,CAAQ,CACpE;CAAO;AAC5C"}
1
+ {"version":3,"file":"useCanvasCamera.js","names":["useCanvasCamera","opts","size","useLatest","animationRef","useRef","runnerWroteRef","viewState","useCanvasView","onViewChange","next","animator","useAnimator","channel","useMemo","viewRef","setViewFromInput","viewAnimation","useViewAnimationOn","lastControlledRef","controlled","useInsertionEffect","was"],"sources":["../../../src/canvas/SceneCanvas/useCanvasCamera.ts"],"sourcesContent":["import { useInsertionEffect, useMemo, useRef } from 'react';\nimport { useAnimator } from '@weasel-js/animator';\nimport { useLatest } from '@weasel-js/react';\nimport { useViewAnimationOn, type ViewAnimationApi } from 'core/viewport/useViewAnimation';\nimport { sameView, type View } from 'core/viewport/view';\nimport type { SceneCanvasApi } from '../canvasExtension';\nimport { useCanvasView, type CameraProps, type CanvasViewState } from '../useCanvasView';\n\n/**\n * The canvas's camera: the view `<Canvas>` looks through, the runner behind\n * `animateView`, and the target and animator it runs on.\n */\nexport function useCanvasCamera(opts: CameraProps & {\n /** The size the camera looks through, which `viewBounds` clamps against. */\n width: number;\n height: number;\n requestRedraw: () => void;\n}): {\n viewState: CanvasViewState;\n viewAnimation: ViewAnimationApi;\n camera: SceneCanvasApi['camera'];\n} {\n const { view, defaultView, onViewChange, viewBounds, width, height, requestRedraw } = opts;\n const size = useLatest({ width, height });\n const animationRef = useRef<ViewAnimationApi | null>(null);\n /** The runner has written a frame since the controlled view last moved. */\n const runnerWroteRef = useRef(false);\n const viewState = useCanvasView({\n view,\n defaultView,\n // Every write to the view is reported here, so it is the runner's one\n // interrupt feed.\n onViewChange: (next) => {\n animationRef.current?.stopIfExternal();\n onViewChange?.(next);\n },\n viewBounds,\n dims: () => size.current,\n requestRedraw,\n });\n\n // The camera runs on its own animator, never the `animator` prop's: that prop\n // is the consumer's scene animator, and their `cancelAll()` or `pause()` must\n // not strand a zoom half-finished or freeze the camera.\n const animator = useAnimator();\n const { viewRef, setViewFromInput, controlled } = viewState;\n const channel = useMemo(\n () => ({\n get: () => viewRef.current,\n set: (next: View) => {\n runnerWroteRef.current = true;\n setViewFromInput(next);\n },\n }),\n [viewRef, setViewFromInput],\n );\n const viewAnimation = useViewAnimationOn(channel, animator);\n useInsertionEffect(() => { animationRef.current = viewAnimation; });\n\n // A controlled consumer writing `view` in their own state never passes\n // through `onViewChange`. Their handling of a frame cannot be told from such\n // a write by value, since they may clamp or round what they are handed, so it\n // is told by order: a prop that moves with no frame written since it last\n // moved is theirs. One that lands in the same render as a frame's is missed.\n const lastControlledRef = useRef(controlled);\n useInsertionEffect(() => {\n const was = lastControlledRef.current;\n lastControlledRef.current = controlled;\n if (!controlled || !was || sameView(was, controlled)) return;\n if (runnerWroteRef.current) runnerWroteRef.current = false;\n else viewAnimation.stopIfExternal();\n });\n const camera = useMemo(() => ({ target: viewAnimation.viewTarget, animator }), [viewAnimation, animator]);\n return { viewState, viewAnimation, camera };\n}\n"],"mappings":";;;;;;;AAYA,SAAgBA,EAAgB,GAS9B;CACA,IAAM,EAAE,SAAM,gBAAa,iBAAc,eAAY,UAAO,WAAQ,qBAAkBC,GAChFC,IAAOC,EAAU;EAAE;EAAO;CAAO,CAAC,GAClCC,IAAeC,EAAgC,IAAI,GAEnDC,IAAiBD,EAAO,EAAK,GAC7BE,IAAYC,EAAc;EAC9B;EACA;EAGA,eAAe,MAAS;GAEtB,AADAJ,EAAa,SAAS,eAAe,GACrCK,IAAeC,CAAI;EACrB;EACA;EACA,YAAYR,EAAK;EACjB;CACF,CAAC,GAKKS,IAAWC,EAAY,GACvB,EAAE,YAAS,qBAAkB,kBAAeL,GAC5CM,IAAUC,SACP;EACL,WAAWC,EAAQ;EACnB,MAAM,MAAe;GAEnB,AADA,EAAe,UAAU,IACzBC,EAAiBN,CAAI;EACvB;CACF,IACA,CAACK,GAASC,CAAgB,CAC5B,GACMC,IAAgBC,EAAmBL,GAASF,CAAQ;CAC1D,QAAyB;EAAE,EAAa,UAAUM;CAAe,CAAC;CAOlE,IAAME,IAAoBd,EAAOe,CAAU;CAS3C,OARAC,QAAyB;EACvB,IAAMC,IAAMH,EAAkB;EAE9B,AADA,EAAkB,UAAUC,GACvBA,KAAeE,KAAO,GAASA,GAAKF,CAAU,MAC/Cd,EAAe,UAAS,EAAe,UAAU,KAChDW,EAAc,eAAe;CACpC,CAAC,GAEM;EAAE;EAAW;EAAe,QADpBH,SAAe;GAAE,QAAQG,EAAc;GAAY;EAAS,IAAI,CAACA,GAAeN,CAAQ,CACpE;CAAO;AAC5C"}
@@ -1,20 +1,20 @@
1
1
  import { createDispatcherPreviewSources as e, createGestureSource as t } from "./dispatcherGestureBounds.js";
2
2
  import { useRef as n, useState as r } from "react";
3
- import { createDispatcher as i } from "@weasel-js/routing";
3
+ import { useLatest as i } from "@weasel-js/react";
4
+ import { createDispatcher as a } from "@weasel-js/routing";
4
5
  //#region src/canvas/SceneCanvas/useCanvasDispatcher.ts
5
- function a() {
6
- let a = n(null), o = n(null);
7
- o.current ||= i({ getAction: (e) => a.current?.(e) });
8
- let s = o.current, [c] = r(() => t(() => o.current)), [{ previewIdsExtra: l, previewPoseExtra: u }] = r(() => e(() => o.current));
6
+ function o(o) {
7
+ let s = i(o), c = n(null);
8
+ c.current ||= a({ getAction: (e) => s.current?.list().find((t) => t.id === e) });
9
+ let l = c.current, [u] = r(() => t(() => c.current)), [{ previewIdsExtra: d, previewPoseExtra: f }] = r(() => e(() => c.current));
9
10
  return {
10
- dispatcher: s,
11
- getActionRef: a,
12
- gestureSource: c,
13
- previewIdsExtra: l,
14
- previewPoseExtra: u
11
+ dispatcher: l,
12
+ gestureSource: u,
13
+ previewIdsExtra: d,
14
+ previewPoseExtra: f
15
15
  };
16
16
  }
17
17
  //#endregion
18
- export { a as useCanvasDispatcher };
18
+ export { o as useCanvasDispatcher };
19
19
 
20
20
  //# sourceMappingURL=useCanvasDispatcher.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useCanvasDispatcher.js","names":["useCanvasDispatcher","getActionRef","useRef","dispatcherRef","createDispatcher","id","dispatcher","gestureSource","useState","createGestureSource","createDispatcherPreviewSources"],"sources":["../../../src/canvas/SceneCanvas/useCanvasDispatcher.ts"],"sourcesContent":["import { useRef, useState, type MutableRefObject } from 'react';\nimport { createDispatcher, type Action, type Dispatcher } from '@weasel-js/routing';\nimport type { GestureSource } from '../gestureBounds';\nimport { createDispatcherPreviewSources, createGestureSource } from './dispatcherGestureBounds';\n\n/**\n * One `Dispatcher` for the life of a `<SceneCanvas>`, shared by the gesture\n * mounter that pumps input into it and the layers that walk its in-flight\n * handles, with the lookups those layers and `<Canvas>` read it through.\n */\nexport function useCanvasDispatcher(): {\n dispatcher: Dispatcher;\n /** How the dispatcher resolves an action id at call time. Populated by\n * `StandardActionsRegistrar` once it has the registry in scope. */\n getActionRef: MutableRefObject<((id: string) => Action | undefined) | null>;\n /** In-flight preview ids, nascent-insert bounds, and the pump signal. */\n gestureSource: GestureSource;\n /** Ids whose committed paint an in-flight ghost hides. */\n previewIdsExtra: () => string[];\n /** The pose an in-flight handle proposes for an id. */\n previewPoseExtra: (id: string) => unknown;\n} {\n const getActionRef = useRef<((id: string) => Action | undefined) | null>(null);\n const dispatcherRef = useRef<Dispatcher | null>(null);\n if (!dispatcherRef.current) {\n dispatcherRef.current = createDispatcher({\n getAction: (id) => getActionRef.current?.(id),\n });\n }\n const dispatcher = dispatcherRef.current;\n const [gestureSource] = useState(() => createGestureSource(() => dispatcherRef.current));\n const [{ previewIdsExtra, previewPoseExtra }] = useState(\n () => createDispatcherPreviewSources(() => dispatcherRef.current),\n );\n return { dispatcher, getActionRef, gestureSource, previewIdsExtra, previewPoseExtra };\n}\n"],"mappings":";;;;AAUA,SAAgBA,IAWd;CACA,IAAMC,IAAeC,EAAoD,IAAI,GACvEC,IAAgBD,EAA0B,IAAI;CACpD,AACEC,EAAc,YAAUC,EAAiB,EACvC,YAAY,MAAOH,EAAa,UAAUI,CAAE,EAC9C,CAAC;CAEH,IAAMC,IAAaH,EAAc,SAC3B,CAACI,KAAiBC,QAAeC,QAA0BN,EAAc,OAAO,CAAC,GACjF,CAAC,EAAE,oBAAiB,yBAAsBK,QACxCE,QAAqCP,EAAc,OAAO,CAClE;CACA,OAAO;EAAE;EAAY;EAAc;EAAe;EAAiB;CAAiB;AACtF"}
1
+ {"version":3,"file":"useCanvasDispatcher.js","names":["useCanvasDispatcher","registryRef","useLatest","registry","dispatcherRef","useRef","createDispatcher","a","id","dispatcher","gestureSource","useState","createGestureSource","createDispatcherPreviewSources"],"sources":["../../../src/canvas/SceneCanvas/useCanvasDispatcher.ts"],"sourcesContent":["import { useRef, useState } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport { createDispatcher, type ActionsRegistry, type Dispatcher } from '@weasel-js/routing';\nimport type { GestureSource } from '../gestureBounds';\nimport { createDispatcherPreviewSources, createGestureSource } from './dispatcherGestureBounds';\n\n/**\n * One `Dispatcher` for the life of a `<SceneCanvas>`, shared by the gesture\n * mounter that pumps input into it and the layers that walk its in-flight\n * handles, with the lookups those layers and `<Canvas>` read it through. It\n * resolves an action id in `registry`, read at call time.\n */\nexport function useCanvasDispatcher(registry: ActionsRegistry | null): {\n dispatcher: Dispatcher;\n /** In-flight preview ids, nascent-insert bounds, and the pump signal. */\n gestureSource: GestureSource;\n /** Ids whose committed paint an in-flight ghost hides. */\n previewIdsExtra: () => string[];\n /** The pose an in-flight handle proposes for an id. */\n previewPoseExtra: (id: string) => unknown;\n} {\n const registryRef = useLatest(registry);\n const dispatcherRef = useRef<Dispatcher | null>(null);\n if (!dispatcherRef.current) {\n dispatcherRef.current = createDispatcher({\n getAction: (id) => registryRef.current?.list().find((a) => a.id === id),\n });\n }\n const dispatcher = dispatcherRef.current;\n const [gestureSource] = useState(() => createGestureSource(() => dispatcherRef.current));\n const [{ previewIdsExtra, previewPoseExtra }] = useState(\n () => createDispatcherPreviewSources(() => dispatcherRef.current),\n );\n return { dispatcher, gestureSource, previewIdsExtra, previewPoseExtra };\n}\n"],"mappings":";;;;;AAYA,SAAgBA,EAAoB,GAQlC;CACA,IAAMC,IAAcC,EAAUC,CAAQ,GAChCC,IAAgBC,EAA0B,IAAI;CACpD,AACED,EAAc,YAAUE,EAAiB,EACvC,YAAY,MAAOL,EAAY,SAAS,KAAK,CAAC,CAAC,MAAM,MAAMM,EAAE,OAAOC,CAAE,EACxE,CAAC;CAEH,IAAMC,IAAaL,EAAc,SAC3B,CAACM,KAAiBC,QAAeC,QAA0BR,EAAc,OAAO,CAAC,GACjF,CAAC,EAAE,oBAAiB,yBAAsBO,QACxCE,QAAqCT,EAAc,OAAO,CAClE;CACA,OAAO;EAAE;EAAY;EAAe;EAAiB;CAAiB;AACxE"}
@@ -3,126 +3,62 @@ import { worldToScreen as t } from "../../core/viewport/viewTransform.js";
3
3
  import { OVERLAY_ROLE_STROKES as n } from "../overlayRoleStrokes.js";
4
4
  import { gestureOverlaysFrom as r, isVisibleFrom as i } from "../drawEnvelope.js";
5
5
  import { resolveOverlays as a } from "../../interactions/actions/resolveOverlays.js";
6
- import { getImageBitmap as o } from "@weasel-js/renderer";
7
- import { ellipsePath as s, linePath as c, polygonFromPoints as l, polylineFromPoints as u, rectPath as d, regularPolygonPath as f, starPath as p } from "@weasel-js/geom";
8
- import { useEffect as m, useMemo as h, useReducer as g } from "react";
9
- import { useLatest as _ } from "@weasel-js/react";
6
+ import { insertPreviewCommands as o } from "./insertPreviewCommands.js";
7
+ import { polygonFromPoints as s, polylineFromPoints as c } from "@weasel-js/geom";
8
+ import { useEffect as l, useMemo as u, useReducer as d } from "react";
9
+ import { useLatest as f } from "@weasel-js/react";
10
10
  //#region src/canvas/SceneCanvas/useDispatcherOverlayLayer.ts
11
- var v = {
11
+ var p = {
12
12
  fill: "rgba(164, 139, 212, 0.18)",
13
13
  stroke: "#a48bd4",
14
14
  dash: [3, 3],
15
15
  lineWidth: 1
16
- }, y = .85;
17
- function b(b) {
18
- let { dispatcher: x, style: S } = b, C = _(S), [, w] = g((e) => e + 1, 0);
19
- return m(() => {
20
- if (x) return x.subscribe(w);
21
- }, [x]), h(() => ({
16
+ };
17
+ function m(m) {
18
+ let { dispatcher: h, style: g } = m, _ = f(g), [, v] = d((e) => e + 1, 0);
19
+ return l(() => {
20
+ if (h) return h.subscribe(v);
21
+ }, [h]), u(() => ({
22
22
  id: "dispatcher-overlay",
23
23
  label: "Dispatcher overlay",
24
24
  space: "screen",
25
- draw: (m, h) => {
26
- let g = {
27
- ...v,
28
- ...C.current ?? {}
29
- }, _ = {
25
+ draw: (l, u) => {
26
+ let d = {
27
+ ...p,
28
+ ..._.current ?? {}
29
+ }, f = {
30
30
  ...n,
31
- ...C.current?.roles ?? {}
32
- }, b = e(h), x = [], S = i(m), w = (e) => !S || S(e);
33
- for (let e of a(r(m))) if (w(e.visibilityId)) {
31
+ ..._.current?.roles ?? {}
32
+ }, m = e(u), h = [], g = i(l), v = (e) => !g || g(e);
33
+ for (let e of a(r(l))) if (v(e.visibilityId)) {
34
34
  if (e.kind === "marquee") {
35
- let n = e.bounds, [r, i] = t(n.x, n.y, b), a = {
35
+ let n = e.bounds, [r, i] = t(n.x, n.y, m), a = {
36
36
  kind: "path",
37
37
  path: {
38
38
  kind: "rect",
39
39
  x: r,
40
40
  y: i,
41
- width: n.width * h.scale.x,
42
- height: n.height * h.scale.y
41
+ width: n.width * u.scale.x,
42
+ height: n.height * u.scale.y
43
43
  },
44
- fill: { paint: { color: g.fill } },
44
+ fill: { paint: { color: d.fill } },
45
45
  stroke: {
46
- paint: { color: g.stroke },
47
- width: g.lineWidth,
48
- dash: g.dash
46
+ paint: { color: d.stroke },
47
+ width: d.lineWidth,
48
+ dash: d.dash
49
49
  }
50
50
  };
51
- x.push(a);
51
+ h.push(a);
52
52
  continue;
53
53
  }
54
54
  if (e.kind === "insertPreview") {
55
- let n = e.bounds, r = (e, n) => {
56
- let [r, i] = t(e, n, b);
57
- return {
58
- x: r,
59
- y: i
60
- };
61
- }, i = (e) => e.map((e) => r(e.x, e.y)), a = (h.scale.x + h.scale.y) / 2, l = null, m = e.geometry;
62
- switch (m.kind) {
63
- case "box": {
64
- let [r, i] = t(n.x, n.y, b), a = n.width * h.scale.x, c = n.height * h.scale.y;
65
- if (e.shape === "image") {
66
- let t = e.extras, n = t.preview === "outline" || !t.src ? void 0 : o(t.src);
67
- n && x.push({
68
- kind: "image",
69
- image: n,
70
- x: r,
71
- y: i,
72
- w: a,
73
- h: c,
74
- opacity: y
75
- });
76
- }
77
- l = e.shape === "ellipse" ? s({
78
- x: r,
79
- y: i,
80
- width: a,
81
- height: c
82
- }) : d(r, i, a, c);
83
- break;
84
- }
85
- case "line":
86
- l = c(r(m.a.x, m.a.y), r(m.b.x, m.b.y));
87
- break;
88
- case "polygon":
89
- l = f(r(m.center.x, m.center.y), m.radius * a, m.sides, m.rotation);
90
- break;
91
- case "star":
92
- l = p(r(m.center.x, m.center.y), m.outerRadius * a, m.points, m.innerRadius * a, m.rotation);
93
- break;
94
- case "pencil": l = u(i(m.samples));
95
- }
96
- if (!l) continue;
97
- let _ = {
98
- kind: "path",
99
- path: l,
100
- fill: e.shape === "line" || e.shape === "pencil" || e.shape === "image" ? void 0 : { paint: { color: g.fill } },
101
- stroke: {
102
- paint: { color: g.stroke },
103
- width: g.lineWidth,
104
- dash: g.dash
105
- }
106
- };
107
- if (x.push(_), e.anchorPoint) {
108
- let t = r(e.anchorPoint.x, e.anchorPoint.y);
109
- x.push({
110
- kind: "path",
111
- path: s({
112
- x: t.x - 4,
113
- y: t.y - 4,
114
- width: 8,
115
- height: 8
116
- }),
117
- fill: { paint: { color: g.stroke } }
118
- });
119
- }
55
+ for (let t of o(e, u, d)) h.push(t);
120
56
  continue;
121
57
  }
122
58
  if (e.kind === "lasso") {
123
59
  let n = [];
124
60
  for (let r of e.vertices) {
125
- let [e, i] = t(r.x, r.y, b);
61
+ let [e, i] = t(r.x, r.y, m);
126
62
  n.push({
127
63
  x: e,
128
64
  y: i
@@ -130,43 +66,43 @@ function b(b) {
130
66
  }
131
67
  let r = {
132
68
  kind: "path",
133
- path: l(n),
134
- fill: { paint: { color: g.fill } },
69
+ path: s(n),
70
+ fill: { paint: { color: d.fill } },
135
71
  stroke: {
136
- paint: { color: g.stroke },
137
- width: g.lineWidth,
138
- dash: g.dash
72
+ paint: { color: d.stroke },
73
+ width: d.lineWidth,
74
+ dash: d.dash
139
75
  }
140
76
  };
141
- x.push(r);
77
+ h.push(r);
142
78
  continue;
143
79
  }
144
80
  if (e.kind === "polyline") {
145
- let n = _[e.role] ?? {
146
- paint: { color: g.stroke },
147
- width: g.lineWidth,
148
- dash: g.dash
81
+ let n = f[e.role] ?? {
82
+ paint: { color: d.stroke },
83
+ width: d.lineWidth,
84
+ dash: d.dash
149
85
  }, r = [];
150
86
  for (let n of e.points) {
151
- let [e, i] = t(n.x, n.y, b);
87
+ let [e, i] = t(n.x, n.y, m);
152
88
  r.push({
153
89
  x: e,
154
90
  y: i
155
91
  });
156
92
  }
157
- x.push({
93
+ h.push({
158
94
  kind: "path",
159
- path: u(r),
95
+ path: c(r),
160
96
  stroke: n
161
97
  });
162
98
  continue;
163
99
  }
164
100
  }
165
- return x.length === 0 ? [] : x;
101
+ return h.length === 0 ? [] : h;
166
102
  }
167
- }), [C]);
103
+ }), [_]);
168
104
  }
169
105
  //#endregion
170
- export { b as useDispatcherOverlayLayer };
106
+ export { m as useDispatcherOverlayLayer };
171
107
 
172
108
  //# sourceMappingURL=useDispatcherOverlayLayer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useDispatcherOverlayLayer.js","names":["DEFAULT_STYLE","PREVIEW_CONTENT_OPACITY","useDispatcherOverlayLayer","args","styleRef","useLatest","style","forceRerender","useReducer","n","useEffect","dispatcher","useMemo","cfg","roles","OVERLAY_ROLE_STROKES","t","viewToTransform","view","out","isVisible","isVisibleFrom","data","passes","id","ov","resolveOverlays","gestureOverlaysFrom","b","sx","sy","worldToScreen","cmd","projectPoint","wx","wy","projectPoints","pts","p","radialScale","pathCmd","geom","sw","sh","e","bmp","getImageBitmap","ellipsePath","rectPath","linePath","regularPolygonPath","starPath","polylineFromPoints","anchorScreen","screenPts","v","polygonFromPoints","stroke","pt"],"sources":["../../../src/canvas/SceneCanvas/useDispatcherOverlayLayer.ts"],"sourcesContent":["/**\n * Dispatcher overlay render layer for `<SceneCanvas>`.\n *\n * Paints the overlay shapes the drawing view's in-flight handles publish,\n * taken off the draw envelope so a panel shows its own gesture rather than\n * the surface's. `resolveOverlays` does the reading; everything here is\n * painting.\n *\n * Distinct from `usePreviewGhostLayer`, which paints displaced scene-node\n * silhouettes. This layer is for gestures whose visual feedback isn't a moved\n * scene node — a marquee rect, a lasso polyline, an insert preview.\n */\nimport { useEffect, useMemo, useReducer } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport type { DrawCommand, PathDrawCommand } from '@weasel-js/renderer';\nimport type { CommandStroke } from '@weasel-js/paint';\nimport type { RenderLayer } from 'core/layers/render';\nimport { viewToTransform } from 'core/viewport/view';\nimport { worldToScreen } from 'core/viewport/viewTransform';\nimport type { Dispatcher } from '@weasel-js/routing';\nimport {\n polygonFromPoints,\n polylineFromPoints,\n rectPath,\n ellipsePath,\n linePath,\n regularPolygonPath,\n starPath,\n} from '@weasel-js/geom';\nimport { getImageBitmap } from '@weasel-js/renderer';\nimport { resolveOverlays } from 'interactions/actions/resolveOverlays';\nimport { gestureOverlaysFrom, isVisibleFrom } from '../drawEnvelope';\nimport { OVERLAY_ROLE_STROKES } from '../overlayRoleStrokes';\n\n/** Style knobs for the dispatcher-overlay layer's marquee + lasso paints. */\nexport interface DispatcherOverlayStyle {\n fill?: string;\n stroke?: string;\n dash?: number[];\n lineWidth?: number;\n /** Stroke per `polyline` overlay role, merged over the kit's. A role with\n * no entry here and none of the kit's paints as plain chrome — the\n * `stroke` / `lineWidth` / `dash` above. */\n roles?: Readonly<Record<string, CommandStroke>>;\n}\n\nconst DEFAULT_STYLE: Required<Omit<DispatcherOverlayStyle, 'roles'>> = {\n fill: 'rgba(164, 139, 212, 0.18)',\n stroke: '#a48bd4',\n dash: [3, 3],\n lineWidth: 1,\n};\n\n/** Alpha for content previewed inside an in-flight gesture. Matches the\n * preview-ghost layer, so a dragged node and an uncommitted insert read as\n * equally provisional. */\nconst PREVIEW_CONTENT_OPACITY = 0.85;\n\n\nexport function useDispatcherOverlayLayer(args: {\n /** The surface's dispatcher, subscribed to only so a pump repaints. What\n * gets painted is the drawing view's own `getGestureOverlays()`. */\n dispatcher: Dispatcher | null | undefined;\n style?: DispatcherOverlayStyle;\n}): RenderLayer<unknown> {\n const { dispatcher, style } = args;\n\n const styleRef = useLatest(style);\n\n // Re-render on every dispatcher pump so live overlay (marquee, lasso\n // polyline) tracks pointermove instead of freezing on the first frame.\n const [, forceRerender] = useReducer((n: number) => n + 1, 0);\n useEffect(() => {\n if (!dispatcher) return;\n return dispatcher.subscribe(forceRerender);\n }, [dispatcher]);\n\n return useMemo<RenderLayer<unknown>>(\n () => ({\n id: 'dispatcher-overlay',\n label: 'Dispatcher overlay',\n space: 'screen',\n draw: (data, view) => {\n const cfg = { ...DEFAULT_STYLE, ...(styleRef.current ?? {}) };\n // Merged rather than replaced: naming one role must not delete the\n // kit's others.\n const roles = { ...OVERLAY_ROLE_STROKES, ...(styleRef.current?.roles ?? {}) };\n const t = viewToTransform(view);\n const out: DrawCommand[] = [];\n\n // Chrome-caps gate. Absent envelope → every overlay paints. This stays\n // on the painting side: the predicate is a property of the view's\n // envelope, and two views of one surface may answer differently for\n // the same in-flight gesture.\n const isVisible = isVisibleFrom(data);\n const passes = (id: string) => (isVisible ? isVisible(id) : true);\n\n for (const ov of resolveOverlays(gestureOverlaysFrom(data))) {\n if (!passes(ov.visibilityId)) continue;\n\n if (ov.kind === 'marquee') {\n const b = ov.bounds;\n const [sx, sy] = worldToScreen(b.x, b.y, t);\n const sw = b.width * view.scale.x;\n const sh = b.height * view.scale.y;\n const cmd: PathDrawCommand = {\n kind: 'path',\n path: { kind: 'rect', x: sx, y: sy, width: sw, height: sh },\n fill: { paint: { color: cfg.fill } },\n stroke: { paint: { color: cfg.stroke }, width: cfg.lineWidth, dash: cfg.dash },\n };\n out.push(cmd);\n continue;\n }\n\n if (ov.kind === 'insertPreview') {\n const b = ov.bounds;\n const projectPoint = (wx: number, wy: number): { x: number; y: number } => {\n const [sx, sy] = worldToScreen(wx, wy, t);\n return { x: sx, y: sy };\n };\n const projectPoints = (\n pts: ReadonlyArray<{ x: number; y: number }>,\n ): { x: number; y: number }[] => pts.map((p) => projectPoint(p.x, p.y));\n // Radial shapes inscribe in a square, so a single screen-space\n // radius needs one scale factor; average the axes.\n const radialScale = (view.scale.x + view.scale.y) / 2;\n\n let pathCmd: PathDrawCommand['path'] | null = null;\n const geom = ov.geometry;\n switch (geom.kind) {\n case 'box': {\n const [sx, sy] = worldToScreen(b.x, b.y, t);\n const sw = b.width * view.scale.x;\n const sh = b.height * view.scale.y;\n if (ov.shape === 'image') {\n const e = ov.extras as Partial<{ src: string; preview: string }>;\n // The bitmap when it has decoded, the bare outline until then\n // (or when the tool opted out) — the outline is drawn either\n // way, so the drag always has an edge to read.\n const bmp = e.preview === 'outline' || !e.src\n ? undefined\n : getImageBitmap(e.src);\n if (bmp) {\n out.push({\n kind: 'image',\n image: bmp,\n x: sx, y: sy, w: sw, h: sh,\n opacity: PREVIEW_CONTENT_OPACITY,\n });\n }\n }\n pathCmd = ov.shape === 'ellipse'\n ? ellipsePath({ x: sx, y: sy, width: sw, height: sh })\n : rectPath(sx, sy, sw, sh);\n break;\n }\n case 'line':\n pathCmd = linePath(projectPoint(geom.a.x, geom.a.y), projectPoint(geom.b.x, geom.b.y));\n break;\n case 'polygon':\n pathCmd = regularPolygonPath(\n projectPoint(geom.center.x, geom.center.y),\n geom.radius * radialScale,\n geom.sides,\n geom.rotation,\n );\n break;\n case 'star':\n pathCmd = starPath(\n projectPoint(geom.center.x, geom.center.y),\n geom.outerRadius * radialScale,\n geom.points,\n geom.innerRadius * radialScale,\n geom.rotation,\n );\n break;\n case 'pencil':\n // Genuinely open: `polygonFromPoints` closes the path, and the\n // closing edge from the last sample back to the first reads as\n // a marquee rather than as the stroke being drawn.\n pathCmd = polylineFromPoints(projectPoints(geom.samples));\n break;\n }\n\n if (!pathCmd) continue;\n const cmd: PathDrawCommand = {\n kind: 'path',\n path: pathCmd,\n fill: ov.shape === 'line' || ov.shape === 'pencil' || ov.shape === 'image'\n ? undefined\n : { paint: { color: cfg.fill } },\n stroke: { paint: { color: cfg.stroke }, width: cfg.lineWidth, dash: cfg.dash },\n };\n out.push(cmd);\n // Anchor dot at the drag's click point: for radial shapes no\n // vertex sits at the AABB corner, and in center mode the dot marks\n // the growth axis.\n if (ov.anchorPoint) {\n const anchorScreen = projectPoint(ov.anchorPoint.x, ov.anchorPoint.y);\n out.push({\n kind: 'path',\n path: ellipsePath({\n x: anchorScreen.x - 4,\n y: anchorScreen.y - 4,\n width: 8,\n height: 8,\n }),\n fill: { paint: { color: cfg.stroke } },\n });\n }\n continue;\n }\n\n if (ov.kind === 'lasso') {\n // `polygonFromPoints` closes the path, which draws the dashed\n // close-line back to the first vertex.\n const screenPts: { x: number; y: number }[] = [];\n for (const v of ov.vertices) {\n const [sx, sy] = worldToScreen(v.x, v.y, t);\n screenPts.push({ x: sx, y: sy });\n }\n const cmd: PathDrawCommand = {\n kind: 'path',\n path: polygonFromPoints(screenPts),\n fill: { paint: { color: cfg.fill } },\n stroke: { paint: { color: cfg.stroke }, width: cfg.lineWidth, dash: cfg.dash },\n };\n out.push(cmd);\n continue;\n }\n\n if (ov.kind === 'polyline') {\n const stroke =\n roles[ov.role] ??\n { paint: { color: cfg.stroke }, width: cfg.lineWidth, dash: cfg.dash };\n const screenPts: { x: number; y: number }[] = [];\n for (const pt of ov.points) {\n const [sx, sy] = worldToScreen(pt.x, pt.y, t);\n screenPts.push({ x: sx, y: sy });\n }\n out.push({\n kind: 'path',\n path: polylineFromPoints(screenPts),\n stroke,\n } satisfies PathDrawCommand);\n continue;\n }\n }\n\n if (out.length === 0) return [];\n return out;\n },\n }),\n [styleRef],\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useDispatcherOverlayLayer.js","names":["DEFAULT_STYLE","useDispatcherOverlayLayer","args","styleRef","useLatest","style","forceRerender","useReducer","n","useEffect","dispatcher","useMemo","cfg","roles","OVERLAY_ROLE_STROKES","t","viewToTransform","view","out","isVisible","isVisibleFrom","data","passes","id","ov","resolveOverlays","gestureOverlaysFrom","b","sx","sy","worldToScreen","cmd","insertPreviewCommands","screenPts","v","polygonFromPoints","stroke","pt","polylineFromPoints"],"sources":["../../../src/canvas/SceneCanvas/useDispatcherOverlayLayer.ts"],"sourcesContent":["/**\n * Dispatcher overlay render layer for `<SceneCanvas>`.\n *\n * Paints the overlay shapes the drawing view's in-flight handles publish,\n * taken off the draw envelope so a panel shows its own gesture rather than\n * the surface's. `resolveOverlays` does the reading; everything here is\n * painting.\n *\n * Distinct from `usePreviewGhostLayer`, which paints displaced scene-node\n * silhouettes. This layer is for gestures whose visual feedback isn't a moved\n * scene node — a marquee rect, a lasso polyline, an insert preview.\n */\nimport { useEffect, useMemo, useReducer } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport type { DrawCommand, PathDrawCommand } from '@weasel-js/renderer';\nimport type { CommandStroke } from '@weasel-js/paint';\nimport type { RenderLayer } from 'core/layers/render';\nimport { viewToTransform } from 'core/viewport/view';\nimport { worldToScreen } from 'core/viewport/viewTransform';\nimport type { Dispatcher } from '@weasel-js/routing';\nimport { polygonFromPoints, polylineFromPoints } from '@weasel-js/geom';\nimport { resolveOverlays } from 'interactions/actions/resolveOverlays';\nimport { gestureOverlaysFrom, isVisibleFrom } from '../drawEnvelope';\nimport { insertPreviewCommands } from './insertPreviewCommands';\nimport { OVERLAY_ROLE_STROKES } from '../overlayRoleStrokes';\n\n/** Style knobs for the dispatcher-overlay layer's marquee + lasso paints. */\nexport interface DispatcherOverlayStyle {\n fill?: string;\n stroke?: string;\n dash?: number[];\n lineWidth?: number;\n /** Stroke per `polyline` overlay role, merged over the kit's. A role with\n * no entry here and none of the kit's paints as plain chrome — the\n * `stroke` / `lineWidth` / `dash` above. */\n roles?: Readonly<Record<string, CommandStroke>>;\n}\n\nconst DEFAULT_STYLE: Required<Omit<DispatcherOverlayStyle, 'roles'>> = {\n fill: 'rgba(164, 139, 212, 0.18)',\n stroke: '#a48bd4',\n dash: [3, 3],\n lineWidth: 1,\n};\n\n\n\nexport function useDispatcherOverlayLayer(args: {\n /** The surface's dispatcher, subscribed to only so a pump repaints. What\n * gets painted is the drawing view's own `getGestureOverlays()`. */\n dispatcher: Dispatcher | null | undefined;\n style?: DispatcherOverlayStyle;\n}): RenderLayer<unknown> {\n const { dispatcher, style } = args;\n\n const styleRef = useLatest(style);\n\n // Re-render on every dispatcher pump so live overlay (marquee, lasso\n // polyline) tracks pointermove instead of freezing on the first frame.\n const [, forceRerender] = useReducer((n: number) => n + 1, 0);\n useEffect(() => {\n if (!dispatcher) return;\n return dispatcher.subscribe(forceRerender);\n }, [dispatcher]);\n\n return useMemo<RenderLayer<unknown>>(\n () => ({\n id: 'dispatcher-overlay',\n label: 'Dispatcher overlay',\n space: 'screen',\n draw: (data, view) => {\n const cfg = { ...DEFAULT_STYLE, ...(styleRef.current ?? {}) };\n // Merged rather than replaced: naming one role must not delete the\n // kit's others.\n const roles = { ...OVERLAY_ROLE_STROKES, ...(styleRef.current?.roles ?? {}) };\n const t = viewToTransform(view);\n const out: DrawCommand[] = [];\n\n // Chrome-caps gate. Absent envelope → every overlay paints. This stays\n // on the painting side: the predicate is a property of the view's\n // envelope, and two views of one surface may answer differently for\n // the same in-flight gesture.\n const isVisible = isVisibleFrom(data);\n const passes = (id: string) => (isVisible ? isVisible(id) : true);\n\n for (const ov of resolveOverlays(gestureOverlaysFrom(data))) {\n if (!passes(ov.visibilityId)) continue;\n\n if (ov.kind === 'marquee') {\n const b = ov.bounds;\n const [sx, sy] = worldToScreen(b.x, b.y, t);\n const sw = b.width * view.scale.x;\n const sh = b.height * view.scale.y;\n const cmd: PathDrawCommand = {\n kind: 'path',\n path: { kind: 'rect', x: sx, y: sy, width: sw, height: sh },\n fill: { paint: { color: cfg.fill } },\n stroke: { paint: { color: cfg.stroke }, width: cfg.lineWidth, dash: cfg.dash },\n };\n out.push(cmd);\n continue;\n }\n\n if (ov.kind === 'insertPreview') {\n for (const cmd of insertPreviewCommands(ov, view, cfg)) out.push(cmd);\n continue;\n }\n\n if (ov.kind === 'lasso') {\n // `polygonFromPoints` closes the path, which draws the dashed\n // close-line back to the first vertex.\n const screenPts: { x: number; y: number }[] = [];\n for (const v of ov.vertices) {\n const [sx, sy] = worldToScreen(v.x, v.y, t);\n screenPts.push({ x: sx, y: sy });\n }\n const cmd: PathDrawCommand = {\n kind: 'path',\n path: polygonFromPoints(screenPts),\n fill: { paint: { color: cfg.fill } },\n stroke: { paint: { color: cfg.stroke }, width: cfg.lineWidth, dash: cfg.dash },\n };\n out.push(cmd);\n continue;\n }\n\n if (ov.kind === 'polyline') {\n const stroke =\n roles[ov.role] ??\n { paint: { color: cfg.stroke }, width: cfg.lineWidth, dash: cfg.dash };\n const screenPts: { x: number; y: number }[] = [];\n for (const pt of ov.points) {\n const [sx, sy] = worldToScreen(pt.x, pt.y, t);\n screenPts.push({ x: sx, y: sy });\n }\n out.push({\n kind: 'path',\n path: polylineFromPoints(screenPts),\n stroke,\n } satisfies PathDrawCommand);\n continue;\n }\n }\n\n if (out.length === 0) return [];\n return out;\n },\n }),\n [styleRef],\n );\n}\n"],"mappings":"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"}