@weasel-js/core 1.11.0 → 1.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (365) hide show
  1. package/CHANGELOG.md +427 -0
  2. package/README.md +1 -1
  3. package/dist/animation/index.js +3 -3
  4. package/dist/animation/rig/bindRig.js +1 -1
  5. package/dist/animation/rig/rigNode.js.map +1 -1
  6. package/dist/barrel/canvas.js +7 -3
  7. package/dist/barrel/interactions.js +5 -4
  8. package/dist/barrel/paths.js +3 -3
  9. package/dist/barrel/renderer.js +3 -2
  10. package/dist/barrel/routing.js +6 -11
  11. package/dist/barrel/scene.js +8 -5
  12. package/dist/barrel/viewport.js +4 -3
  13. package/dist/canvas/Canvas.js +3 -1
  14. package/dist/canvas/Canvas.js.map +1 -1
  15. package/dist/canvas/SceneCanvas/SceneCanvasInput.js +17 -3
  16. package/dist/canvas/SceneCanvas/SceneCanvasInput.js.map +1 -1
  17. package/dist/canvas/SceneCanvas/builtinToolSets.js +30 -0
  18. package/dist/canvas/SceneCanvas/builtinToolSets.js.map +1 -0
  19. package/dist/canvas/SceneCanvas/canvasPassThrough.js +1 -0
  20. package/dist/canvas/SceneCanvas/canvasPassThrough.js.map +1 -1
  21. package/dist/canvas/SceneCanvas/coordTrace.js +5 -16
  22. package/dist/canvas/SceneCanvas/coordTrace.js.map +1 -1
  23. package/dist/canvas/SceneCanvas/defaultNodeProperties.js +5 -0
  24. package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -1
  25. package/dist/canvas/SceneCanvas/features.js +45 -5
  26. package/dist/canvas/SceneCanvas/features.js.map +1 -1
  27. package/dist/canvas/SceneCanvas/props.js +1 -11
  28. package/dist/canvas/SceneCanvas/props.js.map +1 -1
  29. package/dist/canvas/SceneCanvas/toolRegistry.js +8 -4
  30. package/dist/canvas/SceneCanvas/toolRegistry.js.map +1 -1
  31. package/dist/canvas/SceneCanvas/useActionsPropResolver.js +1 -11
  32. package/dist/canvas/SceneCanvas/useActionsPropResolver.js.map +1 -1
  33. package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js.map +1 -1
  34. package/dist/canvas/SceneCanvas/useBuiltinTools.js +2 -9
  35. package/dist/canvas/SceneCanvas/useBuiltinTools.js.map +1 -1
  36. package/dist/canvas/SceneCanvas/useCanvasDevtoolsRoot.js +93 -0
  37. package/dist/canvas/SceneCanvas/useCanvasDevtoolsRoot.js.map +1 -0
  38. package/dist/canvas/SceneCanvas/useCanvasSelection.js +7 -2
  39. package/dist/canvas/SceneCanvas/useCanvasSelection.js.map +1 -1
  40. package/dist/canvas/SceneCanvas/useCanvasTools.js +8 -8
  41. package/dist/canvas/SceneCanvas/useCanvasTools.js.map +1 -1
  42. package/dist/canvas/SceneCanvas/useNodeKinds.js +1 -1
  43. package/dist/canvas/SceneCanvas/useNodeKinds.js.map +1 -1
  44. package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js +13 -2
  45. package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js.map +1 -1
  46. package/dist/canvas/SceneCanvas/useSceneCanvasTools.js +1 -3
  47. package/dist/canvas/SceneCanvas/useSceneCanvasTools.js.map +1 -1
  48. package/dist/canvas/SceneCanvas/useSceneChrome.js +6 -7
  49. package/dist/canvas/SceneCanvas/useSceneChrome.js.map +1 -1
  50. package/dist/canvas/SceneCanvas/useSceneGestureDispatcher.js +5 -3
  51. package/dist/canvas/SceneCanvas/useSceneGestureDispatcher.js.map +1 -1
  52. package/dist/canvas/SceneCanvas/useScenePicking.js +2 -3
  53. package/dist/canvas/SceneCanvas/useScenePicking.js.map +1 -1
  54. package/dist/canvas/SceneCanvas/useSceneSelectTool.js +2 -1
  55. package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
  56. package/dist/canvas/SceneCanvas/useSceneStandardActions.js +3 -4
  57. package/dist/canvas/SceneCanvas/useSceneStandardActions.js.map +1 -1
  58. package/dist/canvas/SceneCanvas.js +16 -14
  59. package/dist/canvas/SceneCanvas.js.map +1 -1
  60. package/dist/canvas/SurfaceCanvas.js +5 -22
  61. package/dist/canvas/SurfaceCanvas.js.map +1 -1
  62. package/dist/canvas/canvasRenderer.js +9 -5
  63. package/dist/canvas/canvasRenderer.js.map +1 -1
  64. package/dist/canvas/contextAttributes.js +14 -0
  65. package/dist/canvas/contextAttributes.js.map +1 -0
  66. package/dist/canvas/deps/editAnchors.js +9 -113
  67. package/dist/canvas/deps/editAnchors.js.map +1 -1
  68. package/dist/canvas/deps/insert.js +4 -2
  69. package/dist/canvas/deps/insert.js.map +1 -1
  70. package/dist/canvas/deps/pathEditCommits.js +193 -0
  71. package/dist/canvas/deps/pathEditCommits.js.map +1 -0
  72. package/dist/canvas/deps/snap.js +12 -9
  73. package/dist/canvas/deps/snap.js.map +1 -1
  74. package/dist/canvas/deps/transformFollowers.js +20 -0
  75. package/dist/canvas/deps/transformFollowers.js.map +1 -0
  76. package/dist/canvas/derivedPath.js +20 -1
  77. package/dist/canvas/derivedPath.js.map +1 -1
  78. package/dist/canvas/drawnBounds.js +29 -3
  79. package/dist/canvas/drawnBounds.js.map +1 -1
  80. package/dist/canvas/nodeShapes/derivedPainter.js +9 -1
  81. package/dist/canvas/nodeShapes/derivedPainter.js.map +1 -1
  82. package/dist/canvas/nodeShapes/pathPainter.js +3 -2
  83. package/dist/canvas/nodeShapes/pathPainter.js.map +1 -1
  84. package/dist/canvas/nodeShapes/shapePainter.js +1 -1
  85. package/dist/canvas/overlayRoleStrokes.js +12 -0
  86. package/dist/canvas/overlayRoleStrokes.js.map +1 -1
  87. package/dist/canvas/pathOverlay.js +27 -7
  88. package/dist/canvas/pathOverlay.js.map +1 -1
  89. package/dist/canvas/renderDebugSnapshot.js +1 -0
  90. package/dist/canvas/renderDebugSnapshot.js.map +1 -1
  91. package/dist/canvas/renderSceneToPixels.js +6 -5
  92. package/dist/canvas/renderSceneToPixels.js.map +1 -1
  93. package/dist/canvas/sceneAdapter.js.map +1 -1
  94. package/dist/canvas/useCanvasPaint.js +2 -1
  95. package/dist/canvas/useCanvasPaint.js.map +1 -1
  96. package/dist/canvas/useInFlightBounds.js +52 -0
  97. package/dist/canvas/useInFlightBounds.js.map +1 -0
  98. package/dist/canvas/useViewHelpers.js +7 -9
  99. package/dist/canvas/useViewHelpers.js.map +1 -1
  100. package/dist/clipboard.d.ts +3 -2
  101. package/dist/{clone-DZDrfIlU.d.ts → clone-C3e0OTuF.d.ts} +8 -21
  102. package/dist/clone.d.ts +4 -3
  103. package/dist/core/geometry/autoPoseDescriptor.js +1 -1
  104. package/dist/core/ops/setDependsOn.js +37 -0
  105. package/dist/core/ops/setDependsOn.js.map +1 -0
  106. package/dist/core/ops/writtenBy.js +53 -0
  107. package/dist/core/ops/writtenBy.js.map +1 -0
  108. package/dist/core/pages/fitViewToPage.js +12 -1
  109. package/dist/core/pages/fitViewToPage.js.map +1 -1
  110. package/dist/core/pages/pageEdits.js +164 -0
  111. package/dist/core/pages/pageEdits.js.map +1 -0
  112. package/dist/core/pages/pages.js +30 -1
  113. package/dist/core/pages/pages.js.map +1 -1
  114. package/dist/core/scene/NodeRouting.js +8 -3
  115. package/dist/core/scene/NodeRouting.js.map +1 -1
  116. package/dist/core/scene/arrivalWindow.js.map +1 -1
  117. package/dist/core/scene/carryDescendants.js +51 -0
  118. package/dist/core/scene/carryDescendants.js.map +1 -0
  119. package/dist/core/scene/docValues.js +57 -0
  120. package/dist/core/scene/docValues.js.map +1 -0
  121. package/dist/core/scene/editPass.js +111 -0
  122. package/dist/core/scene/editPass.js.map +1 -0
  123. package/dist/core/scene/effectivePose.js +7 -1
  124. package/dist/core/scene/effectivePose.js.map +1 -1
  125. package/dist/core/scene/fieldEdits.js +4 -1
  126. package/dist/core/scene/fieldEdits.js.map +1 -1
  127. package/dist/core/scene/historyFacade.js +1 -0
  128. package/dist/core/scene/historyFacade.js.map +1 -1
  129. package/dist/core/scene/layoutPass.js +28 -3
  130. package/dist/core/scene/layoutPass.js.map +1 -1
  131. package/dist/core/scene/recorder.js +28 -19
  132. package/dist/core/scene/recorder.js.map +1 -1
  133. package/dist/core/scene/scene.js +15 -9
  134. package/dist/core/scene/scene.js.map +1 -1
  135. package/dist/core/scene/sceneChanges.js +13 -0
  136. package/dist/core/scene/sceneChanges.js.map +1 -0
  137. package/dist/core/scene/sceneEdits.js +8 -1
  138. package/dist/core/scene/sceneEdits.js.map +1 -1
  139. package/dist/core/scene/sceneMutators.js +1 -0
  140. package/dist/core/scene/sceneMutators.js.map +1 -1
  141. package/dist/core/scene/sceneRecording.js +20 -3
  142. package/dist/core/scene/sceneRecording.js.map +1 -1
  143. package/dist/core/scene/sceneSelection.js +4 -1
  144. package/dist/core/scene/sceneSelection.js.map +1 -1
  145. package/dist/core/scene/sceneState.js +11 -5
  146. package/dist/core/scene/sceneState.js.map +1 -1
  147. package/dist/core/scene/serialization.js +5 -3
  148. package/dist/core/scene/serialization.js.map +1 -1
  149. package/dist/core/scene/types.js.map +1 -1
  150. package/dist/core/scene/unitScopes.js +19 -1
  151. package/dist/core/scene/unitScopes.js.map +1 -1
  152. package/dist/core/selection/usePublishSceneSelection.js +6 -12
  153. package/dist/core/selection/usePublishSceneSelection.js.map +1 -1
  154. package/dist/core/shapeKinds.js +25 -11
  155. package/dist/core/shapeKinds.js.map +1 -1
  156. package/dist/{cornerHandles-Camw_yeu.d.ts → cornerHandles-BHuoMs1o.d.ts} +1 -1
  157. package/dist/debug/createDebugOverlayLayer.js +16 -111
  158. package/dist/debug/createDebugOverlayLayer.js.map +1 -1
  159. package/dist/debug/createDebugSink.js +2 -1
  160. package/dist/debug/createDebugSink.js.map +1 -1
  161. package/dist/debug/defaultTheme.js +4 -2
  162. package/dist/debug/defaultTheme.js.map +1 -1
  163. package/dist/debug/features.js +17 -0
  164. package/dist/debug/features.js.map +1 -0
  165. package/dist/debug/overlayPanels.js +117 -0
  166. package/dist/debug/overlayPanels.js.map +1 -0
  167. package/dist/debug/parseDebugFlags.js +4 -13
  168. package/dist/debug/parseDebugFlags.js.map +1 -1
  169. package/dist/{depSchema-Cgfu_G9s.d.ts → depSchema-BpZNOv7q.d.ts} +114 -892
  170. package/dist/devtools/handlers.js +112 -0
  171. package/dist/devtools/handlers.js.map +1 -0
  172. package/dist/devtools/history.js +71 -0
  173. package/dist/devtools/history.js.map +1 -0
  174. package/dist/devtools/hook.js +74 -0
  175. package/dist/devtools/hook.js.map +1 -0
  176. package/dist/devtools/label.js +25 -0
  177. package/dist/devtools/label.js.map +1 -0
  178. package/dist/devtools/notices.js +58 -0
  179. package/dist/devtools/notices.js.map +1 -0
  180. package/dist/devtools/protocol.js +7 -0
  181. package/dist/devtools/protocol.js.map +1 -0
  182. package/dist/devtools/registry.js +90 -0
  183. package/dist/devtools/registry.js.map +1 -0
  184. package/dist/devtools/root.js +80 -0
  185. package/dist/devtools/root.js.map +1 -0
  186. package/dist/devtools/serialize.js +86 -0
  187. package/dist/devtools/serialize.js.map +1 -0
  188. package/dist/devtools/session.js +111 -0
  189. package/dist/devtools/session.js.map +1 -0
  190. package/dist/devtools/transport.js +67 -0
  191. package/dist/devtools/transport.js.map +1 -0
  192. package/dist/devtools/useDevtoolsRoot.js +81 -0
  193. package/dist/devtools/useDevtoolsRoot.js.map +1 -0
  194. package/dist/devtools-protocol.d.ts +435 -0
  195. package/dist/devtools-protocol.js +7 -0
  196. package/dist/devtools.d.ts +8 -0
  197. package/dist/devtools.js +12 -0
  198. package/dist/devtools.js.map +1 -0
  199. package/dist/features/chrome-caps/useHoverTracking.js +16 -10
  200. package/dist/features/chrome-caps/useHoverTracking.js.map +1 -1
  201. package/dist/features/ingestion/contentHandlers.js +25 -2
  202. package/dist/features/ingestion/contentHandlers.js.map +1 -1
  203. package/dist/features/measure/measureCommands.js +7 -5
  204. package/dist/features/measure/measureCommands.js.map +1 -1
  205. package/dist/features/paths/index.js +2 -2
  206. package/dist/features/paths/pathEditExtension.js.map +1 -1
  207. package/dist/features/paths/pathSnap/pathSnapSource.js +5 -5
  208. package/dist/features/paths/pathSnap/pathSnapSource.js.map +1 -1
  209. package/dist/features/paths/pathSnap/sceneIndex.js +10 -3
  210. package/dist/features/paths/pathSnap/sceneIndex.js.map +1 -1
  211. package/dist/features/selection/selectionPose.js +4 -1
  212. package/dist/features/selection/selectionPose.js.map +1 -1
  213. package/dist/features/snap/gather.js +9 -1
  214. package/dist/features/snap/gather.js.map +1 -1
  215. package/dist/features/snap/lazySession.js +17 -0
  216. package/dist/features/snap/lazySession.js.map +1 -0
  217. package/dist/features/snap/marks.js.map +1 -1
  218. package/dist/features/snap/probes2d.js +27 -19
  219. package/dist/features/snap/probes2d.js.map +1 -1
  220. package/dist/features/snap/readoutLayer.js.map +1 -1
  221. package/dist/features/snap/roles.js +2 -1
  222. package/dist/features/snap/roles.js.map +1 -1
  223. package/dist/features/snap/rotationSource.js +25 -8
  224. package/dist/features/snap/rotationSource.js.map +1 -1
  225. package/dist/features/snap/sceneSession2d.js +6 -4
  226. package/dist/features/snap/sceneSession2d.js.map +1 -1
  227. package/dist/features/snap/session2d.js +37 -23
  228. package/dist/features/snap/session2d.js.map +1 -1
  229. package/dist/features/snap/spanSnap.js +5 -2
  230. package/dist/features/snap/spanSnap.js.map +1 -1
  231. package/dist/icons.table.js +1 -1
  232. package/dist/icons.table.js.map +1 -1
  233. package/dist/icons.table.json +0 -10
  234. package/dist/index.d.ts +701 -696
  235. package/dist/index.js +35 -29
  236. package/dist/interactions/actions/align/action.js +6 -4
  237. package/dist/interactions/actions/align/action.js.map +1 -1
  238. package/dist/interactions/actions/align/align.js.map +1 -1
  239. package/dist/interactions/actions/booleans/action.js +7 -1
  240. package/dist/interactions/actions/booleans/action.js.map +1 -1
  241. package/dist/interactions/actions/clone/action.js +1 -1
  242. package/dist/interactions/actions/clone/behaviors.js +4 -4
  243. package/dist/interactions/actions/clone/behaviors.js.map +1 -1
  244. package/dist/interactions/actions/defaults/bendSegment.js +1 -1
  245. package/dist/interactions/actions/defaults/bendSegment.js.map +1 -1
  246. package/dist/interactions/actions/defaults/createPaintAction.js +1 -1
  247. package/dist/interactions/actions/defaults/delete.js +48 -39
  248. package/dist/interactions/actions/defaults/delete.js.map +1 -1
  249. package/dist/interactions/actions/defaults/duplicate.js +1 -1
  250. package/dist/interactions/actions/defaults/group.js +2 -2
  251. package/dist/interactions/actions/defaults/ingest.js +7 -5
  252. package/dist/interactions/actions/defaults/ingest.js.map +1 -1
  253. package/dist/interactions/actions/defaults/nudge.js +13 -38
  254. package/dist/interactions/actions/defaults/nudge.js.map +1 -1
  255. package/dist/interactions/actions/distribute/action.js +6 -4
  256. package/dist/interactions/actions/distribute/action.js.map +1 -1
  257. package/dist/interactions/actions/drawnBoxes.js +2 -1
  258. package/dist/interactions/actions/drawnBoxes.js.map +1 -1
  259. package/dist/interactions/actions/edit-anchors/action.js +3 -6
  260. package/dist/interactions/actions/edit-anchors/action.js.map +1 -1
  261. package/dist/interactions/actions/edit-anchors/preview.js +41 -8
  262. package/dist/interactions/actions/edit-anchors/preview.js.map +1 -1
  263. package/dist/interactions/actions/flip/action.js +6 -4
  264. package/dist/interactions/actions/flip/action.js.map +1 -1
  265. package/dist/interactions/actions/gestureLifecycle.js +5 -2
  266. package/dist/interactions/actions/gestureLifecycle.js.map +1 -1
  267. package/dist/interactions/actions/insert/action.js +1 -2
  268. package/dist/interactions/actions/insert/action.js.map +1 -1
  269. package/dist/interactions/actions/insert/commit.js +1 -1
  270. package/dist/interactions/actions/insert/parent.js +11 -0
  271. package/dist/interactions/actions/insert/parent.js.map +1 -0
  272. package/dist/interactions/actions/insert/placeAction.js +7 -2
  273. package/dist/interactions/actions/insert/placeAction.js.map +1 -1
  274. package/dist/interactions/actions/insert/session.js +5 -1
  275. package/dist/interactions/actions/insert/session.js.map +1 -1
  276. package/dist/interactions/actions/move/action.js +8 -4
  277. package/dist/interactions/actions/move/action.js.map +1 -1
  278. package/dist/interactions/actions/move/behaviors/layoutDrop.js +0 -1
  279. package/dist/interactions/actions/move/behaviors/layoutDrop.js.map +1 -1
  280. package/dist/interactions/actions/move/behaviors/snapToContainer.js +1 -1
  281. package/dist/interactions/actions/move/capture.js +1 -1
  282. package/dist/interactions/actions/move/commit/index.js +0 -2
  283. package/dist/interactions/actions/move/commit/index.js.map +1 -1
  284. package/dist/interactions/actions/move/commit/layoutDrop.js +2 -2
  285. package/dist/interactions/actions/move/commit/layoutRelease.js +2 -2
  286. package/dist/interactions/actions/move/commit/reparent.js +11 -5
  287. package/dist/interactions/actions/move/commit/reparent.js.map +1 -1
  288. package/dist/interactions/actions/move/frame.js +4 -10
  289. package/dist/interactions/actions/move/frame.js.map +1 -1
  290. package/dist/interactions/actions/move/landedDescendants.js +20 -17
  291. package/dist/interactions/actions/move/landedDescendants.js.map +1 -1
  292. package/dist/interactions/actions/move/layout/container.js +2 -1
  293. package/dist/interactions/actions/move/layout/container.js.map +1 -1
  294. package/dist/interactions/actions/move/layout/dragged.js +1 -1
  295. package/dist/interactions/actions/move/layout/dropPass.js +18 -1
  296. package/dist/interactions/actions/move/layout/dropPass.js.map +1 -1
  297. package/dist/interactions/actions/move/layout/exits.js +5 -5
  298. package/dist/interactions/actions/move/layout/exits.js.map +1 -1
  299. package/dist/interactions/actions/move/session.js +14 -3
  300. package/dist/interactions/actions/move/session.js.map +1 -1
  301. package/dist/interactions/actions/move/translate.js +8 -37
  302. package/dist/interactions/actions/move/translate.js.map +1 -1
  303. package/dist/interactions/actions/moveNodes.js +87 -0
  304. package/dist/interactions/actions/moveNodes.js.map +1 -0
  305. package/dist/interactions/actions/planeInput.js.map +1 -1
  306. package/dist/interactions/actions/resize/action.js +83 -72
  307. package/dist/interactions/actions/resize/action.js.map +1 -1
  308. package/dist/interactions/actions/resize/commit.js +2 -1
  309. package/dist/interactions/actions/resize/commit.js.map +1 -1
  310. package/dist/interactions/actions/resize/session.js +2 -0
  311. package/dist/interactions/actions/resize/session.js.map +1 -1
  312. package/dist/interactions/actions/resolvePreviews.js +3 -3
  313. package/dist/interactions/actions/resolvePreviews.js.map +1 -1
  314. package/dist/interactions/actions/rotate/action.js +7 -4
  315. package/dist/interactions/actions/rotate/action.js.map +1 -1
  316. package/dist/interactions/actions/rotate/commit.js +2 -1
  317. package/dist/interactions/actions/rotate/commit.js.map +1 -1
  318. package/dist/interactions/actions/rotate/session.js +2 -0
  319. package/dist/interactions/actions/rotate/session.js.map +1 -1
  320. package/dist/interactions/actions/selectionSubtree.js +13 -2
  321. package/dist/interactions/actions/selectionSubtree.js.map +1 -1
  322. package/dist/interactions/actions/testUtils.js.map +1 -1
  323. package/dist/interactions/actions/transform-again/action.js +5 -6
  324. package/dist/interactions/actions/transform-again/action.js.map +1 -1
  325. package/dist/interactions/actions/transformFinish.js +106 -0
  326. package/dist/interactions/actions/transformFinish.js.map +1 -0
  327. package/dist/kitSettingsSchema.js +0 -4
  328. package/dist/kitSettingsSchema.js.map +1 -1
  329. package/dist/move.d.ts +5 -4
  330. package/dist/{options-p9GZMXbY.d.ts → options-DBxEryYq.d.ts} +1 -1
  331. package/dist/resize.d.ts +4 -3
  332. package/dist/routing.d.ts +1 -1
  333. package/dist/routing.js +2 -2
  334. package/dist/test-hook/createTestHook.js +1 -1
  335. package/dist/test-hook/createTestHook.js.map +1 -1
  336. package/dist/test-hook/useTestHook.js +2 -1
  337. package/dist/test-hook/useTestHook.js.map +1 -1
  338. package/dist/test-seams.d.ts +9 -5
  339. package/dist/tools/builtin/pen/penHandle.js +3 -5
  340. package/dist/tools/builtin/pen/penHandle.js.map +1 -1
  341. package/dist/tools/index.js +26 -0
  342. package/dist/{types-CHVXGfYm.d.ts → types-7puAuVD2.d.ts} +3 -262
  343. package/dist/types-BN9hbdMI.d.ts +184 -0
  344. package/dist/types-CniVctmk.d.ts +949 -0
  345. package/dist/types-oFeQ5VjV.d.ts +264 -0
  346. package/dist/version.js +1 -1
  347. package/package.json +35 -25
  348. package/dist/canvas/SceneCanvas/useBuiltinRigTools.js +0 -65
  349. package/dist/canvas/SceneCanvas/useBuiltinRigTools.js.map +0 -1
  350. package/dist/tools/builtin/bone/boneActions.js +0 -156
  351. package/dist/tools/builtin/bone/boneActions.js.map +0 -1
  352. package/dist/tools/builtin/bone/boneOverlay.js +0 -71
  353. package/dist/tools/builtin/bone/boneOverlay.js.map +0 -1
  354. package/dist/tools/builtin/bone/placedRig.js +0 -28
  355. package/dist/tools/builtin/bone/placedRig.js.map +0 -1
  356. package/dist/tools/builtin/bone/rigEditState.js +0 -30
  357. package/dist/tools/builtin/bone/rigEditState.js.map +0 -1
  358. package/dist/tools/builtin/bone/useBoneTool.js +0 -125
  359. package/dist/tools/builtin/bone/useBoneTool.js.map +0 -1
  360. package/dist/tools/builtin/weight/useWeightTool.js +0 -101
  361. package/dist/tools/builtin/weight/useWeightTool.js.map +0 -1
  362. package/dist/tools/builtin/weight/weightActions.js +0 -140
  363. package/dist/tools/builtin/weight/weightActions.js.map +0 -1
  364. package/dist/tools/builtin/weight/weightOverlay.js +0 -78
  365. package/dist/tools/builtin/weight/weightOverlay.js.map +0 -1
@@ -6,6 +6,30 @@ var QUARTER = Math.PI / 2;
6
6
  * Every `<SceneCanvas>` asks it, under the id `'rotation'`.
7
7
  */
8
8
  function rotationSnapSource() {
9
+ let cached = null;
10
+ const nodeAngles = (q) => {
11
+ const { scene, rotationOf } = q;
12
+ if (!scene || !rotationOf) return [];
13
+ const key = [
14
+ scene,
15
+ scene.getVersion(),
16
+ rotationOf,
17
+ q.exclude
18
+ ];
19
+ if (cached && key.every((k, i) => k === cached.key[i])) return cached.angles;
20
+ const exclude = new Set(q.exclude);
21
+ const angles = [];
22
+ for (const id of scene.nodes.keys()) {
23
+ if (exclude.has(id) || scene.isHidden(id)) continue;
24
+ const angle = rotationOf(id);
25
+ if (angle !== void 0 && Number.isFinite(angle)) angles.push(angle);
26
+ }
27
+ cached = {
28
+ key,
29
+ angles
30
+ };
31
+ return angles;
32
+ };
9
33
  return {
10
34
  id: "rotation",
11
35
  roles: [],
@@ -13,14 +37,7 @@ function rotationSnapSource() {
13
37
  collect: () => [],
14
38
  *angles(q) {
15
39
  for (let k = 0; k < 4; k++) yield { angle: k * QUARTER };
16
- const { scene, rotationOf } = q;
17
- if (!scene || !rotationOf) return;
18
- const exclude = new Set(q.exclude);
19
- for (const id of scene.nodes.keys()) {
20
- if (exclude.has(id) || scene.isHidden(id)) continue;
21
- const angle = rotationOf(id);
22
- if (angle !== void 0 && Number.isFinite(angle)) yield { angle };
23
- }
40
+ for (const angle of nodeAngles(q)) yield { angle };
24
41
  }
25
42
  };
26
43
  }
@@ -1 +1 @@
1
- {"version":3,"file":"rotationSource.js","names":[],"sources":["../../../src/features/snap/rotationSource.ts"],"sourcesContent":["import type { NodeId } from 'core/scene/types';\nimport type { AngleCandidate, SnapSource } from './types';\n\nconst QUARTER = Math.PI / 2;\n\n/**\n * A rotate's angle targets: every quarter turn, and the world rotation of\n * every other visible node that can turn. Shift's step is the rotate's own.\n * Every `<SceneCanvas>` asks it, under the id `'rotation'`.\n */\nexport function rotationSnapSource(): SnapSource {\n return {\n id: 'rotation',\n roles: [],\n gestures: ['rotate'],\n collect: () => [],\n *angles(q): Iterable<AngleCandidate> {\n for (let k = 0; k < 4; k++) yield { angle: k * QUARTER };\n const { scene, rotationOf } = q;\n if (!scene || !rotationOf) return;\n const exclude = new Set(q.exclude);\n for (const id of scene.nodes.keys()) {\n if (exclude.has(id) || scene.isHidden(id as NodeId)) continue;\n const angle = rotationOf(id);\n if (angle !== undefined && Number.isFinite(angle)) yield { angle };\n }\n },\n };\n}\n"],"mappings":";AAGA,IAAM,UAAU,KAAK,KAAK;;;;;;AAO1B,SAAgB,qBAAiC;CAC/C,OAAO;EACL,IAAI;EACJ,OAAO,CAAC;EACR,UAAU,CAAC,QAAQ;EACnB,eAAe,CAAC;EAChB,CAAC,OAAO,GAA6B;GACnC,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,MAAM,EAAE,OAAO,IAAI,QAAQ;GACvD,MAAM,EAAE,OAAO,eAAe;GAC9B,IAAI,CAAC,SAAS,CAAC,YAAY;GAC3B,MAAM,UAAU,IAAI,IAAI,EAAE,OAAO;GACjC,KAAK,MAAM,MAAM,MAAM,MAAM,KAAK,GAAG;IACnC,IAAI,QAAQ,IAAI,EAAE,KAAK,MAAM,SAAS,EAAY,GAAG;IACrD,MAAM,QAAQ,WAAW,EAAE;IAC3B,IAAI,UAAU,UAAa,OAAO,SAAS,KAAK,GAAG,MAAM,EAAE,MAAM;GACnE;EACF;CACF;AACF"}
1
+ {"version":3,"file":"rotationSource.js","names":[],"sources":["../../../src/features/snap/rotationSource.ts"],"sourcesContent":["import type { NodeId } from 'core/scene/types';\nimport type { AngleCandidate, AngleCollect, SnapSource } from './types';\n\nconst QUARTER = Math.PI / 2;\n\n/**\n * A rotate's angle targets: every quarter turn, and the world rotation of\n * every other visible node that can turn. Shift's step is the rotate's own.\n * Every `<SceneCanvas>` asks it, under the id `'rotation'`.\n */\nexport function rotationSnapSource(): SnapSource {\n let cached: { key: readonly unknown[]; angles: number[] } | null = null;\n const nodeAngles = (q: AngleCollect): readonly number[] => {\n const { scene, rotationOf } = q;\n if (!scene || !rotationOf) return [];\n const key = [scene, scene.getVersion(), rotationOf, q.exclude];\n if (cached && key.every((k, i) => k === cached!.key[i])) return cached.angles;\n const exclude = new Set(q.exclude);\n const angles: number[] = [];\n for (const id of scene.nodes.keys()) {\n if (exclude.has(id) || scene.isHidden(id as NodeId)) continue;\n const angle = rotationOf(id);\n if (angle !== undefined && Number.isFinite(angle)) angles.push(angle);\n }\n cached = { key, angles };\n return angles;\n };\n return {\n id: 'rotation',\n roles: [],\n gestures: ['rotate'],\n collect: () => [],\n *angles(q): Iterable<AngleCandidate> {\n for (let k = 0; k < 4; k++) yield { angle: k * QUARTER };\n for (const angle of nodeAngles(q)) yield { angle };\n },\n };\n}\n"],"mappings":";AAGA,IAAM,UAAU,KAAK,KAAK;;;;;;AAO1B,SAAgB,qBAAiC;CAC/C,IAAI,SAA+D;CACnE,MAAM,cAAc,MAAuC;EACzD,MAAM,EAAE,OAAO,eAAe;EAC9B,IAAI,CAAC,SAAS,CAAC,YAAY,OAAO,CAAC;EACnC,MAAM,MAAM;GAAC;GAAO,MAAM,WAAW;GAAG;GAAY,EAAE;EAAO;EAC7D,IAAI,UAAU,IAAI,OAAO,GAAG,MAAM,MAAM,OAAQ,IAAI,EAAE,GAAG,OAAO,OAAO;EACvE,MAAM,UAAU,IAAI,IAAI,EAAE,OAAO;EACjC,MAAM,SAAmB,CAAC;EAC1B,KAAK,MAAM,MAAM,MAAM,MAAM,KAAK,GAAG;GACnC,IAAI,QAAQ,IAAI,EAAE,KAAK,MAAM,SAAS,EAAY,GAAG;GACrD,MAAM,QAAQ,WAAW,EAAE;GAC3B,IAAI,UAAU,UAAa,OAAO,SAAS,KAAK,GAAG,OAAO,KAAK,KAAK;EACtE;EACA,SAAS;GAAE;GAAK;EAAO;EACvB,OAAO;CACT;CACA,OAAO;EACL,IAAI;EACJ,OAAO,CAAC;EACR,UAAU,CAAC,QAAQ;EACnB,eAAe,CAAC;EAChB,CAAC,OAAO,GAA6B;GACnC,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,MAAM,EAAE,OAAO,IAAI,QAAQ;GACvD,KAAK,MAAM,SAAS,WAAW,CAAC,GAAG,MAAM,EAAE,MAAM;EACnD;CACF;AACF"}
@@ -1,7 +1,7 @@
1
1
  import { drawnBoxes } from "../../interactions/actions/drawnBoxes.js";
2
2
  import { createSnapOutcomeStore } from "./outcomeStore.js";
3
3
  import { DEFAULT_SNAP_PX, createSession2d } from "./session2d.js";
4
- import { buildProbes, resizeSubjectOf, subjectBox } from "./probes2d.js";
4
+ import { buildProbes, subjectOf } from "./probes2d.js";
5
5
  import { sceneProbeReads, sceneRotations, withSubtrees } from "./sceneReads.js";
6
6
 
7
7
  //#region src/features/snap/sceneSession2d.ts
@@ -13,12 +13,13 @@ function sceneSession2d(i) {
13
13
  ...i.geometryAt ? { geometryAt: i.geometryAt } : {},
14
14
  ...i.originProjection ? { originProjection: i.originProjection } : {}
15
15
  });
16
+ const subject = subjectOf(i.req, reads);
16
17
  return createSession2d({
17
18
  req: i.req,
18
19
  sources: i.sources,
19
- probes: buildProbes(i.req, reads),
20
- box: i.req.ids ? subjectBox(i.req.ids, reads) : null,
21
- resize: resizeSubjectOf(i.req, reads),
20
+ probes: buildProbes(i.req, reads, subject),
21
+ box: subject.box,
22
+ resize: subject.resize,
22
23
  drawnBox: (id) => {
23
24
  const pose = reads.pose(id);
24
25
  return pose === void 0 ? void 0 : reads.drawnBox(id, pose);
@@ -45,6 +46,7 @@ function createSnapSession2d(opts) {
45
46
  gesture: opts.gesture,
46
47
  press: opts.press,
47
48
  ...opts.ids ? { ids: opts.ids } : {},
49
+ ...opts.parent !== void 0 ? { parent: opts.parent } : {},
48
50
  ...opts.origin ? { origin: opts.origin } : {},
49
51
  ...opts.constrain ? { constrain: opts.constrain } : {},
50
52
  ...opts.handle ? { handle: opts.handle } : {},
@@ -1 +1 @@
1
- {"version":3,"file":"sceneSession2d.js","names":[],"sources":["../../../src/features/snap/sceneSession2d.ts"],"sourcesContent":["import type { ResizeAnchor } from '@weasel-js/routing';\nimport type { View } from '@weasel-js/geom';\nimport type { DebugSink } from '@weasel-js/routing';\nimport type { PoseDescriptor } from 'core/geometry/poseDescriptor';\nimport type { Scene } from 'core/scene/types';\nimport type { PlaneMap } from 'core/viewport/parallax';\nimport type { OriginProjection } from 'interactions/gestures/shared/originProjection';\nimport { drawnBoxes, type DrawnBoxes } from 'interactions/actions/drawnBoxes';\nimport type { SnapBegin, SnapConstrain, SnapGeometry, SnapResizeBox, SnapSession } from 'interactions/actions/snapDep';\nimport { createSnapOutcomeStore, type SnapOutcomeStore } from './outcomeStore';\nimport { buildProbes, resizeSubjectOf, subjectBox } from './probes2d';\nimport { sceneProbeReads, sceneRotations, withSubtrees } from './sceneReads';\nimport { createSession2d, DEFAULT_SNAP_PX } from './session2d';\nimport type { SnapGesture, SnapSource } from './types';\n\ntype Point = { x: number; y: number };\ntype AnyScene = Scene<unknown, string, unknown>;\n\n/** What a session over a scene runs on: its subject's probes and boxes come\n * from `scene`, measured through `boxes`. */\nexport interface SceneSessionInputs {\n req: SnapBegin;\n scene: AnyScene;\n boxes: DrawnBoxes;\n sources: readonly SnapSource[];\n view(): View | null;\n reachPx: number;\n store: SnapOutcomeStore;\n geometryAt?: (press: Point, ids: readonly string[]) => Point | null;\n /** How a pose's origin is read. Default `AUTO_ORIGIN_PROJECTION`. */\n originProjection?: OriginProjection<unknown>;\n /** How a node's rotation is read. Default `AUTO_POSE_DESCRIPTOR`. */\n poseDescriptor?: PoseDescriptor<unknown>;\n /** Where each frame's candidates are recorded. */\n debug?: DebugSink;\n}\n\n/** A 2D session whose probes are the subject's, read from the scene at press. */\nexport function sceneSession2d(i: SceneSessionInputs): SnapSession {\n const reads = sceneProbeReads({\n scene: i.scene, boxes: i.boxes,\n ...(i.geometryAt ? { geometryAt: i.geometryAt } : {}),\n ...(i.originProjection ? { originProjection: i.originProjection } : {}),\n });\n return createSession2d({\n req: i.req,\n sources: i.sources,\n probes: buildProbes(i.req, reads),\n box: i.req.ids ? subjectBox(i.req.ids, reads) : null,\n resize: resizeSubjectOf(i.req, reads),\n drawnBox: (id) => {\n const pose = reads.pose(id);\n return pose === undefined ? undefined : reads.drawnBox(id, pose);\n },\n ...(i.req.ids ? { exclude: withSubtrees(i.scene, i.req.ids) } : {}),\n view: i.view,\n reachPx: i.reachPx,\n scene: i.scene,\n rotationOf: sceneRotations(i.scene, i.poseDescriptor),\n store: i.store,\n ...(i.debug ? { debug: i.debug } : {}),\n });\n}\n\n/** Options for {@link createSnapSession2d}. */\nexport interface SnapSession2dOptions {\n scene: AnyScene;\n /** The camera the reach is measured through. */\n view: View;\n sources: readonly SnapSource[];\n gesture: SnapGesture;\n /** World coords. */\n press: Point;\n /** The subject, whose geometry offers no targets. */\n ids?: readonly string[];\n /** Point gestures: the previous anchor, a line's start. */\n origin?: Point;\n constrain?: SnapConstrain;\n /** Resize: the sides the drag pins. */\n handle?: ResizeAnchor;\n /** Rotate: the point the angle turns about. */\n pivot?: Point;\n /** Rotate: the subject's angle at press. */\n theta0?: number;\n /** Angle gestures: the reach as an angle, radians. */\n reachRad?: number;\n /** Resize: the box `handle` belongs to. Default: the subjects' drawn box. */\n box?: SnapResizeBox;\n also?: SnapGeometry;\n /** The reach of a source that sets none, in screen px. Default `DEFAULT_SNAP_PX`. */\n reachPx?: number;\n /** Where the session writes its marks. Default: a store of its own. */\n store?: SnapOutcomeStore;\n /** How poses are read. Default `AUTO_POSE_DESCRIPTOR`. */\n poseDescriptor?: PoseDescriptor<unknown>;\n /** Whether drawn boxes include the stroke. Default `true`. */\n boundsIncludeStroke?: boolean;\n /** How a pose's origin, the point a grid or a guide snaps, is read.\n * Default `AUTO_ORIGIN_PROJECTION`: a rect's `{x, y}`, a path's bounds. */\n originProjection?: OriginProjection<unknown>;\n /** How `view`'s world maps into the parallax plane the gesture's points\n * are in. Default: they are in `view`'s own world. */\n plane?: PlaneMap | null;\n}\n\n/**\n * One gesture's snapping over a scene, for a host without `<SceneCanvas>`:\n * the session a canvas's `snap` dep begins, built from the same probes and\n * drawn boxes. Call `at` with each world point the gesture reaches, and\n * `end` when it lets go.\n */\nexport function createSnapSession2d(opts: SnapSession2dOptions): SnapSession {\n const view = opts.view;\n const req: SnapBegin = {\n gesture: opts.gesture,\n press: opts.press,\n ...(opts.ids ? { ids: opts.ids } : {}),\n ...(opts.origin ? { origin: opts.origin } : {}),\n ...(opts.constrain ? { constrain: opts.constrain } : {}),\n ...(opts.handle ? { handle: opts.handle } : {}),\n ...(opts.pivot ? { pivot: opts.pivot } : {}),\n ...(opts.theta0 !== undefined ? { theta0: opts.theta0 } : {}),\n ...(opts.reachRad !== undefined ? { reachRad: opts.reachRad } : {}),\n ...(opts.box ? { box: opts.box } : {}),\n ...(opts.also ? { also: opts.also } : {}),\n ...(opts.plane ? { plane: () => opts.plane ?? null } : {}),\n };\n return sceneSession2d({\n req,\n scene: opts.scene,\n boxes: drawnBoxes({\n scene: opts.scene,\n view: { get: () => view, set: () => {} },\n ...(opts.poseDescriptor ? { poseDescriptor: opts.poseDescriptor } : {}),\n ...(opts.boundsIncludeStroke !== undefined ? { boundsIncludeStroke: opts.boundsIncludeStroke } : {}),\n }),\n sources: opts.sources,\n view: () => view,\n reachPx: opts.reachPx ?? DEFAULT_SNAP_PX,\n store: opts.store ?? createSnapOutcomeStore(),\n ...(opts.originProjection ? { originProjection: opts.originProjection } : {}),\n ...(opts.poseDescriptor ? { poseDescriptor: opts.poseDescriptor } : {}),\n });\n}\n"],"mappings":";;;;;;;;AAsCA,SAAgB,eAAe,GAAoC;CACjE,MAAM,QAAQ,gBAAgB;EAC5B,OAAO,EAAE;EAAO,OAAO,EAAE;EACzB,GAAI,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,IAAI,CAAC;EACnD,GAAI,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,iBAAiB,IAAI,CAAC;CACvE,CAAC;CACD,OAAO,gBAAgB;EACrB,KAAK,EAAE;EACP,SAAS,EAAE;EACX,QAAQ,YAAY,EAAE,KAAK,KAAK;EAChC,KAAK,EAAE,IAAI,MAAM,WAAW,EAAE,IAAI,KAAK,KAAK,IAAI;EAChD,QAAQ,gBAAgB,EAAE,KAAK,KAAK;EACpC,WAAW,OAAO;GAChB,MAAM,OAAO,MAAM,KAAK,EAAE;GAC1B,OAAO,SAAS,SAAY,SAAY,MAAM,SAAS,IAAI,IAAI;EACjE;EACA,GAAI,EAAE,IAAI,MAAM,EAAE,SAAS,aAAa,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,IAAI,CAAC;EACjE,MAAM,EAAE;EACR,SAAS,EAAE;EACX,OAAO,EAAE;EACT,YAAY,eAAe,EAAE,OAAO,EAAE,cAAc;EACpD,OAAO,EAAE;EACT,GAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;CACtC,CAAC;AACH;;;;;;;AAiDA,SAAgB,oBAAoB,MAAyC;CAC3E,MAAM,OAAO,KAAK;CAelB,OAAO,eAAe;EACpB;GAdA,SAAS,KAAK;GACd,OAAO,KAAK;GACZ,GAAI,KAAK,MAAM,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC;GACpC,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;GAC7C,GAAI,KAAK,YAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;GACtD,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;GAC7C,GAAI,KAAK,QAAQ,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;GAC1C,GAAI,KAAK,WAAW,SAAY,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;GAC3D,GAAI,KAAK,aAAa,SAAY,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;GACjE,GAAI,KAAK,MAAM,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC;GACpC,GAAI,KAAK,OAAO,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;GACvC,GAAI,KAAK,QAAQ,EAAE,aAAa,KAAK,SAAS,KAAK,IAAI,CAAC;EAGxD;EACA,OAAO,KAAK;EACZ,OAAO,WAAW;GAChB,OAAO,KAAK;GACZ,MAAM;IAAE,WAAW;IAAM,WAAW,CAAC;GAAE;GACvC,GAAI,KAAK,iBAAiB,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;GACrE,GAAI,KAAK,wBAAwB,SAAY,EAAE,qBAAqB,KAAK,oBAAoB,IAAI,CAAC;EACpG,CAAC;EACD,SAAS,KAAK;EACd,YAAY;EACZ,SAAS,KAAK,WAAW;EACzB,OAAO,KAAK,SAAS,uBAAuB;EAC5C,GAAI,KAAK,mBAAmB,EAAE,kBAAkB,KAAK,iBAAiB,IAAI,CAAC;EAC3E,GAAI,KAAK,iBAAiB,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;CACvE,CAAC;AACH"}
1
+ {"version":3,"file":"sceneSession2d.js","names":[],"sources":["../../../src/features/snap/sceneSession2d.ts"],"sourcesContent":["import type { ResizeAnchor } from '@weasel-js/routing';\nimport type { View } from '@weasel-js/geom';\nimport type { DebugSink } from '@weasel-js/routing';\nimport type { PoseDescriptor } from 'core/geometry/poseDescriptor';\nimport type { Scene } from 'core/scene/types';\nimport type { PlaneMap } from 'core/viewport/parallax';\nimport type { OriginProjection } from 'interactions/gestures/shared/originProjection';\nimport { drawnBoxes, type DrawnBoxes } from 'interactions/actions/drawnBoxes';\nimport type { SnapBegin, SnapConstrain, SnapGeometry, SnapResizeBox, SnapSession } from 'interactions/actions/snapDep';\nimport { createSnapOutcomeStore, type SnapOutcomeStore } from './outcomeStore';\nimport { buildProbes, subjectOf } from './probes2d';\nimport { sceneProbeReads, sceneRotations, withSubtrees } from './sceneReads';\nimport { createSession2d, DEFAULT_SNAP_PX } from './session2d';\nimport type { SnapGesture, SnapSource } from './types';\n\ntype Point = { x: number; y: number };\ntype AnyScene = Scene<unknown, string, unknown>;\n\n/** What a session over a scene runs on: its subject's probes and boxes come\n * from `scene`, measured through `boxes`. */\nexport interface SceneSessionInputs {\n req: SnapBegin;\n scene: AnyScene;\n boxes: DrawnBoxes;\n sources: readonly SnapSource[];\n view(): View | null;\n reachPx: number;\n store: SnapOutcomeStore;\n geometryAt?: (press: Point, ids: readonly string[]) => Point | null;\n /** How a pose's origin is read. Default `AUTO_ORIGIN_PROJECTION`. */\n originProjection?: OriginProjection<unknown>;\n /** How a node's rotation is read. Default `AUTO_POSE_DESCRIPTOR`. */\n poseDescriptor?: PoseDescriptor<unknown>;\n /** Where each frame's candidates are recorded. */\n debug?: DebugSink;\n}\n\n/** A 2D session whose probes are the subject's, read from the scene at press. */\nexport function sceneSession2d(i: SceneSessionInputs): SnapSession {\n const reads = sceneProbeReads({\n scene: i.scene, boxes: i.boxes,\n ...(i.geometryAt ? { geometryAt: i.geometryAt } : {}),\n ...(i.originProjection ? { originProjection: i.originProjection } : {}),\n });\n const subject = subjectOf(i.req, reads);\n return createSession2d({\n req: i.req,\n sources: i.sources,\n probes: buildProbes(i.req, reads, subject),\n box: subject.box,\n resize: subject.resize,\n drawnBox: (id) => {\n const pose = reads.pose(id);\n return pose === undefined ? undefined : reads.drawnBox(id, pose);\n },\n ...(i.req.ids ? { exclude: withSubtrees(i.scene, i.req.ids) } : {}),\n view: i.view,\n reachPx: i.reachPx,\n scene: i.scene,\n rotationOf: sceneRotations(i.scene, i.poseDescriptor),\n store: i.store,\n ...(i.debug ? { debug: i.debug } : {}),\n });\n}\n\n/** Options for {@link createSnapSession2d}. */\nexport interface SnapSession2dOptions {\n scene: AnyScene;\n /** The camera the reach is measured through. */\n view: View;\n sources: readonly SnapSource[];\n gesture: SnapGesture;\n /** World coords. */\n press: Point;\n /** The subject, whose geometry offers no targets. */\n ids?: readonly string[];\n /** The container a subject not yet in the scene lands in. */\n parent?: string;\n /** Point gestures: the previous anchor, a line's start. */\n origin?: Point;\n constrain?: SnapConstrain;\n /** Resize: the sides the drag pins. */\n handle?: ResizeAnchor;\n /** Rotate: the point the angle turns about. */\n pivot?: Point;\n /** Rotate: the subject's angle at press. */\n theta0?: number;\n /** Angle gestures: the reach as an angle, radians. */\n reachRad?: number;\n /** Resize: the box `handle` belongs to. Default: the subjects' drawn box. */\n box?: SnapResizeBox;\n also?: SnapGeometry;\n /** The reach of a source that sets none, in screen px. Default `DEFAULT_SNAP_PX`. */\n reachPx?: number;\n /** Where the session writes its marks. Default: a store of its own. */\n store?: SnapOutcomeStore;\n /** How poses are read. Default `AUTO_POSE_DESCRIPTOR`. */\n poseDescriptor?: PoseDescriptor<unknown>;\n /** Whether drawn boxes include the stroke. Default `true`. */\n boundsIncludeStroke?: boolean;\n /** How a pose's origin, the point a grid or a guide snaps, is read.\n * Default `AUTO_ORIGIN_PROJECTION`: a rect's `{x, y}`, a path's bounds. */\n originProjection?: OriginProjection<unknown>;\n /** How `view`'s world maps into the parallax plane the gesture's points\n * are in. Default: they are in `view`'s own world. */\n plane?: PlaneMap | null;\n}\n\n/**\n * One gesture's snapping over a scene, for a host without `<SceneCanvas>`:\n * the session a canvas's `snap` dep begins, built from the same probes and\n * drawn boxes. Call `at` with each world point the gesture reaches, and\n * `end` when it lets go.\n */\nexport function createSnapSession2d(opts: SnapSession2dOptions): SnapSession {\n const view = opts.view;\n const req: SnapBegin = {\n gesture: opts.gesture,\n press: opts.press,\n ...(opts.ids ? { ids: opts.ids } : {}),\n ...(opts.parent !== undefined ? { parent: opts.parent } : {}),\n ...(opts.origin ? { origin: opts.origin } : {}),\n ...(opts.constrain ? { constrain: opts.constrain } : {}),\n ...(opts.handle ? { handle: opts.handle } : {}),\n ...(opts.pivot ? { pivot: opts.pivot } : {}),\n ...(opts.theta0 !== undefined ? { theta0: opts.theta0 } : {}),\n ...(opts.reachRad !== undefined ? { reachRad: opts.reachRad } : {}),\n ...(opts.box ? { box: opts.box } : {}),\n ...(opts.also ? { also: opts.also } : {}),\n ...(opts.plane ? { plane: () => opts.plane ?? null } : {}),\n };\n return sceneSession2d({\n req,\n scene: opts.scene,\n boxes: drawnBoxes({\n scene: opts.scene,\n view: { get: () => view, set: () => {} },\n ...(opts.poseDescriptor ? { poseDescriptor: opts.poseDescriptor } : {}),\n ...(opts.boundsIncludeStroke !== undefined ? { boundsIncludeStroke: opts.boundsIncludeStroke } : {}),\n }),\n sources: opts.sources,\n view: () => view,\n reachPx: opts.reachPx ?? DEFAULT_SNAP_PX,\n store: opts.store ?? createSnapOutcomeStore(),\n ...(opts.originProjection ? { originProjection: opts.originProjection } : {}),\n ...(opts.poseDescriptor ? { poseDescriptor: opts.poseDescriptor } : {}),\n });\n}\n"],"mappings":";;;;;;;;AAsCA,SAAgB,eAAe,GAAoC;CACjE,MAAM,QAAQ,gBAAgB;EAC5B,OAAO,EAAE;EAAO,OAAO,EAAE;EACzB,GAAI,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,IAAI,CAAC;EACnD,GAAI,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,iBAAiB,IAAI,CAAC;CACvE,CAAC;CACD,MAAM,UAAU,UAAU,EAAE,KAAK,KAAK;CACtC,OAAO,gBAAgB;EACrB,KAAK,EAAE;EACP,SAAS,EAAE;EACX,QAAQ,YAAY,EAAE,KAAK,OAAO,OAAO;EACzC,KAAK,QAAQ;EACb,QAAQ,QAAQ;EAChB,WAAW,OAAO;GAChB,MAAM,OAAO,MAAM,KAAK,EAAE;GAC1B,OAAO,SAAS,SAAY,SAAY,MAAM,SAAS,IAAI,IAAI;EACjE;EACA,GAAI,EAAE,IAAI,MAAM,EAAE,SAAS,aAAa,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,IAAI,CAAC;EACjE,MAAM,EAAE;EACR,SAAS,EAAE;EACX,OAAO,EAAE;EACT,YAAY,eAAe,EAAE,OAAO,EAAE,cAAc;EACpD,OAAO,EAAE;EACT,GAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;CACtC,CAAC;AACH;;;;;;;AAmDA,SAAgB,oBAAoB,MAAyC;CAC3E,MAAM,OAAO,KAAK;CAgBlB,OAAO,eAAe;EACpB;GAfA,SAAS,KAAK;GACd,OAAO,KAAK;GACZ,GAAI,KAAK,MAAM,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC;GACpC,GAAI,KAAK,WAAW,SAAY,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;GAC3D,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;GAC7C,GAAI,KAAK,YAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;GACtD,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;GAC7C,GAAI,KAAK,QAAQ,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;GAC1C,GAAI,KAAK,WAAW,SAAY,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;GAC3D,GAAI,KAAK,aAAa,SAAY,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;GACjE,GAAI,KAAK,MAAM,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC;GACpC,GAAI,KAAK,OAAO,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;GACvC,GAAI,KAAK,QAAQ,EAAE,aAAa,KAAK,SAAS,KAAK,IAAI,CAAC;EAGxD;EACA,OAAO,KAAK;EACZ,OAAO,WAAW;GAChB,OAAO,KAAK;GACZ,MAAM;IAAE,WAAW;IAAM,WAAW,CAAC;GAAE;GACvC,GAAI,KAAK,iBAAiB,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;GACrE,GAAI,KAAK,wBAAwB,SAAY,EAAE,qBAAqB,KAAK,oBAAoB,IAAI,CAAC;EACpG,CAAC;EACD,SAAS,KAAK;EACd,YAAY;EACZ,SAAS,KAAK,WAAW;EACzB,OAAO,KAAK,SAAS,uBAAuB;EAC5C,GAAI,KAAK,mBAAmB,EAAE,kBAAkB,KAAK,iBAAiB,IAAI,CAAC;EAC3E,GAAI,KAAK,iBAAiB,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;CACvE,CAAC;AACH"}
@@ -15,6 +15,7 @@ var DEFAULT_SNAP_PX = 8;
15
15
  function createSession2d(inputs) {
16
16
  const { req, store } = inputs;
17
17
  const sources = snapSourcesFor(inputs.sources, req.gesture);
18
+ const fixed = collectAtPress(inputs);
18
19
  return {
19
20
  at(p, mods) {
20
21
  const delta0 = {
@@ -29,7 +30,15 @@ function createSession2d(inputs) {
29
30
  }
30
31
  const view = inputs.view();
31
32
  const plane = req.plane?.() ?? null;
32
- const candidates = collectAll(inputs, sources, delta0, view, plane);
33
+ const subject = subjectAt(inputs, delta0);
34
+ const candidates = collectAll(sources, inputs.probes, {
35
+ ...fixed,
36
+ ...subject
37
+ }, {
38
+ delta0,
39
+ view,
40
+ plane
41
+ }, inputs.reachPx);
33
42
  const res = resolveSnap({
34
43
  probes: inputs.probes.map((q) => ({
35
44
  id: q.id,
@@ -67,47 +76,52 @@ function outcome(press, delta, held, marks) {
67
76
  marks
68
77
  };
69
78
  }
70
- function collectAll(inputs, sources, delta0, view, plane) {
79
+ function collectAtPress(inputs) {
71
80
  const { req } = inputs;
81
+ return {
82
+ gesture: req.gesture,
83
+ ...req.ids ? { ids: req.ids } : {},
84
+ ...req.parent !== void 0 ? { parent: req.parent } : {},
85
+ exclude: inputs.exclude ?? req.ids ?? [],
86
+ ...inputs.drawnBox ? { drawnBox: inputs.drawnBox } : {},
87
+ ...req.origin ? { origin: req.origin } : {},
88
+ ...req.also ? { also: req.also } : {},
89
+ ...inputs.scene ? { scene: inputs.scene } : {}
90
+ };
91
+ }
92
+ function collectAll(sources, probesAtPress, fixed, { delta0, view, plane }, reachPx) {
72
93
  const camera = view ? Math.min(Math.abs(view.scale.x), Math.abs(view.scale.y)) : 1;
73
94
  const scale = plane ? camera / Math.max(Math.abs(plane.scale.x), Math.abs(plane.scale.y)) : camera;
74
- const probes = inputs.probes.map((q) => ({
95
+ const probes = probesAtPress.map((q) => ({
75
96
  ...q,
76
97
  at: {
77
98
  x: q.at.x + delta0.x,
78
99
  y: q.at.y + delta0.y
79
100
  }
80
101
  }));
81
- return gatherSnapCandidates(sources, probes, (_source, offered, reachPx) => ({
82
- gesture: req.gesture,
102
+ return gatherSnapCandidates(sources, probes, (_source, offered, sourceReach) => ({
103
+ ...fixed,
83
104
  probes: offered,
84
105
  delta0,
85
- exclude: inputs.exclude ?? req.ids ?? [],
86
106
  ...plane ? { plane } : {},
87
- ...subjectAt(inputs, delta0),
88
- ...inputs.drawnBox ? { drawnBox: inputs.drawnBox } : {},
89
- ...req.origin ? { origin: req.origin } : {},
90
- ...req.also ? { also: req.also } : {},
91
107
  reachWorld: (px) => px / scale,
92
- reachPx,
93
- ...inputs.scene ? { scene: inputs.scene } : {}
108
+ reachPx: sourceReach
94
109
  }), {
95
110
  toVec: (p) => [p.x, p.y],
96
- reachPx: inputs.reachPx,
97
- ...req.origin ? { origin: req.origin } : {}
111
+ reachPx,
112
+ ...fixed.origin ? { origin: fixed.origin } : {}
98
113
  });
99
114
  }
100
115
  /** The subject's box where `delta0` puts it, and the sides that moved. */
101
- function subjectAt(inputs, delta0) {
102
- if (inputs.resize) return {
103
- box: resizedBox(inputs.resize, delta0),
104
- edges: resizeEdges(inputs.resize, delta0)
116
+ function subjectAt({ box, resize }, delta0) {
117
+ if (resize) return {
118
+ box: resizedBox(resize, delta0),
119
+ edges: resizeEdges(resize, delta0)
105
120
  };
106
- const b = inputs.req.gesture === "move" ? inputs.box : null;
107
- return b ? { box: {
108
- ...b,
109
- x: b.x + delta0.x,
110
- y: b.y + delta0.y
121
+ return box ? { box: {
122
+ ...box,
123
+ x: box.x + delta0.x,
124
+ y: box.y + delta0.y
111
125
  } } : {};
112
126
  }
113
127
  /** A session no source answers: it only holds the point to the gesture's
@@ -1 +1 @@
1
- {"version":3,"file":"session2d.js","names":[],"sources":["../../../src/features/snap/session2d.ts"],"sourcesContent":["import { closestOnFlat, resolveSnap, type SnapCandidate } from '@weasel-js/geom/nd';\nimport type { View } from '@weasel-js/geom';\nimport type { DebugSink } from '@weasel-js/routing';\nimport type { Scene } from 'core/scene/types';\nimport type { Bounds } from 'core/viewport/fitViewToBounds';\nimport type { PlaneMap } from 'core/viewport/parallax';\nimport type { SnapBegin, SnapOutcome, SnapSession } from 'interactions/actions/snapDep';\nimport { angleAt } from './angle2d';\nimport { inputFlat } from './inputSubspace';\nimport { gatherSnapCandidates, resolvedSnapMarks, snapSourcesFor, type SnapCandidateMark } from './gather';\nimport { recordSnapCandidates } from './debugCandidates';\nimport { markFromPlane } from './marks';\nimport { createSnapOutcomeStore, type SnapOutcomeStore } from './outcomeStore';\nimport { resizedBox, resizeEdges, resizeSubject, type ResizeSubject } from './resizeBox';\nimport { screenOf } from './screen';\nimport type { SnapCollect, SnapMark, SnapProbeAt, SnapSource } from './types';\n\ntype Point = { x: number; y: number };\n\n/** The canvas's reach when neither a source nor the kit settings name one. */\nexport const DEFAULT_SNAP_PX = 8;\n\n\n/** What a 2D session runs on, captured at press. */\nexport interface Session2dInputs {\n req: SnapBegin;\n /** In source order: earlier wins a full tie. */\n sources: readonly SnapSource[];\n /** At press. */\n probes: readonly SnapProbeAt[];\n /** A move's subject: its drawn box at press. */\n box?: Bounds | null;\n /** A resize's box and frame. */\n resize?: ResizeSubject | null;\n /** `id`'s drawn box now, for sources measuring the scene the way the\n * subject's box was. */\n drawnBox?: (id: string) => Bounds | undefined;\n view(): View | null;\n /** The reach of a source that sets none, in screen px. */\n reachPx: number;\n scene?: Scene<unknown, string, unknown>;\n /** `id`'s world rotation, for angle targets; undefined for a node that\n * cannot turn. */\n rotationOf?: (id: string) => number | undefined;\n store: SnapOutcomeStore;\n /** Nodes that offer no targets. Default `req.ids`. */\n exclude?: readonly string[];\n /** Where each frame's candidates are recorded, cleared at `end`. */\n debug?: DebugSink;\n}\n\n/** A snap session over a 2D canvas: ctx points are world points. */\nexport function createSession2d(inputs: Session2dInputs): SnapSession {\n const { req, store } = inputs;\n const sources = snapSourcesFor(inputs.sources, req.gesture);\n return {\n at(p, mods) {\n const delta0 = { x: p.x - req.press.x, y: p.y - req.press.y };\n const input = inputFlat(req, mods, delta0, inputs.resize);\n if (mods.suspend) {\n store.set([]);\n inputs.debug?.clearSnap();\n return outcome(req.press, closestOnFlat(input, [delta0.x, delta0.y]), false, []);\n }\n const view = inputs.view();\n const plane = req.plane?.() ?? null;\n const candidates = collectAll(inputs, sources, delta0, view, plane);\n const res = resolveSnap({\n probes: inputs.probes.map((q) => ({ id: q.id, at: [q.at.x, q.at.y], role: q.role })),\n input,\n delta0: [delta0.x, delta0.y],\n candidates,\n toScreen: screenOf(view, plane),\n });\n if (inputs.debug) recordSnapCandidates(inputs.debug, candidates, res.satisfied, inputs.probes, delta0, plane);\n const delta = { x: res.delta[0], y: res.delta[1] };\n const marks = resolvedSnapMarks(res.satisfied, delta);\n store.set(plane ? marks.map((m) => markFromPlane(m, plane)) : marks);\n return outcome(req.press, res.delta, res.members.length > 0, marks);\n },\n angle: (theta, mods) => angleAt(inputs, sources, theta, mods),\n end() {\n store.set([]);\n inputs.debug?.clearSnap();\n },\n };\n}\n\nfunction outcome(press: Point, delta: readonly number[], held: boolean, marks: readonly SnapMark[]): SnapOutcome {\n return { point: { x: press.x + delta[0], y: press.y + delta[1] }, held, marks };\n}\n\nfunction collectAll(\n inputs: Session2dInputs, sources: readonly SnapSource[], delta0: Point, view: View | null, plane: PlaneMap | null,\n): SnapCandidate<SnapCandidateMark<Point>>[] {\n const { req } = inputs;\n const camera = view ? Math.min(Math.abs(view.scale.x), Math.abs(view.scale.y)) : 1;\n // A plane unit is `plane.scale` camera units the other way round.\n const scale = plane ? camera / Math.max(Math.abs(plane.scale.x), Math.abs(plane.scale.y)) : camera;\n const probes = inputs.probes.map((q) => ({ ...q, at: { x: q.at.x + delta0.x, y: q.at.y + delta0.y } }));\n return gatherSnapCandidates(sources, probes, (_source, offered, reachPx) => ({\n gesture: req.gesture, probes: offered, delta0, exclude: inputs.exclude ?? req.ids ?? [],\n ...(plane ? { plane } : {}),\n ...subjectAt(inputs, delta0),\n ...(inputs.drawnBox ? { drawnBox: inputs.drawnBox } : {}),\n ...(req.origin ? { origin: req.origin } : {}),\n ...(req.also ? { also: req.also } : {}),\n reachWorld: (px) => px / scale,\n reachPx,\n ...(inputs.scene ? { scene: inputs.scene } : {}),\n }), { toVec: (p) => [p.x, p.y], reachPx: inputs.reachPx, ...(req.origin ? { origin: req.origin } : {}) });\n}\n\n/** The subject's box where `delta0` puts it, and the sides that moved. */\nfunction subjectAt(inputs: Session2dInputs, delta0: Point): Pick<SnapCollect, 'box' | 'edges'> {\n if (inputs.resize) return { box: resizedBox(inputs.resize, delta0), edges: resizeEdges(inputs.resize, delta0) };\n const b = inputs.req.gesture === 'move' ? inputs.box : null;\n return b ? { box: { ...b, x: b.x + delta0.x, y: b.y + delta0.y } } : {};\n}\n\n/** A session no source answers: it only holds the point to the gesture's\n * input subspace, as when a host provides no `snap` dep. */\nexport function inputSession(req: SnapBegin): SnapSession {\n return createSession2d({\n req,\n sources: [],\n probes: [],\n resize: req.gesture === 'resize' && req.handle && req.box ? resizeSubject(req.box, req.handle) : null,\n view: () => null,\n reachPx: 0,\n store: createSnapOutcomeStore(),\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"session2d.js","names":[],"sources":["../../../src/features/snap/session2d.ts"],"sourcesContent":["import { closestOnFlat, resolveSnap, type SnapCandidate } from '@weasel-js/geom/nd';\nimport type { View } from '@weasel-js/geom';\nimport type { DebugSink } from '@weasel-js/routing';\nimport type { Scene } from 'core/scene/types';\nimport type { Bounds } from 'core/viewport/fitViewToBounds';\nimport type { PlaneMap } from 'core/viewport/parallax';\nimport type { SnapBegin, SnapOutcome, SnapSession } from 'interactions/actions/snapDep';\nimport { angleAt } from './angle2d';\nimport { inputFlat } from './inputSubspace';\nimport { gatherSnapCandidates, resolvedSnapMarks, snapSourcesFor, type SnapCandidateMark } from './gather';\nimport { recordSnapCandidates } from './debugCandidates';\nimport { markFromPlane } from './marks';\nimport { createSnapOutcomeStore, type SnapOutcomeStore } from './outcomeStore';\nimport { resizedBox, resizeEdges, resizeSubject, type ResizeSubject } from './resizeBox';\nimport { screenOf } from './screen';\nimport type { SnapCollect, SnapMark, SnapProbeAt, SnapSource } from './types';\n\ntype Point = { x: number; y: number };\n\n/** The canvas's reach when neither a source nor the kit settings name one. */\nexport const DEFAULT_SNAP_PX = 8;\n\n/** What a 2D session runs on, captured at press. */\nexport interface Session2dInputs {\n req: SnapBegin;\n /** In source order: earlier wins a full tie. */\n sources: readonly SnapSource[];\n /** At press. */\n probes: readonly SnapProbeAt[];\n /** A move's subject: its drawn box at press. */\n box?: Bounds | null;\n /** A resize's box and frame. */\n resize?: ResizeSubject | null;\n /** `id`'s drawn box now, for sources measuring the scene the way the\n * subject's box was. */\n drawnBox?: (id: string) => Bounds | undefined;\n view(): View | null;\n /** The reach of a source that sets none, in screen px. */\n reachPx: number;\n scene?: Scene<unknown, string, unknown>;\n /** `id`'s world rotation, for angle targets; undefined for a node that\n * cannot turn. */\n rotationOf?: (id: string) => number | undefined;\n store: SnapOutcomeStore;\n /** Nodes that offer no targets. Default `req.ids`. */\n exclude?: readonly string[];\n /** Where each frame's candidates are recorded, cleared at `end`. */\n debug?: DebugSink;\n}\n\n/** A snap session over a 2D canvas: ctx points are world points. */\nexport function createSession2d(inputs: Session2dInputs): SnapSession {\n const { req, store } = inputs;\n const sources = snapSourcesFor(inputs.sources, req.gesture);\n const fixed = collectAtPress(inputs);\n return {\n at(p, mods) {\n const delta0 = { x: p.x - req.press.x, y: p.y - req.press.y };\n const input = inputFlat(req, mods, delta0, inputs.resize);\n if (mods.suspend) {\n store.set([]);\n inputs.debug?.clearSnap();\n return outcome(req.press, closestOnFlat(input, [delta0.x, delta0.y]), false, []);\n }\n const view = inputs.view();\n const plane = req.plane?.() ?? null;\n const subject = subjectAt(inputs, delta0);\n const candidates = collectAll(sources, inputs.probes, { ...fixed, ...subject }, { delta0, view, plane }, inputs.reachPx);\n const res = resolveSnap({\n probes: inputs.probes.map((q) => ({ id: q.id, at: [q.at.x, q.at.y], role: q.role })),\n input,\n delta0: [delta0.x, delta0.y],\n candidates,\n toScreen: screenOf(view, plane),\n });\n if (inputs.debug) recordSnapCandidates(inputs.debug, candidates, res.satisfied, inputs.probes, delta0, plane);\n const delta = { x: res.delta[0], y: res.delta[1] };\n const marks = resolvedSnapMarks(res.satisfied, delta);\n store.set(plane ? marks.map((m) => markFromPlane(m, plane)) : marks);\n return outcome(req.press, res.delta, res.members.length > 0, marks);\n },\n angle: (theta, mods) => angleAt(inputs, sources, theta, mods),\n end() {\n store.set([]);\n inputs.debug?.clearSnap();\n },\n };\n}\n\nfunction outcome(press: Point, delta: readonly number[], held: boolean, marks: readonly SnapMark[]): SnapOutcome {\n return { point: { x: press.x + delta[0], y: press.y + delta[1] }, held, marks };\n}\n\n/** What a source is told that holds from press to release. */\ntype FixedCollect = Pick<SnapCollect, 'gesture' | 'ids' | 'parent' | 'exclude' | 'drawnBox' | 'origin' | 'also' | 'scene'>;\n\n/** What changes from one frame to the next. */\ninterface Frame {\n delta0: Point;\n view: View | null;\n plane: PlaneMap | null;\n}\n\nfunction collectAtPress(inputs: Session2dInputs): FixedCollect {\n const { req } = inputs;\n return {\n gesture: req.gesture,\n ...(req.ids ? { ids: req.ids } : {}),\n ...(req.parent !== undefined ? { parent: req.parent } : {}),\n exclude: inputs.exclude ?? req.ids ?? [],\n ...(inputs.drawnBox ? { drawnBox: inputs.drawnBox } : {}),\n ...(req.origin ? { origin: req.origin } : {}),\n ...(req.also ? { also: req.also } : {}),\n ...(inputs.scene ? { scene: inputs.scene } : {}),\n };\n}\n\nfunction collectAll(\n sources: readonly SnapSource[], probesAtPress: readonly SnapProbeAt[],\n fixed: FixedCollect & Pick<SnapCollect, 'box' | 'edges'>, { delta0, view, plane }: Frame, reachPx: number,\n): SnapCandidate<SnapCandidateMark<Point>>[] {\n const camera = view ? Math.min(Math.abs(view.scale.x), Math.abs(view.scale.y)) : 1;\n // A camera unit is `plane.scale` plane units.\n const scale = plane ? camera / Math.max(Math.abs(plane.scale.x), Math.abs(plane.scale.y)) : camera;\n const probes = probesAtPress.map((q) => ({ ...q, at: { x: q.at.x + delta0.x, y: q.at.y + delta0.y } }));\n return gatherSnapCandidates(sources, probes, (_source, offered, sourceReach) => ({\n ...fixed, probes: offered, delta0,\n ...(plane ? { plane } : {}),\n reachWorld: (px) => px / scale,\n reachPx: sourceReach,\n }), { toVec: (p) => [p.x, p.y], reachPx, ...(fixed.origin ? { origin: fixed.origin } : {}) });\n}\n\n/** The subject's box where `delta0` puts it, and the sides that moved. */\nfunction subjectAt(\n { box, resize }: Pick<Session2dInputs, 'box' | 'resize'>, delta0: Point,\n): Pick<SnapCollect, 'box' | 'edges'> {\n if (resize) return { box: resizedBox(resize, delta0), edges: resizeEdges(resize, delta0) };\n return box ? { box: { ...box, x: box.x + delta0.x, y: box.y + delta0.y } } : {};\n}\n\n/** A session no source answers: it only holds the point to the gesture's\n * input subspace, as when a host provides no `snap` dep. */\nexport function inputSession(req: SnapBegin): SnapSession {\n return createSession2d({\n req,\n sources: [],\n probes: [],\n resize: req.gesture === 'resize' && req.handle && req.box ? resizeSubject(req.box, req.handle) : null,\n view: () => null,\n reachPx: 0,\n store: createSnapOutcomeStore(),\n });\n}\n"],"mappings":"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"}
@@ -6,9 +6,10 @@ import { inputSession } from "./session2d.js";
6
6
  * snapped start as its `origin`, so a `constrain` step turns about the start
7
7
  * as drawn. `constrain` is read whenever the end snaps, and a new value
8
8
  * reopens the end's session. With no `snap` dep, or one that runs no
9
- * sessions, only `constrain` applies.
9
+ * sessions, only `constrain` applies. `common` goes into every session's
10
+ * request.
10
11
  */
11
- function spanSnap(dep, constrain = () => void 0) {
12
+ function spanSnap(dep, constrain = () => void 0, common = {}) {
12
13
  const begin = (req) => dep?.begin(req) ?? inputSession(req);
13
14
  let raw = {
14
15
  x: 0,
@@ -24,6 +25,7 @@ function spanSnap(dep, constrain = () => void 0) {
24
25
  live?.session.end();
25
26
  live = {
26
27
  session: begin({
28
+ ...common,
27
29
  gesture: "point",
28
30
  press: start,
29
31
  origin: start,
@@ -38,6 +40,7 @@ function spanSnap(dep, constrain = () => void 0) {
38
40
  live?.session.end();
39
41
  live = null;
40
42
  const out = begin({
43
+ ...common,
41
44
  gesture: "point",
42
45
  press: p
43
46
  });
@@ -1 +1 @@
1
- {"version":3,"file":"spanSnap.js","names":[],"sources":["../../../src/features/snap/spanSnap.ts"],"sourcesContent":["import type { SnapBegin, SnapConstrain, SnapDep, SnapMods, SnapOutcome, SnapSession } from 'interactions/actions/snapDep';\nimport { inputSession } from './session2d';\n\ntype Point = { x: number; y: number };\n\n/** A two-point gesture's snapping: a drawn line, a measurement, a box. */\nexport interface SpanSnap {\n /** Snap the start, pressed at `p`. The end then snaps about where it lands. */\n start(p: Point, mods: SnapMods): SnapOutcome;\n /** Move the start by `(dx, dy)` from where it was pressed or last carried\n * to, unsnapped, and snap it there. */\n carry(dx: number, dy: number, mods: SnapMods): SnapOutcome;\n /** Snap the end. */\n end(p: Point, mods: SnapMods): SnapOutcome;\n /** Turn the end about `p`, a start placed by something other than this\n * snap. */\n anchor(p: Point): void;\n /** Whether a target holds the start. */\n startHeld(): boolean;\n /** Clears the gesture's marks. */\n close(): void;\n}\n\n/**\n * A `point` session for each end of a span. The end's session has the\n * snapped start as its `origin`, so a `constrain` step turns about the start\n * as drawn. `constrain` is read whenever the end snaps, and a new value\n * reopens the end's session. With no `snap` dep, or one that runs no\n * sessions, only `constrain` applies.\n */\nexport function spanSnap(dep: SnapDep | undefined, constrain: () => SnapConstrain | undefined = () => undefined): SpanSnap {\n const begin = (req: SnapBegin): SnapSession => dep?.begin(req) ?? inputSession(req);\n let raw: Point = { x: 0, y: 0 };\n let start: Point = raw;\n let held = false;\n let live: { session: SnapSession; key: string } | null = null;\n\n const open = (): SnapSession => {\n const c = constrain();\n const key = JSON.stringify(c ?? null);\n if (live?.key === key) return live.session;\n live?.session.end();\n live = { session: begin({ gesture: 'point', press: start, origin: start, ...(c ? { constrain: c } : {}) }), key };\n return live.session;\n };\n const place = (p: Point, mods: SnapMods): SnapOutcome => {\n raw = p;\n live?.session.end();\n live = null;\n const out = begin({ gesture: 'point', press: p });\n const landed = out.at(p, mods);\n out.end();\n start = landed.point;\n held = landed.held;\n // Draws the start's marks again, from the session the end runs in.\n open().at(start, { ...mods, constrain: false });\n return landed;\n };\n\n return {\n start: place,\n carry: (dx, dy, mods) => place({ x: raw.x + dx, y: raw.y + dy }, mods),\n end: (p, mods) => open().at(p, mods),\n anchor(p) {\n if (p.x === start.x && p.y === start.y) return;\n start = p;\n live?.session.end();\n live = null;\n },\n startHeld: () => held,\n close() {\n live?.session.end();\n live = null;\n },\n };\n}\n"],"mappings":";;;;;;;;;;AA8BA,SAAgB,SAAS,KAA0B,kBAAmD,QAAqB;CACzH,MAAM,SAAS,QAAgC,KAAK,MAAM,GAAG,KAAK,aAAa,GAAG;CAClF,IAAI,MAAa;EAAE,GAAG;EAAG,GAAG;CAAE;CAC9B,IAAI,QAAe;CACnB,IAAI,OAAO;CACX,IAAI,OAAqD;CAEzD,MAAM,aAA0B;EAC9B,MAAM,IAAI,UAAU;EACpB,MAAM,MAAM,KAAK,UAAU,KAAK,IAAI;EACpC,IAAI,MAAM,QAAQ,KAAK,OAAO,KAAK;EACnC,MAAM,QAAQ,IAAI;EAClB,OAAO;GAAE,SAAS,MAAM;IAAE,SAAS;IAAS,OAAO;IAAO,QAAQ;IAAO,GAAI,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC;GAAG,CAAC;GAAG;EAAI;EAChH,OAAO,KAAK;CACd;CACA,MAAM,SAAS,GAAU,SAAgC;EACvD,MAAM;EACN,MAAM,QAAQ,IAAI;EAClB,OAAO;EACP,MAAM,MAAM,MAAM;GAAE,SAAS;GAAS,OAAO;EAAE,CAAC;EAChD,MAAM,SAAS,IAAI,GAAG,GAAG,IAAI;EAC7B,IAAI,IAAI;EACR,QAAQ,OAAO;EACf,OAAO,OAAO;EAEd,KAAK,CAAC,CAAC,GAAG,OAAO;GAAE,GAAG;GAAM,WAAW;EAAM,CAAC;EAC9C,OAAO;CACT;CAEA,OAAO;EACL,OAAO;EACP,QAAQ,IAAI,IAAI,SAAS,MAAM;GAAE,GAAG,IAAI,IAAI;GAAI,GAAG,IAAI,IAAI;EAAG,GAAG,IAAI;EACrE,MAAM,GAAG,SAAS,KAAK,CAAC,CAAC,GAAG,GAAG,IAAI;EACnC,OAAO,GAAG;GACR,IAAI,EAAE,MAAM,MAAM,KAAK,EAAE,MAAM,MAAM,GAAG;GACxC,QAAQ;GACR,MAAM,QAAQ,IAAI;GAClB,OAAO;EACT;EACA,iBAAiB;EACjB,QAAQ;GACN,MAAM,QAAQ,IAAI;GAClB,OAAO;EACT;CACF;AACF"}
1
+ {"version":3,"file":"spanSnap.js","names":[],"sources":["../../../src/features/snap/spanSnap.ts"],"sourcesContent":["import type { SnapBegin, SnapConstrain, SnapDep, SnapMods, SnapOutcome, SnapSession } from 'interactions/actions/snapDep';\nimport { inputSession } from './session2d';\n\ntype Point = { x: number; y: number };\n\n/** A two-point gesture's snapping: a drawn line, a measurement, a box. */\nexport interface SpanSnap {\n /** Snap the start, pressed at `p`. The end then snaps about where it lands. */\n start(p: Point, mods: SnapMods): SnapOutcome;\n /** Move the start by `(dx, dy)` from where it was pressed or last carried\n * to, unsnapped, and snap it there. */\n carry(dx: number, dy: number, mods: SnapMods): SnapOutcome;\n /** Snap the end. */\n end(p: Point, mods: SnapMods): SnapOutcome;\n /** Turn the end about `p`, a start placed by something other than this\n * snap. */\n anchor(p: Point): void;\n /** Whether a target holds the start. */\n startHeld(): boolean;\n /** Clears the gesture's marks. */\n close(): void;\n}\n\n/**\n * A `point` session for each end of a span. The end's session has the\n * snapped start as its `origin`, so a `constrain` step turns about the start\n * as drawn. `constrain` is read whenever the end snaps, and a new value\n * reopens the end's session. With no `snap` dep, or one that runs no\n * sessions, only `constrain` applies. `common` goes into every session's\n * request.\n */\nexport function spanSnap(\n dep: SnapDep | undefined,\n constrain: () => SnapConstrain | undefined = () => undefined,\n common: Pick<SnapBegin, 'parent'> = {},\n): SpanSnap {\n const begin = (req: SnapBegin): SnapSession => dep?.begin(req) ?? inputSession(req);\n let raw: Point = { x: 0, y: 0 };\n let start: Point = raw;\n let held = false;\n let live: { session: SnapSession; key: string } | null = null;\n\n const open = (): SnapSession => {\n const c = constrain();\n const key = JSON.stringify(c ?? null);\n if (live?.key === key) return live.session;\n live?.session.end();\n live = { session: begin({ ...common, gesture: 'point', press: start, origin: start, ...(c ? { constrain: c } : {}) }), key };\n return live.session;\n };\n const place = (p: Point, mods: SnapMods): SnapOutcome => {\n raw = p;\n live?.session.end();\n live = null;\n const out = begin({ ...common, gesture: 'point', press: p });\n const landed = out.at(p, mods);\n out.end();\n start = landed.point;\n held = landed.held;\n // Draws the start's marks again, from the session the end runs in.\n open().at(start, { ...mods, constrain: false });\n return landed;\n };\n\n return {\n start: place,\n carry: (dx, dy, mods) => place({ x: raw.x + dx, y: raw.y + dy }, mods),\n end: (p, mods) => open().at(p, mods),\n anchor(p) {\n if (p.x === start.x && p.y === start.y) return;\n start = p;\n live?.session.end();\n live = null;\n },\n startHeld: () => held,\n close() {\n live?.session.end();\n live = null;\n },\n };\n}\n"],"mappings":";;;;;;;;;;;AA+BA,SAAgB,SACd,KACA,kBAAmD,QACnD,SAAoC,CAAC,GAC3B;CACV,MAAM,SAAS,QAAgC,KAAK,MAAM,GAAG,KAAK,aAAa,GAAG;CAClF,IAAI,MAAa;EAAE,GAAG;EAAG,GAAG;CAAE;CAC9B,IAAI,QAAe;CACnB,IAAI,OAAO;CACX,IAAI,OAAqD;CAEzD,MAAM,aAA0B;EAC9B,MAAM,IAAI,UAAU;EACpB,MAAM,MAAM,KAAK,UAAU,KAAK,IAAI;EACpC,IAAI,MAAM,QAAQ,KAAK,OAAO,KAAK;EACnC,MAAM,QAAQ,IAAI;EAClB,OAAO;GAAE,SAAS,MAAM;IAAE,GAAG;IAAQ,SAAS;IAAS,OAAO;IAAO,QAAQ;IAAO,GAAI,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC;GAAG,CAAC;GAAG;EAAI;EAC3H,OAAO,KAAK;CACd;CACA,MAAM,SAAS,GAAU,SAAgC;EACvD,MAAM;EACN,MAAM,QAAQ,IAAI;EAClB,OAAO;EACP,MAAM,MAAM,MAAM;GAAE,GAAG;GAAQ,SAAS;GAAS,OAAO;EAAE,CAAC;EAC3D,MAAM,SAAS,IAAI,GAAG,GAAG,IAAI;EAC7B,IAAI,IAAI;EACR,QAAQ,OAAO;EACf,OAAO,OAAO;EAEd,KAAK,CAAC,CAAC,GAAG,OAAO;GAAE,GAAG;GAAM,WAAW;EAAM,CAAC;EAC9C,OAAO;CACT;CAEA,OAAO;EACL,OAAO;EACP,QAAQ,IAAI,IAAI,SAAS,MAAM;GAAE,GAAG,IAAI,IAAI;GAAI,GAAG,IAAI,IAAI;EAAG,GAAG,IAAI;EACrE,MAAM,GAAG,SAAS,KAAK,CAAC,CAAC,GAAG,GAAG,IAAI;EACnC,OAAO,GAAG;GACR,IAAI,EAAE,MAAM,MAAM,KAAK,EAAE,MAAM,MAAM,GAAG;GACxC,QAAQ;GACR,MAAM,QAAQ,IAAI;GAClB,OAAO;EACT;EACA,iBAAiB;EACjB,QAAQ;GACN,MAAM,QAAQ,IAAI;GAClB,OAAO;EACT;CACF;AACF"}