@weasel-js/core 1.9.2 → 1.9.4

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 (542) hide show
  1. package/CHANGELOG.md +393 -0
  2. package/README.md +2 -2
  3. package/dist/WeaselProvider.js +5 -5
  4. package/dist/affordances/composeAffordanceLayer.js +10 -20
  5. package/dist/affordances/composeAffordanceLayer.js.map +1 -1
  6. package/dist/affordances/cornerResize.js +25 -17
  7. package/dist/affordances/cornerResize.js.map +1 -1
  8. package/dist/affordances/hitAffordanceRegions.js +27 -20
  9. package/dist/affordances/hitAffordanceRegions.js.map +1 -1
  10. package/dist/affordances/rotationHandle.js +18 -18
  11. package/dist/affordances/rotationHandle.js.map +1 -1
  12. package/dist/animation/behaviors/momentum.js +93 -55
  13. package/dist/animation/behaviors/momentum.js.map +1 -1
  14. package/dist/animation/loop.js +10 -12
  15. package/dist/animation/loop.js.map +1 -1
  16. package/dist/animation/reflow.js +8 -8
  17. package/dist/animation/reflow.js.map +1 -1
  18. package/dist/animation/stagger.js +64 -56
  19. package/dist/animation/stagger.js.map +1 -1
  20. package/dist/animation/timeline/booking.js +62 -54
  21. package/dist/animation/timeline/booking.js.map +1 -1
  22. package/dist/animation/timeline/createTimeline.js +85 -76
  23. package/dist/animation/timeline/createTimeline.js.map +1 -1
  24. package/dist/animation/timeline/sampleTrack.js +13 -5
  25. package/dist/animation/timeline/sampleTrack.js.map +1 -1
  26. package/dist/animation/useAnimator.js +45 -35
  27. package/dist/animation/useAnimator.js.map +1 -1
  28. package/dist/animation/wrappers/animateLifecycle.js +31 -24
  29. package/dist/animation/wrappers/animateLifecycle.js.map +1 -1
  30. package/dist/animation/wrappers/animateOnSetPose.js +28 -26
  31. package/dist/animation/wrappers/animateOnSetPose.js.map +1 -1
  32. package/dist/animation/wrappers/instantPose.js +13 -0
  33. package/dist/animation/wrappers/instantPose.js.map +1 -0
  34. package/dist/{poseDescriptor-D-OH-tu5.d.ts → autoPoseDescriptor-Ct7yqivU.d.ts} +28 -3
  35. package/dist/barrel/chrome.js +16 -0
  36. package/dist/barrel/input.js +19 -0
  37. package/dist/barrel/interactions.js +42 -0
  38. package/dist/barrel/paint.js +18 -0
  39. package/dist/barrel/paths.js +19 -0
  40. package/dist/barrel/renderer.js +20 -0
  41. package/dist/barrel/routing.js +51 -0
  42. package/dist/barrel/text.js +18 -0
  43. package/dist/barrel/viewport.js +52 -0
  44. package/dist/builtins-DPcdghtB.d.ts +1223 -0
  45. package/dist/canvas/Canvas.js +363 -448
  46. package/dist/canvas/Canvas.js.map +1 -1
  47. package/dist/canvas/CanvasView.js +164 -165
  48. package/dist/canvas/CanvasView.js.map +1 -1
  49. package/dist/canvas/CursorCoordsHud.js +37 -32
  50. package/dist/canvas/CursorCoordsHud.js.map +1 -1
  51. package/dist/canvas/DrawCanvas.js +49 -43
  52. package/dist/canvas/DrawCanvas.js.map +1 -1
  53. package/dist/canvas/MinimapCanvas.js +26 -25
  54. package/dist/canvas/MinimapCanvas.js.map +1 -1
  55. package/dist/canvas/NodeShape.js +59 -377
  56. package/dist/canvas/NodeShape.js.map +1 -1
  57. package/dist/canvas/PickHud.js +50 -47
  58. package/dist/canvas/PickHud.js.map +1 -1
  59. package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js +167 -0
  60. package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js.map +1 -0
  61. package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +13 -13
  62. package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js +67 -0
  63. package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js.map +1 -0
  64. package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js +16 -0
  65. package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js.map +1 -0
  66. package/dist/canvas/SceneCanvas/coordTrace.js +10 -0
  67. package/dist/canvas/SceneCanvas/coordTrace.js.map +1 -0
  68. package/dist/canvas/SceneCanvas/defaultNodeProperties.js +146 -92
  69. package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -1
  70. package/dist/canvas/SceneCanvas/defaultNodeRouting.js +9 -8
  71. package/dist/canvas/SceneCanvas/defaultNodeRouting.js.map +1 -1
  72. package/dist/canvas/SceneCanvas/features.js +1 -0
  73. package/dist/canvas/SceneCanvas/features.js.map +1 -1
  74. package/dist/canvas/SceneCanvas/isDev.js +12 -0
  75. package/dist/canvas/SceneCanvas/isDev.js.map +1 -0
  76. package/dist/canvas/SceneCanvas/poseGeometry.js +29 -28
  77. package/dist/canvas/SceneCanvas/poseGeometry.js.map +1 -1
  78. package/dist/canvas/SceneCanvas/poseRegistrars.js +13 -0
  79. package/dist/canvas/SceneCanvas/poseRegistrars.js.map +1 -0
  80. package/dist/canvas/SceneCanvas/props.js +38 -0
  81. package/dist/canvas/SceneCanvas/props.js.map +1 -0
  82. package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js +21 -62
  83. package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js.map +1 -1
  84. package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js.map +1 -1
  85. package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +46 -48
  86. package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js.map +1 -1
  87. package/dist/canvas/SceneCanvas/useSceneSelectTool.js +33 -33
  88. package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
  89. package/dist/canvas/SceneCanvas.js +534 -788
  90. package/dist/canvas/SceneCanvas.js.map +1 -1
  91. package/dist/canvas/SceneViewCanvas.js +45 -43
  92. package/dist/canvas/SceneViewCanvas.js.map +1 -1
  93. package/dist/canvas/buildSceneLayer.js +91 -0
  94. package/dist/canvas/buildSceneLayer.js.map +1 -0
  95. package/dist/canvas/buildSceneTree.js +16 -19
  96. package/dist/canvas/buildSceneTree.js.map +1 -1
  97. package/dist/canvas/canvasRenderer.js +68 -52
  98. package/dist/canvas/canvasRenderer.js.map +1 -1
  99. package/dist/canvas/deps/changes.js +13 -0
  100. package/dist/canvas/deps/changes.js.map +1 -0
  101. package/dist/canvas/deps/editAnchors.js +28 -28
  102. package/dist/canvas/deps/insert.js +119 -91
  103. package/dist/canvas/deps/insert.js.map +1 -1
  104. package/dist/canvas/deps/slice.js +46 -45
  105. package/dist/canvas/deps/slice.js.map +1 -1
  106. package/dist/canvas/deps/textEdit.js +10 -9
  107. package/dist/canvas/deps/textEdit.js.map +1 -1
  108. package/dist/canvas/derivedPath.js +46 -23
  109. package/dist/canvas/derivedPath.js.map +1 -1
  110. package/dist/canvas/getNodeAtPoint.js +7 -7
  111. package/dist/canvas/getNodeAtPoint.js.map +1 -1
  112. package/dist/canvas/hud.module.js +1 -1
  113. package/dist/canvas/hud.module.js.map +1 -1
  114. package/dist/canvas/kitRequirements.js +2 -2
  115. package/dist/canvas/kitRequirements.js.map +1 -1
  116. package/dist/canvas/layerOrder.js +13 -6
  117. package/dist/canvas/layerOrder.js.map +1 -1
  118. package/dist/canvas/minimapMath.js +12 -10
  119. package/dist/canvas/minimapMath.js.map +1 -1
  120. package/dist/canvas/nodeShapes/derivedPainter.js +34 -0
  121. package/dist/canvas/nodeShapes/derivedPainter.js.map +1 -0
  122. package/dist/canvas/nodeShapes/imagePainter.js +87 -0
  123. package/dist/canvas/nodeShapes/imagePainter.js.map +1 -0
  124. package/dist/canvas/nodeShapes/memo.js +9 -0
  125. package/dist/canvas/nodeShapes/memo.js.map +1 -0
  126. package/dist/canvas/nodeShapes/nodePaint.js +57 -0
  127. package/dist/canvas/nodeShapes/nodePaint.js.map +1 -0
  128. package/dist/canvas/nodeShapes/pathPainter.js +38 -0
  129. package/dist/canvas/nodeShapes/pathPainter.js.map +1 -0
  130. package/dist/canvas/nodeShapes/poseBox.js +20 -0
  131. package/dist/canvas/nodeShapes/poseBox.js.map +1 -0
  132. package/dist/canvas/nodeShapes/rectFallbackPainter.js +38 -0
  133. package/dist/canvas/nodeShapes/rectFallbackPainter.js.map +1 -0
  134. package/dist/canvas/nodeShapes/shapePainter.js +72 -0
  135. package/dist/canvas/nodeShapes/shapePainter.js.map +1 -0
  136. package/dist/canvas/nodeShapes/textPainter.js +55 -0
  137. package/dist/canvas/nodeShapes/textPainter.js.map +1 -0
  138. package/dist/canvas/overlayRoleStrokes.js.map +1 -1
  139. package/dist/canvas/paintCull.js +10 -11
  140. package/dist/canvas/paintCull.js.map +1 -1
  141. package/dist/canvas/pickWalk.js +52 -63
  142. package/dist/canvas/pickWalk.js.map +1 -1
  143. package/dist/canvas/poseRotation.js +11 -23
  144. package/dist/canvas/poseRotation.js.map +1 -1
  145. package/dist/canvas/renderDebugSnapshot.js +5 -5
  146. package/dist/canvas/renderSceneToPixels.js +3 -1
  147. package/dist/canvas/renderSceneToPixels.js.map +1 -1
  148. package/dist/canvas/sceneAdapter.js +66 -148
  149. package/dist/canvas/sceneAdapter.js.map +1 -1
  150. package/dist/canvas/sceneClipboard.js +112 -0
  151. package/dist/canvas/sceneClipboard.js.map +1 -0
  152. package/dist/canvas/sceneSlotWiring.js +4 -4
  153. package/dist/canvas/sceneSlotWiring.js.map +1 -1
  154. package/dist/canvas/sceneViewRender.js +39 -40
  155. package/dist/canvas/sceneViewRender.js.map +1 -1
  156. package/dist/canvas/useCanvasRenderer.js +14 -6
  157. package/dist/canvas/useCanvasRenderer.js.map +1 -1
  158. package/dist/canvas/useCanvasView.js +58 -0
  159. package/dist/canvas/useCanvasView.js.map +1 -0
  160. package/dist/canvas/useFrameLoop.js +35 -26
  161. package/dist/canvas/useFrameLoop.js.map +1 -1
  162. package/dist/canvas/useSceneLayerList.js +21 -0
  163. package/dist/canvas/useSceneLayerList.js.map +1 -0
  164. package/dist/clipboard.d.ts +10 -6
  165. package/dist/clone.d.ts +4 -3
  166. package/dist/core/adapters/arrayAdapter.js +48 -39
  167. package/dist/core/adapters/arrayAdapter.js.map +1 -1
  168. package/dist/core/device/index.js +5 -4
  169. package/dist/core/device/useDeviceProfile.js +38 -44
  170. package/dist/core/device/useDeviceProfile.js.map +1 -1
  171. package/dist/core/device/watchDevicePixelRatio.js +17 -0
  172. package/dist/core/device/watchDevicePixelRatio.js.map +1 -0
  173. package/dist/core/fillInPoseFrame.js.map +1 -1
  174. package/dist/core/geometry/poseDescriptor.js +21 -19
  175. package/dist/core/geometry/poseDescriptor.js.map +1 -1
  176. package/dist/core/geometry/poseFrame.js +44 -0
  177. package/dist/core/geometry/poseFrame.js.map +1 -0
  178. package/dist/core/geometry/poseRotation.js.map +1 -1
  179. package/dist/core/geometry/regionHit.js +9 -10
  180. package/dist/core/geometry/regionHit.js.map +1 -1
  181. package/dist/core/geometry/unionBounds.js +31 -29
  182. package/dist/core/geometry/unionBounds.js.map +1 -1
  183. package/dist/core/isPlainObject.js +2 -11
  184. package/dist/core/ops/arrange.js +1 -0
  185. package/dist/core/ops/arrange.js.map +1 -1
  186. package/dist/core/ops/create.js +10 -5
  187. package/dist/core/ops/create.js.map +1 -1
  188. package/dist/core/ops/delete.js +12 -24
  189. package/dist/core/ops/delete.js.map +1 -1
  190. package/dist/core/ops/reorder/index.js +43 -40
  191. package/dist/core/ops/reorder/index.js.map +1 -1
  192. package/dist/core/ops/reorder/setChildOrder.js +34 -0
  193. package/dist/core/ops/reorder/setChildOrder.js.map +1 -0
  194. package/dist/core/paintKinds.js +5 -5
  195. package/dist/core/paintKinds.js.map +1 -1
  196. package/dist/core/scene/NodeProperties.js.map +1 -1
  197. package/dist/core/scene/appliedLog.js +37 -0
  198. package/dist/core/scene/appliedLog.js.map +1 -0
  199. package/dist/core/scene/arrivalWindow.js +101 -0
  200. package/dist/core/scene/arrivalWindow.js.map +1 -0
  201. package/dist/core/scene/derivedPath.js.map +1 -1
  202. package/dist/core/scene/historyFacade.js +84 -0
  203. package/dist/core/scene/historyFacade.js.map +1 -0
  204. package/dist/core/scene/kitOps.js +173 -0
  205. package/dist/core/scene/kitOps.js.map +1 -0
  206. package/dist/core/scene/layerStack.js +38 -0
  207. package/dist/core/scene/layerStack.js.map +1 -0
  208. package/dist/core/scene/lockGuard.js +37 -0
  209. package/dist/core/scene/lockGuard.js.map +1 -0
  210. package/dist/core/scene/nodeFnFields.js +5 -6
  211. package/dist/core/scene/nodeFnFields.js.map +1 -1
  212. package/dist/core/scene/nodeMemo.js +45 -19
  213. package/dist/core/scene/nodeMemo.js.map +1 -1
  214. package/dist/core/scene/nodeStore.js +126 -0
  215. package/dist/core/scene/nodeStore.js.map +1 -0
  216. package/dist/core/scene/pickability.js +6 -0
  217. package/dist/core/scene/pickability.js.map +1 -0
  218. package/dist/core/scene/poseFeed.js +38 -38
  219. package/dist/core/scene/poseFeed.js.map +1 -1
  220. package/dist/core/scene/poseOverrides.js +34 -38
  221. package/dist/core/scene/poseOverrides.js.map +1 -1
  222. package/dist/core/scene/renderOrder.js +84 -0
  223. package/dist/core/scene/renderOrder.js.map +1 -0
  224. package/dist/core/scene/scene.js +289 -866
  225. package/dist/core/scene/scene.js.map +1 -1
  226. package/dist/core/scene/serialization.js +68 -0
  227. package/dist/core/scene/serialization.js.map +1 -0
  228. package/dist/core/scene/treeOrder.js +13 -0
  229. package/dist/core/scene/treeOrder.js.map +1 -0
  230. package/dist/core/scene/types.js.map +1 -1
  231. package/dist/core/viewport/meanScale.js +1 -1
  232. package/dist/core/viewport/meanScale.js.map +1 -1
  233. package/dist/core/viewport/view.js +12 -12
  234. package/dist/core/viewport/view.js.map +1 -1
  235. package/dist/core/viewport/zoomBounds.js +10 -8
  236. package/dist/core/viewport/zoomBounds.js.map +1 -1
  237. package/dist/{cornerHandles-BCrDp_mH.d.ts → cornerHandles-CtCb8a3G.d.ts} +1 -1
  238. package/dist/debug/createDebugOverlayLayer.js +14 -14
  239. package/dist/debug/createDebugOverlayLayer.js.map +1 -1
  240. package/dist/debug/flag.js +2 -41
  241. package/dist/features/chrome-caps/useHoverTracking.js +22 -17
  242. package/dist/features/chrome-caps/useHoverTracking.js.map +1 -1
  243. package/dist/features/focus/gateLayer.js +3 -4
  244. package/dist/features/focus/gateLayer.js.map +1 -1
  245. package/dist/features/images/imageCache.js +19 -9
  246. package/dist/features/images/imageCache.js.map +1 -1
  247. package/dist/features/ingestion/contentHandlers.js +14 -11
  248. package/dist/features/ingestion/contentHandlers.js.map +1 -1
  249. package/dist/features/ingestion/index.js +1 -1
  250. package/dist/features/ingestion/registerKitHandlers.js +7 -7
  251. package/dist/features/ingestion/weaselJsonHandler.js +17 -14
  252. package/dist/features/ingestion/weaselJsonHandler.js.map +1 -1
  253. package/dist/features/meshPaint/lazyKind.js +201 -35
  254. package/dist/features/meshPaint/lazyKind.js.map +1 -1
  255. package/dist/features/meshPaint/meshPaint.js +82 -79
  256. package/dist/features/meshPaint/meshPaint.js.map +1 -1
  257. package/dist/features/minimap/createMinimapContribution.js +42 -42
  258. package/dist/features/minimap/layers.js +44 -62
  259. package/dist/features/minimap/layers.js.map +1 -1
  260. package/dist/features/parallax/createParallaxPlane.js +10 -14
  261. package/dist/features/parallax/createParallaxPlane.js.map +1 -1
  262. package/dist/features/paths/anchorEdits.js +19 -8
  263. package/dist/features/paths/anchorEdits.js.map +1 -1
  264. package/dist/features/paths/anchors.js +31 -26
  265. package/dist/features/paths/anchors.js.map +1 -1
  266. package/dist/features/paths/booleans.js +2 -2
  267. package/dist/features/paths/index.js +13 -11
  268. package/dist/features/paths/markerCommands.js +37 -36
  269. package/dist/features/paths/markerCommands.js.map +1 -1
  270. package/dist/features/paths/pathInWorld.js +19 -19
  271. package/dist/features/paths/pathInWorld.js.map +1 -1
  272. package/dist/features/paths/pathLayer.js.map +1 -1
  273. package/dist/features/paths/strokeToPath.js +40 -0
  274. package/dist/features/paths/strokeToPath.js.map +1 -0
  275. package/dist/features/paths/tessellate/stroke.js.map +1 -1
  276. package/dist/features/patterns/commandPaint.js +18 -0
  277. package/dist/features/patterns/commandPaint.js.map +1 -0
  278. package/dist/features/patterns/index.js +5 -17
  279. package/dist/features/patterns/index.js.map +1 -1
  280. package/dist/features/patterns/rasterizeTile.js +17 -0
  281. package/dist/features/patterns/rasterizeTile.js.map +1 -0
  282. package/dist/features/patterns/resolveSpec.js +52 -44
  283. package/dist/features/patterns/resolveSpec.js.map +1 -1
  284. package/dist/features/poseRun/usePoseRun.js +8 -3
  285. package/dist/features/poseRun/usePoseRun.js.map +1 -1
  286. package/dist/features/selection/SelectionContext.js +5 -0
  287. package/dist/features/selection/SelectionContext.js.map +1 -1
  288. package/dist/features/selection/overlay.js +18 -18
  289. package/dist/features/selection/overlay.js.map +1 -1
  290. package/dist/features/text/domOffsets.js +82 -0
  291. package/dist/features/text/domOffsets.js.map +1 -0
  292. package/dist/features/text/domRuns.js +103 -131
  293. package/dist/features/text/domRuns.js.map +1 -1
  294. package/dist/features/text/hitTest.js +5 -2
  295. package/dist/features/text/hitTest.js.map +1 -1
  296. package/dist/features/text/isTextData.js +8 -0
  297. package/dist/features/text/isTextData.js.map +1 -0
  298. package/dist/features/text/overlayDirection.js +15 -0
  299. package/dist/features/text/overlayDirection.js.map +1 -0
  300. package/dist/features/text/runs/rangeStyle.js +32 -34
  301. package/dist/features/text/runs/rangeStyle.js.map +1 -1
  302. package/dist/features/text/textCommand.js +34 -33
  303. package/dist/features/text/textCommand.js.map +1 -1
  304. package/dist/features/text/textToPath.js +40 -40
  305. package/dist/features/text/textToPath.js.map +1 -1
  306. package/dist/features/text/useSceneTextEdit.js +76 -82
  307. package/dist/features/text/useSceneTextEdit.js.map +1 -1
  308. package/dist/features/text/useTextEdit.js +184 -160
  309. package/dist/features/text/useTextEdit.js.map +1 -1
  310. package/dist/features/tiling/createTiledLayer.js +24 -22
  311. package/dist/features/tiling/createTiledLayer.js.map +1 -1
  312. package/dist/index.d.ts +11010 -7700
  313. package/dist/index.js +316 -309
  314. package/dist/input/keyState.js +42 -43
  315. package/dist/input/keyState.js.map +1 -1
  316. package/dist/input/useKeyModifiers.js +11 -0
  317. package/dist/input/useKeyModifiers.js.map +1 -0
  318. package/dist/interactions/actions/align/align.js +8 -8
  319. package/dist/interactions/actions/clipboard/clipboardOps.js +34 -32
  320. package/dist/interactions/actions/clipboard/clipboardOps.js.map +1 -1
  321. package/dist/interactions/actions/clipboard/materializePaste.js +10 -7
  322. package/dist/interactions/actions/clipboard/materializePaste.js.map +1 -1
  323. package/dist/interactions/actions/clipboard/wireFormat.js.map +1 -1
  324. package/dist/interactions/actions/clone/behaviors/cloneByAltDrag.js.map +1 -1
  325. package/dist/interactions/actions/defaultCommitAdapter.js +20 -18
  326. package/dist/interactions/actions/defaultCommitAdapter.js.map +1 -1
  327. package/dist/interactions/actions/defaults/align.js +9 -10
  328. package/dist/interactions/actions/defaults/align.js.map +1 -1
  329. package/dist/interactions/actions/defaults/anchorEditing.js +59 -81
  330. package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -1
  331. package/dist/interactions/actions/defaults/areaSelect.js +35 -38
  332. package/dist/interactions/actions/defaults/areaSelect.js.map +1 -1
  333. package/dist/interactions/actions/defaults/clipboard.js +26 -10
  334. package/dist/interactions/actions/defaults/clipboard.js.map +1 -1
  335. package/dist/interactions/actions/defaults/clone.js +44 -60
  336. package/dist/interactions/actions/defaults/clone.js.map +1 -1
  337. package/dist/interactions/actions/defaults/copySubtree.js +40 -0
  338. package/dist/interactions/actions/defaults/copySubtree.js.map +1 -0
  339. package/dist/interactions/actions/defaults/distribute.js +14 -13
  340. package/dist/interactions/actions/defaults/distribute.js.map +1 -1
  341. package/dist/interactions/actions/defaults/duplicate.js +17 -57
  342. package/dist/interactions/actions/defaults/duplicate.js.map +1 -1
  343. package/dist/interactions/actions/defaults/editAnchors.js +18 -18
  344. package/dist/interactions/actions/defaults/enterTextEdit.js.map +1 -1
  345. package/dist/interactions/actions/defaults/flip.js +52 -46
  346. package/dist/interactions/actions/defaults/flip.js.map +1 -1
  347. package/dist/interactions/actions/defaults/group.js +43 -48
  348. package/dist/interactions/actions/defaults/group.js.map +1 -1
  349. package/dist/interactions/actions/defaults/ingest.js +35 -33
  350. package/dist/interactions/actions/defaults/ingest.js.map +1 -1
  351. package/dist/interactions/actions/defaults/insert.js +50 -51
  352. package/dist/interactions/actions/defaults/insert.js.map +1 -1
  353. package/dist/interactions/actions/defaults/insertPathAnchor.js +7 -7
  354. package/dist/interactions/actions/defaults/lassoSelect.js +67 -70
  355. package/dist/interactions/actions/defaults/lassoSelect.js.map +1 -1
  356. package/dist/interactions/actions/defaults/move.js +267 -249
  357. package/dist/interactions/actions/defaults/move.js.map +1 -1
  358. package/dist/interactions/actions/defaults/nudge.js +40 -68
  359. package/dist/interactions/actions/defaults/nudge.js.map +1 -1
  360. package/dist/interactions/actions/defaults/nudgeSteps.js +37 -0
  361. package/dist/interactions/actions/defaults/nudgeSteps.js.map +1 -0
  362. package/dist/interactions/actions/defaults/reorder.js +2 -0
  363. package/dist/interactions/actions/defaults/reorder.js.map +1 -1
  364. package/dist/interactions/actions/defaults/resize.js +104 -98
  365. package/dist/interactions/actions/defaults/resize.js.map +1 -1
  366. package/dist/interactions/actions/defaults/rotate.js +111 -110
  367. package/dist/interactions/actions/defaults/rotate.js.map +1 -1
  368. package/dist/interactions/actions/defaults/setFill.js +7 -7
  369. package/dist/interactions/actions/defaults/setFillOpacity.js +4 -4
  370. package/dist/interactions/actions/defaults/setStroke.js +12 -12
  371. package/dist/interactions/actions/defaults/setStrokeOpacity.js +6 -6
  372. package/dist/interactions/actions/defaults/sliceOps.js +19 -19
  373. package/dist/interactions/actions/defaults/viewportDragPan.js +37 -26
  374. package/dist/interactions/actions/defaults/viewportDragPan.js.map +1 -1
  375. package/dist/interactions/actions/edit-anchors/geometry.js +28 -23
  376. package/dist/interactions/actions/edit-anchors/geometry.js.map +1 -1
  377. package/dist/interactions/actions/flip/helpers.js +30 -17
  378. package/dist/interactions/actions/flip/helpers.js.map +1 -1
  379. package/dist/interactions/actions/hitSelection.js +8 -0
  380. package/dist/interactions/actions/hitSelection.js.map +1 -0
  381. package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js +14 -18
  382. package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js.map +1 -1
  383. package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js +5 -5
  384. package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js.map +1 -1
  385. package/dist/interactions/actions/move/behaviors/snapToContainer.js +32 -21
  386. package/dist/interactions/actions/move/behaviors/snapToContainer.js.map +1 -1
  387. package/dist/interactions/actions/move/gestureAdapter.js +32 -15
  388. package/dist/interactions/actions/move/gestureAdapter.js.map +1 -1
  389. package/dist/interactions/actions/move/landedDescendants.js +33 -0
  390. package/dist/interactions/actions/move/landedDescendants.js.map +1 -0
  391. package/dist/interactions/actions/outlines/createOutlines.js +18 -18
  392. package/dist/interactions/actions/poseDescriptorDep.js +16 -4
  393. package/dist/interactions/actions/poseDescriptorDep.js.map +1 -1
  394. package/dist/interactions/actions/poseFrame.js +11 -6
  395. package/dist/interactions/actions/poseFrame.js.map +1 -1
  396. package/dist/interactions/actions/previewOverrides.js +5 -5
  397. package/dist/interactions/actions/previewOverrides.js.map +1 -1
  398. package/dist/interactions/actions/selectionSubtree.js +69 -0
  399. package/dist/interactions/actions/selectionSubtree.js.map +1 -0
  400. package/dist/interactions/actions/useStandardActions.js +66 -62
  401. package/dist/interactions/actions/useStandardActions.js.map +1 -1
  402. package/dist/interactions/gestures/dragGesture/dragGesture.js +4 -7
  403. package/dist/interactions/gestures/dragGesture/dragGesture.js.map +1 -1
  404. package/dist/interactions/gestures/dragGesture/dragPointOf.js +23 -0
  405. package/dist/interactions/gestures/dragGesture/dragPointOf.js.map +1 -0
  406. package/dist/interactions/gestures/handleDrag/handleDrag.js +21 -26
  407. package/dist/interactions/gestures/handleDrag/handleDrag.js.map +1 -1
  408. package/dist/interactions/gestures/pointerDrag/pointerDrag.js +8 -6
  409. package/dist/interactions/gestures/pointerDrag/pointerDrag.js.map +1 -1
  410. package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js +8 -4
  411. package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js.map +1 -1
  412. package/dist/{math-Drrw4ewZ.d.ts → math-J-ACHyEg.d.ts} +1 -2
  413. package/dist/math.d.ts +2 -3
  414. package/dist/move.d.ts +12 -11
  415. package/dist/{originProjection-DEklpDc_.d.ts → originProjection-gHnOup4e.d.ts} +1 -1
  416. package/dist/{registerProgram-BMZRDgrh.d.ts → registerProgram-T9S_PfAX.d.ts} +18 -7
  417. package/dist/renderer/DrawCommand.js.map +1 -1
  418. package/dist/renderer/WeaselRenderer.js +75 -73
  419. package/dist/renderer/WeaselRenderer.js.map +1 -1
  420. package/dist/renderer/cache/GLImageCache.js +15 -5
  421. package/dist/renderer/cache/GLImageCache.js.map +1 -1
  422. package/dist/renderer/cache/GLMeshCache.js +23 -23
  423. package/dist/renderer/cache/GLMeshCache.js.map +1 -1
  424. package/dist/renderer/cache/GLTextureCache.js +18 -1
  425. package/dist/renderer/cache/GLTextureCache.js.map +1 -1
  426. package/dist/renderer/cache/cache.js.map +1 -1
  427. package/dist/renderer/cache/markerCommandCache.js.map +1 -1
  428. package/dist/renderer/cache/strokeMeshCache.js.map +1 -1
  429. package/dist/renderer/cullDrawCommands.js +11 -11
  430. package/dist/renderer/draw/batch.js +133 -0
  431. package/dist/renderer/draw/batch.js.map +1 -0
  432. package/dist/renderer/draw/clip.js +89 -0
  433. package/dist/renderer/draw/clip.js.map +1 -0
  434. package/dist/renderer/draw/customShader.js +230 -0
  435. package/dist/renderer/draw/customShader.js.map +1 -0
  436. package/dist/renderer/draw/drawTriangles.js +8 -0
  437. package/dist/renderer/draw/drawTriangles.js.map +1 -0
  438. package/dist/renderer/draw/effects.js +28 -0
  439. package/dist/renderer/draw/effects.js.map +1 -0
  440. package/dist/renderer/draw/flushBatch.js +35 -0
  441. package/dist/renderer/draw/flushBatch.js.map +1 -0
  442. package/dist/renderer/draw/gradient.js +90 -0
  443. package/dist/renderer/draw/gradient.js.map +1 -0
  444. package/dist/renderer/draw/image.js +38 -0
  445. package/dist/renderer/draw/image.js.map +1 -0
  446. package/dist/renderer/draw/mesh.js +16 -0
  447. package/dist/renderer/draw/mesh.js.map +1 -0
  448. package/dist/renderer/draw/paintBind.js +70 -0
  449. package/dist/renderer/draw/paintBind.js.map +1 -0
  450. package/dist/renderer/draw/pathPaint.js +142 -0
  451. package/dist/renderer/draw/pathPaint.js.map +1 -0
  452. package/dist/renderer/draw/scratchPass.js +83 -0
  453. package/dist/renderer/draw/scratchPass.js.map +1 -0
  454. package/dist/renderer/draw/stencil.js +28 -0
  455. package/dist/renderer/draw/stencil.js.map +1 -0
  456. package/dist/renderer/draw/text.js +167 -0
  457. package/dist/renderer/draw/text.js.map +1 -0
  458. package/dist/renderer/draw/uniforms.js +77 -0
  459. package/dist/renderer/draw/uniforms.js.map +1 -0
  460. package/dist/renderer/draw.js +60 -1116
  461. package/dist/renderer/draw.js.map +1 -1
  462. package/dist/renderer/effects/EffectTargets.js +3 -0
  463. package/dist/renderer/effects/EffectTargets.js.map +1 -1
  464. package/dist/renderer/effects/composite.js +7 -5
  465. package/dist/renderer/effects/composite.js.map +1 -1
  466. package/dist/renderer/index.js +18 -17
  467. package/dist/renderer/math/color.js +63 -83
  468. package/dist/renderer/math/color.js.map +1 -1
  469. package/dist/renderer/math/mat3.js +15 -11
  470. package/dist/renderer/math/mat3.js.map +1 -1
  471. package/dist/renderer/math/viewToMat3.js +1 -1
  472. package/dist/renderer/math/viewToMat3.js.map +1 -1
  473. package/dist/renderer/shaders/ShaderProgram.js +13 -13
  474. package/dist/renderer/shaders/ShaderProgram.js.map +1 -1
  475. package/dist/renderer/shaders/glyphPaint.js +3 -3
  476. package/dist/renderer/shaders/glyphPaint.js.map +1 -1
  477. package/dist/renderer/shaders/gradFill.js +2 -1
  478. package/dist/renderer/shaders/gradFill.js.map +1 -1
  479. package/dist/renderer/shaders/pathFill.js +2 -1
  480. package/dist/renderer/shaders/pathFill.js.map +1 -1
  481. package/dist/renderer/shaders/patternFill.js +2 -1
  482. package/dist/renderer/shaders/patternFill.js.map +1 -1
  483. package/dist/renderer/shaders/registerProgram.js.map +1 -1
  484. package/dist/renderer/strokeLengths.js.map +1 -1
  485. package/dist/renderer/textures/registerTexture.js +25 -5
  486. package/dist/renderer/textures/registerTexture.js.map +1 -1
  487. package/dist/renderer.d.ts +16 -15
  488. package/dist/renderer.js +17 -16
  489. package/dist/resize.d.ts +5 -6
  490. package/dist/resize.js +5 -5
  491. package/dist/style.css +1 -1
  492. package/dist/test-hook/install.js +12 -6
  493. package/dist/test-hook/install.js.map +1 -1
  494. package/dist/{test-seams-CuIxe0xY.d.ts → test-seams-DM2B87-g.d.ts} +4 -4
  495. package/dist/test-seams.d.ts +2 -2
  496. package/dist/tools/builtin/ellipse/useEllipseTool.js +1 -0
  497. package/dist/tools/builtin/ellipse/useEllipseTool.js.map +1 -1
  498. package/dist/tools/builtin/hand/useHandTool.js +1 -0
  499. package/dist/tools/builtin/hand/useHandTool.js.map +1 -1
  500. package/dist/tools/builtin/lasso/useLassoTool.js +11 -11
  501. package/dist/tools/builtin/lasso/useLassoTool.js.map +1 -1
  502. package/dist/tools/builtin/line/useLineTool.js +1 -0
  503. package/dist/tools/builtin/line/useLineTool.js.map +1 -1
  504. package/dist/tools/builtin/pen/usePenTool.js +153 -103
  505. package/dist/tools/builtin/pen/usePenTool.js.map +1 -1
  506. package/dist/tools/builtin/pencil/usePencilTool.js +1 -0
  507. package/dist/tools/builtin/pencil/usePencilTool.js.map +1 -1
  508. package/dist/tools/builtin/polygon/usePolygonTool.js +13 -8
  509. package/dist/tools/builtin/polygon/usePolygonTool.js.map +1 -1
  510. package/dist/tools/builtin/rect/useRectTool.js +1 -0
  511. package/dist/tools/builtin/rect/useRectTool.js.map +1 -1
  512. package/dist/tools/builtin/select/selectionContributions.js +24 -23
  513. package/dist/tools/builtin/select/selectionContributions.js.map +1 -1
  514. package/dist/tools/builtin/select/useSelectTool.js +51 -48
  515. package/dist/tools/builtin/select/useSelectTool.js.map +1 -1
  516. package/dist/tools/builtin/shared/pointerFollower.js +17 -0
  517. package/dist/tools/builtin/shared/pointerFollower.js.map +1 -0
  518. package/dist/tools/builtin/slice/useSliceTool.js +49 -54
  519. package/dist/tools/builtin/slice/useSliceTool.js.map +1 -1
  520. package/dist/tools/builtin/star/useStarTool.js +22 -16
  521. package/dist/tools/builtin/star/useStarTool.js.map +1 -1
  522. package/dist/tools/builtin/text/useTextTool.js +13 -2
  523. package/dist/tools/builtin/text/useTextTool.js.map +1 -1
  524. package/dist/tools/useKeybindings.js +14 -30
  525. package/dist/tools/useKeybindings.js.map +1 -1
  526. package/dist/{types-B_9g6hMM.d.ts → types-B4iJRHC3.d.ts} +5 -1
  527. package/dist/{types-A37hYkeR.d.ts → types-k-5Oqh-U.d.ts} +31 -7
  528. package/dist/util/color.js +3 -3
  529. package/dist/util/color.js.map +1 -1
  530. package/dist/util/paint.js.map +1 -1
  531. package/dist/version.js +1 -1
  532. package/package.json +20 -18
  533. package/dist/autoPoseDescriptor-vCdt55xm.d.ts +0 -27
  534. package/dist/builtins-C-VgUlWI.d.ts +0 -4514
  535. package/dist/core/isPlainObject.js.map +0 -1
  536. package/dist/debug/flag.js.map +0 -1
  537. package/dist/interactions/actions/defaults/freshNodeId.js +0 -10
  538. package/dist/interactions/actions/defaults/freshNodeId.js.map +0 -1
  539. package/dist/renderer/shaders/imageFill.js +0 -14
  540. package/dist/renderer/shaders/imageFill.js.map +0 -1
  541. package/dist/tools/prefs.js +0 -47
  542. package/dist/tools/prefs.js.map +0 -1
@@ -1,13 +1,13 @@
1
- import { createPaintAction as e } from "./createPaintAction.js";
2
- import { DEFAULT_FILL_COLOR as t, paintWithColor as n } from "../../../util/paint.js";
1
+ import { DEFAULT_FILL_COLOR as e, paintWithColor as t } from "../../../util/paint.js";
2
+ import { createPaintAction as n } from "./createPaintAction.js";
3
3
  //#region src/interactions/actions/defaults/setFill.ts
4
- var r = e({
4
+ var r = n({
5
5
  id: "setFill",
6
6
  label: "Set fill",
7
7
  dataKey: "fill",
8
- initialState: (e) => ({
9
- color: e("color") ?? t,
10
- paint: e("paint")
8
+ initialState: (t) => ({
9
+ color: t("color") ?? e,
10
+ paint: t("paint")
11
11
  }),
12
12
  readParams: (e, t) => {
13
13
  let n = t?.color, r = t?.paint;
@@ -19,7 +19,7 @@ var r = e({
19
19
  paint: r
20
20
  };
21
21
  },
22
- merge: (e, t) => t.paint === void 0 ? n(e ?? void 0, t.color) : t.paint
22
+ merge: (e, n) => n.paint === void 0 ? t(e ?? void 0, n.color) : n.paint
23
23
  });
24
24
  //#endregion
25
25
  export { r as setFillAction };
@@ -1,13 +1,13 @@
1
- import { createPaintAction as e } from "./createPaintAction.js";
2
- import { DEFAULT_FILL_COLOR as t, paintWithAlpha as n, solid as r } from "../../../util/paint.js";
1
+ import { DEFAULT_FILL_COLOR as e, paintWithAlpha as t, solid as n } from "../../../util/paint.js";
2
+ import { createPaintAction as r } from "./createPaintAction.js";
3
3
  //#region src/interactions/actions/defaults/setFillOpacity.ts
4
- var i = e({
4
+ var i = r({
5
5
  id: "setFillOpacity",
6
6
  label: "Set fill opacity",
7
7
  dataKey: "fill",
8
8
  initialState: (e) => e("alpha01") ?? 1,
9
9
  readParams: (e, t) => t?.alpha01 ?? null,
10
- merge: (e, i) => n(e ?? r(t), i)
10
+ merge: (r, i) => t(r ?? n(e), i)
11
11
  });
12
12
  //#endregion
13
13
  export { i as setFillOpacityAction };
@@ -1,22 +1,22 @@
1
- import { createPaintAction as e } from "./createPaintAction.js";
2
- import { DEFAULT_STROKE_COLOR as t, paintWithColor as n, strokeOf as r, strokeWith as i } from "../../../util/paint.js";
1
+ import { DEFAULT_STROKE_COLOR as e, paintWithColor as t, strokeOf as n, strokeWith as r } from "../../../util/paint.js";
2
+ import { createPaintAction as i } from "./createPaintAction.js";
3
3
  //#region src/interactions/actions/defaults/setStroke.ts
4
- function a(e, t) {
5
- return t.paint === null ? null : t.paint ? e ? {
4
+ function a(e, i) {
5
+ return i.paint === null ? null : i.paint ? e ? {
6
6
  ...e,
7
- paint: t.paint
8
- } : i(t.paint) : e ? {
7
+ paint: i.paint
8
+ } : r(i.paint) : e ? {
9
9
  ...e,
10
- paint: n(e.paint, t.color)
11
- } : r(t.color);
10
+ paint: t(e.paint, i.color)
11
+ } : n(i.color);
12
12
  }
13
- var o = e({
13
+ var o = i({
14
14
  id: "setStroke",
15
15
  label: "Set stroke",
16
16
  dataKey: "stroke",
17
- initialState: (e) => ({
18
- color: e("color") ?? t,
19
- paint: e("paint")
17
+ initialState: (t) => ({
18
+ color: t("color") ?? e,
19
+ paint: t("paint")
20
20
  }),
21
21
  readParams: (e, t) => {
22
22
  let n = t?.color, r = t?.paint;
@@ -1,17 +1,17 @@
1
- import { createPaintAction as e } from "./createPaintAction.js";
2
- import { DEFAULT_STROKE_COLOR as t, paintWithAlpha as n, solid as r, strokeOf as i } from "../../../util/paint.js";
1
+ import { DEFAULT_STROKE_COLOR as e, paintWithAlpha as t, solid as n, strokeOf as r } from "../../../util/paint.js";
2
+ import { createPaintAction as i } from "./createPaintAction.js";
3
3
  //#region src/interactions/actions/defaults/setStrokeOpacity.ts
4
- var a = e({
4
+ var a = i({
5
5
  id: "setStrokeOpacity",
6
6
  label: "Set stroke opacity",
7
7
  dataKey: "stroke",
8
8
  initialState: (e) => e("alpha01") ?? 1,
9
9
  readParams: (e, t) => t?.alpha01 ?? null,
10
- merge: (e, a) => {
11
- let o = e ?? i(t);
10
+ merge: (i, a) => {
11
+ let o = i ?? r(e);
12
12
  return {
13
13
  ...o,
14
- paint: n(o.paint ?? r(t), a)
14
+ paint: t(o.paint ?? n(e), a)
15
15
  };
16
16
  }
17
17
  });
@@ -1,39 +1,39 @@
1
- import { createDeleteOp as e } from "../../../core/ops/delete.js";
2
- import { createInsertOp as t } from "../../../core/ops/create.js";
3
- import { pathToAnchors as n } from "../../../features/paths/anchors.js";
1
+ import { pathToAnchors as e } from "../../../features/paths/anchors.js";
2
+ import { createDeleteOp as t } from "../../../core/ops/delete.js";
3
+ import { createInsertOp as n } from "../../../core/ops/create.js";
4
4
  import { boundsOfPath as r } from "@weasel-js/geom";
5
5
  import { snipPathByPolyline as i, splitPathByPolyline as a } from "@weasel-js/geom/booleans";
6
6
  //#region src/interactions/actions/defaults/sliceOps.ts
7
- function o(n) {
8
- let { cut: o, nextId: l, selection: u } = n, d = n.placePiece ?? ((e, t) => ({
7
+ function o(e) {
8
+ let { cut: o, nextId: l, selection: u } = e, d = e.placePiece ?? ((e, t) => ({
9
9
  pose: s(e.node.pose, r(t)),
10
10
  path: t
11
- })), f = [], p = new Set(u ?? []), m = /* @__PURE__ */ new Set(), h = [], g = n.leaves.map((e, t) => ({
11
+ })), f = [], p = new Set(u ?? []), m = /* @__PURE__ */ new Set(), h = [], g = e.leaves.map((e, t) => ({
12
12
  leaf: e,
13
13
  i: t
14
14
  })).sort((e, t) => t.leaf.index - e.leaf.index || e.i - t.i);
15
- for (let { leaf: n } of g) {
16
- let r = c(n.worldPath) ? i(n.worldPath, o) : a(n.worldPath, o);
15
+ for (let { leaf: e } of g) {
16
+ let r = c(e.worldPath) ? i(e.worldPath, o) : a(e.worldPath, o);
17
17
  if (!r) continue;
18
- let s = n.node.id;
19
- m.add(s), f.push(e({
20
- node: n.node,
21
- index: n.index,
18
+ let s = e.node.id;
19
+ m.add(s), f.push(t({
20
+ node: e.node,
21
+ index: e.index,
22
22
  label: "Slice"
23
23
  }));
24
- for (let e of r) {
25
- let r = d(n, e), i = {
26
- ...n.node,
24
+ for (let t of r) {
25
+ let r = d(e, t), i = {
26
+ ...e.node,
27
27
  id: l(),
28
28
  pose: r.pose,
29
29
  data: {
30
- ...n.node.data,
30
+ ...e.node.data,
31
31
  path: r.path
32
32
  }
33
33
  };
34
- f.push(t({
34
+ f.push(n({
35
35
  node: i,
36
- index: n.index,
36
+ index: e.index,
37
37
  label: "Slice"
38
38
  })), p.has(s) && h.push(i.id);
39
39
  }
@@ -53,7 +53,7 @@ function s(e, t) {
53
53
  height: t.height
54
54
  };
55
55
  }
56
- var c = (e) => e.kind === "polygon" && n(e).closed.some((e) => !e);
56
+ var c = (t) => t.kind === "polygon" && e(t).closed.some((e) => !e);
57
57
  //#endregion
58
58
  export { o as computeSliceOps };
59
59
 
@@ -8,7 +8,10 @@ function n(e, t) {
8
8
  y: (e.current.y - r.y - (e.start.y - n.y)) * n.scale.y
9
9
  };
10
10
  }
11
- var r = {
11
+ function r(e, t) {
12
+ return e === t || e.x === t.x && e.y === t.y && e.scale.x === t.scale.x && e.scale.y === t.scale.y;
13
+ }
14
+ var i = {
12
15
  id: "viewport.dragPan",
13
16
  label: "Drag to pan viewport",
14
17
  group: "viewport",
@@ -17,43 +20,51 @@ var r = {
17
20
  requires: ["view", "debug"],
18
21
  invoker: {
19
22
  timing: "ongoing",
20
- start(r, i) {
21
- let a = r.deps.view;
22
- if (!a) return {};
23
- let o = a.get(), s = t(i?.params) ?? {}, c = s.inertia === !1 ? void 0 : s.inertia, l = {
24
- startView: o,
25
- view: a,
26
- axis: s.axis ?? "both",
27
- inertia: c,
28
- tracker: c && a.decay ? e() : void 0,
23
+ start(i, a) {
24
+ let o = i.deps.view;
25
+ if (!o) return {};
26
+ let s = o.get(), c = t(a?.params) ?? {}, l = c.inertia === !1 ? void 0 : c.inertia, u = {
27
+ startView: s,
28
+ base: s,
29
+ baseScreen: {
30
+ x: 0,
31
+ y: 0
32
+ },
33
+ seen: s,
34
+ view: o,
35
+ axis: c.axis ?? "both",
36
+ inertia: l,
37
+ tracker: l && o.decay ? e() : void 0,
29
38
  lastScreen: {
30
39
  x: 0,
31
40
  y: 0
32
41
  }
33
- }, u = r.deps.debug, d = r.drag?.start;
42
+ }, d = i.deps.debug, f = i.drag?.start;
34
43
  return {
35
44
  kind: "pan",
36
45
  onMove(e) {
37
46
  if (!e.drag) return;
38
- let t = e.drag.screenDelta ?? n(e.drag, l), r = l.axis === "y" ? 0 : t.x, i = l.axis === "x" ? 0 : t.y;
39
- l.tracker && (l.tracker.record(r - l.lastScreen.x, i - l.lastScreen.y, performance.now()), l.lastScreen = {
40
- x: r,
41
- y: i
42
- });
43
- let a = l.startView, o = {
44
- ...a,
45
- x: a.x - r / a.scale.x,
46
- y: a.y - i / a.scale.y
47
+ let t = e.drag.screenDelta ?? n(e.drag, u), i = u.axis === "y" ? 0 : t.x, a = u.axis === "x" ? 0 : t.y;
48
+ u.tracker?.record(i - u.lastScreen.x, a - u.lastScreen.y, performance.now());
49
+ let o = u.view.get();
50
+ r(o, u.seen) || (u.base = o, u.baseScreen = u.lastScreen), u.lastScreen = {
51
+ x: i,
52
+ y: a
53
+ };
54
+ let s = u.base, c = {
55
+ ...s,
56
+ x: s.x - (i - u.baseScreen.x) / s.scale.x,
57
+ y: s.y - (a - u.baseScreen.y) / s.scale.y
47
58
  };
48
- l.view.set(o), u?.recordViewport("pan", a, o, d && {
49
- x: d.x,
50
- y: d.y
59
+ u.view.set(c), u.seen = u.view.get(), d?.recordViewport("pan", s, c, f && {
60
+ x: f.x,
61
+ y: f.y
51
62
  });
52
63
  },
53
64
  onEnd(e, t) {
54
- let { tracker: n, inertia: r, view: i } = l;
65
+ let { tracker: n, inertia: r, view: i } = u;
55
66
  if (t === "cancel" || !n || !r || !i.decay) return;
56
- let { vx: a, vy: o } = n.getVelocity(), s = l.startView.scale;
67
+ let { vx: a, vy: o } = n.getVelocity(), s = u.base.scale;
57
68
  i.decay({
58
69
  velocity: {
59
70
  vx: -a / s.x,
@@ -83,6 +94,6 @@ var r = {
83
94
  enabled: () => !0
84
95
  };
85
96
  //#endregion
86
- export { r as viewportDragPanAction };
97
+ export { i as viewportDragPanAction };
87
98
 
88
99
  //# sourceMappingURL=viewportDragPan.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"viewportDragPan.js","names":["screenDeltaFromWorld","v0","scratch","now","drag","viewportDragPanAction","view","ctx","startView","params","resolveParams","opts","inertia","createVelocityTracker","debug","grab","moveCtx","screen","screenDx","screenDy","sv","next","v","reason","tracker","scale","vx","vy","cur","dx","dy"],"sources":["../../../../src/interactions/actions/defaults/viewportDragPan.ts"],"sourcesContent":["/**\n * `viewportDragPanAction` — ongoing Action descriptor for drag-to-pan the viewport.\n *\n * ## Bindings\n * None of its own. The hand tool binds a drag to it, and a canvas that pans on\n * any unclaimed drag adds `dragPanContribution`.\n *\n * ## Design notes\n * The drag delta from the dispatcher is in screen space (pixels). The pan\n * formula converts screen pixels to world units by dividing by zoom:\n *\n * newView.x = startView.x - screenDx / startView.scale.x\n * newView.y = startView.y - screenDy / startView.scale.y\n *\n * where `screenDx` / `screenDy` are the screen-space pixel deltas from the\n * drag origin. This ensures that at any zoom level, the drag behavior is\n * consistent: 1 screen pixel always pans the same amount relative to the\n * viewport's zoom (e.g., at 1x zoom: 100px → 100 world units; at 2x zoom:\n * 100px → 50 world units). The camera moves opposite to the drag direction\n * so that the scene content appears to follow the pointer.\n *\n * The descriptor captures `startView` in its own scratch at `start` time,\n * parallel to `useHandTool`'s `startView` capture in its scratch object.\n *\n * ## Axis locking and inertia\n * Both are read from the binding's `params` at `start`, so any consumer\n * binding this action gets them — not just `useHandTool`. `axis` drops one\n * component of every pan delta. `inertia` coasts the view after release,\n * through the optional `view.decay` dep; with no such dep wired the pan\n * simply lands, which is what an unconfigured consumer already expects.\n *\n * @see useHandTool — the React hook this descriptor parallels.\n */\n\nimport type { Action } from '@weasel-js/routing';\nimport { resolveParams, type InvocationCtx, type OngoingHandle, type BindingOpts } from '@weasel-js/routing';\nimport type { View } from 'core/viewport/view';\nimport type { ViewApi } from '../depSchema';\nimport type { InertiaConfig } from 'core/viewport/useDecayLoop';\nimport { createVelocityTracker, type VelocityTracker } from 'core/viewport/createVelocityTracker';\n\n// ---------------------------------------------------------------------------\n// Internal scratch\n// ---------------------------------------------------------------------------\n\ninterface DragPanScratch {\n startView: View;\n view: ViewApi;\n axis: 'both' | 'x' | 'y';\n inertia: InertiaConfig | undefined;\n tracker: VelocityTracker | undefined;\n lastScreen: { x: number; y: number };\n}\n\n/**\n * Rebuild the client-pixel drag delta from the world one, for an event source\n * that supplied no `clientX`/`clientY`.\n *\n * A world delta is self-referential mid-pan — its two ends were measured under\n * different views — so it cannot simply be scaled. Undoing each end against the\n * view that produced it recovers the client delta exactly, since\n * `world = (client - origin) / scale + view` and neither the canvas origin nor\n * the scale moves during a pan.\n */\nfunction screenDeltaFromWorld(\n drag: NonNullable<InvocationCtx['drag']>,\n scratch: DragPanScratch,\n): { x: number; y: number } {\n const v0 = scratch.startView;\n const now = scratch.view.get();\n return {\n x: (drag.current.x - now.x - (drag.start.x - v0.x)) * v0.scale.x,\n y: (drag.current.y - now.y - (drag.start.y - v0.y)) * v0.scale.y,\n };\n}\n\n/** Binding params `viewport.dragPan` understands. `useHandTool` supplies both;\n * a bare binding supplies neither and pans both axes with no coasting. */\nexport interface DragPanParams {\n axis?: 'both' | 'x' | 'y';\n inertia?: false | InertiaConfig;\n}\n\n// ---------------------------------------------------------------------------\n// Descriptor\n// ---------------------------------------------------------------------------\n\n/**\n * @experimental\n * Static descriptor for the `viewport.dragPan` Action.\n *\n * Requires dep-schema entry: `view`.\n *\n * Translates the viewport by the screen-space drag delta so the canvas content\n * follows the pointer. Produces no scene ops — view changes are not undoable.\n */\n// No `eligible` field → viewport pan is always eligible across all modes.\nexport const viewportDragPanAction: Action & { requires: string[] } = {\n id: 'viewport.dragPan',\n label: 'Drag to pan viewport',\n group: 'viewport',\n // Hover hint: when this action would win the drag at the hovered point\n // (e.g. empty canvas with no marquee-capable tool ahead of it), the\n // hover-cursor pump shows the open hand.\n cursor: 'grab',\n // ...and the closed hand once the pan is actually running. This was\n // `useHandTool`'s `engaged: { cursor: 'grabbing' }` — a phase-table entry\n // on a tool, which meant a consumer who bound `viewport.dragPan` without\n // the hand tool got no state cursor at all.\n activeCursor: 'grabbing',\n requires: ['view', 'debug'],\n invoker: {\n timing: 'ongoing',\n start(ctx: InvocationCtx, opts?: BindingOpts): OngoingHandle {\n const view = ctx.deps.view;\n if (!view) return {};\n\n const startView = view.get();\n // Gesture-driven ongoing actions never see `ctx.params` — the dispatcher\n // hands the binding's unresolved `opts` here and nowhere else, and pumps\n // `onMove` / `onEnd` with an empty deps bag. Everything the gesture needs\n // has to be captured now.\n const params = (resolveParams(opts?.params) ?? {}) as DragPanParams;\n const inertia = params.inertia === false ? undefined : params.inertia;\n const scratch: DragPanScratch = {\n startView,\n view,\n axis: params.axis ?? 'both',\n inertia,\n // Only track when a coast could actually happen, so the common\n // no-inertia drag does no per-move work.\n tracker: inertia && view.decay ? createVelocityTracker() : undefined,\n lastScreen: { x: 0, y: 0 },\n };\n const debug = ctx.deps.debug;\n const grab = ctx.drag?.start;\n\n return {\n kind: 'pan',\n onMove(moveCtx: InvocationCtx): void {\n if (!moveCtx.drag) return;\n // Use `screenDelta` (client/CSS pixels), NOT `delta` (world). Pan\n // mutates the view itself, so world deltas are self-referential —\n // after the first commit, `toWorld(currentClient)` returns a\n // position offset by the just-applied pan, halving the apparent\n // movement on every subsequent pointermove. Screen coords come\n // straight from the DOM event and don't drift.\n const screen = moveCtx.drag.screenDelta ?? screenDeltaFromWorld(moveCtx.drag, scratch);\n // An axis lock drops the other component of the *cumulative* delta,\n // so the locked axis never moves however the pointer wanders.\n const screenDx = scratch.axis === 'y' ? 0 : screen.x;\n const screenDy = scratch.axis === 'x' ? 0 : screen.y;\n if (scratch.tracker) {\n scratch.tracker.record(\n screenDx - scratch.lastScreen.x,\n screenDy - scratch.lastScreen.y,\n performance.now(),\n );\n scratch.lastScreen = { x: screenDx, y: screenDy };\n }\n const sv = scratch.startView;\n // 1 screen px maps to 1/scale world units (at 2x zoom, 100 px →\n // 50 world units of pan).\n const next = {\n ...sv,\n x: sv.x - screenDx / sv.scale.x,\n y: sv.y - screenDy / sv.scale.y,\n };\n scratch.view.set(next);\n debug?.recordViewport('pan', sv, next, grab && { x: grab.x, y: grab.y });\n },\n onEnd(_endCtx: InvocationCtx, reason: 'commit' | 'cancel'): void {\n // No scene ops to commit; the pan itself is already live. What is\n // left is the coast, and only for a drag that actually ended.\n const { tracker, inertia, view: v } = scratch;\n if (reason === 'cancel' || !tracker || !inertia || !v.decay) return;\n const { vx, vy } = tracker.getVelocity();\n const scale = scratch.startView.scale;\n v.decay({\n // Screen px/ms → world units/ms, matching the onMove conversion.\n velocity: { vx: -vx / scale.x, vy: -vy / scale.y },\n friction: inertia.friction,\n minSpeed: inertia.minSpeed,\n boundary: inertia.boundary,\n viewBounds: inertia.bounds,\n initialPosition: { x: v.get().x, y: v.get().y },\n onTick: (dx, dy) => {\n const cur = v.get();\n v.set({ ...cur, x: cur.x + dx, y: cur.y + dy });\n },\n });\n },\n };\n },\n },\n enabled: () => true,\n};\n"],"mappings":";;;AAgEA,SAASA,EACP,GACA,GAC0B;CAC1B,IAAMC,IAAKC,EAAQ,WACbC,IAAMD,EAAQ,KAAK,IAAI;CAC7B,OAAO;EACL,IAAIE,EAAK,QAAQ,IAAID,EAAI,KAAKC,EAAK,MAAM,IAAIH,EAAG,MAAMA,EAAG,MAAM;EAC/D,IAAIG,EAAK,QAAQ,IAAID,EAAI,KAAKC,EAAK,MAAM,IAAIH,EAAG,MAAMA,EAAG,MAAM;CACjE;AACF;AAuBA,IAAaI,IAAyD;CACpE,IAAI;CACJ,OAAO;CACP,OAAO;CAIP,QAAQ;CAKR,cAAc;CACd,UAAU,CAAC,QAAQ,OAAO;CAC1B,SAAS;EACP,QAAQ;EACR,MAAM,GAAoB,GAAmC;GAC3D,IAAMC,IAAOC,EAAI,KAAK;GACtB,IAAI,CAACD,GAAM,OAAO,CAAC;GAEnB,IAAME,IAAYF,EAAK,IAAI,GAKrBG,IAAUC,EAAcC,GAAM,MAAM,KAAK,CAAC,GAC1CC,IAAUH,EAAO,YAAY,KAAQ,KAAA,IAAYA,EAAO,SACxDP,IAA0B;IAC9B;IACA;IACA,MAAMO,EAAO,QAAQ;IACrB;IAGA,SAASG,KAAWN,EAAK,QAAQO,EAAsB,IAAI,KAAA;IAC3D,YAAY;KAAE,GAAG;KAAG,GAAG;IAAE;GAC3B,GACMC,IAAQP,EAAI,KAAK,OACjBQ,IAAOR,EAAI,MAAM;GAEvB,OAAO;IACL,MAAM;IACN,OAAO,GAA8B;KACnC,IAAI,CAACS,EAAQ,MAAM;KAOnB,IAAMC,IAASD,EAAQ,KAAK,eAAehB,EAAqBgB,EAAQ,MAAMd,CAAO,GAG/EgB,IAAWhB,EAAQ,SAAS,MAAM,IAAIe,EAAO,GAC7CE,IAAWjB,EAAQ,SAAS,MAAM,IAAIe,EAAO;KACnD,AAAIf,EAAQ,YACVA,EAAQ,QAAQ,OACdgB,IAAWhB,EAAQ,WAAW,GAC9BiB,IAAWjB,EAAQ,WAAW,GAC9B,YAAY,IAAI,CAClB,GACA,EAAQ,aAAa;MAAE,GAAGgB;MAAU,GAAGC;KAAS;KAElD,IAAMC,IAAKlB,EAAQ,WAGbmB,IAAO;MACX,GAAGD;MACH,GAAGA,EAAG,IAAIF,IAAWE,EAAG,MAAM;MAC9B,GAAGA,EAAG,IAAID,IAAWC,EAAG,MAAM;KAChC;KAEA,AADAlB,EAAQ,KAAK,IAAImB,CAAI,GACrBP,GAAO,eAAe,OAAOM,GAAIC,GAAMN,KAAQ;MAAE,GAAGA,EAAK;MAAG,GAAGA,EAAK;KAAE,CAAC;IACzE;IACA,MAAM,GAAwB,GAAmC;KAG/D,IAAM,EAAE,YAAS,YAAS,MAAMO,MAAMpB;KACtC,IAAIqB,MAAW,YAAY,CAACC,KAAW,CAACZ,KAAW,CAACU,EAAE,OAAO;KAC7D,IAAM,EAAE,OAAI,UAAOE,EAAQ,YAAY,GACjCC,IAAQvB,EAAQ,UAAU;KAChC,EAAE,MAAM;MAEN,UAAU;OAAE,IAAI,CAACwB,IAAKD,EAAM;OAAG,IAAI,CAACE,IAAKF,EAAM;MAAE;MACjD,UAAUb,EAAQ;MAClB,UAAUA,EAAQ;MAClB,UAAUA,EAAQ;MAClB,YAAYA,EAAQ;MACpB,iBAAiB;OAAE,GAAGU,EAAE,IAAI,CAAC,CAAC;OAAG,GAAGA,EAAE,IAAI,CAAC,CAAC;MAAE;MAC9C,SAAS,GAAI,MAAO;OAClB,IAAMM,IAAMN,EAAE,IAAI;OAClB,EAAE,IAAI;QAAE,GAAGM;QAAK,GAAGA,EAAI,IAAIC;QAAI,GAAGD,EAAI,IAAIE;OAAG,CAAC;MAChD;KACF,CAAC;IACH;GACF;EACF;CACF;CACA,eAAe;AACjB"}
1
+ {"version":3,"file":"viewportDragPan.js","names":["screenDeltaFromWorld","v0","scratch","now","drag","sameCamera","a","b","viewportDragPanAction","view","ctx","startView","params","resolveParams","opts","inertia","createVelocityTracker","debug","grab","moveCtx","screen","screenDx","screenDy","sv","next","v","reason","tracker","scale","vx","vy","cur","dx","dy"],"sources":["../../../../src/interactions/actions/defaults/viewportDragPan.ts"],"sourcesContent":["/**\n * `viewportDragPanAction` — ongoing Action descriptor for drag-to-pan the viewport.\n *\n * ## Bindings\n * None of its own. The hand tool binds a drag to it, and a canvas that pans on\n * any unclaimed drag adds `dragPanContribution`.\n *\n * ## Design notes\n * The drag delta from the dispatcher is in screen space (pixels). The pan\n * formula converts screen pixels to world units by dividing by zoom:\n *\n * newView.x = startView.x - screenDx / startView.scale.x\n * newView.y = startView.y - screenDy / startView.scale.y\n *\n * where `screenDx` / `screenDy` are the screen-space pixel deltas from the\n * drag origin. This ensures that at any zoom level, the drag behavior is\n * consistent: 1 screen pixel always pans the same amount relative to the\n * viewport's zoom (e.g., at 1x zoom: 100px → 100 world units; at 2x zoom:\n * 100px → 50 world units). The camera moves opposite to the drag direction\n * so that the scene content appears to follow the pointer.\n *\n * The descriptor captures `startView` in its own scratch at `start` time,\n * parallel to `useHandTool`'s `startView` capture in its scratch object.\n *\n * ## Axis locking and inertia\n * Both are read from the binding's `params` at `start`, so any consumer\n * binding this action gets them — not just `useHandTool`. `axis` drops one\n * component of every pan delta. `inertia` coasts the view after release,\n * through the optional `view.decay` dep; with no such dep wired the pan\n * simply lands, which is what an unconfigured consumer already expects.\n *\n * @see useHandTool — the React hook this descriptor parallels.\n */\n\nimport type { Action } from '@weasel-js/routing';\nimport { resolveParams, type InvocationCtx, type OngoingHandle, type BindingOpts } from '@weasel-js/routing';\nimport type { View } from 'core/viewport/view';\nimport type { ViewApi } from '../depSchema';\nimport type { InertiaConfig } from 'core/viewport/useDecayLoop';\nimport { createVelocityTracker, type VelocityTracker } from 'core/viewport/createVelocityTracker';\n\n// ---------------------------------------------------------------------------\n// Internal scratch\n// ---------------------------------------------------------------------------\n\ninterface DragPanScratch {\n startView: View;\n /** The view the pan is measured from, and the cumulative screen delta it\n * was taken at. The press, until something else moves the camera. */\n base: View;\n baseScreen: { x: number; y: number };\n /** The view as this pan last left it. */\n seen: View;\n view: ViewApi;\n axis: 'both' | 'x' | 'y';\n inertia: InertiaConfig | undefined;\n tracker: VelocityTracker | undefined;\n lastScreen: { x: number; y: number };\n}\n\n/**\n * Rebuild the client-pixel drag delta from the world one, for an event source\n * that supplied no `clientX`/`clientY`.\n *\n * A world delta is self-referential mid-pan — its two ends were measured under\n * different views — so it cannot simply be scaled. Undoing each end against the\n * view that produced it recovers the client delta exactly, since\n * `world = (client - origin) / scale + view` and neither the canvas origin nor\n * the scale moves during a pan.\n */\nfunction screenDeltaFromWorld(\n drag: NonNullable<InvocationCtx['drag']>,\n scratch: DragPanScratch,\n): { x: number; y: number } {\n const v0 = scratch.startView;\n const now = scratch.view.get();\n return {\n x: (drag.current.x - now.x - (drag.start.x - v0.x)) * v0.scale.x,\n y: (drag.current.y - now.y - (drag.start.y - v0.y)) * v0.scale.y,\n };\n}\n\nfunction sameCamera(a: View, b: View): boolean {\n return a === b\n || (a.x === b.x && a.y === b.y && a.scale.x === b.scale.x && a.scale.y === b.scale.y);\n}\n\n/** Binding params `viewport.dragPan` understands. `useHandTool` supplies both;\n * a bare binding supplies neither and pans both axes with no coasting. */\nexport interface DragPanParams {\n axis?: 'both' | 'x' | 'y';\n inertia?: false | InertiaConfig;\n}\n\n// ---------------------------------------------------------------------------\n// Descriptor\n// ---------------------------------------------------------------------------\n\n/**\n * @experimental\n * Static descriptor for the `viewport.dragPan` Action.\n *\n * Requires dep-schema entry: `view`.\n *\n * Translates the viewport by the screen-space drag delta so the canvas content\n * follows the pointer. Produces no scene ops — view changes are not undoable.\n */\n// No `eligible` field → viewport pan is always eligible across all modes.\nexport const viewportDragPanAction: Action & { requires: string[] } = {\n id: 'viewport.dragPan',\n label: 'Drag to pan viewport',\n group: 'viewport',\n // Hover hint: when this action would win the drag at the hovered point\n // (e.g. empty canvas with no marquee-capable tool ahead of it), the\n // hover-cursor pump shows the open hand.\n cursor: 'grab',\n // ...and the closed hand once the pan is actually running. This was\n // `useHandTool`'s `engaged: { cursor: 'grabbing' }` — a phase-table entry\n // on a tool, which meant a consumer who bound `viewport.dragPan` without\n // the hand tool got no state cursor at all.\n activeCursor: 'grabbing',\n requires: ['view', 'debug'],\n invoker: {\n timing: 'ongoing',\n start(ctx: InvocationCtx, opts?: BindingOpts): OngoingHandle {\n const view = ctx.deps.view;\n if (!view) return {};\n\n const startView = view.get();\n // Gesture-driven ongoing actions never see `ctx.params` — the dispatcher\n // hands the binding's unresolved `opts` here and nowhere else, and pumps\n // `onMove` / `onEnd` with an empty deps bag. Everything the gesture needs\n // has to be captured now.\n const params = (resolveParams(opts?.params) ?? {}) as DragPanParams;\n const inertia = params.inertia === false ? undefined : params.inertia;\n const scratch: DragPanScratch = {\n startView,\n base: startView,\n baseScreen: { x: 0, y: 0 },\n seen: startView,\n view,\n axis: params.axis ?? 'both',\n inertia,\n // Only track when a coast could actually happen, so the common\n // no-inertia drag does no per-move work.\n tracker: inertia && view.decay ? createVelocityTracker() : undefined,\n lastScreen: { x: 0, y: 0 },\n };\n const debug = ctx.deps.debug;\n const grab = ctx.drag?.start;\n\n return {\n kind: 'pan',\n onMove(moveCtx: InvocationCtx): void {\n if (!moveCtx.drag) return;\n // Use `screenDelta` (client/CSS pixels), NOT `delta` (world). Pan\n // mutates the view itself, so world deltas are self-referential —\n // after the first commit, `toWorld(currentClient)` returns a\n // position offset by the just-applied pan, halving the apparent\n // movement on every subsequent pointermove. Screen coords come\n // straight from the DOM event and don't drift.\n const screen = moveCtx.drag.screenDelta ?? screenDeltaFromWorld(moveCtx.drag, scratch);\n // An axis lock drops the other component of the *cumulative* delta,\n // so the locked axis never moves however the pointer wanders.\n const screenDx = scratch.axis === 'y' ? 0 : screen.x;\n const screenDy = scratch.axis === 'x' ? 0 : screen.y;\n scratch.tracker?.record(\n screenDx - scratch.lastScreen.x,\n screenDy - scratch.lastScreen.y,\n performance.now(),\n );\n // A zoom or pan from elsewhere while the drag is held (a wheel, a\n // key) is kept: the pan carries on from where it left the camera.\n const now = scratch.view.get();\n if (!sameCamera(now, scratch.seen)) {\n scratch.base = now;\n scratch.baseScreen = scratch.lastScreen;\n }\n scratch.lastScreen = { x: screenDx, y: screenDy };\n const sv = scratch.base;\n // 1 screen px maps to 1/scale world units (at 2x zoom, 100 px →\n // 50 world units of pan).\n const next = {\n ...sv,\n x: sv.x - (screenDx - scratch.baseScreen.x) / sv.scale.x,\n y: sv.y - (screenDy - scratch.baseScreen.y) / sv.scale.y,\n };\n scratch.view.set(next);\n scratch.seen = scratch.view.get();\n debug?.recordViewport('pan', sv, next, grab && { x: grab.x, y: grab.y });\n },\n onEnd(_endCtx: InvocationCtx, reason: 'commit' | 'cancel'): void {\n // No scene ops to commit; the pan itself is already live. What is\n // left is the coast, and only for a drag that actually ended.\n const { tracker, inertia, view: v } = scratch;\n if (reason === 'cancel' || !tracker || !inertia || !v.decay) return;\n const { vx, vy } = tracker.getVelocity();\n const scale = scratch.base.scale;\n v.decay({\n // Screen px/ms → world units/ms, matching the onMove conversion.\n velocity: { vx: -vx / scale.x, vy: -vy / scale.y },\n friction: inertia.friction,\n minSpeed: inertia.minSpeed,\n boundary: inertia.boundary,\n viewBounds: inertia.bounds,\n initialPosition: { x: v.get().x, y: v.get().y },\n onTick: (dx, dy) => {\n const cur = v.get();\n v.set({ ...cur, x: cur.x + dx, y: cur.y + dy });\n },\n });\n },\n };\n },\n },\n enabled: () => true,\n};\n"],"mappings":";;;AAsEA,SAASA,EACP,GACA,GAC0B;CAC1B,IAAMC,IAAKC,EAAQ,WACbC,IAAMD,EAAQ,KAAK,IAAI;CAC7B,OAAO;EACL,IAAIE,EAAK,QAAQ,IAAID,EAAI,KAAKC,EAAK,MAAM,IAAIH,EAAG,MAAMA,EAAG,MAAM;EAC/D,IAAIG,EAAK,QAAQ,IAAID,EAAI,KAAKC,EAAK,MAAM,IAAIH,EAAG,MAAMA,EAAG,MAAM;CACjE;AACF;AAEA,SAASI,EAAW,GAAS,GAAkB;CAC7C,OAAOC,MAAMC,KACPD,EAAE,MAAMC,EAAE,KAAKD,EAAE,MAAMC,EAAE,KAAKD,EAAE,MAAM,MAAMC,EAAE,MAAM,KAAKD,EAAE,MAAM,MAAMC,EAAE,MAAM;AACvF;AAuBA,IAAaC,IAAyD;CACpE,IAAI;CACJ,OAAO;CACP,OAAO;CAIP,QAAQ;CAKR,cAAc;CACd,UAAU,CAAC,QAAQ,OAAO;CAC1B,SAAS;EACP,QAAQ;EACR,MAAM,GAAoB,GAAmC;GAC3D,IAAMC,IAAOC,EAAI,KAAK;GACtB,IAAI,CAACD,GAAM,OAAO,CAAC;GAEnB,IAAME,IAAYF,EAAK,IAAI,GAKrBG,IAAUC,EAAcC,GAAM,MAAM,KAAK,CAAC,GAC1CC,IAAUH,EAAO,YAAY,KAAQ,KAAA,IAAYA,EAAO,SACxDV,IAA0B;IAC9B;IACA,MAAMS;IACN,YAAY;KAAE,GAAG;KAAG,GAAG;IAAE;IACzB,MAAMA;IACN;IACA,MAAMC,EAAO,QAAQ;IACrB;IAGA,SAASG,KAAWN,EAAK,QAAQO,EAAsB,IAAI,KAAA;IAC3D,YAAY;KAAE,GAAG;KAAG,GAAG;IAAE;GAC3B,GACMC,IAAQP,EAAI,KAAK,OACjBQ,IAAOR,EAAI,MAAM;GAEvB,OAAO;IACL,MAAM;IACN,OAAO,GAA8B;KACnC,IAAI,CAACS,EAAQ,MAAM;KAOnB,IAAMC,IAASD,EAAQ,KAAK,eAAenB,EAAqBmB,EAAQ,MAAMjB,CAAO,GAG/EmB,IAAWnB,EAAQ,SAAS,MAAM,IAAIkB,EAAO,GAC7CE,IAAWpB,EAAQ,SAAS,MAAM,IAAIkB,EAAO;KACnD,EAAQ,SAAS,OACfC,IAAWnB,EAAQ,WAAW,GAC9BoB,IAAWpB,EAAQ,WAAW,GAC9B,YAAY,IAAI,CAClB;KAGA,IAAMC,IAAMD,EAAQ,KAAK,IAAI;KAK7B,AAJKG,EAAWF,GAAKD,EAAQ,IAAI,MAC/B,EAAQ,OAAOC,GACf,EAAQ,aAAaD,EAAQ,aAE/B,EAAQ,aAAa;MAAE,GAAGmB;MAAU,GAAGC;KAAS;KAChD,IAAMC,IAAKrB,EAAQ,MAGbsB,IAAO;MACX,GAAGD;MACH,GAAGA,EAAG,KAAKF,IAAWnB,EAAQ,WAAW,KAAKqB,EAAG,MAAM;MACvD,GAAGA,EAAG,KAAKD,IAAWpB,EAAQ,WAAW,KAAKqB,EAAG,MAAM;KACzD;KAGA,AAFArB,EAAQ,KAAK,IAAIsB,CAAI,GACrB,EAAQ,OAAOtB,EAAQ,KAAK,IAAI,GAChCe,GAAO,eAAe,OAAOM,GAAIC,GAAMN,KAAQ;MAAE,GAAGA,EAAK;MAAG,GAAGA,EAAK;KAAE,CAAC;IACzE;IACA,MAAM,GAAwB,GAAmC;KAG/D,IAAM,EAAE,YAAS,YAAS,MAAMO,MAAMvB;KACtC,IAAIwB,MAAW,YAAY,CAACC,KAAW,CAACZ,KAAW,CAACU,EAAE,OAAO;KAC7D,IAAM,EAAE,OAAI,UAAOE,EAAQ,YAAY,GACjCC,IAAQ1B,EAAQ,KAAK;KAC3B,EAAE,MAAM;MAEN,UAAU;OAAE,IAAI,CAAC2B,IAAKD,EAAM;OAAG,IAAI,CAACE,IAAKF,EAAM;MAAE;MACjD,UAAUb,EAAQ;MAClB,UAAUA,EAAQ;MAClB,UAAUA,EAAQ;MAClB,YAAYA,EAAQ;MACpB,iBAAiB;OAAE,GAAGU,EAAE,IAAI,CAAC,CAAC;OAAG,GAAGA,EAAE,IAAI,CAAC,CAAC;MAAE;MAC9C,SAAS,GAAI,MAAO;OAClB,IAAMM,IAAMN,EAAE,IAAI;OAClB,EAAE,IAAI;QAAE,GAAGM;QAAK,GAAGA,EAAI,IAAIC;QAAI,GAAGD,EAAI,IAAIE;OAAG,CAAC;MAChD;KACF,CAAC;IACH;GACF;EACF;CACF;CACA,eAAe;AACjB"}
@@ -1,52 +1,57 @@
1
1
  import { PATH_C as e, PATH_L as t, PATH_M as n, PATH_Q as r, PATH_Z as i, forEachSegment as a } from "@weasel-js/geom";
2
2
  //#region src/interactions/actions/edit-anchors/geometry.ts
3
3
  function o(o) {
4
- let { commands: s, coords: c } = o, l = [], u = null, d = (e, t) => {
4
+ let { commands: c, coords: l } = o, u = [], d = null, f = null, p = (e, t) => {
5
5
  let n = {
6
- anchorIndex: l.length,
7
- x: c[e],
8
- y: c[e + 1],
6
+ anchorIndex: u.length,
7
+ x: l[e],
8
+ y: l[e + 1],
9
9
  coordIndex: e,
10
10
  ...t ? { controlIn: t } : {}
11
11
  };
12
- l.push(n), u = n;
12
+ u.push(n), d = n;
13
13
  };
14
- return a(s, c, (a, o) => {
14
+ return a(c, l, (a, o) => {
15
15
  switch (a) {
16
16
  case n:
17
+ p(o), f = d;
18
+ break;
17
19
  case t:
18
- d(o);
20
+ p(o);
19
21
  break;
20
22
  case e:
21
- u && (u.controlOut = {
22
- x: c[o],
23
- y: c[o + 1],
23
+ d && (d.controlOut = {
24
+ x: l[o],
25
+ y: l[o + 1],
24
26
  coordIndex: o
25
- }), d(o + 4, {
26
- x: c[o + 2],
27
- y: c[o + 3],
27
+ }), p(o + 4, {
28
+ x: l[o + 2],
29
+ y: l[o + 3],
28
30
  coordIndex: o + 2
29
31
  });
30
32
  break;
31
33
  case r:
32
- u && (u.controlOut = {
33
- x: c[o],
34
- y: c[o + 1],
34
+ d && (d.controlOut = {
35
+ x: l[o],
36
+ y: l[o + 1],
35
37
  coordIndex: o
36
- }), d(o + 2, {
37
- x: c[o],
38
- y: c[o + 1],
38
+ }), p(o + 2, {
39
+ x: l[o],
40
+ y: l[o + 1],
39
41
  coordIndex: o
40
42
  });
41
43
  break;
42
44
  case i:
43
- u = null;
45
+ s(u, f, d), d = null, f = null;
44
46
  break;
45
47
  default: throw Error(`enumerateAnchors: unknown command ${a}`);
46
48
  }
47
- }), l;
49
+ }), u;
50
+ }
51
+ function s(e, t, n) {
52
+ t && n && t !== n && n.controlIn && n.x === t.x && n.y === t.y && (e.pop(), t.closeCoordIndex = n.coordIndex, t.controlIn = n.controlIn);
48
53
  }
49
- function s(e, t, n, r) {
54
+ function c(e, t, n, r) {
50
55
  let i = new Float32Array(e.coords);
51
56
  return i[t] = n, i[t + 1] = r, {
52
57
  kind: "polygon",
@@ -56,6 +61,6 @@ function s(e, t, n, r) {
56
61
  };
57
62
  }
58
63
  //#endregion
59
- export { o as enumerateAnchors, s as withCoord };
64
+ export { o as enumerateAnchors, c as withCoord };
60
65
 
61
66
  //# sourceMappingURL=geometry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"geometry.js","names":["enumerateAnchors","path","anchors","lastAnchor","push","a","coords","coordIndex","controlIn","forEachSegment","commands","cmd","PATH_M","PATH_L","ci","PATH_C","PATH_Q","PATH_Z","withCoord","next","x","y"],"sources":["../../../../src/interactions/actions/edit-anchors/geometry.ts"],"sourcesContent":["import { forEachSegment, PATH_C, PATH_L, PATH_M, PATH_Q, PATH_Z, type PolygonPath } from '@weasel-js/geom';\n\n/** A single anchor on a `PolygonPath`, with its incoming/outgoing bezier\n * control points (when present). `coordIndex` points at the anchor's own\n * on-curve x in the `coords` array. `inCoordIndex` / `outCoordIndex` point\n * at the corresponding control x. */\nexport interface PathAnchor {\n /** Sequential anchor index in walk order (0-based). */\n anchorIndex: number;\n /** On-curve point. */\n x: number;\n y: number;\n /** Incoming control (from the previous segment, when it was C/Q). */\n controlIn?: { x: number; y: number; coordIndex: number };\n /** Outgoing control (from the next segment, when it is C/Q). */\n controlOut?: { x: number; y: number; coordIndex: number };\n /** Index of the anchor's on-curve x in `coords`. */\n coordIndex: number;\n}\n\n/** Walk a PolygonPath's command stream and yield one `PathAnchor` per\n * on-curve point. Adjacent C/Q control points are attached as\n * `controlIn`/`controlOut`. Subpath boundaries (M after a previous M or Z)\n * start fresh — the new M's anchor has no `controlIn` from a Z. */\nexport function enumerateAnchors(path: PolygonPath): PathAnchor[] {\n const { commands, coords } = path;\n const anchors: PathAnchor[] = [];\n let lastAnchor: PathAnchor | null = null;\n\n const push = (coordIndex: number, controlIn?: PathAnchor['controlIn']): void => {\n const a: PathAnchor = {\n anchorIndex: anchors.length,\n x: coords[coordIndex],\n y: coords[coordIndex + 1],\n coordIndex,\n ...(controlIn ? { controlIn } : {}),\n };\n anchors.push(a);\n lastAnchor = a;\n };\n\n forEachSegment(commands, coords, (cmd, ci) => {\n switch (cmd) {\n case PATH_M:\n case PATH_L:\n push(ci);\n break;\n case PATH_C:\n if (lastAnchor) {\n lastAnchor.controlOut = { x: coords[ci], y: coords[ci + 1], coordIndex: ci };\n }\n push(ci + 4, { x: coords[ci + 2], y: coords[ci + 3], coordIndex: ci + 2 });\n break;\n case PATH_Q:\n if (lastAnchor) {\n lastAnchor.controlOut = { x: coords[ci], y: coords[ci + 1], coordIndex: ci };\n }\n push(ci + 2, { x: coords[ci], y: coords[ci + 1], coordIndex: ci });\n break;\n case PATH_Z:\n lastAnchor = null;\n break;\n default:\n throw new Error(`enumerateAnchors: unknown command ${cmd}`);\n }\n });\n return anchors;\n}\n\n/** Mutate `coords` in-place: write `(x, y)` at `coordIndex`, return a new\n * PolygonPath sharing the same commands but with a fresh coords buffer. */\nexport function withCoord(path: PolygonPath, coordIndex: number, x: number, y: number): PolygonPath {\n const next = new Float32Array(path.coords);\n next[coordIndex] = x;\n next[coordIndex + 1] = y;\n return { kind: 'polygon', commands: path.commands, coords: next, fillRule: path.fillRule };\n}\n\n/** Translate anchor `anchorIndex` AND its attached control handles\n * (`controlIn` / `controlOut`) by `(dx, dy)`. Used by `editAnchorsAction`\n * when the dragged affordance is the anchor itself — moving the anchor\n * without its handles would shear the surrounding bezier segments. */\nexport function translateAnchor(\n path: PolygonPath,\n anchorIndex: number,\n dx: number,\n dy: number,\n): PolygonPath {\n const anchors = enumerateAnchors(path);\n const a = anchors[anchorIndex];\n if (!a) return path;\n const next = new Float32Array(path.coords);\n // Anchor itself.\n next[a.coordIndex] += dx;\n next[a.coordIndex + 1] += dy;\n // In-handle of THIS anchor — the trailing pair of the incoming C/Q.\n if (a.controlIn) {\n next[a.controlIn.coordIndex] += dx;\n next[a.controlIn.coordIndex + 1] += dy;\n }\n // Out-handle: the leading pair of the OUTGOING C/Q. Owned by this\n // anchor's segment.\n if (a.controlOut) {\n next[a.controlOut.coordIndex] += dx;\n next[a.controlOut.coordIndex + 1] += dy;\n }\n return { kind: 'polygon', commands: path.commands, coords: next, fillRule: path.fillRule };\n}\n"],"mappings":";;AAwBA,SAAgBA,EAAiB,GAAiC;CAChE,IAAM,EAAE,aAAU,cAAWC,GACvBC,IAAwB,CAAC,GAC3BC,IAAgC,MAE9BC,KAAQ,GAAoB,MAA8C;EAC9E,IAAMC,IAAgB;GACpB,aAAaH,EAAQ;GACrB,GAAGI,EAAOC;GACV,GAAGD,EAAOC,IAAa;GACvB;GACA,GAAIC,IAAY,EAAE,aAAU,IAAI,CAAC;EACnC;EAEA,AADAN,EAAQ,KAAKG,CAAC,GACd,IAAaA;CACf;CA2BA,OAzBAI,EAAeC,GAAUJ,IAAS,GAAK,MAAO;EAC5C,QAAQK,GAAR;GACE,KAAKC;GACL,KAAKC;IACH,EAAKC,CAAE;IACP;GACF,KAAKC;IAIH,AAHIZ,MACF,EAAW,aAAa;KAAE,GAAGG,EAAOQ;KAAK,GAAGR,EAAOQ,IAAK;KAAI,YAAYA;IAAG,IAE7EV,EAAKU,IAAK,GAAG;KAAE,GAAGR,EAAOQ,IAAK;KAAI,GAAGR,EAAOQ,IAAK;KAAI,YAAYA,IAAK;IAAE,CAAC;IACzE;GACF,KAAKE;IAIH,AAHIb,MACF,EAAW,aAAa;KAAE,GAAGG,EAAOQ;KAAK,GAAGR,EAAOQ,IAAK;KAAI,YAAYA;IAAG,IAE7EV,EAAKU,IAAK,GAAG;KAAE,GAAGR,EAAOQ;KAAK,GAAGR,EAAOQ,IAAK;KAAI,YAAYA;IAAG,CAAC;IACjE;GACF,KAAKG;IACH,IAAa;IACb;GACF,SACE,MAAU,MAAM,qCAAqCN,GAAK;EAC9D;CACF,CAAC,GACMT;AACT;AAIA,SAAgBgB,EAAU,GAAmB,GAAoB,GAAW,GAAwB;CAClG,IAAMC,IAAO,IAAI,aAAalB,EAAK,MAAM;CAGzC,OAFA,EAAKM,KAAca,GACnB,EAAKb,IAAa,KAAKc,GAChB;EAAE,MAAM;EAAW,UAAUpB,EAAK;EAAU,QAAQkB;EAAM,UAAUlB,EAAK;CAAS;AAC3F"}
1
+ {"version":3,"file":"geometry.js","names":["enumerateAnchors","path","anchors","lastAnchor","firstInSubpath","push","a","coords","coordIndex","controlIn","forEachSegment","commands","cmd","PATH_M","ci","PATH_L","PATH_C","PATH_Q","PATH_Z","foldClosingCurve","first","last","withCoord","next","x","y"],"sources":["../../../../src/interactions/actions/edit-anchors/geometry.ts"],"sourcesContent":["import { forEachSegment, PATH_C, PATH_L, PATH_M, PATH_Q, PATH_Z, type PolygonPath } from '@weasel-js/geom';\n\n/** A single anchor on a `PolygonPath`, with its incoming/outgoing bezier\n * control points (when present). `coordIndex` points at the anchor's own\n * on-curve x in the `coords` array. `inCoordIndex` / `outCoordIndex` point\n * at the corresponding control x. */\nexport interface PathAnchor {\n /** Sequential anchor index in walk order (0-based). */\n anchorIndex: number;\n /** On-curve point. */\n x: number;\n y: number;\n /** Incoming control (from the previous segment, when it was C/Q). */\n controlIn?: { x: number; y: number; coordIndex: number };\n /** Outgoing control (from the next segment, when it is C/Q). */\n controlOut?: { x: number; y: number; coordIndex: number };\n /** Index of the anchor's on-curve x in `coords`. */\n coordIndex: number;\n /** Set on the first anchor of a closed subpath whose last curve ends\n * exactly on it: the index of that curve's end x, the same point again. */\n closeCoordIndex?: number;\n}\n\n/** Walk a PolygonPath's command stream and yield one `PathAnchor` per\n * on-curve point. Adjacent C/Q control points are attached as\n * `controlIn`/`controlOut`. Subpath boundaries (M after a previous M or Z)\n * start fresh — the new M's anchor has no `controlIn` from a Z. A closing\n * curve that ends exactly on the subpath's first point is not a second\n * anchor: its control becomes the first anchor's `controlIn`, the way\n * `pathToAnchors` reads it, so the two walkers count alike. */\nexport function enumerateAnchors(path: PolygonPath): PathAnchor[] {\n const { commands, coords } = path;\n const anchors: PathAnchor[] = [];\n let lastAnchor: PathAnchor | null = null;\n let firstInSubpath: PathAnchor | null = null;\n\n const push = (coordIndex: number, controlIn?: PathAnchor['controlIn']): void => {\n const a: PathAnchor = {\n anchorIndex: anchors.length,\n x: coords[coordIndex],\n y: coords[coordIndex + 1],\n coordIndex,\n ...(controlIn ? { controlIn } : {}),\n };\n anchors.push(a);\n lastAnchor = a;\n };\n\n forEachSegment(commands, coords, (cmd, ci) => {\n switch (cmd) {\n case PATH_M:\n push(ci);\n firstInSubpath = lastAnchor;\n break;\n case PATH_L:\n push(ci);\n break;\n case PATH_C:\n if (lastAnchor) {\n lastAnchor.controlOut = { x: coords[ci], y: coords[ci + 1], coordIndex: ci };\n }\n push(ci + 4, { x: coords[ci + 2], y: coords[ci + 3], coordIndex: ci + 2 });\n break;\n case PATH_Q:\n if (lastAnchor) {\n lastAnchor.controlOut = { x: coords[ci], y: coords[ci + 1], coordIndex: ci };\n }\n push(ci + 2, { x: coords[ci], y: coords[ci + 1], coordIndex: ci });\n break;\n case PATH_Z:\n foldClosingCurve(anchors, firstInSubpath, lastAnchor);\n lastAnchor = null;\n firstInSubpath = null;\n break;\n default:\n throw new Error(`enumerateAnchors: unknown command ${cmd}`);\n }\n });\n return anchors;\n}\n\nfunction foldClosingCurve(anchors: PathAnchor[], first: PathAnchor | null, last: PathAnchor | null): void {\n if (!first || !last || first === last) return;\n if (!last.controlIn || last.x !== first.x || last.y !== first.y) return;\n anchors.pop();\n first.closeCoordIndex = last.coordIndex;\n first.controlIn = last.controlIn;\n}\n\n/** Mutate `coords` in-place: write `(x, y)` at `coordIndex`, return a new\n * PolygonPath sharing the same commands but with a fresh coords buffer. */\nexport function withCoord(path: PolygonPath, coordIndex: number, x: number, y: number): PolygonPath {\n const next = new Float32Array(path.coords);\n next[coordIndex] = x;\n next[coordIndex + 1] = y;\n return { kind: 'polygon', commands: path.commands, coords: next, fillRule: path.fillRule };\n}\n\n/** Translate anchor `anchorIndex` AND its attached control handles\n * (`controlIn` / `controlOut`) by `(dx, dy)`. Used by `editAnchorsAction`\n * when the dragged affordance is the anchor itself — moving the anchor\n * without its handles would shear the surrounding bezier segments. */\nexport function translateAnchor(\n path: PolygonPath,\n anchorIndex: number,\n dx: number,\n dy: number,\n): PolygonPath {\n const anchors = enumerateAnchors(path);\n const a = anchors[anchorIndex];\n if (!a) return path;\n const next = new Float32Array(path.coords);\n // Anchor itself.\n next[a.coordIndex] += dx;\n next[a.coordIndex + 1] += dy;\n if (a.closeCoordIndex !== undefined) {\n next[a.closeCoordIndex] += dx;\n next[a.closeCoordIndex + 1] += dy;\n }\n // In-handle of THIS anchor — the trailing pair of the incoming C/Q.\n if (a.controlIn) {\n next[a.controlIn.coordIndex] += dx;\n next[a.controlIn.coordIndex + 1] += dy;\n }\n // Out-handle: the leading pair of the OUTGOING C/Q. Owned by this\n // anchor's segment.\n if (a.controlOut) {\n next[a.controlOut.coordIndex] += dx;\n next[a.controlOut.coordIndex + 1] += dy;\n }\n return { kind: 'polygon', commands: path.commands, coords: next, fillRule: path.fillRule };\n}\n"],"mappings":";;AA8BA,SAAgBA,EAAiB,GAAiC;CAChE,IAAM,EAAE,aAAU,cAAWC,GACvBC,IAAwB,CAAC,GAC3BC,IAAgC,MAChCC,IAAoC,MAElCC,KAAQ,GAAoB,MAA8C;EAC9E,IAAMC,IAAgB;GACpB,aAAaJ,EAAQ;GACrB,GAAGK,EAAOC;GACV,GAAGD,EAAOC,IAAa;GACvB;GACA,GAAIC,IAAY,EAAE,aAAU,IAAI,CAAC;EACnC;EAEA,AADAP,EAAQ,KAAKI,CAAC,GACd,IAAaA;CACf;CAgCA,OA9BAI,EAAeC,GAAUJ,IAAS,GAAK,MAAO;EAC5C,QAAQK,GAAR;GACE,KAAKC;IAEH,AADAR,EAAKS,CAAE,GACP,IAAiBX;IACjB;GACF,KAAKY;IACH,EAAKD,CAAE;IACP;GACF,KAAKE;IAIH,AAHIb,MACF,EAAW,aAAa;KAAE,GAAGI,EAAOO;KAAK,GAAGP,EAAOO,IAAK;KAAI,YAAYA;IAAG,IAE7ET,EAAKS,IAAK,GAAG;KAAE,GAAGP,EAAOO,IAAK;KAAI,GAAGP,EAAOO,IAAK;KAAI,YAAYA,IAAK;IAAE,CAAC;IACzE;GACF,KAAKG;IAIH,AAHId,MACF,EAAW,aAAa;KAAE,GAAGI,EAAOO;KAAK,GAAGP,EAAOO,IAAK;KAAI,YAAYA;IAAG,IAE7ET,EAAKS,IAAK,GAAG;KAAE,GAAGP,EAAOO;KAAK,GAAGP,EAAOO,IAAK;KAAI,YAAYA;IAAG,CAAC;IACjE;GACF,KAAKI;IAGH,AAFAC,EAAiBjB,GAASE,GAAgBD,CAAU,GACpD,IAAa,MACb,IAAiB;IACjB;GACF,SACE,MAAU,MAAM,qCAAqCS,GAAK;EAC9D;CACF,CAAC,GACMV;AACT;AAEA,SAASiB,EAAiB,GAAuB,GAA0B,GAA+B;CACxG,AAAKC,KAAUC,KAAQD,MAAUC,KAC5BA,EAAK,aAAaA,EAAK,MAAMD,EAAM,KAAKC,EAAK,MAAMD,EAAM,MAC9DlB,EAAQ,IAAI,GACZ,EAAM,kBAAkBmB,EAAK,YAC7B,EAAM,YAAYA,EAAK;AACzB;AAIA,SAAgBC,EAAU,GAAmB,GAAoB,GAAW,GAAwB;CAClG,IAAMC,IAAO,IAAI,aAAatB,EAAK,MAAM;CAGzC,OAFA,EAAKO,KAAcgB,GACnB,EAAKhB,IAAa,KAAKiB,GAChB;EAAE,MAAM;EAAW,UAAUxB,EAAK;EAAU,QAAQsB;EAAM,UAAUtB,EAAK;CAAS;AAC3F"}
@@ -1,25 +1,26 @@
1
+ import { poseLinearOf as e } from "../../../core/geometry/poseFrame.js";
1
2
  //#region src/interactions/actions/flip/helpers.ts
2
- function e(e, t, i, a) {
3
- let o = i.getBounds(e), s = a.x + a.width / 2, c = a.y + a.height / 2, l = t === "x" ? {
4
- x: 2 * s - o.x,
5
- y: o.y,
6
- width: -o.width,
7
- height: o.height
3
+ function t(e, t, n, o) {
4
+ let s = n.getBounds(e), c = o.x + o.width / 2, l = o.y + o.height / 2, u = t === "x" ? {
5
+ x: 2 * c - s.x,
6
+ y: s.y,
7
+ width: -s.width,
8
+ height: s.height
8
9
  } : {
9
- x: o.x,
10
- y: 2 * c - o.y,
11
- width: o.width,
12
- height: -o.height
13
- }, u = i.remapBounds(e, o, l), d = i.getRotation?.(e) ?? o.rotation ?? 0;
14
- return n(r(u), d, i);
10
+ x: s.x,
11
+ y: 2 * l - s.y,
12
+ width: s.width,
13
+ height: -s.height
14
+ }, d = n.remapBounds(e, s, u), f = n.getRotation?.(e) ?? s.rotation ?? 0;
15
+ return a(r(i(d), f, n));
15
16
  }
16
- function t(t, n, r) {
17
- return e(t, n, r, r.getBounds(t));
17
+ function n(e, n, r) {
18
+ return t(e, n, r, r.getBounds(e));
18
19
  }
19
- function n(e, t, n) {
20
+ function r(e, t, n) {
20
21
  return t === 0 ? e : n.withRotation ? n.withRotation(e, -t) : e;
21
22
  }
22
- function r(e) {
23
+ function i(e) {
23
24
  let t = e, n = !1, r = t.x, i = t.y, a = t.width, o = t.height;
24
25
  return typeof a == "number" && a < 0 && typeof r == "number" && (r += a, a = -a, n = !0), typeof o == "number" && o < 0 && typeof i == "number" && (i += o, o = -o, n = !0), n ? {
25
26
  ...e,
@@ -29,7 +30,19 @@ function r(e) {
29
30
  height: o
30
31
  } : e;
31
32
  }
33
+ function a(t) {
34
+ let n = e(t);
35
+ return !n || n[1] === 0 && n[2] === 0 ? t : {
36
+ ...t,
37
+ transform: [
38
+ n[0],
39
+ -n[1],
40
+ -n[2],
41
+ n[3]
42
+ ]
43
+ };
44
+ }
32
45
  //#endregion
33
- export { e as flipPoseAboutBounds, t as flipPoseViaDescriptor };
46
+ export { t as flipPoseAboutBounds, n as flipPoseViaDescriptor };
34
47
 
35
48
  //# sourceMappingURL=helpers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","names":["flipPoseAboutBounds","src","geometry","pose","cxPivot","pivotBounds","cyPivot","dst","axis","next","rotation","negateRotation","normalizeNegativeExtent","flipPoseViaDescriptor","p","mutated","nx","ny","nw","nh"],"sources":["../../../../src/interactions/actions/flip/helpers.ts"],"sourcesContent":["/**\n * Pose-flip helpers used by `flipAction` (via `defaults/flip.ts`).\n *\n * These were extracted from the legacy `useFlip` hook when it was removed —\n * they remain because the descriptor-style `flipAction` still needs to reflect\n * arbitrary `TPose` values through a `PoseDescriptor`.\n */\nimport type { PoseDescriptor } from '../resize/geometry';\nimport type { SpatialReference } from '../spatialReference';\n\n/** Axis for flip. `'x'` mirrors horizontally (left↔right); `'y'` mirrors vertically (top↔bottom). */\nexport type FlipAxis = 'x' | 'y';\n\n/** How a multi-selection flip chooses its pivot.\n *\n * - `'each'` — every pose mirrors about its own AABB; spatial layout of the\n * selection is unchanged, individual items are reflected in place.\n * - `'union'` — every pose mirrors about the selection's union AABB; items\n * swap sides as well as reflect, matching Illustrator/Figma defaults.\n * - a {@link SpatialReference} — every pose mirrors about the center of the\n * bounds it names: the pointer, a world point or rect, or a key node. */\nexport type FlipPivot = 'each' | 'union' | SpatialReference;\n\n/** Reflect `pose` across the centerline of `pivotBounds` along `axis`, using\n * `geometry` to read bounds and remap. The pose's own AABB is read once to\n * compute the reflected destination rect; coords inside the pose are then\n * remapped through the affine that takes its own bounds → reflected dst.\n * A rotation the pose carries is negated: a mirror reverses the sense of the\n * turn, and `remapBounds` carries the original angle through untouched. */\nexport function flipPoseAboutBounds<TPose>(\n pose: TPose,\n axis: FlipAxis,\n geometry: PoseDescriptor<TPose>,\n pivotBounds: { x: number; y: number; width: number; height: number },\n): TPose {\n const src = geometry.getBounds(pose);\n const cxPivot = pivotBounds.x + pivotBounds.width / 2;\n const cyPivot = pivotBounds.y + pivotBounds.height / 2;\n const dst = axis === 'x'\n ? { x: 2 * cxPivot - src.x, y: src.y, width: -src.width, height: src.height }\n : { x: src.x, y: 2 * cyPivot - src.y, width: src.width, height: -src.height };\n const next = geometry.remapBounds(pose, src, dst);\n const rotation = geometry.getRotation?.(pose) ?? (src as { rotation?: number }).rotation ?? 0;\n return negateRotation(normalizeNegativeExtent(next), rotation, geometry);\n}\n\n/** Reflect `pose` across the centerline of its own AABB along `axis`. */\nexport function flipPoseViaDescriptor<TPose>(\n pose: TPose,\n axis: FlipAxis,\n geometry: PoseDescriptor<TPose>,\n): TPose {\n return flipPoseAboutBounds(pose, axis, geometry, geometry.getBounds(pose));\n}\n\nfunction negateRotation<TPose>(pose: TPose, rotation: number, geometry: PoseDescriptor<TPose>): TPose {\n if (rotation === 0) return pose;\n return geometry.withRotation ? geometry.withRotation(pose, -rotation) : pose;\n}\n\nfunction normalizeNegativeExtent<TPose>(pose: TPose): TPose {\n const p = pose as unknown as { x?: number; y?: number; width?: number; height?: number };\n let mutated = false;\n let nx = p.x;\n let ny = p.y;\n let nw = p.width;\n let nh = p.height;\n if (typeof nw === 'number' && nw < 0 && typeof nx === 'number') {\n nx = nx + nw;\n nw = -nw;\n mutated = true;\n }\n if (typeof nh === 'number' && nh < 0 && typeof ny === 'number') {\n ny = ny + nh;\n nh = -nh;\n mutated = true;\n }\n if (!mutated) return pose;\n return { ...(pose as object), x: nx, y: ny, width: nw, height: nh } as TPose;\n}\n"],"mappings":";AA6BA,SAAgBA,EACd,GACA,GACA,GACA,GACO;CACP,IAAMC,IAAMC,EAAS,UAAUC,CAAI,GAC7BC,IAAUC,EAAY,IAAIA,EAAY,QAAQ,GAC9CC,IAAUD,EAAY,IAAIA,EAAY,SAAS,GAC/CE,IAAMC,MAAS,MACjB;EAAE,GAAG,IAAIJ,IAAUH,EAAI;EAAG,GAAGA,EAAI;EAAG,OAAO,CAACA,EAAI;EAAO,QAAQA,EAAI;CAAO,IAC1E;EAAE,GAAGA,EAAI;EAAG,GAAG,IAAIK,IAAUL,EAAI;EAAG,OAAOA,EAAI;EAAO,QAAQ,CAACA,EAAI;CAAO,GACxEQ,IAAOP,EAAS,YAAYC,GAAMF,GAAKM,CAAG,GAC1CG,IAAWR,EAAS,cAAcC,CAAI,KAAMF,EAA8B,YAAY;CAC5F,OAAOU,EAAeC,EAAwBH,CAAI,GAAGC,GAAUR,CAAQ;AACzE;AAGA,SAAgBW,EACd,GACA,GACA,GACO;CACP,OAAOb,EAAoBG,GAAMK,GAAMN,GAAUA,EAAS,UAAUC,CAAI,CAAC;AAC3E;AAEA,SAASQ,EAAsB,GAAa,GAAkB,GAAwC;CAEpG,OADID,MAAa,IAAUP,IACpBD,EAAS,eAAeA,EAAS,aAAaC,GAAM,CAACO,CAAQ,IAAIP;AAC1E;AAEA,SAASS,EAA+B,GAAoB;CAC1D,IAAME,IAAIX,GACNY,IAAU,IACVC,IAAKF,EAAE,GACPG,IAAKH,EAAE,GACPI,IAAKJ,EAAE,OACPK,IAAKL,EAAE;CAYX,OAXI,OAAOI,KAAO,YAAYA,IAAK,KAAK,OAAOF,KAAO,aACpD,KAAUE,GACV,IAAK,CAACA,GACN,IAAU,KAER,OAAOC,KAAO,YAAYA,IAAK,KAAK,OAAOF,KAAO,aACpD,KAAUE,GACV,IAAK,CAACA,GACN,IAAU,KAEPJ,IACE;EAAE,GAAIZ;EAAiB,GAAGa;EAAI,GAAGC;EAAI,OAAOC;EAAI,QAAQC;CAAG,IAD7ChB;AAEvB"}
1
+ {"version":3,"file":"helpers.js","names":["flipPoseAboutBounds","src","geometry","pose","cxPivot","pivotBounds","cyPivot","dst","axis","next","rotation","mirrorLinear","negateRotation","normalizeNegativeExtent","flipPoseViaDescriptor","p","mutated","nx","ny","nw","nh","l","poseLinearOf"],"sources":["../../../../src/interactions/actions/flip/helpers.ts"],"sourcesContent":["/**\n * Pose-flip helpers used by `flipAction` (via `defaults/flip.ts`).\n *\n * These were extracted from the legacy `useFlip` hook when it was removed —\n * they remain because the descriptor-style `flipAction` still needs to reflect\n * arbitrary `TPose` values through a `PoseDescriptor`.\n */\nimport type { PoseDescriptor } from '../resize/geometry';\nimport type { SpatialReference } from '../spatialReference';\nimport { poseLinearOf } from 'core/geometry/poseFrame';\n\n/** Axis for flip. `'x'` mirrors horizontally (left↔right); `'y'` mirrors vertically (top↔bottom). */\nexport type FlipAxis = 'x' | 'y';\n\n/** How a multi-selection flip chooses its pivot.\n *\n * - `'each'` — every pose mirrors about its own AABB; spatial layout of the\n * selection is unchanged, individual items are reflected in place.\n * - `'union'` — every pose mirrors about the selection's union AABB; items\n * swap sides as well as reflect, matching Illustrator/Figma defaults.\n * - a {@link SpatialReference} — every pose mirrors about the center of the\n * bounds it names: the pointer, a world point or rect, or a key node. */\nexport type FlipPivot = 'each' | 'union' | SpatialReference;\n\n/** Reflect `pose` across the centerline of `pivotBounds` along `axis`, using\n * `geometry` to read bounds and remap. The pose's own AABB is read once to\n * compute the reflected destination rect; coords inside the pose are then\n * remapped through the affine that takes its own bounds → reflected dst.\n * A rotation the pose carries is negated: a mirror reverses the sense of the\n * turn, and `remapBounds` carries the original angle through untouched. A\n * `transform` it carries is mirrored the same way, on either axis. */\nexport function flipPoseAboutBounds<TPose>(\n pose: TPose,\n axis: FlipAxis,\n geometry: PoseDescriptor<TPose>,\n pivotBounds: { x: number; y: number; width: number; height: number },\n): TPose {\n const src = geometry.getBounds(pose);\n const cxPivot = pivotBounds.x + pivotBounds.width / 2;\n const cyPivot = pivotBounds.y + pivotBounds.height / 2;\n const dst = axis === 'x'\n ? { x: 2 * cxPivot - src.x, y: src.y, width: -src.width, height: src.height }\n : { x: src.x, y: 2 * cyPivot - src.y, width: src.width, height: -src.height };\n const next = geometry.remapBounds(pose, src, dst);\n const rotation = geometry.getRotation?.(pose) ?? (src as { rotation?: number }).rotation ?? 0;\n return mirrorLinear(negateRotation(normalizeNegativeExtent(next), rotation, geometry));\n}\n\n/** Reflect `pose` across the centerline of its own AABB along `axis`. */\nexport function flipPoseViaDescriptor<TPose>(\n pose: TPose,\n axis: FlipAxis,\n geometry: PoseDescriptor<TPose>,\n): TPose {\n return flipPoseAboutBounds(pose, axis, geometry, geometry.getBounds(pose));\n}\n\nfunction negateRotation<TPose>(pose: TPose, rotation: number, geometry: PoseDescriptor<TPose>): TPose {\n if (rotation === 0) return pose;\n return geometry.withRotation ? geometry.withRotation(pose, -rotation) : pose;\n}\n\nfunction normalizeNegativeExtent<TPose>(pose: TPose): TPose {\n const p = pose as unknown as { x?: number; y?: number; width?: number; height?: number };\n let mutated = false;\n let nx = p.x;\n let ny = p.y;\n let nw = p.width;\n let nh = p.height;\n if (typeof nw === 'number' && nw < 0 && typeof nx === 'number') {\n nx = nx + nw;\n nw = -nw;\n mutated = true;\n }\n if (typeof nh === 'number' && nh < 0 && typeof ny === 'number') {\n ny = ny + nh;\n nh = -nh;\n mutated = true;\n }\n if (!mutated) return pose;\n return { ...(pose as object), x: nx, y: ny, width: nw, height: nh } as TPose;\n}\n\n/** `M · L · M` for a mirror `M` on either axis: the off-diagonal terms change sign. */\nfunction mirrorLinear<TPose>(pose: TPose): TPose {\n const l = poseLinearOf(pose);\n if (!l || (l[1] === 0 && l[2] === 0)) return pose;\n return { ...(pose as object), transform: [l[0], -l[1], -l[2], l[3]] } as TPose;\n}\n"],"mappings":";;AA+BA,SAAgBA,EACd,GACA,GACA,GACA,GACO;CACP,IAAMC,IAAMC,EAAS,UAAUC,CAAI,GAC7BC,IAAUC,EAAY,IAAIA,EAAY,QAAQ,GAC9CC,IAAUD,EAAY,IAAIA,EAAY,SAAS,GAC/CE,IAAMC,MAAS,MACjB;EAAE,GAAG,IAAIJ,IAAUH,EAAI;EAAG,GAAGA,EAAI;EAAG,OAAO,CAACA,EAAI;EAAO,QAAQA,EAAI;CAAO,IAC1E;EAAE,GAAGA,EAAI;EAAG,GAAG,IAAIK,IAAUL,EAAI;EAAG,OAAOA,EAAI;EAAO,QAAQ,CAACA,EAAI;CAAO,GACxEQ,IAAOP,EAAS,YAAYC,GAAMF,GAAKM,CAAG,GAC1CG,IAAWR,EAAS,cAAcC,CAAI,KAAMF,EAA8B,YAAY;CAC5F,OAAOU,EAAaC,EAAeC,EAAwBJ,CAAI,GAAGC,GAAUR,CAAQ,CAAC;AACvF;AAGA,SAAgBY,EACd,GACA,GACA,GACO;CACP,OAAOd,EAAoBG,GAAMK,GAAMN,GAAUA,EAAS,UAAUC,CAAI,CAAC;AAC3E;AAEA,SAASS,EAAsB,GAAa,GAAkB,GAAwC;CAEpG,OADIF,MAAa,IAAUP,IACpBD,EAAS,eAAeA,EAAS,aAAaC,GAAM,CAACO,CAAQ,IAAIP;AAC1E;AAEA,SAASU,EAA+B,GAAoB;CAC1D,IAAME,IAAIZ,GACNa,IAAU,IACVC,IAAKF,EAAE,GACPG,IAAKH,EAAE,GACPI,IAAKJ,EAAE,OACPK,IAAKL,EAAE;CAYX,OAXI,OAAOI,KAAO,YAAYA,IAAK,KAAK,OAAOF,KAAO,aACpD,KAAUE,GACV,IAAK,CAACA,GACN,IAAU,KAER,OAAOC,KAAO,YAAYA,IAAK,KAAK,OAAOF,KAAO,aACpD,KAAUE,GACV,IAAK,CAACA,GACN,IAAU,KAEPJ,IACE;EAAE,GAAIb;EAAiB,GAAGc;EAAI,GAAGC;EAAI,OAAOC;EAAI,QAAQC;CAAG,IAD7CjB;AAEvB;AAGA,SAASQ,EAAoB,GAAoB;CAC/C,IAAMU,IAAIC,EAAanB,CAAI;CAE3B,OADI,CAACkB,KAAMA,EAAE,OAAO,KAAKA,EAAE,OAAO,IAAWlB,IACtC;EAAE,GAAIA;EAAiB,WAAW;GAACkB,EAAE;GAAI,CAACA,EAAE;GAAI,CAACA,EAAE;GAAIA,EAAE;EAAE;CAAE;AACtE"}
@@ -0,0 +1,8 @@
1
+ //#region src/interactions/actions/hitSelection.ts
2
+ function e(e, t, n) {
3
+ return [...new Set(n ? [...e, ...t] : t)];
4
+ }
5
+ //#endregion
6
+ export { e as selectionFromHits };
7
+
8
+ //# sourceMappingURL=hitSelection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hitSelection.js","names":["selectionFromHits","extend","current","hits"],"sources":["../../../src/interactions/actions/hitSelection.ts"],"sourcesContent":["/** The selection a hit list leaves behind: the hits alone, or, when the\n * gesture extends the selection, the current ids with the new hits after them. */\nexport function selectionFromHits<T extends string>(\n current: readonly T[],\n hits: readonly T[],\n extend: boolean,\n): T[] {\n return [...new Set(extend ? [...current, ...hits] : hits)];\n}\n"],"mappings":";AAEA,SAAgBA,EACd,GACA,GACA,GACK;CACL,OAAO,CAAC,GAAG,IAAI,IAAIC,IAAS,CAAC,GAAGC,GAAS,GAAGC,CAAI,IAAIA,CAAI,CAAC;AAC3D"}
@@ -1,39 +1,35 @@
1
- import { createSetSelectionOp as e } from "../../../../core/ops/select.js";
2
- import { getScratch as t, scratchKey as n } from "@weasel-js/routing";
1
+ import { selectionFromHits as e } from "../../hitSelection.js";
2
+ import { createSetSelectionOp as t } from "../../../../core/ops/select.js";
3
+ import { getScratch as n, scratchKey as r } from "@weasel-js/routing";
3
4
  //#region src/interactions/actions/lasso-select/behaviors/selectFromLasso.ts
4
- var r = n("lassoSelect.vertices"), i = 4;
5
- function a(n) {
6
- let a = n?.mode ?? "intersect";
5
+ var i = r("lassoSelect.vertices"), a = 4;
6
+ function o(r) {
7
+ let o = r?.mode ?? "intersect";
7
8
  return {
8
9
  defaultTransient: !0,
9
- onEnd(n) {
10
- let c = n.adapter;
10
+ onEnd(r) {
11
+ let c = r.adapter;
11
12
  if (!c.getSelection || !c.hitTestLasso) return null;
12
- let l = t(n.scratch, r) ?? [], u = n.origin.get("gesture"), d = u ? u.shiftHeld === !0 : !1, f = c.getSelection();
13
- if (l.length < 3 || o(l) < i) return [e({
13
+ let l = n(r.scratch, i) ?? [], u = r.origin.get("gesture"), d = u ? u.shiftHeld === !0 : !1, f = c.getSelection();
14
+ if (l.length < 3 || s(l) < a) return [t({
14
15
  from: f,
15
16
  to: d ? f : []
16
17
  })];
17
- let p = c.hitTestLasso(l, a), m = d ? s(f, p) : p;
18
- return [e({
18
+ let p = c.hitTestLasso(l, o), m = e(f, p, d);
19
+ return [t({
19
20
  from: f,
20
21
  to: m
21
22
  })];
22
23
  }
23
24
  };
24
25
  }
25
- function o(e) {
26
+ function s(e) {
26
27
  if (e.length === 0) return 0;
27
28
  let t = Infinity, n = Infinity, r = -Infinity, i = -Infinity;
28
29
  for (let a of e) a.x < t && (t = a.x), a.y < n && (n = a.y), a.x > r && (r = a.x), a.y > i && (i = a.y);
29
30
  return (r - t) * (i - n);
30
31
  }
31
- function s(e, t) {
32
- let n = [...e];
33
- for (let e of t) n.includes(e) || n.push(e);
34
- return n;
35
- }
36
32
  //#endregion
37
- export { r as LASSO_VERTICES, a as selectFromLasso };
33
+ export { i as LASSO_VERTICES, o as selectFromLasso };
38
34
 
39
35
  //# sourceMappingURL=selectFromLasso.js.map