@weasel-js/core 1.9.3 → 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 +356 -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 +112 -70
  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 +11033 -7749
  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 +1 -0
  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 -62
  542. package/dist/tools/prefs.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"sampleTrack.js","names":["keys","keysPatch","NO_SETTING","BUILT","build","keys$1","track","t0","t1","exact","k","span","out","v","ease","resolveEasing","interpolator","interpolate","boxes","lerp","fn","cache","b","a","u","keys","i","axes","axesOf","scalar","sampleTrack","segmentCache","hit"],"sources":["../../../src/animation/timeline/sampleTrack.ts"],"sourcesContent":["import { keys as keysPatch, type Patch, type Setting } from '@msb235/blits';\nimport { resolveEasing } from '@weasel-js/geom';\nimport { axesOf } from '../engine/axes';\nimport type { SampledTrack } from './types';\n\ntype Out = { v: unknown };\n/** What an interpolated track's stops carry: blits finds the segment and eases it, and the\n * track's own function makes the value. */\ninterface Box { i: number; value: unknown }\n\ninterface Built {\n /** What it was built from, so a cache handed another track, or new keys, rebuilds. */\n track: object;\n keys: readonly unknown[];\n /** Null where there is nothing to interpolate: one key time, or values with no way to lerp. */\n patch: Patch<number, Out, void> | null;\n t0: number;\n span: number;\n /** Every key's time to the value sampling exactly there returns: the later of keys sharing a\n * time, and the key's own value where blits would reach it as `a + (b - a) * ease(1)`. */\n exact: Map<number, unknown>;\n first: unknown;\n last: unknown;\n read: (v: unknown) => unknown;\n}\n\nconst NO_SETTING = {} as Setting<void>;\n/** Where a cache holds its track's `Built`; segment indexes start at 1. A `WeakMap` keyed on the\n * cache instead cost about a fifth of every sample. */\nconst BUILT = -1;\n\nfunction build<T>(track: SampledTrack<T>, cache: Map<number, (u: number) => T> | undefined): Built {\n const { keys } = track;\n let t0 = Infinity;\n let t1 = -Infinity;\n const exact = new Map<number, unknown>();\n for (const k of keys) {\n t0 = Math.min(t0, k.t);\n t1 = Math.max(t1, k.t);\n exact.set(k.t, k.value);\n }\n const span = t1 - t0;\n const out: Built = { track, keys, patch: null, t0, span, exact, first: keys[0].value, last: keys[keys.length - 1].value, read: (v) => v };\n if (span <= 0) return out;\n\n const ease = (k: (typeof keys)[number]) => (k.easing ? resolveEasing(k.easing) : undefined);\n const { interpolator, interpolate } = track;\n if (interpolator || interpolate) {\n const boxes: Box[] = keys.map((k, i) => ({ i, value: k.value }));\n const lerp = (a: Box, b: Box, u: number): Box => {\n if (interpolator) {\n let fn = cache?.get(b.i);\n if (!fn) {\n fn = interpolator(a.value as T, b.value as T);\n cache?.set(b.i, fn);\n }\n return { i: -1, value: fn(u) };\n }\n return { i: -1, value: interpolate!(a.value as T, b.value as T, u) };\n };\n out.patch = keysPatch<number, Out>(\n 1,\n keys.map((k, i) => ({ at: (k.t - t0) / span, delta: { v: boxes[i] }, ease: ease(k) })),\n { lerpBy: () => lerp as (a: never, b: never, u: number) => unknown },\n );\n out.read = (v) => (v as Box).value;\n return out;\n }\n\n const axes = axesOf(keys[0].value);\n if (!axes) return out;\n for (const k of keys) {\n if (axesOf(k.value)?.shape !== axes.shape) {\n throw new Error(`sampleTrack: every key needs the shape of the first (${axes.shape})`);\n }\n }\n const scalar = axes.shape === 'number';\n out.patch = keysPatch<number, Out>(\n 1,\n keys.map((k) => ({ at: (k.t - t0) / span, delta: { v: scalar ? k.value : axes.to(k.value) }, ease: ease(k) })),\n );\n if (!scalar) out.read = (v) => axes.from(v as number[]);\n return out;\n}\n\n/**\n * Sample a track at `t`. Pure: no state, no side effects, safe to call for any\n * `t` in any order — which is what makes scrubbing free.\n *\n * `segmentCache` holds what sampling builds from the keys: the track's blits\n * patch and its `interpolator` factories. Handed another track or a replaced\n * `keys` array, it rebuilds; a key edited in place needs the cache dropped,\n * which `createTimeline` does on `edit`. With no cache, every call builds afresh.\n */\nexport function sampleTrack<T>(\n track: SampledTrack<T>,\n t: number,\n segmentCache?: Map<number, (u: number) => T>,\n): T | undefined {\n if (track.keys.length === 0) return undefined;\n const cache = segmentCache as Map<number, unknown> | undefined;\n let b = cache?.get(BUILT) as Built | undefined;\n if (!b || b.track !== track || b.keys !== track.keys) {\n cache?.clear();\n b = build(track, segmentCache);\n cache?.set(BUILT, b);\n }\n const hit = b.exact.get(t);\n if (hit !== undefined || b.exact.has(t)) return hit as T;\n if (!b.patch) {\n if (t < b.t0) return b.first as T;\n if (t >= b.t0 + b.span) return b.last as T;\n throw new Error('sampleTrack: interpolate or interpolator is required for non-numeric keyframe values');\n }\n return b.read(b.patch.at((t - b.t0) / b.span, 0, NO_SETTING).v) as T;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sampleTrack.js","names":["keys","keysPatch","NO_SETTING","BUILT","build","keys$1","track","t0","t1","exact","k","span","out","v","ease","resolveEasing","interpolator","interpolate","boxes","lerp","fn","cache","b","a","u","keys","i","at","axes","axesOf","scalar","sampleTrack","segmentCache","fresh","hit"],"sources":["../../../src/animation/timeline/sampleTrack.ts"],"sourcesContent":["import { keys as keysPatch, type Patch, type Setting } from '@msb235/blits';\nimport { resolveEasing } from '@weasel-js/geom';\nimport { axesOf } from '../engine/axes';\nimport type { SampledTrack } from './types';\n\ntype Out = { v: unknown };\n/** What an interpolated track's stops carry: blits finds the segment and eases it, and the\n * track's own function makes the value. */\ninterface Box { i: number; value: unknown }\n\ninterface Built {\n /** What it was built from, so a cache handed another track, or new keys, rebuilds. */\n track: object;\n keys: readonly unknown[];\n /** Null where there is nothing to interpolate: one key time, or values with no way to lerp. */\n patch: Patch<number, Out, void> | null;\n t0: number;\n span: number;\n /** Every key's time to the value sampling exactly there returns: the later of keys sharing a\n * time, and the key's own value where blits would reach it as `a + (b - a) * ease(1)`. */\n exact: Map<number, unknown>;\n /** For a track that makes its own values, each interior key's time to a fresh value there, so\n * a caller changing its sample leaves the key alone. */\n fresh: Map<number, () => unknown> | null;\n first: unknown;\n last: unknown;\n read: (v: unknown) => unknown;\n}\n\nconst NO_SETTING = {} as Setting<void>;\n/** Where a cache holds its track's `Built`; segment indexes start at 1. A `WeakMap` keyed on the\n * cache instead cost about a fifth of every sample. */\nconst BUILT = -1;\n\nfunction build<T>(track: SampledTrack<T>, cache: Map<number, (u: number) => T> | undefined): Built {\n const { keys } = track;\n let t0 = Infinity;\n let t1 = -Infinity;\n const exact = new Map<number, unknown>();\n for (const k of keys) {\n t0 = Math.min(t0, k.t);\n t1 = Math.max(t1, k.t);\n exact.set(k.t, k.value);\n }\n const span = t1 - t0;\n const out: Built = { track, keys, patch: null, t0, span, exact, fresh: null, first: keys[0].value, last: keys[keys.length - 1].value, read: (v) => v };\n if (span <= 0) return out;\n\n const ease = (k: (typeof keys)[number]) => (k.easing ? resolveEasing(k.easing) : undefined);\n const { interpolator, interpolate } = track;\n if (interpolator || interpolate) {\n const boxes: Box[] = keys.map((k, i) => ({ i, value: k.value }));\n const lerp = (a: Box, b: Box, u: number): Box => {\n if (interpolator) {\n let fn = cache?.get(b.i);\n if (!fn) {\n fn = interpolator(a.value as T, b.value as T);\n cache?.set(b.i, fn);\n }\n return { i: -1, value: fn(u) };\n }\n return { i: -1, value: interpolate!(a.value as T, b.value as T, u) };\n };\n out.patch = keysPatch<number, Out>(\n 1,\n keys.map((k, i) => ({ at: (k.t - t0) / span, delta: { v: boxes[i] }, ease: ease(k) })),\n { lerpBy: () => lerp as (a: never, b: never, u: number) => unknown },\n );\n out.read = (v) => (v as Box).value;\n out.fresh = new Map();\n for (let i = 0; i < keys.length - 1; i++) {\n const at = keys[i].t;\n if (at > t0 && at < t1) out.fresh.set(at, () => lerp(boxes[i], boxes[i + 1], 0).value);\n }\n return out;\n }\n\n const axes = axesOf(keys[0].value);\n if (!axes) return out;\n for (const k of keys) {\n if (axesOf(k.value)?.shape !== axes.shape) {\n throw new Error(`sampleTrack: every key needs the shape of the first (${axes.shape})`);\n }\n }\n const scalar = axes.shape === 'number';\n out.patch = keysPatch<number, Out>(\n 1,\n keys.map((k) => ({ at: (k.t - t0) / span, delta: { v: scalar ? k.value : axes.to(k.value) }, ease: ease(k) })),\n );\n if (!scalar) out.read = (v) => axes.from(v as number[]);\n return out;\n}\n\n/**\n * Sample a track at `t`. Pure: no state, no side effects, safe to call for any\n * `t` in any order — which is what makes scrubbing free.\n *\n * `segmentCache` holds what sampling builds from the keys: the track's blits\n * patch and its `interpolator` factories. Handed another track or a replaced\n * `keys` array, it rebuilds; a key edited in place needs the cache dropped,\n * which `createTimeline` does on `edit`. With no cache, every call builds afresh.\n */\nexport function sampleTrack<T>(\n track: SampledTrack<T>,\n t: number,\n segmentCache?: Map<number, (u: number) => T>,\n): T | undefined {\n if (track.keys.length === 0) return undefined;\n const cache = segmentCache as Map<number, unknown> | undefined;\n let b = cache?.get(BUILT) as Built | undefined;\n if (!b || b.track !== track || b.keys !== track.keys) {\n cache?.clear();\n b = build(track, segmentCache);\n cache?.set(BUILT, b);\n }\n if (Number.isNaN(t)) return b.first as T;\n const fresh = b.fresh?.get(t);\n if (fresh) return fresh() as T;\n const hit = b.exact.get(t);\n if (hit !== undefined || b.exact.has(t)) return hit as T;\n if (!b.patch) {\n if (t < b.t0) return b.first as T;\n if (t >= b.t0 + b.span) return b.last as T;\n throw new Error('sampleTrack: interpolate or interpolator is required for non-numeric keyframe values');\n }\n return b.read(b.patch.at((t - b.t0) / b.span, 0, NO_SETTING).v) as T;\n}\n"],"mappings":"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"}
@@ -30,17 +30,14 @@ function b(u = {}) {
30
30
  w.current = null;
31
31
  }
32
32
  }), j = v(A), M = _(!0), N = _(!1), P = () => !M.current && (N.current || (N.current = !0, (typeof process > "u" || process.env.NODE_ENV !== "production") && console.error("weasel useAnimator: animation tick fired after the host component unmounted. This usually means cleanup logic was bypassed — check for refactors that removed the unmount effect or replaced cancelAll with a custom path.")), !0), { api: F, tickAll: I } = g(() => {
33
- let e = () => (b.current.now ?? (typeof performance < "u" ? performance.now.bind(performance) : Date.now))(), c = {
34
- setTimer: (e, t) => (b.current.setTimer ?? ((e, t) => setTimeout(e, t)))(e, t),
35
- clearTimer: (e) => (b.current.clearTimer ?? ((e) => clearTimeout(e)))(e),
36
- now: e
37
- }, u = /* @__PURE__ */ new Map(), p = (e) => {
33
+ let e = () => (b.current.now ?? (typeof performance < "u" ? performance.now.bind(performance) : Date.now))(), c = [], u = /* @__PURE__ */ new Map(), p = (e) => {
38
34
  let t = u.get(e);
39
35
  if (t) {
40
36
  u.delete(e);
41
37
  for (let e of t) e();
42
38
  }
43
39
  }, m = (e, t) => {
40
+ if (!x.current.has(e)) return t(), () => {};
44
41
  let n = u.get(e) ?? [];
45
42
  return n.push(t), u.set(e, n), () => {
46
43
  let n = u.get(e);
@@ -76,7 +73,8 @@ function b(u = {}) {
76
73
  }, A = (e) => {
77
74
  let t = [], n = [], r = w.current == null ? 0 : Math.max(0, e - w.current);
78
75
  w.current = e, g.frame(r * (E.current ? 0 : T.current));
79
- for (let r of x.current.values()) {
76
+ for (let r of [...x.current.values()]) {
77
+ if (x.current.get(r.id) !== r) continue;
80
78
  let i = r.lastRealNow == null ? 0 : Math.max(0, e - r.lastRealNow);
81
79
  r.lastRealNow = e;
82
80
  let a = E.current ? 0 : T.current * (r.paused ? 0 : r.timeScale);
@@ -95,6 +93,11 @@ function b(u = {}) {
95
93
  error: t
96
94
  }));
97
95
  for (let e of t) x.current.get(e.id) === e && (v(e.id), x.current.delete(e.id), p(e.id));
96
+ for (let e of c.splice(0)) try {
97
+ e();
98
+ } catch (e) {
99
+ console.error("useAnimator: a staggered start threw", e);
100
+ }
98
101
  for (let e of O.current) try {
99
102
  e();
100
103
  } catch (e) {
@@ -108,7 +111,7 @@ function b(u = {}) {
108
111
  for (let t of x.current.values()) t.cancelKey === e && n.push(t.id);
109
112
  for (let e of n) k(e, t);
110
113
  }, F = (e) => {
111
- g.has(e.id) && g.rate(e.id, e.paused ? 0 : e.timeScale);
114
+ g.has(e.id) && g.rate(e.id, e.paused ? 0 : e.timeScale), e.onRate?.(e.paused, e.timeScale);
112
115
  }, I = (t) => {
113
116
  let n = t;
114
117
  return t.cancelKey != null && !t.keepExisting && N(t.cancelKey, n), n.paused = !1, n.timeScale = 1, n.virtualNow = 0, n.lastRealNow = e(), x.current.set(n.id, n), h.watched && h.emit({
@@ -133,25 +136,32 @@ function b(u = {}) {
133
136
  isPaused: () => x.current.get(n.id)?.paused ?? !1
134
137
  };
135
138
  }, L = ({ kind: e, cancelKey: t, label: n }) => {
136
- let r = S.current++, i, a = I({
139
+ let r = S.current++, i, a, o, s = I({
137
140
  id: r,
138
141
  kind: e,
139
142
  cancelKey: t,
140
143
  label: n,
141
- tick: () => !1,
142
- onCancel: () => i?.()
144
+ tick: (e) => (o && c.push(() => o?.(e)), !1),
145
+ onCancel: () => i?.(),
146
+ onRate: (e, t) => a?.(e, t)
143
147
  });
144
148
  return {
145
- id: a.id,
146
- cancel: a.cancel,
147
- pause: a.pause,
148
- resume: a.resume,
149
- setTimeScale: a.setTimeScale,
150
- timeScale: a.timeScale,
151
- isPaused: a.isPaused,
149
+ id: s.id,
150
+ cancel: s.cancel,
151
+ pause: s.pause,
152
+ resume: s.resume,
153
+ setTimeScale: s.setTimeScale,
154
+ timeScale: s.timeScale,
155
+ isPaused: s.isPaused,
152
156
  setOnCancel: (e) => {
153
157
  i = e;
154
158
  },
159
+ setOnRate: (e) => {
160
+ a = e;
161
+ },
162
+ setOnFrame: (e) => {
163
+ o = e;
164
+ },
155
165
  finish: () => {
156
166
  x.current.has(r) && (v(r), x.current.delete(r), p(r));
157
167
  },
@@ -189,18 +199,18 @@ function b(u = {}) {
189
199
  }, z = (t, n = "physics") => {
190
200
  let i = S.current++;
191
201
  if (typeof t.from != "number" && (!t.add || !t.subtract || !t.scale || !t.magnitude)) throw Error("physics: add/subtract/scale/magnitude are required for non-numeric T");
192
- let o = t.add ?? ((e, t) => e + t), s = t.subtract ?? ((e, t) => e - t), c = t.scale ?? ((e, t) => e * t), l = t.magnitude ?? ((e) => Math.abs(e)), { stiffness: u, damping: d, mass: f } = y(t), p = t.restThreshold ?? .01, m = t.to ?? null, h = t.from, _ = t.velocity ?? c(t.from, 0), b = null, x = d > 0 && f > 0 && (u > 0 || n === "decay") ? a(t.from) : null, C = (e) => e == null || a(e)?.shape === x.shape, T = x && C(t.to) && C(t.velocity) ? x : null, E = null;
193
- T && (w.current ??= e(), E = g.spring({
202
+ let o = t.add ?? ((e, t) => e + t), s = t.subtract ?? ((e, t) => e - t), c = t.scale ?? ((e, t) => e * t), l = t.magnitude ?? ((e) => Math.abs(e)), { stiffness: u, damping: d, mass: f } = y(t), p = t.restThreshold ?? .01, m = t.to ?? null, h = t.from, _ = t.velocity ?? c(t.from, 0), b = null, C = d > 0 && f > 0 && (u > 0 || n === "decay") ? a(t.from) : null, T = (e) => e == null || a(e)?.shape === C.shape, E = C && T(t.to) && T(t.velocity) ? C : null, D = null;
203
+ E && (w.current ??= e(), D = g.spring({
194
204
  id: i,
195
- axes: T.count,
196
- from: T.to(t.from),
197
- to: t.to == null ? null : T.to(t.to),
198
- velocity: t.velocity == null ? Array(T.count).fill(0) : T.to(t.velocity),
205
+ axes: E.count,
206
+ from: E.to(t.from),
207
+ to: t.to == null ? null : E.to(t.to),
208
+ velocity: t.velocity == null ? Array(E.count).fill(0) : E.to(t.velocity),
199
209
  stiffness: u,
200
210
  damping: d,
201
211
  mass: f
202
212
  }));
203
- let D = I({
213
+ let O = I({
204
214
  id: i,
205
215
  kind: n,
206
216
  cancelKey: t.cancelKey,
@@ -209,11 +219,11 @@ function b(u = {}) {
209
219
  if (P()) return g.stop(i), !0;
210
220
  if (b == null) {
211
221
  if (b = e, m == null && l(_) < p) return g.stop(i), v(i), t.onDone?.(), !0;
212
- if (!T) return t.onTick(h), !1;
222
+ if (!E) return t.onTick(h), !1;
213
223
  }
214
- if (T) {
215
- let e = E.motion();
216
- h = T.from(e.value), _ = T.from(e.velocity);
224
+ if (E) {
225
+ let e = D.motion();
226
+ h = E.from(e.value), _ = E.from(e.velocity);
217
227
  } else {
218
228
  let t = Math.min(.064, (e - b) / 1e3), n = r({
219
229
  add: o,
@@ -224,18 +234,18 @@ function b(u = {}) {
224
234
  }
225
235
  b = e, t.onTick(h);
226
236
  let n = l(_) < p, a = m == null || l(s(h, m)) < p;
227
- return n && a ? (m != null && t.onTick(m), g.stop(i), v(i), t.onDone?.(), !0) : !1;
237
+ return n && a ? (m != null && t.onTick(m), g.stop(i), x.current.has(i) && (v(i), t.onDone?.()), !0) : !1;
228
238
  }
229
- }), O = (e, t) => {
230
- if (!C(e)) throw Error(`physics: ${t} is not the same shape as \`from\``);
239
+ }), k = (e, t) => {
240
+ if (!T(e)) throw Error(`physics: ${t} is not the same shape as \`from\``);
231
241
  };
232
242
  return {
233
- ...D,
243
+ ...O,
234
244
  setTarget: (e) => {
235
- T && e != null && O(e, "setTarget"), m = e, T && g.has(i) && g.retarget(i, e == null ? null : T.to(e));
245
+ E && e != null && k(e, "setTarget"), m = e, E && g.has(i) && g.retarget(i, e == null ? null : E.to(e));
236
246
  },
237
247
  setVelocity: (e) => {
238
- T && O(e, "setVelocity"), _ = e, T && g.has(i) && g.push(i, T.to(e));
248
+ E && k(e, "setVelocity"), _ = e, E && g.has(i) && g.push(i, E.to(e));
239
249
  }
240
250
  };
241
251
  }, B = {
@@ -303,7 +313,7 @@ function b(u = {}) {
303
313
  },
304
314
  loop: (e, n) => t(L, e, n),
305
315
  tweenLoop: (e) => n(B, L, e),
306
- stagger: ((e, t, n, r) => o(B, c, L, m, e, t, n, r)),
316
+ stagger: ((e, t, n, r) => o(B, L, m, e, t, n, r)),
307
317
  timeline: (e) => {
308
318
  let t = S.current++, n = () => {
309
319
  let e = x.current.get(t);
@@ -1 +1 @@
1
- {"version":3,"file":"useAnimator.js","names":["resolveSpringConstants","preset","o","SPRING_PRESETS","useAnimator","optsRef","useLatest","opts","animations","useRef","nextId","tickDepth","codecFrameT","globalTimeScale","globalPaused","colorOverrides","ColorOverrideRegistry","tickSubscribers","tickAllRef","frameLoop","useVisibleRaf","useCallback","t","anim","frameLoopRef","mountedRef","trippedRef","tripwire","useMemo","now","staggerTimers","c","m","cb","ms","x","h","completionListeners","fireCompletion","ls","id","watchCompletion","cur","idx","hub","AnimatorEventHub","codec","createCodec","infoOf","a","info","reportEnd","retire","error","by","tickAll","finished","threw","frameDt","realDt","scale","sub","err","ensureLoop","cancelByKey","ids","key","rateOf","register","seed","s","createSupervisor","onCancelCb","base","tween","fromAxes","axesOf","toAxes","axes","easing","resolveEasing","easeOut","factoryFn","lastValueEmitted","reader","virtualNow","nowMs","value","eased","physics","add","b","subtract","v","k","magnitude","kBase","restThreshold","target","velocity","lastTime","damping","mass","kind","sameShape","baseHandle","dt","next","stepSpring","velRested","posRested","checkShape","what","newTo","api","friction","handle","retired","createLoop","factory","loopOpts","createTweenLoop","tweenLoopOpts","createStagger","items","delay","staggerOpts","createTimeline","animation","path","sup","listener","rows","row","useInsertionEffect","useEffect","overrides"],"sources":["../../src/animation/useAnimator.ts"],"sourcesContent":["import { useCallback, useEffect, useInsertionEffect, useMemo, useRef } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport { useVisibleRaf } from '../scheduling/useVisibleRaf';\nimport { easeOut, SPRING_PRESETS, resolveEasing } from '@weasel-js/geom';\nimport { createLoop, createTweenLoop } from './loop';\nimport { stepSpring } from './engine/integrator';\nimport { createCodec, type SpringReader } from './engine/codec';\nimport { axesOf } from './engine/axes';\nimport { createStagger, type StaggerTimers } from './stagger';\nimport { createTimeline } from './timeline/createTimeline';\nimport { ColorOverrideRegistry } from './colorRegistry';\nimport { AnimatorEventHub } from './observe';\nimport type { Supervisor, SupervisorOptions, WatchCompletion } from './supervisor';\nimport type {\n AnimationHandle,\n AnimationInfo,\n AnimationKind,\n Animator,\n TweenOptions,\n SpringOptions,\n DecayOptions,\n PhysicsOptions,\n PhysicsHandle,\n UseAnimatorOptions,\n LiveAnimation,\n} from './types';\nimport type { TimelineOptions } from './timeline/types';\n\ninterface ActiveAnimation {\n id: number;\n kind: AnimationKind;\n cancelKey?: string;\n label?: string;\n /** Built the first time something reports on this entry, then shared. */\n info?: AnimationInfo;\n /** 0–1 where the animation has an end to measure against. */\n progress?(virtualNow: number): number;\n /** Its `end` is reported, though the entry stays on the table until the\n * frame's ticks are done. */\n ended?: boolean;\n paused: boolean;\n timeScale: number;\n virtualNow: number;\n lastRealNow: number | null;\n /** Returns true when finished. Called once per frame with the current\n * virtual-ms timestamp and the effective scale it advanced at this frame. */\n tick(virtualNow: number, scale: number): boolean;\n /** Called when the animation is cancelled. Skips onDone. */\n onCancel?(): void;\n}\n\nfunction resolveSpringConstants(o: { preset?: string; stiffness?: number; damping?: number; mass?: number }) {\n const preset = o.preset ? SPRING_PRESETS[o.preset as keyof typeof SPRING_PRESETS] : null;\n return {\n stiffness: o.stiffness ?? preset?.stiffness ?? 170,\n damping: o.damping ?? preset?.damping ?? 26,\n mass: o.mass ?? preset?.mass ?? 1,\n };\n}\n\n/** Create the animator for a canvas. One rAF loop drives every animation it\n * owns, and everything still running is cancelled on unmount. */\nexport function useAnimator(opts: UseAnimatorOptions = {}): Animator {\n const optsRef = useLatest(opts);\n const animations = useRef<Map<number, ActiveAnimation>>(new Map());\n const nextId = useRef(1);\n /**\n * Re-entrancy counter incremented around each animation tick in tickAll.\n * Exposed via `isTicking()`. > 0 ⇒ we're currently inside an animation's\n * onTick; an adapter wrapper (`animateOnSetPose`) seeing this flag should\n * write through to the base adapter rather than schedule a new tween.\n */\n const tickDepth = useRef(0);\n /** The timestamp the codec last advanced to. Null after the page was hidden and while nothing\n * runs, so neither gap is charged to the codec; a tween starting then seeds it from `now()`. */\n const codecFrameT = useRef<number | null>(null);\n const globalTimeScale = useRef(1);\n const globalPaused = useRef(false);\n const colorOverrides = useRef<ColorOverrideRegistry>(new ColorOverrideRegistry());\n // Per-frame tick subscribers. Notified after each batch of animation\n // ticks (i.e. after `colorOverrides` has settled to its latest values\n // but before the next RAF schedules). Used by `<SceneCanvas animator>`\n // to request a redraw on every active frame.\n const tickSubscribers = useRef<Set<() => void>>(new Set());\n\n // The loop runs behind the visibility gate. `tickAll` is built inside the\n // memo below, so the frame callback reaches it through a ref, published\n // once the memo's render commits.\n const tickAllRef = useRef<((t: number) => void) | null>(null);\n const frameLoop = useVisibleRaf(\n useCallback((t: number) => { tickAllRef.current?.(t); }, []),\n {\n requestFrame: opts.requestFrame,\n cancelFrame: opts.cancelFrame,\n // An hour spent hidden is not an hour the animation ran: dropping each\n // animation's last timestamp makes the resuming frame's `realDt` zero.\n onResume: () => {\n for (const anim of animations.current.values()) anim.lastRealNow = null;\n codecFrameT.current = null;\n },\n },\n );\n const frameLoopRef = useLatest(frameLoop);\n\n // Tripwire: dev-only flag that every tween/spring/decay's tick reads to\n // detect \"animation fired after the host component unmounted.\" This is a\n // symptom of cleanup not running (regression) — typically because someone\n // refactored useAnimator and forgot to wire the unmount effect. The flag\n // flips false on cleanup; ticks see it and log a one-time error so the\n // bug is loud rather than just visually-doubled animation.\n const mountedRef = useRef(true);\n const trippedRef = useRef(false);\n const tripwire = (): boolean => {\n if (mountedRef.current) return false;\n if (!trippedRef.current) {\n trippedRef.current = true;\n const isDev = typeof process !== 'undefined' ? process.env.NODE_ENV !== 'production' : true;\n if (isDev) {\n console.error(\n 'weasel useAnimator: animation tick fired after the host component unmounted. ' +\n 'This usually means cleanup logic was bypassed — check for refactors that ' +\n 'removed the unmount effect or replaced cancelAll with a custom path.',\n );\n }\n }\n return true;\n };\n\n const { api, tickAll } = useMemo(() => {\n // Default to performance.now() so the time origin matches the\n // requestAnimationFrame callback's DOMHighResTimeStamp argument.\n // Using Date.now() here would mix epoch-millis with page-relative-millis,\n // producing huge negative `elapsed` values that clamp tween `t` to 0\n // forever (never reaching completion).\n const now = (): number =>\n (optsRef.current.now ?? (typeof performance !== 'undefined' ? performance.now.bind(performance) : Date.now))();\n // Resolved timer pair, snapshotted lazily from optsRef on each call so a\n // test that updates the injection after mount still wins. Kept internal —\n // not exposed on the public Animator surface; passed directly into\n // `createStagger` at bind time below.\n const staggerTimers: StaggerTimers = {\n setTimer: (cb, ms) =>\n (optsRef.current.setTimer ?? ((c, m) => setTimeout(c, m)))(cb, ms),\n clearTimer: (h) =>\n (optsRef.current.clearTimer ??\n ((x) => clearTimeout(x as ReturnType<typeof setTimeout>)))(h),\n now,\n };\n\n // Per-id one-shot completion listeners. Used by stagger to detect when\n // each child has left the registry (natural completion OR cancel) so the\n // supervising composite can retire itself when the last child finishes.\n const completionListeners = new Map<number, (() => void)[]>();\n const fireCompletion = (id: number): void => {\n const ls = completionListeners.get(id);\n if (!ls) return;\n completionListeners.delete(id);\n for (const cb of ls) cb();\n };\n const watchCompletion: WatchCompletion = (id, cb) => {\n const ls = completionListeners.get(id) ?? [];\n ls.push(cb);\n completionListeners.set(id, ls);\n return () => {\n const cur = completionListeners.get(id);\n if (!cur) return;\n const idx = cur.indexOf(cb);\n if (idx >= 0) cur.splice(idx, 1);\n if (cur.length === 0) completionListeners.delete(id);\n };\n };\n\n const hub = new AnimatorEventHub();\n const codec = createCodec();\n const infoOf = (a: ActiveAnimation): AnimationInfo => {\n if (!a.info) {\n const info: { -readonly [K in keyof AnimationInfo]: AnimationInfo[K] } = { id: a.id, kind: a.kind };\n if (a.cancelKey != null) info.key = a.cancelKey;\n if (a.label != null) info.label = a.label;\n a.info = info;\n }\n return a.info;\n };\n\n /** Report `id` as finished, ahead of its `onDone`, so whatever that\n * handler starts is heard after it. Nothing revives a primitive; a\n * timeline, which can be revived, is reported as it leaves the table. */\n const reportEnd = (id: number): void => {\n const a = animations.current.get(id);\n if (!a || a.ended) return;\n a.ended = true;\n if (hub.watched) hub.emit({ type: 'end', animation: infoOf(a) });\n };\n\n /** Take `id` off the table as canceled — or, given `by`, as interrupted by\n * the animation claiming its key; given `error`, the caller reports it. */\n const retire = (id: number, by?: ActiveAnimation, error?: true): void => {\n const a = animations.current.get(id);\n if (!a) return;\n a.onCancel?.();\n codec.stop(id);\n animations.current.delete(id);\n fireCompletion(id);\n if (!hub.watched || a.ended || error) return;\n hub.emit(by\n ? { type: 'interrupt', animation: infoOf(a), by: infoOf(by) }\n : { type: 'cancel', animation: infoOf(a) });\n };\n\n const tickAll = (t: number): void => {\n const finished: ActiveAnimation[] = [];\n const threw: [ActiveAnimation, unknown][] = [];\n const frameDt = codecFrameT.current == null ? 0 : Math.max(0, t - codecFrameT.current);\n codecFrameT.current = t;\n codec.frame(frameDt * (globalPaused.current ? 0 : globalTimeScale.current));\n for (const anim of animations.current.values()) {\n // `t` comes from the frame clock; `lastRealNow` is seeded at register()\n // from `now()`. The two share a time origin in a browser, where the rAF\n // timestamp and `performance.now()` are both page-relative — but not\n // everywhere: jsdom starts them ~600ms apart, which made the first\n // frame's delta hugely negative and left `virtualNow` climbing back\n // toward zero for dozens of frames before a tween advanced at all.\n // Time never runs backwards, so a negative sample is never real.\n const realDt = anim.lastRealNow == null ? 0 : Math.max(0, t - anim.lastRealNow);\n anim.lastRealNow = t;\n const scale = globalPaused.current\n ? 0\n : globalTimeScale.current * (anim.paused ? 0 : anim.timeScale);\n anim.virtualNow += realDt * scale;\n // Increment tick depth around each animation's tick so re-entrant\n // calls (e.g. `decay.onTick` → `adapter.setPose` →\n // `animateOnSetPose` checking `isTicking()`) see the flag and\n // skip scheduling a new wrap-tween that would fight the caller.\n tickDepth.current += 1;\n try {\n if (anim.tick(anim.virtualNow, scale)) finished.push(anim);\n } catch (error) {\n threw.push([anim, error]);\n } finally {\n tickDepth.current -= 1;\n }\n }\n for (const [anim, error] of threw) {\n console.error('useAnimator: animation tick threw; retiring it', error);\n if (animations.current.get(anim.id) !== anim) continue;\n // One that ended before throwing (from `onDone`) is finished, not canceled.\n if (anim.ended) {\n animations.current.delete(anim.id);\n fireCompletion(anim.id);\n } else {\n retire(anim.id, undefined, true);\n }\n if (hub.watched) hub.emit({ type: 'error', animation: infoOf(anim), error });\n }\n for (const anim of finished) {\n // Gone already if its own tick canceled it; replaced if something\n // revived it under the same id since.\n if (animations.current.get(anim.id) !== anim) continue;\n reportEnd(anim.id);\n animations.current.delete(anim.id);\n fireCompletion(anim.id);\n }\n // Notify every onTick subscriber AFTER the tick batch so they\n // see the latest `colorOverrides` / pose values. Errors in one\n // subscriber don't suppress the others.\n for (const sub of tickSubscribers.current) {\n try { sub(); } catch (err) { console.error('useAnimator: onTick subscriber threw', err); }\n }\n if (animations.current.size > 0) frameLoopRef.current.request();\n else codecFrameT.current = null;\n };\n\n const ensureLoop = (): void => {\n if (animations.current.size === 0) return;\n frameLoopRef.current.request();\n };\n\n const cancelByKey = (key: string, by?: ActiveAnimation): void => {\n const ids: number[] = [];\n for (const anim of animations.current.values()) {\n if (anim.cancelKey === key) ids.push(anim.id);\n }\n for (const id of ids) retire(id, by);\n };\n\n type AnimationSeed =\n Omit<ActiveAnimation, 'paused' | 'timeScale' | 'virtualNow' | 'lastRealNow'>\n & {\n /** Registers under an existing `cancelKey` without cancelling whoever\n * holds it. For an animation re-registering itself — a revived\n * timeline — which is not a new claim on the key. */\n keepExisting?: boolean;\n };\n /** Gives a codec subject the rate its own pause and time scale now ask for. */\n const rateOf = (a: ActiveAnimation): void => {\n if (codec.has(a.id)) codec.rate(a.id, a.paused ? 0 : a.timeScale);\n };\n\n const register = (seed: AnimationSeed): AnimationHandle => {\n const anim = seed as ActiveAnimation;\n if (seed.cancelKey != null && !seed.keepExisting) cancelByKey(seed.cancelKey, anim);\n anim.paused = false;\n anim.timeScale = 1;\n anim.virtualNow = 0;\n // Seed lastRealNow at registration so the first frame's realDt reflects\n // the gap between register() and the first RAF callback: it places a\n // tween's end, and gives spring/decay a non-zero first dt sample.\n anim.lastRealNow = now();\n animations.current.set(anim.id, anim);\n if (hub.watched) hub.emit({ type: 'start', animation: infoOf(anim) });\n ensureLoop();\n return {\n id: anim.id,\n cancel: () => retire(anim.id),\n pause: () => { const a = animations.current.get(anim.id); if (a) { a.paused = true; rateOf(a); } },\n resume: () => { const a = animations.current.get(anim.id); if (a) { a.paused = false; rateOf(a); } },\n setTimeScale: (s) => { const a = animations.current.get(anim.id); if (a) { a.timeScale = s; rateOf(a); } },\n timeScale: () => animations.current.get(anim.id)?.timeScale ?? 1,\n isPaused: () => animations.current.get(anim.id)?.paused ?? false,\n };\n };\n\n // Supervisor: a registered animation whose tick is a no-op (never\n // finishes naturally) so loop/stagger can sit in the animator's id table\n // and benefit from `cancel`/`cancelKey`/`isActive`. The owning composite\n // (loop/stagger) installs an onCancel to actually tear down its children.\n const createSupervisor = ({ kind, cancelKey, label }: SupervisorOptions): Supervisor => {\n const id = nextId.current++;\n let onCancelCb: (() => void) | undefined;\n const base = register({\n id,\n kind,\n cancelKey,\n label,\n // tick is a no-op: the supervisor only ends when the owner calls\n // `cancel()` (either via animator.cancel, animator.cancelKey, or the\n // composite's natural-completion path which forwards to `cancel`).\n tick: () => false,\n onCancel: () => onCancelCb?.(),\n });\n return {\n id: base.id,\n cancel: base.cancel,\n pause: base.pause,\n resume: base.resume,\n setTimeScale: base.setTimeScale,\n timeScale: base.timeScale,\n isPaused: base.isPaused,\n setOnCancel: (cb) => { onCancelCb = cb; },\n finish: () => {\n if (!animations.current.has(id)) return;\n reportEnd(id);\n animations.current.delete(id);\n fireCompletion(id);\n },\n cancelKey,\n };\n };\n\n const tween = <T,>(o: TweenOptions<T>): AnimationHandle => {\n // blits blends in a straight line, which a caller's own function may not do.\n const fromAxes = o.interpolate || o.interpolator ? null : axesOf(o.from);\n const toAxes = fromAxes && axesOf(o.to);\n const axes = fromAxes && toAxes && toAxes.shape === fromAxes.shape ? fromAxes : null;\n // Refused here rather than on a tick, where a throw would stop every other animation.\n if (!axes && !o.interpolate && !o.interpolator) {\n throw new Error('tween: interpolate or interpolator is required for non-numeric T');\n }\n const id = nextId.current++;\n const easing = resolveEasing(o.easing ?? easeOut);\n // Precedence: factory > per-tick. Factory is built once at tween start so\n // expensive setup (color space conversion etc.) doesn't repeat per frame.\n const factoryFn = o.interpolator ? o.interpolator(o.from, o.to) : null;\n let lastValueEmitted = false;\n // Seeds the codec's clock where `register` seeds the call's, so both charge the same wait.\n if (codecFrameT.current == null) codecFrameT.current = now();\n // Started ahead of `register`, whose `start` listeners may already cancel it.\n const reader = codec.tween({\n id, ms: Math.max(o.ms, 1), ease: easing,\n from: axes ? axes.to(o.from) : [0],\n to: axes ? axes.to(o.to) : [1],\n });\n return register({\n id,\n kind: 'tween',\n cancelKey: o.cancelKey,\n label: o.label,\n progress: (virtualNow) => (o.ms <= 0 ? 1 : Math.min(1, virtualNow / o.ms)),\n // `nowMs` is the call's own virtual time, so it still decides when the tween ends; the codec\n // supplies only the value in between.\n tick(nowMs) {\n if (tripwire()) { codec.stop(id); return true; }\n const t = o.ms <= 0 ? 1 : Math.min(1, nowMs / o.ms);\n let value: T;\n if (axes) {\n value = t >= 1 ? o.to : axes.from(reader.cols, reader.at);\n } else {\n const eased = t >= 1 ? easing(1) : reader.cols[reader.at]!;\n value = factoryFn ? factoryFn(eased) : o.interpolate!(o.from, o.to, eased);\n }\n o.onTick(value);\n if (t >= 1 && !lastValueEmitted) {\n lastValueEmitted = true;\n codec.stop(id);\n // That last onTick may have cancelled us — deregistering the id.\n // A cancelled tween never completes, whenever the cancel landed.\n if (animations.current.has(id)) {\n reportEnd(id);\n o.onDone?.();\n }\n return true;\n }\n return false;\n },\n });\n };\n\n const physics = <T,>(o: PhysicsOptions<T>, kind: AnimationKind = 'physics'): PhysicsHandle<T> => {\n const id = nextId.current++;\n const isNumeric = typeof o.from === 'number';\n if (!isNumeric && (!o.add || !o.subtract || !o.scale || !o.magnitude)) {\n throw new Error('physics: add/subtract/scale/magnitude are required for non-numeric T');\n }\n const add = o.add ?? ((a: T, b: T) => ((a as unknown as number) + (b as unknown as number)) as unknown as T);\n const subtract = o.subtract ?? ((a: T, b: T) => ((a as unknown as number) - (b as unknown as number)) as unknown as T);\n const scale = o.scale ?? ((v: T, k: number) => ((v as unknown as number) * k) as unknown as T);\n const magnitude = o.magnitude ?? ((v: T) => Math.abs(v as unknown as number));\n const { stiffness: kBase, damping, mass } = resolveSpringConstants(o);\n const restThreshold = o.restThreshold ?? 0.01;\n\n let target: T | null = o.to ?? null;\n let value = o.from;\n // Default to zero velocity: assumes scale(_, 0) returns the zero vector of T. Pass an explicit velocity for unusual T where this isn't true.\n let velocity: T = o.velocity ?? scale(o.from, 0);\n let lastTime: number | null = null;\n\n // blits' closed forms need positive damping and mass, and a spring with a target needs\n // stiffness; decay's handle never takes a target.\n const solvable = damping > 0 && mass > 0 && (kBase > 0 || kind === 'decay');\n const fromAxes = solvable ? axesOf(o.from) : null;\n const sameShape = (v: T | null | undefined): boolean => v == null || axesOf(v)?.shape === fromAxes!.shape;\n const axes = fromAxes && sameShape(o.to) && sameShape(o.velocity) ? fromAxes : null;\n let reader: SpringReader | null = null;\n if (axes) {\n // Seeds the codec's clock where `register` seeds the call's, so both charge the same wait.\n if (codecFrameT.current == null) codecFrameT.current = now();\n // Started ahead of `register`, whose `start` listeners may already cancel it.\n reader = codec.spring({\n id, axes: axes.count,\n from: axes.to(o.from),\n to: o.to == null ? null : axes.to(o.to),\n velocity: o.velocity == null ? new Array<number>(axes.count).fill(0) : axes.to(o.velocity),\n stiffness: kBase, damping, mass,\n });\n }\n\n const baseHandle = register({\n id,\n kind,\n cancelKey: o.cancelKey,\n label: o.label,\n tick(nowMs) {\n if (tripwire()) { codec.stop(id); return true; }\n if (lastTime == null) {\n lastTime = nowMs;\n // Already-at-rest short-circuit: decay-mode (target == null)\n // with starting velocity below threshold should complete\n // immediately rather than emit a tick and wait a frame.\n if (target == null && magnitude(velocity) < restThreshold) {\n codec.stop(id);\n reportEnd(id);\n o.onDone?.();\n return true;\n }\n // The codec's voice has run since registration, so only Euler starts its clock here.\n if (!axes) {\n o.onTick(value);\n return false;\n }\n }\n if (axes) {\n const m = reader!.motion();\n value = axes.from(m.value);\n velocity = axes.from(m.velocity);\n } else {\n // Semi-implicit Euler, for a T blits cannot move as axes, or constants its closed forms can't solve.\n const dt = Math.min(0.064, (nowMs - lastTime) / 1000);\n const next = stepSpring({ add, subtract, scale }, value, velocity, target, kBase, damping, mass, dt);\n value = next.value;\n velocity = next.velocity;\n }\n lastTime = nowMs;\n o.onTick(value);\n const velRested = magnitude(velocity) < restThreshold;\n const posRested = target == null\n ? true\n : magnitude(subtract(value, target)) < restThreshold;\n if (velRested && posRested) {\n if (target != null) o.onTick(target);\n codec.stop(id);\n reportEnd(id);\n o.onDone?.();\n return true;\n }\n return false;\n },\n });\n\n const checkShape = (v: T, what: string): void => {\n if (!sameShape(v)) throw new Error(`physics: ${what} is not the same shape as \\`from\\``);\n };\n const handle: PhysicsHandle<T> = {\n ...baseHandle,\n setTarget: (newTo: T | null) => {\n if (axes && newTo != null) checkShape(newTo, 'setTarget');\n target = newTo;\n if (axes && codec.has(id)) codec.retarget(id, newTo == null ? null : axes.to(newTo));\n },\n setVelocity: (v: T) => {\n if (axes) checkShape(v, 'setVelocity');\n velocity = v;\n if (axes && codec.has(id)) codec.push(id, axes.to(v));\n },\n };\n return handle;\n };\n\n const spring = <T,>(o: SpringOptions<T>): AnimationHandle => physics<T>(o, 'spring');\n\n const decay = <T,>(o: DecayOptions<T>): AnimationHandle => {\n const friction = o.friction ?? 0.95;\n // Per-second friction v(t) = v0 * friction^t corresponds to\n // m*dv/dt = -c*v with c = -ln(friction), m = 1, k = 0.\n const damping = -Math.log(friction);\n return physics<T>({\n from: o.from,\n to: null,\n velocity: o.velocity,\n stiffness: 0,\n damping,\n mass: 1,\n restThreshold: o.threshold ?? 0.5,\n add: o.add,\n // DecayOptions doesn't carry subtract; derive from add+scale.\n subtract: (a, b) => o.add(a, o.scale(b, -1)),\n scale: o.scale,\n magnitude: o.magnitude,\n onTick: o.onTick,\n onDone: o.onDone,\n cancelKey: o.cancelKey,\n label: o.label,\n }, 'decay');\n };\n\n const cancelAll = (): void => {\n const retired: ActiveAnimation[] = [];\n for (const a of animations.current.values()) {\n a.onCancel?.();\n codec.stop(a.id);\n retired.push(a);\n }\n animations.current.clear();\n codecFrameT.current = null;\n for (const a of retired) fireCompletion(a.id);\n if (hub.watched) for (const a of retired) hub.emit({ type: 'cancel', animation: infoOf(a) });\n frameLoopRef.current.cancel();\n };\n const api: Animator = {\n tween,\n spring,\n decay,\n physics,\n cancel: (handle) => retire(handle.id),\n cancelKey: (key) => cancelByKey(key),\n cancelAll,\n isActive: (key) => {\n if (key == null) return animations.current.size > 0;\n for (const a of animations.current.values()) {\n if (a.cancelKey === key) return true;\n }\n return false;\n },\n isTicking: () => tickDepth.current > 0,\n pause: () => { globalPaused.current = true; },\n resume: () => { globalPaused.current = false; },\n isPaused: () => globalPaused.current,\n setTimeScale: (s) => { globalTimeScale.current = s; },\n timeScale: () => globalTimeScale.current,\n pauseKey: (key) => {\n for (const a of animations.current.values()) if (a.cancelKey === key) { a.paused = true; rateOf(a); }\n },\n resumeKey: (key) => {\n for (const a of animations.current.values()) if (a.cancelKey === key) { a.paused = false; rateOf(a); }\n },\n setTimeScaleByKey: (key, s) => {\n for (const a of animations.current.values()) if (a.cancelKey === key) { a.timeScale = s; rateOf(a); }\n },\n loop: (factory, loopOpts) => createLoop(createSupervisor, factory, loopOpts),\n tweenLoop: (tweenLoopOpts) =>\n createTweenLoop(api, createSupervisor, tweenLoopOpts),\n stagger: ((items, delay, factory, staggerOpts) =>\n createStagger(\n api,\n staggerTimers,\n createSupervisor,\n watchCompletion,\n items,\n delay,\n factory as never,\n staggerOpts,\n )) as Animator['stagger'],\n timeline: (o: TimelineOptions) => {\n const id = nextId.current++;\n const info = (): AnimationInfo | undefined => {\n const a = animations.current.get(id);\n return a && infoOf(a);\n };\n return createTimeline(register, id, o, {\n get watched() { return hub.watched; },\n fire: (track, path, event, lateBy) => {\n const animation = info();\n if (animation) hub.emit({ type: 'fire', animation, track, path: path.slice(), event, lateBy });\n },\n lap: (lap) => {\n const animation = info();\n if (animation) hub.emit({ type: 'lap', animation, lap });\n },\n });\n },\n colorOverrides: colorOverrides.current,\n onTick: (cb) => {\n tickSubscribers.current.add(cb);\n return () => { tickSubscribers.current.delete(cb); };\n },\n keepAlive: () => {\n const sup = createSupervisor({ kind: 'keepAlive' });\n return () => sup.cancel();\n },\n watch: (listener) => hub.add(listener),\n live: () => {\n const rows: LiveAnimation[] = [];\n for (const a of animations.current.values()) {\n const row: LiveAnimation = {\n ...infoOf(a),\n paused: a.paused,\n timeScale: a.timeScale,\n elapsed: a.virtualNow,\n ...(a.progress ? { progress: a.progress(a.virtualNow) } : {}),\n };\n rows.push(row);\n }\n return rows;\n },\n };\n return { api, tickAll };\n }, [frameLoopRef, optsRef]);\n\n useInsertionEffect(() => {\n tickAllRef.current = tickAll;\n }, [tickAll]);\n\n // StrictMode-safe cleanup: when the component unmounts (including the\n // dev-mode double-mount that StrictMode performs), cancel every running\n // animation and stop the RAF loop. Without this, the FIRST mount's\n // animator keeps ticking with stale callbacks pointing at the unmounted\n // adapter, while the SECOND mount creates its own animator on top —\n // visible to the user as every animation playing twice.\n useEffect(() => {\n const overrides = colorOverrides.current;\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n api.cancelAll();\n overrides.clearAll();\n };\n }, [api]);\n\n return api;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useAnimator.js","names":["resolveSpringConstants","preset","o","SPRING_PRESETS","useAnimator","optsRef","useLatest","opts","animations","useRef","nextId","tickDepth","codecFrameT","globalTimeScale","globalPaused","colorOverrides","ColorOverrideRegistry","tickSubscribers","tickAllRef","frameLoop","useVisibleRaf","useCallback","t","anim","frameLoopRef","mountedRef","trippedRef","tripwire","useMemo","now","afterTicks","completionListeners","fireCompletion","ls","id","cb","watchCompletion","cur","idx","hub","AnimatorEventHub","codec","createCodec","infoOf","a","info","reportEnd","retire","error","by","tickAll","finished","threw","frameDt","realDt","scale","err","sub","ensureLoop","cancelByKey","ids","key","rateOf","register","seed","s","createSupervisor","onCancelCb","onRateCb","onFrameCb","base","virtualNow","paused","timeScale","tween","fromAxes","axesOf","toAxes","axes","easing","resolveEasing","easeOut","factoryFn","lastValueEmitted","reader","nowMs","value","eased","physics","add","b","subtract","v","k","magnitude","kBase","restThreshold","target","velocity","lastTime","damping","mass","kind","sameShape","baseHandle","m","dt","next","stepSpring","velRested","posRested","checkShape","what","newTo","api","friction","handle","retired","createLoop","factory","loopOpts","createTweenLoop","tweenLoopOpts","createStagger","items","delay","staggerOpts","createTimeline","animation","path","sup","listener","rows","row","useInsertionEffect","useEffect","overrides"],"sources":["../../src/animation/useAnimator.ts"],"sourcesContent":["import { useCallback, useEffect, useInsertionEffect, useMemo, useRef } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport { useVisibleRaf } from '../scheduling/useVisibleRaf';\nimport { easeOut, SPRING_PRESETS, resolveEasing } from '@weasel-js/geom';\nimport { createLoop, createTweenLoop } from './loop';\nimport { stepSpring } from './engine/integrator';\nimport { createCodec, type SpringReader } from './engine/codec';\nimport { axesOf } from './engine/axes';\nimport { createStagger } from './stagger';\nimport { createTimeline } from './timeline/createTimeline';\nimport { ColorOverrideRegistry } from './colorRegistry';\nimport { AnimatorEventHub } from './observe';\nimport type { Supervisor, SupervisorOptions, WatchCompletion } from './supervisor';\nimport type {\n AnimationHandle,\n AnimationInfo,\n AnimationKind,\n Animator,\n TweenOptions,\n SpringOptions,\n DecayOptions,\n PhysicsOptions,\n PhysicsHandle,\n UseAnimatorOptions,\n LiveAnimation,\n} from './types';\nimport type { TimelineOptions } from './timeline/types';\n\ninterface ActiveAnimation {\n id: number;\n kind: AnimationKind;\n cancelKey?: string;\n label?: string;\n /** Built the first time something reports on this entry, then shared. */\n info?: AnimationInfo;\n /** 0–1 where the animation has an end to measure against. */\n progress?(virtualNow: number): number;\n /** Its `end` is reported, though the entry stays on the table until the\n * frame's ticks are done. */\n ended?: boolean;\n paused: boolean;\n timeScale: number;\n virtualNow: number;\n lastRealNow: number | null;\n /** Returns true when finished. Called once per frame with the current\n * virtual-ms timestamp and the effective scale it advanced at this frame. */\n tick(virtualNow: number, scale: number): boolean;\n /** Called when the animation is cancelled. Skips onDone. */\n onCancel?(): void;\n /** Called when its pause state or time scale is set, by handle or by key. */\n onRate?(paused: boolean, timeScale: number): void;\n}\n\nfunction resolveSpringConstants(o: { preset?: string; stiffness?: number; damping?: number; mass?: number }) {\n const preset = o.preset ? SPRING_PRESETS[o.preset as keyof typeof SPRING_PRESETS] : null;\n return {\n stiffness: o.stiffness ?? preset?.stiffness ?? 170,\n damping: o.damping ?? preset?.damping ?? 26,\n mass: o.mass ?? preset?.mass ?? 1,\n };\n}\n\n/** Create the animator for a canvas. One rAF loop drives every animation it\n * owns, and everything still running is cancelled on unmount. */\nexport function useAnimator(opts: UseAnimatorOptions = {}): Animator {\n const optsRef = useLatest(opts);\n const animations = useRef<Map<number, ActiveAnimation>>(new Map());\n const nextId = useRef(1);\n /**\n * Re-entrancy counter incremented around each animation tick in tickAll.\n * Exposed via `isTicking()`. > 0 ⇒ we're currently inside an animation's\n * onTick; an adapter wrapper (`animateOnSetPose`) seeing this flag should\n * write through to the base adapter rather than schedule a new tween.\n */\n const tickDepth = useRef(0);\n /** The timestamp the codec last advanced to. Null after the page was hidden and while nothing\n * runs, so neither gap is charged to the codec; a tween starting then seeds it from `now()`. */\n const codecFrameT = useRef<number | null>(null);\n const globalTimeScale = useRef(1);\n const globalPaused = useRef(false);\n const colorOverrides = useRef<ColorOverrideRegistry>(new ColorOverrideRegistry());\n // Per-frame tick subscribers. Notified after each batch of animation\n // ticks (i.e. after `colorOverrides` has settled to its latest values\n // but before the next RAF schedules). Used by `<SceneCanvas animator>`\n // to request a redraw on every active frame.\n const tickSubscribers = useRef<Set<() => void>>(new Set());\n\n // The loop runs behind the visibility gate. `tickAll` is built inside the\n // memo below, so the frame callback reaches it through a ref, published\n // once the memo's render commits.\n const tickAllRef = useRef<((t: number) => void) | null>(null);\n const frameLoop = useVisibleRaf(\n useCallback((t: number) => { tickAllRef.current?.(t); }, []),\n {\n requestFrame: opts.requestFrame,\n cancelFrame: opts.cancelFrame,\n // An hour spent hidden is not an hour the animation ran: dropping each\n // animation's last timestamp makes the resuming frame's `realDt` zero.\n onResume: () => {\n for (const anim of animations.current.values()) anim.lastRealNow = null;\n codecFrameT.current = null;\n },\n },\n );\n const frameLoopRef = useLatest(frameLoop);\n\n // Tripwire: dev-only flag that every tween/spring/decay's tick reads to\n // detect \"animation fired after the host component unmounted.\" This is a\n // symptom of cleanup not running (regression) — typically because someone\n // refactored useAnimator and forgot to wire the unmount effect. The flag\n // flips false on cleanup; ticks see it and log a one-time error so the\n // bug is loud rather than just visually-doubled animation.\n const mountedRef = useRef(true);\n const trippedRef = useRef(false);\n const tripwire = (): boolean => {\n if (mountedRef.current) return false;\n if (!trippedRef.current) {\n trippedRef.current = true;\n const isDev = typeof process !== 'undefined' ? process.env.NODE_ENV !== 'production' : true;\n if (isDev) {\n console.error(\n 'weasel useAnimator: animation tick fired after the host component unmounted. ' +\n 'This usually means cleanup logic was bypassed — check for refactors that ' +\n 'removed the unmount effect or replaced cancelAll with a custom path.',\n );\n }\n }\n return true;\n };\n\n const { api, tickAll } = useMemo(() => {\n // Default to performance.now() so the time origin matches the\n // requestAnimationFrame callback's DOMHighResTimeStamp argument.\n // Using Date.now() here would mix epoch-millis with page-relative-millis,\n // producing huge negative `elapsed` values that clamp tween `t` to 0\n // forever (never reaching completion).\n const now = (): number =>\n (optsRef.current.now ?? (typeof performance !== 'undefined' ? performance.now.bind(performance) : Date.now))();\n /** Supervisor frame callbacks due this frame, run once its ticks are done. */\n const afterTicks: (() => void)[] = [];\n\n // Per-id one-shot completion listeners. Used by stagger to detect when\n // each child has left the registry (natural completion OR cancel) so the\n // supervising composite can retire itself when the last child finishes.\n const completionListeners = new Map<number, (() => void)[]>();\n const fireCompletion = (id: number): void => {\n const ls = completionListeners.get(id);\n if (!ls) return;\n completionListeners.delete(id);\n for (const cb of ls) cb();\n };\n const watchCompletion: WatchCompletion = (id, cb) => {\n if (!animations.current.has(id)) {\n cb();\n return () => {};\n }\n const ls = completionListeners.get(id) ?? [];\n ls.push(cb);\n completionListeners.set(id, ls);\n return () => {\n const cur = completionListeners.get(id);\n if (!cur) return;\n const idx = cur.indexOf(cb);\n if (idx >= 0) cur.splice(idx, 1);\n if (cur.length === 0) completionListeners.delete(id);\n };\n };\n\n const hub = new AnimatorEventHub();\n const codec = createCodec();\n const infoOf = (a: ActiveAnimation): AnimationInfo => {\n if (!a.info) {\n const info: { -readonly [K in keyof AnimationInfo]: AnimationInfo[K] } = { id: a.id, kind: a.kind };\n if (a.cancelKey != null) info.key = a.cancelKey;\n if (a.label != null) info.label = a.label;\n a.info = info;\n }\n return a.info;\n };\n\n /** Report `id` as finished, ahead of its `onDone`, so whatever that\n * handler starts is heard after it. Nothing revives a primitive; a\n * timeline, which can be revived, is reported as it leaves the table. */\n const reportEnd = (id: number): void => {\n const a = animations.current.get(id);\n if (!a || a.ended) return;\n a.ended = true;\n if (hub.watched) hub.emit({ type: 'end', animation: infoOf(a) });\n };\n\n /** Take `id` off the table as canceled — or, given `by`, as interrupted by\n * the animation claiming its key; given `error`, the caller reports it. */\n const retire = (id: number, by?: ActiveAnimation, error?: true): void => {\n const a = animations.current.get(id);\n if (!a) return;\n a.onCancel?.();\n codec.stop(id);\n animations.current.delete(id);\n fireCompletion(id);\n if (!hub.watched || a.ended || error) return;\n hub.emit(by\n ? { type: 'interrupt', animation: infoOf(a), by: infoOf(by) }\n : { type: 'cancel', animation: infoOf(a) });\n };\n\n const tickAll = (t: number): void => {\n const finished: ActiveAnimation[] = [];\n const threw: [ActiveAnimation, unknown][] = [];\n const frameDt = codecFrameT.current == null ? 0 : Math.max(0, t - codecFrameT.current);\n codecFrameT.current = t;\n codec.frame(frameDt * (globalPaused.current ? 0 : globalTimeScale.current));\n // A snapshot: an animation registered by this frame's ticks first ticks on the\n // next, or a zero-duration loop would chain inside one frame and never leave it.\n for (const anim of [...animations.current.values()]) {\n if (animations.current.get(anim.id) !== anim) continue;\n // `t` comes from the frame clock; `lastRealNow` is seeded at register()\n // from `now()`. The two share a time origin in a browser, where the rAF\n // timestamp and `performance.now()` are both page-relative — but not\n // everywhere: jsdom starts them ~600ms apart, which made the first\n // frame's delta hugely negative and left `virtualNow` climbing back\n // toward zero for dozens of frames before a tween advanced at all.\n // Time never runs backwards, so a negative sample is never real.\n const realDt = anim.lastRealNow == null ? 0 : Math.max(0, t - anim.lastRealNow);\n anim.lastRealNow = t;\n const scale = globalPaused.current\n ? 0\n : globalTimeScale.current * (anim.paused ? 0 : anim.timeScale);\n anim.virtualNow += realDt * scale;\n // Increment tick depth around each animation's tick so re-entrant\n // calls (e.g. `decay.onTick` → `adapter.setPose` →\n // `animateOnSetPose` checking `isTicking()`) see the flag and\n // skip scheduling a new wrap-tween that would fight the caller.\n tickDepth.current += 1;\n try {\n if (anim.tick(anim.virtualNow, scale)) finished.push(anim);\n } catch (error) {\n threw.push([anim, error]);\n } finally {\n tickDepth.current -= 1;\n }\n }\n for (const [anim, error] of threw) {\n console.error('useAnimator: animation tick threw; retiring it', error);\n if (animations.current.get(anim.id) !== anim) continue;\n // One that ended before throwing (from `onDone`) is finished, not canceled.\n if (anim.ended) {\n animations.current.delete(anim.id);\n fireCompletion(anim.id);\n } else {\n retire(anim.id, undefined, true);\n }\n if (hub.watched) hub.emit({ type: 'error', animation: infoOf(anim), error });\n }\n for (const anim of finished) {\n // Gone already if its own tick canceled it; replaced if something\n // revived it under the same id since.\n if (animations.current.get(anim.id) !== anim) continue;\n reportEnd(anim.id);\n animations.current.delete(anim.id);\n fireCompletion(anim.id);\n }\n for (const cb of afterTicks.splice(0)) {\n try { cb(); } catch (err) { console.error('useAnimator: a staggered start threw', err); }\n }\n // Notify every onTick subscriber AFTER the tick batch so they\n // see the latest `colorOverrides` / pose values. Errors in one\n // subscriber don't suppress the others.\n for (const sub of tickSubscribers.current) {\n try { sub(); } catch (err) { console.error('useAnimator: onTick subscriber threw', err); }\n }\n if (animations.current.size > 0) frameLoopRef.current.request();\n else codecFrameT.current = null;\n };\n\n const ensureLoop = (): void => {\n if (animations.current.size === 0) return;\n frameLoopRef.current.request();\n };\n\n const cancelByKey = (key: string, by?: ActiveAnimation): void => {\n const ids: number[] = [];\n for (const anim of animations.current.values()) {\n if (anim.cancelKey === key) ids.push(anim.id);\n }\n for (const id of ids) retire(id, by);\n };\n\n type AnimationSeed =\n Omit<ActiveAnimation, 'paused' | 'timeScale' | 'virtualNow' | 'lastRealNow'>\n & {\n /** Registers under an existing `cancelKey` without cancelling whoever\n * holds it. For an animation re-registering itself — a revived\n * timeline — which is not a new claim on the key. */\n keepExisting?: boolean;\n };\n /** Gives a codec subject the rate its own pause and time scale now ask for. */\n const rateOf = (a: ActiveAnimation): void => {\n if (codec.has(a.id)) codec.rate(a.id, a.paused ? 0 : a.timeScale);\n a.onRate?.(a.paused, a.timeScale);\n };\n\n const register = (seed: AnimationSeed): AnimationHandle => {\n const anim = seed as ActiveAnimation;\n if (seed.cancelKey != null && !seed.keepExisting) cancelByKey(seed.cancelKey, anim);\n anim.paused = false;\n anim.timeScale = 1;\n anim.virtualNow = 0;\n // Seed lastRealNow at registration so the first frame's realDt reflects\n // the gap between register() and the first RAF callback: it places a\n // tween's end, and gives spring/decay a non-zero first dt sample.\n anim.lastRealNow = now();\n animations.current.set(anim.id, anim);\n if (hub.watched) hub.emit({ type: 'start', animation: infoOf(anim) });\n ensureLoop();\n return {\n id: anim.id,\n cancel: () => retire(anim.id),\n pause: () => { const a = animations.current.get(anim.id); if (a) { a.paused = true; rateOf(a); } },\n resume: () => { const a = animations.current.get(anim.id); if (a) { a.paused = false; rateOf(a); } },\n setTimeScale: (s) => { const a = animations.current.get(anim.id); if (a) { a.timeScale = s; rateOf(a); } },\n timeScale: () => animations.current.get(anim.id)?.timeScale ?? 1,\n isPaused: () => animations.current.get(anim.id)?.paused ?? false,\n };\n };\n\n // Supervisor: a registered animation whose tick is a no-op (never\n // finishes naturally) so loop/stagger can sit in the animator's id table\n // and benefit from `cancel`/`cancelKey`/`isActive`. The owning composite\n // (loop/stagger) installs an onCancel to actually tear down its children.\n const createSupervisor = ({ kind, cancelKey, label }: SupervisorOptions): Supervisor => {\n const id = nextId.current++;\n let onCancelCb: (() => void) | undefined;\n let onRateCb: ((paused: boolean, timeScale: number) => void) | undefined;\n let onFrameCb: ((virtualNow: number) => void) | undefined;\n const base = register({\n id,\n kind,\n cancelKey,\n label,\n // tick is a no-op: the supervisor only ends when the owner calls\n // `cancel()` (either via animator.cancel, animator.cancelKey, or the\n // composite's natural-completion path which forwards to `cancel`).\n tick: (virtualNow) => {\n if (onFrameCb) afterTicks.push(() => onFrameCb?.(virtualNow));\n return false;\n },\n onCancel: () => onCancelCb?.(),\n onRate: (paused, timeScale) => onRateCb?.(paused, timeScale),\n });\n return {\n id: base.id,\n cancel: base.cancel,\n pause: base.pause,\n resume: base.resume,\n setTimeScale: base.setTimeScale,\n timeScale: base.timeScale,\n isPaused: base.isPaused,\n setOnCancel: (cb) => { onCancelCb = cb; },\n setOnRate: (cb) => { onRateCb = cb; },\n setOnFrame: (cb) => { onFrameCb = cb; },\n finish: () => {\n if (!animations.current.has(id)) return;\n reportEnd(id);\n animations.current.delete(id);\n fireCompletion(id);\n },\n cancelKey,\n };\n };\n\n const tween = <T,>(o: TweenOptions<T>): AnimationHandle => {\n // blits blends in a straight line, which a caller's own function may not do.\n const fromAxes = o.interpolate || o.interpolator ? null : axesOf(o.from);\n const toAxes = fromAxes && axesOf(o.to);\n const axes = fromAxes && toAxes && toAxes.shape === fromAxes.shape ? fromAxes : null;\n // Refused here rather than on a tick, where a throw would stop every other animation.\n if (!axes && !o.interpolate && !o.interpolator) {\n throw new Error('tween: interpolate or interpolator is required for non-numeric T');\n }\n const id = nextId.current++;\n const easing = resolveEasing(o.easing ?? easeOut);\n // Precedence: factory > per-tick. Factory is built once at tween start so\n // expensive setup (color space conversion etc.) doesn't repeat per frame.\n const factoryFn = o.interpolator ? o.interpolator(o.from, o.to) : null;\n let lastValueEmitted = false;\n // Seeds the codec's clock where `register` seeds the call's, so both charge the same wait.\n if (codecFrameT.current == null) codecFrameT.current = now();\n // Started ahead of `register`, whose `start` listeners may already cancel it.\n const reader = codec.tween({\n id, ms: Math.max(o.ms, 1), ease: easing,\n from: axes ? axes.to(o.from) : [0],\n to: axes ? axes.to(o.to) : [1],\n });\n return register({\n id,\n kind: 'tween',\n cancelKey: o.cancelKey,\n label: o.label,\n progress: (virtualNow) => (o.ms <= 0 ? 1 : Math.min(1, virtualNow / o.ms)),\n // `nowMs` is the call's own virtual time, so it still decides when the tween ends; the codec\n // supplies only the value in between.\n tick(nowMs) {\n if (tripwire()) { codec.stop(id); return true; }\n const t = o.ms <= 0 ? 1 : Math.min(1, nowMs / o.ms);\n let value: T;\n if (axes) {\n value = t >= 1 ? o.to : axes.from(reader.cols, reader.at);\n } else {\n const eased = t >= 1 ? easing(1) : reader.cols[reader.at]!;\n value = factoryFn ? factoryFn(eased) : o.interpolate!(o.from, o.to, eased);\n }\n o.onTick(value);\n if (t >= 1 && !lastValueEmitted) {\n lastValueEmitted = true;\n codec.stop(id);\n // That last onTick may have cancelled us — deregistering the id.\n // A cancelled tween never completes, whenever the cancel landed.\n if (animations.current.has(id)) {\n reportEnd(id);\n o.onDone?.();\n }\n return true;\n }\n return false;\n },\n });\n };\n\n const physics = <T,>(o: PhysicsOptions<T>, kind: AnimationKind = 'physics'): PhysicsHandle<T> => {\n const id = nextId.current++;\n const isNumeric = typeof o.from === 'number';\n if (!isNumeric && (!o.add || !o.subtract || !o.scale || !o.magnitude)) {\n throw new Error('physics: add/subtract/scale/magnitude are required for non-numeric T');\n }\n const add = o.add ?? ((a: T, b: T) => ((a as unknown as number) + (b as unknown as number)) as unknown as T);\n const subtract = o.subtract ?? ((a: T, b: T) => ((a as unknown as number) - (b as unknown as number)) as unknown as T);\n const scale = o.scale ?? ((v: T, k: number) => ((v as unknown as number) * k) as unknown as T);\n const magnitude = o.magnitude ?? ((v: T) => Math.abs(v as unknown as number));\n const { stiffness: kBase, damping, mass } = resolveSpringConstants(o);\n const restThreshold = o.restThreshold ?? 0.01;\n\n let target: T | null = o.to ?? null;\n let value = o.from;\n // Default to zero velocity: assumes scale(_, 0) returns the zero vector of T. Pass an explicit velocity for unusual T where this isn't true.\n let velocity: T = o.velocity ?? scale(o.from, 0);\n let lastTime: number | null = null;\n\n // blits' closed forms need positive damping and mass, and a spring with a target needs\n // stiffness; decay's handle never takes a target.\n const solvable = damping > 0 && mass > 0 && (kBase > 0 || kind === 'decay');\n const fromAxes = solvable ? axesOf(o.from) : null;\n const sameShape = (v: T | null | undefined): boolean => v == null || axesOf(v)?.shape === fromAxes!.shape;\n const axes = fromAxes && sameShape(o.to) && sameShape(o.velocity) ? fromAxes : null;\n let reader: SpringReader | null = null;\n if (axes) {\n // Seeds the codec's clock where `register` seeds the call's, so both charge the same wait.\n if (codecFrameT.current == null) codecFrameT.current = now();\n // Started ahead of `register`, whose `start` listeners may already cancel it.\n reader = codec.spring({\n id, axes: axes.count,\n from: axes.to(o.from),\n to: o.to == null ? null : axes.to(o.to),\n velocity: o.velocity == null ? new Array<number>(axes.count).fill(0) : axes.to(o.velocity),\n stiffness: kBase, damping, mass,\n });\n }\n\n const baseHandle = register({\n id,\n kind,\n cancelKey: o.cancelKey,\n label: o.label,\n tick(nowMs) {\n if (tripwire()) { codec.stop(id); return true; }\n if (lastTime == null) {\n lastTime = nowMs;\n // Already-at-rest short-circuit: decay-mode (target == null)\n // with starting velocity below threshold should complete\n // immediately rather than emit a tick and wait a frame.\n if (target == null && magnitude(velocity) < restThreshold) {\n codec.stop(id);\n reportEnd(id);\n o.onDone?.();\n return true;\n }\n // The codec's voice has run since registration, so only Euler starts its clock here.\n if (!axes) {\n o.onTick(value);\n return false;\n }\n }\n if (axes) {\n const m = reader!.motion();\n value = axes.from(m.value);\n velocity = axes.from(m.velocity);\n } else {\n // Semi-implicit Euler, for a T blits cannot move as axes, or constants its closed forms can't solve.\n const dt = Math.min(0.064, (nowMs - lastTime) / 1000);\n const next = stepSpring({ add, subtract, scale }, value, velocity, target, kBase, damping, mass, dt);\n value = next.value;\n velocity = next.velocity;\n }\n lastTime = nowMs;\n o.onTick(value);\n const velRested = magnitude(velocity) < restThreshold;\n const posRested = target == null\n ? true\n : magnitude(subtract(value, target)) < restThreshold;\n if (velRested && posRested) {\n if (target != null) o.onTick(target);\n codec.stop(id);\n // As for a tween: canceled from its own onTick, it never completes.\n if (animations.current.has(id)) {\n reportEnd(id);\n o.onDone?.();\n }\n return true;\n }\n return false;\n },\n });\n\n const checkShape = (v: T, what: string): void => {\n if (!sameShape(v)) throw new Error(`physics: ${what} is not the same shape as \\`from\\``);\n };\n const handle: PhysicsHandle<T> = {\n ...baseHandle,\n setTarget: (newTo: T | null) => {\n if (axes && newTo != null) checkShape(newTo, 'setTarget');\n target = newTo;\n if (axes && codec.has(id)) codec.retarget(id, newTo == null ? null : axes.to(newTo));\n },\n setVelocity: (v: T) => {\n if (axes) checkShape(v, 'setVelocity');\n velocity = v;\n if (axes && codec.has(id)) codec.push(id, axes.to(v));\n },\n };\n return handle;\n };\n\n const spring = <T,>(o: SpringOptions<T>): AnimationHandle => physics<T>(o, 'spring');\n\n const decay = <T,>(o: DecayOptions<T>): AnimationHandle => {\n const friction = o.friction ?? 0.95;\n // Per-second friction v(t) = v0 * friction^t corresponds to\n // m*dv/dt = -c*v with c = -ln(friction), m = 1, k = 0.\n const damping = -Math.log(friction);\n return physics<T>({\n from: o.from,\n to: null,\n velocity: o.velocity,\n stiffness: 0,\n damping,\n mass: 1,\n restThreshold: o.threshold ?? 0.5,\n add: o.add,\n // DecayOptions doesn't carry subtract; derive from add+scale.\n subtract: (a, b) => o.add(a, o.scale(b, -1)),\n scale: o.scale,\n magnitude: o.magnitude,\n onTick: o.onTick,\n onDone: o.onDone,\n cancelKey: o.cancelKey,\n label: o.label,\n }, 'decay');\n };\n\n const cancelAll = (): void => {\n const retired: ActiveAnimation[] = [];\n for (const a of animations.current.values()) {\n a.onCancel?.();\n codec.stop(a.id);\n retired.push(a);\n }\n animations.current.clear();\n codecFrameT.current = null;\n for (const a of retired) fireCompletion(a.id);\n if (hub.watched) for (const a of retired) hub.emit({ type: 'cancel', animation: infoOf(a) });\n frameLoopRef.current.cancel();\n };\n const api: Animator = {\n tween,\n spring,\n decay,\n physics,\n cancel: (handle) => retire(handle.id),\n cancelKey: (key) => cancelByKey(key),\n cancelAll,\n isActive: (key) => {\n if (key == null) return animations.current.size > 0;\n for (const a of animations.current.values()) {\n if (a.cancelKey === key) return true;\n }\n return false;\n },\n isTicking: () => tickDepth.current > 0,\n pause: () => { globalPaused.current = true; },\n resume: () => { globalPaused.current = false; },\n isPaused: () => globalPaused.current,\n setTimeScale: (s) => { globalTimeScale.current = s; },\n timeScale: () => globalTimeScale.current,\n pauseKey: (key) => {\n for (const a of animations.current.values()) if (a.cancelKey === key) { a.paused = true; rateOf(a); }\n },\n resumeKey: (key) => {\n for (const a of animations.current.values()) if (a.cancelKey === key) { a.paused = false; rateOf(a); }\n },\n setTimeScaleByKey: (key, s) => {\n for (const a of animations.current.values()) if (a.cancelKey === key) { a.timeScale = s; rateOf(a); }\n },\n loop: (factory, loopOpts) => createLoop(createSupervisor, factory, loopOpts),\n tweenLoop: (tweenLoopOpts) =>\n createTweenLoop(api, createSupervisor, tweenLoopOpts),\n stagger: ((items, delay, factory, staggerOpts) =>\n createStagger(\n api,\n createSupervisor,\n watchCompletion,\n items,\n delay,\n factory as never,\n staggerOpts,\n )) as Animator['stagger'],\n timeline: (o: TimelineOptions) => {\n const id = nextId.current++;\n const info = (): AnimationInfo | undefined => {\n const a = animations.current.get(id);\n return a && infoOf(a);\n };\n return createTimeline(register, id, o, {\n get watched() { return hub.watched; },\n fire: (track, path, event, lateBy) => {\n const animation = info();\n if (animation) hub.emit({ type: 'fire', animation, track, path: path.slice(), event, lateBy });\n },\n lap: (lap) => {\n const animation = info();\n if (animation) hub.emit({ type: 'lap', animation, lap });\n },\n });\n },\n colorOverrides: colorOverrides.current,\n onTick: (cb) => {\n tickSubscribers.current.add(cb);\n return () => { tickSubscribers.current.delete(cb); };\n },\n keepAlive: () => {\n const sup = createSupervisor({ kind: 'keepAlive' });\n return () => sup.cancel();\n },\n watch: (listener) => hub.add(listener),\n live: () => {\n const rows: LiveAnimation[] = [];\n for (const a of animations.current.values()) {\n const row: LiveAnimation = {\n ...infoOf(a),\n paused: a.paused,\n timeScale: a.timeScale,\n elapsed: a.virtualNow,\n ...(a.progress ? { progress: a.progress(a.virtualNow) } : {}),\n };\n rows.push(row);\n }\n return rows;\n },\n };\n return { api, tickAll };\n }, [frameLoopRef, optsRef]);\n\n useInsertionEffect(() => {\n tickAllRef.current = tickAll;\n }, [tickAll]);\n\n // StrictMode-safe cleanup: when the component unmounts (including the\n // dev-mode double-mount that StrictMode performs), cancel every running\n // animation and stop the RAF loop. Without this, the FIRST mount's\n // animator keeps ticking with stale callbacks pointing at the unmounted\n // adapter, while the SECOND mount creates its own animator on top —\n // visible to the user as every animation playing twice.\n useEffect(() => {\n const overrides = colorOverrides.current;\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n api.cancelAll();\n overrides.clearAll();\n };\n }, [api]);\n\n return api;\n}\n"],"mappings":"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"}
@@ -1,40 +1,47 @@
1
1
  import { tweenPose as e } from "../poseHelpers.js";
2
+ import { setPoseInstant as t } from "./instantPose.js";
2
3
  //#region src/animation/wrappers/animateLifecycle.ts
3
- function t(t, n, r) {
4
- let i = r.ms ?? 200;
4
+ function n(n, r, i) {
5
+ let a = i.ms ?? 200, o = /* @__PURE__ */ new Set();
5
6
  return {
6
- ...t,
7
- insertNode(a, o) {
8
- if (t.insertNode(a, o), !r.enterFrom) return;
9
- let s = t.getPose(a.id), c = r.enterFrom(s);
10
- t.setPose(a.id, c), e(n, t, {
11
- id: a.id,
12
- to: s,
13
- ms: i,
14
- easing: r.easing,
15
- geometry: r.geometry,
7
+ ...n,
8
+ insertNode(o, s) {
9
+ if (n.insertNode(o, s), !i.enterFrom) return;
10
+ let c = n.getPose(o.id), l = i.enterFrom(c);
11
+ t(n, o.id, l), e(r, n, {
12
+ id: o.id,
13
+ to: c,
14
+ ms: a,
15
+ easing: i.easing,
16
+ geometry: i.geometry,
16
17
  recordOp: !1
17
18
  });
18
19
  },
19
- removeNode(a) {
20
- if (!r.exitTo) {
21
- t.removeNode(a);
20
+ removeNode(t) {
21
+ if (!i.exitTo) {
22
+ n.removeNode(t);
22
23
  return;
23
24
  }
24
- let o = t.getPose(a);
25
- e(n, t, {
26
- id: a,
27
- to: r.exitTo(o),
28
- ms: i,
29
- easing: r.easing,
30
- geometry: r.geometry,
25
+ if (o.has(t)) return;
26
+ o.add(t);
27
+ let s = () => {}, c = () => {
28
+ o.delete(t) && (s(), n.removeNode(t));
29
+ }, l = n.getPose(t), u = e(r, n, {
30
+ id: t,
31
+ to: i.exitTo(l),
32
+ ms: a,
33
+ easing: i.easing,
34
+ geometry: i.geometry,
31
35
  recordOp: !1,
32
- onDone: () => t.removeNode(a)
36
+ onDone: c
37
+ });
38
+ s = r.watch((e) => {
39
+ (e.type === "cancel" || e.type === "interrupt") && e.animation.id === u.id && c();
33
40
  });
34
41
  }
35
42
  };
36
43
  }
37
44
  //#endregion
38
- export { t as animateLifecycle };
45
+ export { n as animateLifecycle };
39
46
 
40
47
  //# sourceMappingURL=animateLifecycle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"animateLifecycle.js","names":["animateLifecycle","ms","opts","adapter","object","index","final","start","tweenPose","animator","id","current"],"sources":["../../../src/animation/wrappers/animateLifecycle.ts"],"sourcesContent":["import { tweenPose } from '../poseHelpers';\nimport type { PoseDescriptor } from 'interactions/actions/resize/geometry';\nimport type { SceneAdapter } from 'core/adapters/types';\nimport type { Animator, EasingSpec } from '../types';\n\n/** How nodes enter and leave. `enterFrom` derives the pose a new node starts\n * at, given where it belongs; `exitTo` derives the pose a departing node\n * animates to before it is actually removed. Omit either to leave that\n * transition instant. */\nexport interface LifecycleAnimation<TPose> {\n /** Pose to animate the new object FROM at insert. */\n enterFrom?: (final: TPose) => TPose;\n /** Pose to animate the existing object TO at remove. */\n exitTo?: (current: TPose) => TPose;\n ms?: number;\n easing?: EasingSpec;\n geometry?: PoseDescriptor<TPose>;\n}\n\n/** Wrap an adapter so inserts and removals animate — the scene-graph\n * equivalent of CSS enter/leave transitions. */\nexport function animateLifecycle<TNode extends { id: string; pose?: TPose }, TPose>(\n adapter: SceneAdapter<TNode, TPose>,\n animator: Animator,\n opts: LifecycleAnimation<TPose>,\n): SceneAdapter<TNode, TPose> {\n const ms = opts.ms ?? 200;\n\n return {\n ...adapter,\n insertNode(object: TNode, index?: number): void {\n adapter.insertNode(object, index);\n if (!opts.enterFrom) return;\n const final = adapter.getPose(object.id);\n const start = opts.enterFrom(final);\n adapter.setPose(object.id, start);\n tweenPose(animator, adapter as never, {\n id: object.id,\n to: final,\n ms,\n easing: opts.easing,\n geometry: opts.geometry,\n recordOp: false,\n });\n },\n removeNode(id: string): void {\n if (!opts.exitTo) {\n adapter.removeNode(id);\n return;\n }\n const current = adapter.getPose(id);\n tweenPose(animator, adapter as never, {\n id,\n to: opts.exitTo(current),\n ms,\n easing: opts.easing,\n geometry: opts.geometry,\n recordOp: false,\n onDone: () => adapter.removeNode(id),\n });\n },\n };\n}\n"],"mappings":";;AAqBA,SAAgBA,EACd,GACA,GACA,GAC4B;CAC5B,IAAMC,IAAKC,EAAK,MAAM;CAEtB,OAAO;EACL,GAAGC;EACH,WAAW,GAAe,GAAsB;GAE9C,IADAA,EAAQ,WAAWC,GAAQC,CAAK,GAC5B,CAACH,EAAK,WAAW;GACrB,IAAMI,IAAQH,EAAQ,QAAQC,EAAO,EAAE,GACjCG,IAAQL,EAAK,UAAUI,CAAK;GAElC,AADAH,EAAQ,QAAQC,EAAO,IAAIG,CAAK,GAChCC,EAAUC,GAAUN,GAAkB;IACpC,IAAIC,EAAO;IACX,IAAIE;IACJ;IACA,QAAQJ,EAAK;IACb,UAAUA,EAAK;IACf,UAAU;GACZ,CAAC;EACH;EACA,WAAW,GAAkB;GAC3B,IAAI,CAACA,EAAK,QAAQ;IAChB,EAAQ,WAAWQ,CAAE;IACrB;GACF;GACA,IAAMC,IAAUR,EAAQ,QAAQO,CAAE;GAClC,EAAUD,GAAUN,GAAkB;IACpC;IACA,IAAID,EAAK,OAAOS,CAAO;IACvB;IACA,QAAQT,EAAK;IACb,UAAUA,EAAK;IACf,UAAU;IACV,cAAcC,EAAQ,WAAWO,CAAE;GACrC,CAAC;EACH;CACF;AACF"}
1
+ {"version":3,"file":"animateLifecycle.js","names":["animateLifecycle","ms","opts","leaving","adapter","object","index","final","start","setPoseInstant","tweenPose","animator","id","unwatch","remove","current","handle","event"],"sources":["../../../src/animation/wrappers/animateLifecycle.ts"],"sourcesContent":["import { tweenPose } from '../poseHelpers';\nimport { setPoseInstant } from './instantPose';\nimport type { PoseDescriptor } from 'interactions/actions/resize/geometry';\nimport type { SceneAdapter } from 'core/adapters/types';\nimport type { Animator, EasingSpec } from '../types';\n\n/** How nodes enter and leave. `enterFrom` derives the pose a new node starts\n * at, given where it belongs; `exitTo` derives the pose a departing node\n * animates to before it is actually removed. Omit either to leave that\n * transition instant. */\nexport interface LifecycleAnimation<TPose> {\n /** Pose to animate the new object FROM at insert. */\n enterFrom?: (final: TPose) => TPose;\n /** Pose to animate the existing object TO at remove. */\n exitTo?: (current: TPose) => TPose;\n ms?: number;\n easing?: EasingSpec;\n geometry?: PoseDescriptor<TPose>;\n}\n\n/** Wrap an adapter so inserts and removals animate — the scene-graph\n * equivalent of CSS enter/leave transitions. */\nexport function animateLifecycle<TNode extends { id: string; pose?: TPose }, TPose>(\n adapter: SceneAdapter<TNode, TPose>,\n animator: Animator,\n opts: LifecycleAnimation<TPose>,\n): SceneAdapter<TNode, TPose> {\n const ms = opts.ms ?? 200;\n const leaving = new Set<string>();\n\n return {\n ...adapter,\n insertNode(object: TNode, index?: number): void {\n adapter.insertNode(object, index);\n if (!opts.enterFrom) return;\n const final = adapter.getPose(object.id);\n const start = opts.enterFrom(final);\n setPoseInstant(adapter, object.id, start);\n tweenPose(animator, adapter as never, {\n id: object.id,\n to: final,\n ms,\n easing: opts.easing,\n geometry: opts.geometry,\n recordOp: false,\n });\n },\n removeNode(id: string): void {\n if (!opts.exitTo) {\n adapter.removeNode(id);\n return;\n }\n if (leaving.has(id)) return;\n leaving.add(id);\n let unwatch = (): void => {};\n const remove = (): void => {\n if (!leaving.delete(id)) return;\n unwatch();\n adapter.removeNode(id);\n };\n const current = adapter.getPose(id);\n const handle = tweenPose(animator, adapter as never, {\n id,\n to: opts.exitTo(current),\n ms,\n easing: opts.easing,\n geometry: opts.geometry,\n recordOp: false,\n onDone: remove,\n });\n // A canceled tween never calls onDone, and the node still has to go.\n unwatch = animator.watch((event) => {\n if ((event.type === 'cancel' || event.type === 'interrupt') && event.animation.id === handle.id) remove();\n });\n },\n };\n}\n"],"mappings":";;;AAsBA,SAAgBA,EACd,GACA,GACA,GAC4B;CAC5B,IAAMC,IAAKC,EAAK,MAAM,KAChBC,oBAAU,IAAI,IAAY;CAEhC,OAAO;EACL,GAAGC;EACH,WAAW,GAAe,GAAsB;GAE9C,IADAA,EAAQ,WAAWC,GAAQC,CAAK,GAC5B,CAACJ,EAAK,WAAW;GACrB,IAAMK,IAAQH,EAAQ,QAAQC,EAAO,EAAE,GACjCG,IAAQN,EAAK,UAAUK,CAAK;GAElC,AADAE,EAAeL,GAASC,EAAO,IAAIG,CAAK,GACxCE,EAAUC,GAAUP,GAAkB;IACpC,IAAIC,EAAO;IACX,IAAIE;IACJ;IACA,QAAQL,EAAK;IACb,UAAUA,EAAK;IACf,UAAU;GACZ,CAAC;EACH;EACA,WAAW,GAAkB;GAC3B,IAAI,CAACA,EAAK,QAAQ;IAChB,EAAQ,WAAWU,CAAE;IACrB;GACF;GACA,IAAIT,EAAQ,IAAIS,CAAE,GAAG;GACrB,EAAQ,IAAIA,CAAE;GACd,IAAIC,UAAsB,CAAC,GACrBC,UAAqB;IACzB,AAAKX,EAAQ,OAAOS,CAAE,MACtBC,EAAQ,GACRT,EAAQ,WAAWQ,CAAE;GACvB,GACMG,IAAUX,EAAQ,QAAQQ,CAAE,GAC5BI,IAASN,EAAUC,GAAUP,GAAkB;IACnD;IACA,IAAIF,EAAK,OAAOa,CAAO;IACvB;IACA,QAAQb,EAAK;IACb,UAAUA,EAAK;IACf,UAAU;IACV,QAAQY;GACV,CAAC;GAED,IAAUH,EAAS,OAAO,MAAU;IAClC,CAAKM,EAAM,SAAS,YAAYA,EAAM,SAAS,gBAAgBA,EAAM,UAAU,OAAOD,EAAO,MAAIF,EAAO;GAC1G,CAAC;EACH;CACF;AACF"}
@@ -1,44 +1,46 @@
1
1
  import { springPose as e, tweenPose as t } from "../poseHelpers.js";
2
+ import { instantPoseWrite as n } from "./instantPose.js";
2
3
  //#region src/animation/wrappers/animateOnSetPose.ts
3
- function n(n, r, i = {}) {
4
- let a = i.ms ?? 200, o = (e, t, n) => i.shouldAnimate ? !i.shouldAnimate(e, t, n) : !!(i.skipDuringGesture && i.gestureScope?.has(e));
4
+ function r(r, i, a = {}) {
5
+ let o = a.ms ?? 200, s = (e, t, n) => a.shouldAnimate ? !a.shouldAnimate(e, t, n) : !!(a.skipDuringGesture && a.gestureScope?.has(e));
5
6
  return {
6
- ...n,
7
- setPose(s, c) {
8
- let l = n.getPose(s);
9
- if (o(s, l, c)) {
10
- n.setPose(s, c);
7
+ ...r,
8
+ ...n(r),
9
+ setPose(n, c) {
10
+ let l = r.getPose(n);
11
+ if (s(n, l, c)) {
12
+ r.setPose(n, c);
11
13
  return;
12
14
  }
13
- if (r.isTicking()) {
14
- n.setPose(s, c);
15
+ if (i.isTicking()) {
16
+ r.setPose(n, c);
15
17
  return;
16
18
  }
17
- if (r.isActive("pose:" + s)) {
18
- n.setPose(s, c);
19
+ if (i.isActive("pose:" + n)) {
20
+ i.cancelKey("pose:" + n), r.setPose(n, c);
19
21
  return;
20
22
  }
21
- i.spring ? e(r, n, {
22
- id: s,
23
+ a.spring ? e(i, r, {
24
+ id: n,
23
25
  to: c,
24
- preset: i.spring.preset,
25
- stiffness: i.spring.stiffness,
26
- damping: i.spring.damping,
27
- mass: i.spring.mass,
28
- geometry: i.geometry,
29
- opLabel: i.opLabel
30
- }) : t(r, n, {
31
- id: s,
26
+ preset: a.spring.preset,
27
+ stiffness: a.spring.stiffness,
28
+ damping: a.spring.damping,
29
+ mass: a.spring.mass,
30
+ geometry: a.geometry,
31
+ opLabel: a.opLabel
32
+ }) : t(i, r, {
33
+ id: n,
32
34
  to: c,
33
- ms: a,
34
- easing: i.easing,
35
- geometry: i.geometry,
36
- opLabel: i.opLabel
35
+ ms: o,
36
+ easing: a.easing,
37
+ geometry: a.geometry,
38
+ opLabel: a.opLabel
37
39
  });
38
40
  }
39
41
  };
40
42
  }
41
43
  //#endregion
42
- export { n as animateOnSetPose };
44
+ export { r as animateOnSetPose };
43
45
 
44
46
  //# sourceMappingURL=animateOnSetPose.js.map