@rafaelaugusto/jolt 0.1.0-beta.9 → 0.1.0-rc.2

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 (576) hide show
  1. package/README.md +167 -21
  2. package/dist/animate.d.ts +25 -4
  3. package/dist/animate.d.ts.map +1 -1
  4. package/dist/animate.js +67 -26
  5. package/dist/animate.js.map +1 -1
  6. package/dist/blur/index.d.ts +6 -0
  7. package/dist/blur/index.d.ts.map +1 -0
  8. package/dist/blur/index.js +196 -0
  9. package/dist/blur/index.js.map +1 -0
  10. package/dist/blur/native.d.ts +17 -0
  11. package/dist/blur/native.d.ts.map +1 -0
  12. package/dist/blur/native.js +44 -0
  13. package/dist/blur/native.js.map +1 -0
  14. package/dist/blur/types.d.ts +32 -0
  15. package/dist/blur/types.d.ts.map +1 -0
  16. package/dist/blur/types.js +2 -0
  17. package/dist/blur/types.js.map +1 -0
  18. package/dist/bottom-sheet/geometry.d.ts +18 -0
  19. package/dist/bottom-sheet/geometry.d.ts.map +1 -0
  20. package/dist/bottom-sheet/geometry.js +51 -0
  21. package/dist/bottom-sheet/geometry.js.map +1 -0
  22. package/dist/bottom-sheet/index.d.ts +56 -0
  23. package/dist/bottom-sheet/index.d.ts.map +1 -0
  24. package/dist/bottom-sheet/index.js +462 -0
  25. package/dist/bottom-sheet/index.js.map +1 -0
  26. package/dist/bottom-sheet/native.d.ts +11 -0
  27. package/dist/bottom-sheet/native.d.ts.map +1 -0
  28. package/dist/bottom-sheet/native.js +173 -0
  29. package/dist/bottom-sheet/native.js.map +1 -0
  30. package/dist/config.d.ts +9 -0
  31. package/dist/config.d.ts.map +1 -1
  32. package/dist/config.js +40 -1
  33. package/dist/config.js.map +1 -1
  34. package/dist/decay.d.ts +1 -0
  35. package/dist/decay.d.ts.map +1 -1
  36. package/dist/decay.js +7 -0
  37. package/dist/decay.js.map +1 -1
  38. package/dist/drag-physics.d.ts +6 -1
  39. package/dist/drag-physics.d.ts.map +1 -1
  40. package/dist/drag.d.ts +17 -3
  41. package/dist/drag.d.ts.map +1 -1
  42. package/dist/drag.js +34 -11
  43. package/dist/drag.js.map +1 -1
  44. package/dist/driver/android-gradient.d.ts +5 -0
  45. package/dist/driver/android-gradient.d.ts.map +1 -0
  46. package/dist/driver/android-gradient.js +99 -0
  47. package/dist/driver/android-gradient.js.map +1 -0
  48. package/dist/driver/android-particles.d.ts +6 -0
  49. package/dist/driver/android-particles.d.ts.map +1 -0
  50. package/dist/driver/android-particles.js +93 -0
  51. package/dist/driver/android-particles.js.map +1 -0
  52. package/dist/driver/android.d.ts.map +1 -1
  53. package/dist/driver/android.js +27 -1
  54. package/dist/driver/android.js.map +1 -1
  55. package/dist/driver/frame.d.ts +3 -0
  56. package/dist/driver/frame.d.ts.map +1 -0
  57. package/dist/driver/frame.js +7 -0
  58. package/dist/driver/frame.js.map +1 -0
  59. package/dist/driver/index.d.ts +4 -0
  60. package/dist/driver/index.d.ts.map +1 -1
  61. package/dist/driver/index.js.map +1 -1
  62. package/dist/driver/ios-gradient.d.ts +5 -0
  63. package/dist/driver/ios-gradient.d.ts.map +1 -0
  64. package/dist/driver/ios-gradient.js +131 -0
  65. package/dist/driver/ios-gradient.js.map +1 -0
  66. package/dist/driver/ios-scroll-delegate.d.ts +4 -0
  67. package/dist/driver/ios-scroll-delegate.d.ts.map +1 -0
  68. package/dist/driver/ios-scroll-delegate.js +26 -0
  69. package/dist/driver/ios-scroll-delegate.js.map +1 -0
  70. package/dist/driver/ios.d.ts.map +1 -1
  71. package/dist/driver/ios.js +9 -0
  72. package/dist/driver/ios.js.map +1 -1
  73. package/dist/easing.d.ts +3 -1
  74. package/dist/easing.d.ts.map +1 -1
  75. package/dist/easing.js +18 -1
  76. package/dist/easing.js.map +1 -1
  77. package/dist/engine.d.ts +31 -2
  78. package/dist/engine.d.ts.map +1 -1
  79. package/dist/engine.js +194 -42
  80. package/dist/engine.js.map +1 -1
  81. package/dist/gesture-native.d.ts +28 -0
  82. package/dist/gesture-native.d.ts.map +1 -0
  83. package/dist/gesture-native.js +61 -0
  84. package/dist/gesture-native.js.map +1 -0
  85. package/dist/gestures/index.d.ts +69 -0
  86. package/dist/gestures/index.d.ts.map +1 -0
  87. package/dist/gestures/index.js +262 -0
  88. package/dist/gestures/index.js.map +1 -0
  89. package/dist/glass/index.d.ts +55 -0
  90. package/dist/glass/index.d.ts.map +1 -0
  91. package/dist/glass/index.js +205 -0
  92. package/dist/glass/index.js.map +1 -0
  93. package/dist/gradient-binding.d.ts +38 -0
  94. package/dist/gradient-binding.d.ts.map +1 -0
  95. package/dist/gradient-binding.js +128 -0
  96. package/dist/gradient-binding.js.map +1 -0
  97. package/dist/gradient.d.ts +105 -0
  98. package/dist/gradient.d.ts.map +1 -0
  99. package/dist/gradient.js +514 -0
  100. package/dist/gradient.js.map +1 -0
  101. package/dist/gravity.d.ts +13 -0
  102. package/dist/gravity.d.ts.map +1 -0
  103. package/dist/gravity.js +84 -0
  104. package/dist/gravity.js.map +1 -0
  105. package/dist/haptics.d.ts.map +1 -1
  106. package/dist/haptics.js +101 -28
  107. package/dist/haptics.js.map +1 -1
  108. package/dist/image-effect.d.ts +1 -0
  109. package/dist/image-effect.d.ts.map +1 -1
  110. package/dist/image-effect.js +10 -2
  111. package/dist/image-effect.js.map +1 -1
  112. package/dist/index.d.ts +19 -7
  113. package/dist/index.d.ts.map +1 -1
  114. package/dist/index.js +10 -4
  115. package/dist/index.js.map +1 -1
  116. package/dist/inspector/index.d.ts +86 -0
  117. package/dist/inspector/index.d.ts.map +1 -0
  118. package/dist/inspector/index.js +419 -0
  119. package/dist/inspector/index.js.map +1 -0
  120. package/dist/inspector/plot.d.ts +4 -0
  121. package/dist/inspector/plot.d.ts.map +1 -0
  122. package/dist/inspector/plot.js +23 -0
  123. package/dist/inspector/plot.js.map +1 -0
  124. package/dist/inspector/probe.d.ts +19 -0
  125. package/dist/inspector/probe.d.ts.map +1 -0
  126. package/dist/inspector/probe.js +37 -0
  127. package/dist/inspector/probe.js.map +1 -0
  128. package/dist/inspector/tuning.d.ts +19 -0
  129. package/dist/inspector/tuning.d.ts.map +1 -0
  130. package/dist/inspector/tuning.js +37 -0
  131. package/dist/inspector/tuning.js.map +1 -0
  132. package/dist/interactive-navigation/index.d.ts +44 -0
  133. package/dist/interactive-navigation/index.d.ts.map +1 -0
  134. package/dist/interactive-navigation/index.js +350 -0
  135. package/dist/interactive-navigation/index.js.map +1 -0
  136. package/dist/keyboard.d.ts +24 -0
  137. package/dist/keyboard.d.ts.map +1 -1
  138. package/dist/keyboard.js +199 -6
  139. package/dist/keyboard.js.map +1 -1
  140. package/dist/live-spring-driver.d.ts +52 -0
  141. package/dist/live-spring-driver.d.ts.map +1 -0
  142. package/dist/live-spring-driver.js +104 -0
  143. package/dist/live-spring-driver.js.map +1 -0
  144. package/dist/mixer.d.ts +55 -0
  145. package/dist/mixer.d.ts.map +1 -0
  146. package/dist/mixer.js +286 -0
  147. package/dist/mixer.js.map +1 -0
  148. package/dist/motion-scope.d.ts +8 -2
  149. package/dist/motion-scope.d.ts.map +1 -1
  150. package/dist/motion-scope.js +24 -3
  151. package/dist/motion-scope.js.map +1 -1
  152. package/dist/motion-states.d.ts +19 -7
  153. package/dist/motion-states.d.ts.map +1 -1
  154. package/dist/motion-states.js +116 -26
  155. package/dist/motion-states.js.map +1 -1
  156. package/dist/motion-value.d.ts +227 -0
  157. package/dist/motion-value.d.ts.map +1 -0
  158. package/dist/motion-value.js +1074 -0
  159. package/dist/motion-value.js.map +1 -0
  160. package/dist/native/index.d.ts +10 -0
  161. package/dist/native/index.d.ts.map +1 -0
  162. package/dist/native/index.js +6 -0
  163. package/dist/native/index.js.map +1 -0
  164. package/dist/native-properties.d.ts +28 -0
  165. package/dist/native-properties.d.ts.map +1 -0
  166. package/dist/native-properties.js +154 -0
  167. package/dist/native-properties.js.map +1 -0
  168. package/dist/native-property-driver.d.ts +19 -0
  169. package/dist/native-property-driver.d.ts.map +1 -0
  170. package/dist/native-property-driver.js +69 -0
  171. package/dist/native-property-driver.js.map +1 -0
  172. package/dist/native-property.d.ts +37 -0
  173. package/dist/native-property.d.ts.map +1 -0
  174. package/dist/native-property.js +285 -0
  175. package/dist/native-property.js.map +1 -0
  176. package/dist/particles.d.ts +5 -2
  177. package/dist/particles.d.ts.map +1 -1
  178. package/dist/particles.js +16 -10
  179. package/dist/particles.js.map +1 -1
  180. package/dist/path.d.ts.map +1 -1
  181. package/dist/path.js +2 -2
  182. package/dist/path.js.map +1 -1
  183. package/dist/physics/index.d.ts +139 -0
  184. package/dist/physics/index.d.ts.map +1 -0
  185. package/dist/physics/index.js +316 -0
  186. package/dist/physics/index.js.map +1 -0
  187. package/dist/physics/native.d.ts +54 -0
  188. package/dist/physics/native.d.ts.map +1 -0
  189. package/dist/physics/native.js +64 -0
  190. package/dist/physics/native.js.map +1 -0
  191. package/dist/playback-group.d.ts.map +1 -1
  192. package/dist/playback-group.js +17 -1
  193. package/dist/playback-group.js.map +1 -1
  194. package/dist/playback.d.ts +15 -0
  195. package/dist/playback.d.ts.map +1 -1
  196. package/dist/playback.js +23 -0
  197. package/dist/playback.js.map +1 -1
  198. package/dist/predictive-back/index.d.ts +45 -0
  199. package/dist/predictive-back/index.d.ts.map +1 -0
  200. package/dist/predictive-back/index.js +220 -0
  201. package/dist/predictive-back/index.js.map +1 -0
  202. package/dist/predictive-back/presentation.d.ts +4 -0
  203. package/dist/predictive-back/presentation.d.ts.map +1 -0
  204. package/dist/predictive-back/presentation.js +3 -0
  205. package/dist/predictive-back/presentation.js.map +1 -0
  206. package/dist/press.d.ts.map +1 -1
  207. package/dist/press.js +11 -2
  208. package/dist/press.js.map +1 -1
  209. package/dist/reorder/handle.d.ts +6 -0
  210. package/dist/reorder/handle.d.ts.map +1 -0
  211. package/dist/reorder/handle.js +10 -0
  212. package/dist/reorder/handle.js.map +1 -0
  213. package/dist/reorder/index.d.ts +10 -0
  214. package/dist/reorder/index.d.ts.map +1 -0
  215. package/dist/reorder/index.js +233 -0
  216. package/dist/reorder/index.js.map +1 -0
  217. package/dist/reorder/list-view.d.ts +5 -0
  218. package/dist/reorder/list-view.d.ts.map +1 -0
  219. package/dist/reorder/list-view.js +238 -0
  220. package/dist/reorder/list-view.js.map +1 -0
  221. package/dist/reorder/model.d.ts +6 -0
  222. package/dist/reorder/model.d.ts.map +1 -0
  223. package/dist/reorder/model.js +30 -0
  224. package/dist/reorder/model.js.map +1 -0
  225. package/dist/reorder/surface.d.ts +6 -0
  226. package/dist/reorder/surface.d.ts.map +1 -0
  227. package/dist/reorder/surface.js +10 -0
  228. package/dist/reorder/surface.js.map +1 -0
  229. package/dist/reorder/types.d.ts +92 -0
  230. package/dist/reorder/types.d.ts.map +1 -0
  231. package/dist/reorder/types.js +2 -0
  232. package/dist/reorder/types.js.map +1 -0
  233. package/dist/sampling.d.ts +35 -0
  234. package/dist/sampling.d.ts.map +1 -0
  235. package/dist/sampling.js +123 -0
  236. package/dist/sampling.js.map +1 -0
  237. package/dist/scene-appearance.d.ts +14 -0
  238. package/dist/scene-appearance.d.ts.map +1 -0
  239. package/dist/scene-appearance.js +68 -0
  240. package/dist/scene-appearance.js.map +1 -0
  241. package/dist/scene-camera.d.ts +5 -0
  242. package/dist/scene-camera.d.ts.map +1 -0
  243. package/dist/scene-camera.js +23 -0
  244. package/dist/scene-camera.js.map +1 -0
  245. package/dist/scene-shader.d.ts +18 -0
  246. package/dist/scene-shader.d.ts.map +1 -0
  247. package/dist/scene-shader.js +76 -0
  248. package/dist/scene-shader.js.map +1 -0
  249. package/dist/scroll-header/geometry.d.ts +18 -0
  250. package/dist/scroll-header/geometry.d.ts.map +1 -0
  251. package/dist/scroll-header/geometry.js +46 -0
  252. package/dist/scroll-header/geometry.js.map +1 -0
  253. package/dist/scroll-header/index.d.ts +48 -0
  254. package/dist/scroll-header/index.d.ts.map +1 -0
  255. package/dist/scroll-header/index.js +399 -0
  256. package/dist/scroll-header/index.js.map +1 -0
  257. package/dist/scroll-header/native.d.ts +28 -0
  258. package/dist/scroll-header/native.d.ts.map +1 -0
  259. package/dist/scroll-header/native.js +43 -0
  260. package/dist/scroll-header/native.js.map +1 -0
  261. package/dist/sensors/index.d.ts +69 -0
  262. package/dist/sensors/index.d.ts.map +1 -0
  263. package/dist/sensors/index.js +149 -0
  264. package/dist/sensors/index.js.map +1 -0
  265. package/dist/sensors/native.d.ts +20 -0
  266. package/dist/sensors/native.d.ts.map +1 -0
  267. package/dist/sensors/native.js +48 -0
  268. package/dist/sensors/native.js.map +1 -0
  269. package/dist/sequence.d.ts +24 -0
  270. package/dist/sequence.d.ts.map +1 -1
  271. package/dist/sequence.js +181 -19
  272. package/dist/sequence.js.map +1 -1
  273. package/dist/shapes/android.d.ts +3 -0
  274. package/dist/shapes/android.d.ts.map +1 -0
  275. package/dist/shapes/android.js +51 -0
  276. package/dist/shapes/android.js.map +1 -0
  277. package/dist/shapes/index.d.ts +6 -0
  278. package/dist/shapes/index.d.ts.map +1 -0
  279. package/dist/shapes/index.js +238 -0
  280. package/dist/shapes/index.js.map +1 -0
  281. package/dist/shapes/ios.d.ts +3 -0
  282. package/dist/shapes/ios.d.ts.map +1 -0
  283. package/dist/shapes/ios.js +164 -0
  284. package/dist/shapes/ios.js.map +1 -0
  285. package/dist/shapes/native.d.ts +18 -0
  286. package/dist/shapes/native.d.ts.map +1 -0
  287. package/dist/shapes/native.js +10 -0
  288. package/dist/shapes/native.js.map +1 -0
  289. package/dist/shapes/path.d.ts +10 -0
  290. package/dist/shapes/path.d.ts.map +1 -0
  291. package/dist/shapes/path.js +106 -0
  292. package/dist/shapes/path.js.map +1 -0
  293. package/dist/shapes/types.d.ts +55 -0
  294. package/dist/shapes/types.d.ts.map +1 -0
  295. package/dist/shapes/types.js +11 -0
  296. package/dist/shapes/types.js.map +1 -0
  297. package/dist/shared-layout/index.d.ts +40 -0
  298. package/dist/shared-layout/index.d.ts.map +1 -0
  299. package/dist/shared-layout/index.js +267 -0
  300. package/dist/shared-layout/index.js.map +1 -0
  301. package/dist/shared-layout/native.d.ts +15 -0
  302. package/dist/shared-layout/native.d.ts.map +1 -0
  303. package/dist/shared-layout/native.js +79 -0
  304. package/dist/shared-layout/native.js.map +1 -0
  305. package/dist/shared-layout/timing.d.ts +9 -0
  306. package/dist/shared-layout/timing.d.ts.map +1 -0
  307. package/dist/shared-layout/timing.js +68 -0
  308. package/dist/shared-layout/timing.js.map +1 -0
  309. package/dist/shared-navigation/entry.d.ts +51 -0
  310. package/dist/shared-navigation/entry.d.ts.map +1 -0
  311. package/dist/shared-navigation/entry.js +619 -0
  312. package/dist/shared-navigation/entry.js.map +1 -0
  313. package/dist/shared-navigation/index.d.ts +58 -0
  314. package/dist/shared-navigation/index.d.ts.map +1 -0
  315. package/dist/shared-navigation/index.js +318 -0
  316. package/dist/shared-navigation/index.js.map +1 -0
  317. package/dist/shared-navigation/return-signal.d.ts +16 -0
  318. package/dist/shared-navigation/return-signal.d.ts.map +1 -0
  319. package/dist/shared-navigation/return-signal.js +35 -0
  320. package/dist/shared-navigation/return-signal.js.map +1 -0
  321. package/dist/shared-navigation/return-target.d.ts +32 -0
  322. package/dist/shared-navigation/return-target.d.ts.map +1 -0
  323. package/dist/shared-navigation/return-target.js +168 -0
  324. package/dist/shared-navigation/return-target.js.map +1 -0
  325. package/dist/shared-navigation/scope.d.ts +4 -0
  326. package/dist/shared-navigation/scope.d.ts.map +1 -0
  327. package/dist/shared-navigation/scope.js +2 -0
  328. package/dist/shared-navigation/scope.js.map +1 -0
  329. package/dist/shared-navigation/targets.d.ts +6 -0
  330. package/dist/shared-navigation/targets.d.ts.map +1 -0
  331. package/dist/shared-navigation/targets.js +36 -0
  332. package/dist/shared-navigation/targets.js.map +1 -0
  333. package/dist/size-layout.d.ts +19 -0
  334. package/dist/size-layout.d.ts.map +1 -0
  335. package/dist/size-layout.js +216 -0
  336. package/dist/size-layout.js.map +1 -0
  337. package/dist/size.d.ts +19 -0
  338. package/dist/size.d.ts.map +1 -0
  339. package/dist/size.js +251 -0
  340. package/dist/size.js.map +1 -0
  341. package/dist/spring.d.ts +2 -0
  342. package/dist/spring.d.ts.map +1 -1
  343. package/dist/spring.js +11 -0
  344. package/dist/spring.js.map +1 -1
  345. package/dist/svg-path.d.ts +18 -0
  346. package/dist/svg-path.d.ts.map +1 -1
  347. package/dist/svg-path.js +3 -2
  348. package/dist/svg-path.js.map +1 -1
  349. package/dist/testing/clock.d.ts +40 -0
  350. package/dist/testing/clock.d.ts.map +1 -0
  351. package/dist/testing/clock.js +116 -0
  352. package/dist/testing/clock.js.map +1 -0
  353. package/dist/testing/handoff-recorder.d.ts +8 -0
  354. package/dist/testing/handoff-recorder.d.ts.map +1 -0
  355. package/dist/testing/handoff-recorder.js +77 -0
  356. package/dist/testing/handoff-recorder.js.map +1 -0
  357. package/dist/testing/index.d.ts +5 -0
  358. package/dist/testing/index.d.ts.map +1 -0
  359. package/dist/testing/index.js +5 -0
  360. package/dist/testing/index.js.map +1 -0
  361. package/dist/testing/native.d.ts +46 -0
  362. package/dist/testing/native.d.ts.map +1 -0
  363. package/dist/testing/native.js +313 -0
  364. package/dist/testing/native.js.map +1 -0
  365. package/dist/testing/presentation.d.ts +11 -0
  366. package/dist/testing/presentation.d.ts.map +1 -0
  367. package/dist/testing/presentation.js +45 -0
  368. package/dist/testing/presentation.js.map +1 -0
  369. package/dist/testing/replay.d.ts +39 -0
  370. package/dist/testing/replay.d.ts.map +1 -0
  371. package/dist/testing/replay.js +99 -0
  372. package/dist/testing/replay.js.map +1 -0
  373. package/dist/testing/scroll-handoff-native.d.ts +10 -0
  374. package/dist/testing/scroll-handoff-native.d.ts.map +1 -0
  375. package/dist/testing/scroll-handoff-native.js +151 -0
  376. package/dist/testing/scroll-handoff-native.js.map +1 -0
  377. package/dist/testing/scroll-handoff.d.ts +25 -0
  378. package/dist/testing/scroll-handoff.d.ts.map +1 -0
  379. package/dist/testing/scroll-handoff.js +127 -0
  380. package/dist/testing/scroll-handoff.js.map +1 -0
  381. package/dist/testing/sensors.d.ts +13 -0
  382. package/dist/testing/sensors.d.ts.map +1 -0
  383. package/dist/testing/sensors.js +26 -0
  384. package/dist/testing/sensors.js.map +1 -0
  385. package/dist/testing/trace.d.ts +101 -0
  386. package/dist/testing/trace.d.ts.map +1 -0
  387. package/dist/testing/trace.js +263 -0
  388. package/dist/testing/trace.js.map +1 -0
  389. package/dist/timed-animation.d.ts +38 -0
  390. package/dist/timed-animation.d.ts.map +1 -0
  391. package/dist/timed-animation.js +177 -0
  392. package/dist/timed-animation.js.map +1 -0
  393. package/dist/track.d.ts +3 -0
  394. package/dist/track.d.ts.map +1 -1
  395. package/dist/track.js +281 -40
  396. package/dist/track.js.map +1 -1
  397. package/dist/transition.d.ts +54 -2
  398. package/dist/transition.d.ts.map +1 -1
  399. package/dist/transition.js +128 -8
  400. package/dist/transition.js.map +1 -1
  401. package/dist/types.d.ts +10 -1
  402. package/dist/types.d.ts.map +1 -1
  403. package/dist/value-observers.d.ts +22 -0
  404. package/dist/value-observers.d.ts.map +1 -0
  405. package/dist/value-observers.js +122 -0
  406. package/dist/value-observers.js.map +1 -0
  407. package/dist/value-track.d.ts +13 -0
  408. package/dist/value-track.d.ts.map +1 -0
  409. package/dist/value-track.js +59 -0
  410. package/dist/value-track.js.map +1 -0
  411. package/dist/vue/index.d.ts +33 -3
  412. package/dist/vue/index.d.ts.map +1 -1
  413. package/dist/vue/index.js +118 -3
  414. package/dist/vue/index.js.map +1 -1
  415. package/dist/zoomable.d.ts +1 -1
  416. package/dist/zoomable.d.ts.map +1 -1
  417. package/package.json +68 -3
  418. package/platforms/android/include.gradle +10 -0
  419. package/platforms/android/java/org/rafaelaugusto/jolt/BlurEffect.java +89 -0
  420. package/platforms/android/java/org/rafaelaugusto/jolt/CircleMath.java +158 -0
  421. package/platforms/android/java/org/rafaelaugusto/jolt/CircleWorld.java +221 -0
  422. package/platforms/android/java/org/rafaelaugusto/jolt/GestureSession.java +227 -0
  423. package/platforms/android/java/org/rafaelaugusto/jolt/GestureSurface.java +54 -0
  424. package/platforms/android/java/org/rafaelaugusto/jolt/GradientLayer.java +224 -0
  425. package/platforms/android/java/org/rafaelaugusto/jolt/KeyboardFrame.java +53 -0
  426. package/platforms/android/java/org/rafaelaugusto/jolt/KeyboardFrameFollower.java +57 -0
  427. package/platforms/android/java/org/rafaelaugusto/jolt/KeyboardObserver.java +97 -0
  428. package/platforms/android/java/org/rafaelaugusto/jolt/LiveSpring.java +277 -0
  429. package/platforms/android/java/org/rafaelaugusto/jolt/MotionProbe.java +70 -0
  430. package/platforms/android/java/org/rafaelaugusto/jolt/ParticleEmitter.java +192 -0
  431. package/platforms/android/java/org/rafaelaugusto/jolt/ParticleSimulation.java +114 -0
  432. package/platforms/android/java/org/rafaelaugusto/jolt/PredictiveBackSession.java +212 -0
  433. package/platforms/android/java/org/rafaelaugusto/jolt/ReorderHandle.java +25 -0
  434. package/platforms/android/java/org/rafaelaugusto/jolt/ReorderSession.java +213 -0
  435. package/platforms/android/java/org/rafaelaugusto/jolt/ReorderSurface.java +27 -0
  436. package/platforms/android/java/org/rafaelaugusto/jolt/ScrollHeader.java +84 -0
  437. package/platforms/android/java/org/rafaelaugusto/jolt/SensorMath.java +28 -0
  438. package/platforms/android/java/org/rafaelaugusto/jolt/SensorSource.java +217 -0
  439. package/platforms/android/java/org/rafaelaugusto/jolt/ShapeLayer.java +120 -0
  440. package/platforms/android/java/org/rafaelaugusto/jolt/SharedLayoutFlight.java +287 -0
  441. package/platforms/android/java/org/rafaelaugusto/jolt/SharedNavigationScene.java +115 -0
  442. package/platforms/android/java/org/rafaelaugusto/jolt/SpringState.java +39 -0
  443. package/platforms/android/proguard-rules.pro +20 -0
  444. package/platforms/ios/build.xcconfig +1 -1
  445. package/platforms/ios/src/JoltBlur.h +14 -0
  446. package/platforms/ios/src/JoltBlur.m +86 -0
  447. package/platforms/ios/src/JoltCircleMath.h +191 -0
  448. package/platforms/ios/src/JoltCircleWorld.h +18 -0
  449. package/platforms/ios/src/JoltCircleWorld.m +218 -0
  450. package/platforms/ios/src/JoltGestureSession.h +23 -0
  451. package/platforms/ios/src/JoltGestureSession.m +251 -0
  452. package/platforms/ios/src/JoltInteractiveNavigation.h +23 -0
  453. package/platforms/ios/src/JoltInteractiveNavigation.m +255 -0
  454. package/platforms/ios/src/JoltLiveSpring.h +29 -0
  455. package/platforms/ios/src/JoltLiveSpring.m +243 -0
  456. package/platforms/ios/src/JoltMotionProbe.h +9 -0
  457. package/platforms/ios/src/JoltMotionProbe.m +72 -0
  458. package/platforms/ios/src/JoltReorderSession.h +15 -0
  459. package/platforms/ios/src/JoltReorderSession.m +205 -0
  460. package/platforms/ios/src/JoltScrollHeader.h +13 -0
  461. package/platforms/ios/src/JoltScrollHeader.m +101 -0
  462. package/platforms/ios/src/JoltSensorMath.h +39 -0
  463. package/platforms/ios/src/JoltSensorSource.h +13 -0
  464. package/platforms/ios/src/JoltSensorSource.m +201 -0
  465. package/platforms/ios/src/JoltSharedLayoutFlight.h +19 -0
  466. package/platforms/ios/src/JoltSharedLayoutFlight.m +250 -0
  467. package/platforms/ios/src/JoltSpringState.h +35 -0
  468. package/platforms/ios/src/module.modulemap +10 -0
  469. package/src/android-plugin.d.ts +464 -0
  470. package/src/animate.ts +129 -15
  471. package/src/blur/index.ts +195 -0
  472. package/src/blur/native.ts +70 -0
  473. package/src/blur/types.ts +32 -0
  474. package/src/bottom-sheet/geometry.ts +84 -0
  475. package/src/bottom-sheet/index.ts +536 -0
  476. package/src/bottom-sheet/native.ts +214 -0
  477. package/src/config.ts +39 -1
  478. package/src/decay.ts +9 -0
  479. package/src/drag.ts +67 -21
  480. package/src/driver/android-gradient.ts +116 -0
  481. package/src/driver/android-particles.ts +118 -0
  482. package/src/driver/android.ts +31 -1
  483. package/src/driver/frame.ts +10 -0
  484. package/src/driver/index.ts +4 -0
  485. package/src/driver/ios-gradient.ts +136 -0
  486. package/src/driver/ios-scroll-delegate.ts +23 -0
  487. package/src/driver/ios.ts +10 -0
  488. package/src/easing.ts +21 -1
  489. package/src/engine.ts +209 -60
  490. package/src/gesture-native.ts +139 -0
  491. package/src/gestures/index.ts +365 -0
  492. package/src/glass/index.ts +218 -0
  493. package/src/gradient-binding.ts +158 -0
  494. package/src/gradient.ts +663 -0
  495. package/src/gravity.ts +107 -0
  496. package/src/haptics.ts +106 -28
  497. package/src/image-effect.ts +10 -2
  498. package/src/index.ts +56 -7
  499. package/src/inspector/index.ts +523 -0
  500. package/src/inspector/plot.ts +27 -0
  501. package/src/inspector/probe.ts +50 -0
  502. package/src/inspector/tuning.ts +51 -0
  503. package/src/interactive-navigation/index.ts +427 -0
  504. package/src/ios-plugin.d.ts +280 -0
  505. package/src/keyboard.ts +231 -7
  506. package/src/live-spring-driver.ts +181 -0
  507. package/src/mixer.ts +312 -0
  508. package/src/motion-scope.ts +39 -6
  509. package/src/motion-states.ts +149 -42
  510. package/src/motion-value.ts +1289 -0
  511. package/src/native/index.ts +30 -0
  512. package/src/native-properties.ts +188 -0
  513. package/src/native-property-driver.ts +123 -0
  514. package/src/native-property.ts +366 -0
  515. package/src/particles.ts +18 -17
  516. package/src/path.ts +2 -1
  517. package/src/physics/index.ts +476 -0
  518. package/src/physics/native.ts +121 -0
  519. package/src/playback-group.ts +17 -1
  520. package/src/playback.ts +41 -0
  521. package/src/predictive-back/index.ts +280 -0
  522. package/src/predictive-back/presentation.ts +6 -0
  523. package/src/press.ts +10 -2
  524. package/src/reorder/handle.ts +9 -0
  525. package/src/reorder/index.ts +243 -0
  526. package/src/reorder/list-view.ts +262 -0
  527. package/src/reorder/model.ts +47 -0
  528. package/src/reorder/surface.ts +10 -0
  529. package/src/reorder/types.ts +87 -0
  530. package/src/sampling.ts +173 -0
  531. package/src/scene-appearance.ts +92 -0
  532. package/src/scene-camera.ts +30 -0
  533. package/src/scene-shader.ts +139 -0
  534. package/src/scroll-header/geometry.ts +88 -0
  535. package/src/scroll-header/index.ts +530 -0
  536. package/src/scroll-header/native.ts +89 -0
  537. package/src/sensors/index.ts +246 -0
  538. package/src/sensors/native.ts +72 -0
  539. package/src/sequence.ts +209 -20
  540. package/src/shapes/android.ts +63 -0
  541. package/src/shapes/index.ts +267 -0
  542. package/src/shapes/ios.ts +194 -0
  543. package/src/shapes/native.ts +27 -0
  544. package/src/shapes/path.ts +127 -0
  545. package/src/shapes/types.ts +63 -0
  546. package/src/shared-layout/index.ts +343 -0
  547. package/src/shared-layout/native.ts +138 -0
  548. package/src/shared-layout/timing.ts +87 -0
  549. package/src/shared-navigation/entry.ts +695 -0
  550. package/src/shared-navigation/index.ts +414 -0
  551. package/src/shared-navigation/return-signal.ts +41 -0
  552. package/src/shared-navigation/return-target.ts +197 -0
  553. package/src/shared-navigation/scope.ts +3 -0
  554. package/src/shared-navigation/targets.ts +38 -0
  555. package/src/size-layout.ts +237 -0
  556. package/src/size.ts +302 -0
  557. package/src/spring.ts +18 -0
  558. package/src/svg-path.ts +8 -3
  559. package/src/testing/clock.ts +128 -0
  560. package/src/testing/handoff-recorder.ts +98 -0
  561. package/src/testing/index.ts +4 -0
  562. package/src/testing/native.ts +386 -0
  563. package/src/testing/presentation.ts +46 -0
  564. package/src/testing/replay.ts +149 -0
  565. package/src/testing/scroll-handoff-native.ts +201 -0
  566. package/src/testing/scroll-handoff.ts +140 -0
  567. package/src/testing/sensors.ts +41 -0
  568. package/src/testing/trace.ts +340 -0
  569. package/src/timed-animation.ts +192 -0
  570. package/src/track.ts +334 -38
  571. package/src/transition.ts +197 -9
  572. package/src/types.ts +11 -1
  573. package/src/value-observers.ts +147 -0
  574. package/src/value-track.ts +71 -0
  575. package/src/vue/index.ts +147 -1
  576. package/src/zoomable.ts +1 -1
package/src/mixer.ts ADDED
@@ -0,0 +1,312 @@
1
+ import type { View } from '@nativescript/core'
2
+ import { getDriver } from './driver/index.js'
3
+ import { readValue, writeValue, type Property } from './properties.js'
4
+ import type { Track } from './track.js'
5
+ import type { LiveInput } from './live-spring-driver.js'
6
+
7
+ /** The channel of regular animations; layers are named next to it. */
8
+ export const BASE = ''
9
+
10
+ const SAMPLES_PER_SECOND = 60
11
+ const MAX_SAMPLES = 6000
12
+ /** Endless channels loop natively over the least common multiple of their periods, up to this. */
13
+ const MAX_LOOP = 30000
14
+ /** Beyond it, the composition is played in windows and sampled again at each one. */
15
+ const WINDOW = 4000
16
+
17
+ export const multiplies = (property: Property) =>
18
+ property === 'opacity' || property === 'scaleX' || property === 'scaleY'
19
+ export const identity = (property: Property) => (multiplies(property) ? 1 : 0)
20
+ export const layerable = (property: Property) =>
21
+ multiplies(property) ||
22
+ property === 'x' ||
23
+ property === 'y' ||
24
+ property === 'rotate' ||
25
+ property === 'rotateX' ||
26
+ property === 'rotateY'
27
+
28
+ interface Channel {
29
+ track: Track
30
+ anchor: number
31
+ offset: number
32
+ paused: boolean
33
+ onEnd: (finished: boolean) => void
34
+ timer?: () => void
35
+ }
36
+
37
+ /** What the engine holds instead of a driver handle while a property is mixed. */
38
+ export class MixHandle {
39
+ constructor(
40
+ readonly mix: Mix,
41
+ readonly key: string,
42
+ ) {}
43
+ elapsed() {
44
+ return this.mix.elapsed(this.key)
45
+ }
46
+ control(position: number, paused: boolean) {
47
+ this.mix.control(this.key, position, paused)
48
+ }
49
+ }
50
+
51
+ const mixes = new WeakMap<View, Map<Property, Mix>>()
52
+
53
+ export function mixOf(view: View, property: Property): Mix | undefined {
54
+ return mixes.get(view)?.get(property)
55
+ }
56
+
57
+ export function mixesOf(view: View): Mix[] {
58
+ return [...(mixes.get(view)?.values() ?? [])]
59
+ }
60
+
61
+ export function mixFor(view: View, property: Property): Mix {
62
+ let properties = mixes.get(view)
63
+ if (!properties) mixes.set(view, (properties = new Map()))
64
+ let mix = properties.get(property)
65
+ if (!mix) properties.set(property, (mix = new Mix(view, property)))
66
+ return mix
67
+ }
68
+
69
+ /** One property of one view: a base and named layers, played natively as one composite track. */
70
+ export class Mix {
71
+ private live: { read(): number; layers(inputs: readonly LiveInput[]): void } | undefined
72
+ private readonly rests = new Map<string, number>()
73
+ private readonly channels = new Map<string, Channel>()
74
+ private native: unknown
75
+ private generation = 0
76
+
77
+ constructor(
78
+ readonly view: View,
79
+ readonly property: Property,
80
+ ) {
81
+ this.rests.set(BASE, readValue(view, property))
82
+ }
83
+
84
+ rest(key: string): number {
85
+ if (key === BASE && this.live) return this.live.read()
86
+ return (
87
+ this.rests.get(key) ??
88
+ (key === BASE ? readValue(this.view, this.property) : identity(this.property))
89
+ )
90
+ }
91
+
92
+ attachLive(base: {
93
+ read(): number
94
+ layers(inputs: readonly LiveInput[]): void
95
+ }): () => void {
96
+ this.live = base
97
+ this.compose()
98
+ return () => {
99
+ if (this.live !== base) return
100
+ this.rests.set(BASE, base.read())
101
+ this.live = undefined
102
+ this.compose()
103
+ }
104
+ }
105
+
106
+ setRest(key: string, value: number) {
107
+ this.rests.set(key, value)
108
+ this.compose()
109
+ }
110
+
111
+ adopt(
112
+ key: string,
113
+ track: Track,
114
+ startedAt: number,
115
+ onEnd: (finished: boolean) => void,
116
+ ) {
117
+ this.channels.get(key)?.timer?.()
118
+ const channel: Channel = { track, anchor: startedAt, offset: 0, paused: false, onEnd }
119
+ this.channels.set(key, channel)
120
+ this.schedule(key, channel)
121
+ this.compose()
122
+ return new MixHandle(this, key)
123
+ }
124
+
125
+ elapsed(key: string, now = getDriver().now()): number {
126
+ const channel = this.channels.get(key)
127
+ if (!channel) return 0
128
+ return channel.paused ? channel.offset : channel.offset + now - channel.anchor
129
+ }
130
+
131
+ control(key: string, position: number, paused: boolean) {
132
+ const channel = this.channels.get(key)
133
+ if (!channel) return
134
+ channel.timer?.()
135
+ channel.timer = undefined
136
+ channel.offset = position
137
+ channel.anchor = getDriver().now()
138
+ channel.paused = paused
139
+ if (!paused) this.schedule(key, channel)
140
+ this.compose()
141
+ }
142
+
143
+ /**
144
+ * A channel leaves: replaced, stopped or done. A stopped layer takes its contribution
145
+ * with it; anything else rests where it is.
146
+ */
147
+ detach(key: string, stopped: boolean) {
148
+ const channel = this.channels.get(key)
149
+ if (!channel) return
150
+ const value = channel.track.valueAt(this.elapsed(key))
151
+ channel.timer?.()
152
+ this.channels.delete(key)
153
+ this.rests.set(key, stopped && key !== BASE ? identity(this.property) : value)
154
+ this.compose()
155
+ }
156
+
157
+ /** Everything stops: what is on screen becomes the base, and layers are cleared. */
158
+ freeze() {
159
+ const value = this.value()
160
+ for (const [key, channel] of [...this.channels]) {
161
+ channel.timer?.()
162
+ this.channels.delete(key)
163
+ channel.onEnd(false)
164
+ }
165
+ this.rests.clear()
166
+ this.rests.set(BASE, value)
167
+ this.compose()
168
+ }
169
+
170
+ /** The composed value on screen at `time`. */
171
+ value(time = getDriver().now()): number {
172
+ const now = getDriver().now()
173
+ let result = this.part(BASE, time, now)
174
+ const keys = new Set([...this.rests.keys(), ...this.channels.keys()])
175
+ for (const key of keys) {
176
+ if (key === BASE) continue
177
+ const part = this.part(key, time, now)
178
+ result = multiplies(this.property) ? result * part : result + part
179
+ }
180
+ return result
181
+ }
182
+
183
+ private part(key: string, time: number, now: number) {
184
+ const channel = this.channels.get(key)
185
+ if (!channel) return this.rest(key)
186
+ const elapsed = channel.paused
187
+ ? channel.offset
188
+ : channel.offset + now - channel.anchor + (time - now)
189
+ return channel.track.valueAt(elapsed)
190
+ }
191
+
192
+ private schedule(key: string, channel: Channel) {
193
+ const remaining = channel.track.end - this.elapsed(key)
194
+ if (!Number.isFinite(remaining)) return
195
+ channel.timer = getDriver().after(Math.max(0, remaining), () => {
196
+ if (this.channels.get(key) !== channel) return
197
+ this.channels.delete(key)
198
+ this.rests.set(key, channel.track.valueAt(channel.track.end))
199
+ channel.onEnd(true)
200
+ this.compose()
201
+ })
202
+ }
203
+
204
+ /** Samples the composition from now and plays it as one native track. */
205
+ private compose() {
206
+ const driver = getDriver()
207
+ const now = driver.now()
208
+ const instance = ++this.generation
209
+ const previous = this.native
210
+ this.native = undefined
211
+
212
+ if (this.live) {
213
+ if (previous !== undefined) driver.stop(this.view, previous)
214
+ const layers: LiveInput[] = []
215
+ for (const key of new Set([...this.rests.keys(), ...this.channels.keys()])) {
216
+ if (key === BASE) continue
217
+ const channel = this.channels.get(key)
218
+ const value = this.part(key, now, now)
219
+ const track = channel?.track
220
+ layers.push({
221
+ value,
222
+ running: !!channel && !channel.paused,
223
+ elapsed: this.elapsed(key, now),
224
+ duration: track?.duration ?? 0,
225
+ delay: track?.delay ?? 0,
226
+ repeat: track ? (Number.isFinite(track.repeat) ? track.repeat : -1) : 0,
227
+ reverse: track?.reverse ?? false,
228
+ to: track?.to ?? value,
229
+ times: track?.times ?? [],
230
+ values: track?.values ?? [],
231
+ })
232
+ }
233
+ this.live.layers(layers)
234
+ return
235
+ }
236
+
237
+ let finite = 0
238
+ const periods: number[] = []
239
+ for (const [key, channel] of this.channels) {
240
+ if (channel.paused) continue
241
+ const elapsed = this.elapsed(key, now)
242
+ const { track } = channel
243
+ if (Number.isFinite(track.end)) finite = Math.max(finite, track.end - elapsed)
244
+ else if (elapsed < track.delay) finite = Math.max(finite, track.delay - elapsed)
245
+ else periods.push(Math.max(1, Math.round(track.duration * (track.reverse ? 2 : 1))))
246
+ }
247
+
248
+ if (previous !== undefined) driver.stop(this.view, previous)
249
+ const loop = finite <= 0 && periods.length ? leastCommonMultiple(periods) : undefined
250
+ if (finite <= 0 && !periods.length) {
251
+ writeValue(this.view, this.property, this.value(now))
252
+ driver.sync?.(this.view)
253
+ this.dissolve()
254
+ return
255
+ }
256
+
257
+ const span = finite > 0 ? finite : (loop ?? WINDOW)
258
+ const steps = Math.max(
259
+ 1,
260
+ Math.min(MAX_SAMPLES, Math.ceil((span / 1000) * SAMPLES_PER_SECOND)),
261
+ )
262
+ const times = Array.from({ length: steps + 1 }, (_, i) => i / steps)
263
+ const values = times.map((time) => this.value(now + time * span))
264
+ const endless = loop !== undefined
265
+ const at = (elapsed: number) =>
266
+ this.value(now + (endless ? elapsed % span : Math.min(Math.max(elapsed, 0), span)))
267
+ const track: Track = {
268
+ property: this.property,
269
+ delay: 0,
270
+ duration: span,
271
+ repeat: endless ? Infinity : 0,
272
+ reverse: false,
273
+ times,
274
+ values,
275
+ to: endless ? values[0]! : values[steps]!,
276
+ end: endless ? Infinity : span,
277
+ arrival: endless ? Infinity : span,
278
+ valueAt: at,
279
+ velocityAt: (elapsed) => (at(elapsed + 0.5) - at(elapsed - 0.5)) * 1000,
280
+ }
281
+ writeValue(this.view, this.property, track.to)
282
+ const native = driver.play(this.view, track, now, (finished = true) => {
283
+ if (instance !== this.generation || !finished) return
284
+ this.native = undefined
285
+ this.compose()
286
+ })
287
+ if (instance !== this.generation) return
288
+ this.native = native
289
+ // Building native keyframes can take time. Join the current composition
290
+ // phase after construction, including when a rolling window is replaced.
291
+ const elapsed = driver.now() - now
292
+ if (elapsed > 1) driver.control?.(this.view, native, elapsed, false)
293
+ }
294
+
295
+ private dissolve() {
296
+ if (this.live || this.channels.size) return
297
+ for (const [key, value] of this.rests)
298
+ if (key !== BASE && value !== identity(this.property)) return
299
+ const properties = mixes.get(this.view)
300
+ if (properties?.get(this.property) === this) properties.delete(this.property)
301
+ }
302
+ }
303
+
304
+ function leastCommonMultiple(periods: readonly number[]): number | undefined {
305
+ const gcd = (a: number, b: number): number => (b ? gcd(b, a % b) : a)
306
+ let result = periods[0]!
307
+ for (const period of periods.slice(1)) {
308
+ result = (result / gcd(result, period)) * period
309
+ if (result > MAX_LOOP) return undefined
310
+ }
311
+ return result
312
+ }
@@ -1,9 +1,11 @@
1
1
  import { animate, decay } from './animate.js'
2
2
  import { press } from './press.js'
3
3
  import { drag } from './drag.js'
4
+ import { gradient } from './gradient.js'
4
5
  import { animateLayout, type LayoutOptions } from './layout.js'
6
+ import { animateSize, type SizeDimensions, type SizeOptions } from './size.js'
5
7
  import type { SpringName } from './transition.js'
6
- import { sequence } from './sequence.js'
8
+ import { sequence, timeline } from './sequence.js'
7
9
  import {
8
10
  motionStates,
9
11
  type MotionState,
@@ -34,19 +36,23 @@ export interface MotionScope {
34
36
  /** Owned handles/subscriptions, including suspended subscription factories. */
35
37
  readonly size: number
36
38
  animateLayout: typeof animateLayout
39
+ animateSize: typeof animateSize
37
40
  animate: typeof animate
38
41
  decay: typeof decay
39
42
  sequence: typeof sequence
43
+ timeline: typeof timeline
40
44
  press: typeof press
41
45
  drag: typeof drag
46
+ /** Removed with the scope; suspension holds bindings until resume and stops concrete playback. */
47
+ gradient: typeof gradient
42
48
  states<
43
- T extends Record<string, Target>,
49
+ T extends Record<string, Target | null>,
44
50
  const S extends Record<string, MotionState<keyof T>>,
45
51
  >(
46
52
  targets: T,
47
53
  definitions: MotionDefinitions<T, S>,
48
- options?: Omit<MotionStatesOptions, 'scope'>,
49
- ): MotionStates<Extract<keyof S, string>>
54
+ options?: Omit<MotionStatesOptions<Extract<keyof T, string>>, 'scope'>,
55
+ ): MotionStates<Extract<keyof S, string>, Extract<keyof T, string>>
50
56
  /** Adopt an existing handle. Completed animations are released automatically. */
51
57
  add<T extends MotionResource>(resource: T): T
52
58
  /** Attach a subscription, detach on suspension, and recreate on resume. */
@@ -189,12 +195,26 @@ export function motionScope(): MotionScope {
189
195
  : animateLayout(container, changeOrOptions),
190
196
  )
191
197
  },
192
- animate(...args) {
193
- return startOwned(() => animate(...args))
198
+ animate: ((...args: Parameters<typeof animate>) =>
199
+ startOwned(() => animate(...args))) as typeof animate,
200
+ animateSize(
201
+ target: Target,
202
+ dimensions: SizeDimensions,
203
+ changeOrOptions?: (() => void) | SizeOptions | SpringName,
204
+ options?: SizeOptions | SpringName,
205
+ ) {
206
+ return startOwned(() =>
207
+ typeof changeOrOptions === 'function'
208
+ ? animateSize(target, dimensions, changeOrOptions, options)
209
+ : animateSize(target, dimensions, changeOrOptions),
210
+ )
194
211
  },
195
212
  decay(...args) {
196
213
  return startOwned(() => decay(...args))
197
214
  },
215
+ timeline(...args) {
216
+ return startOwned(() => timeline(...args))
217
+ },
198
218
  sequence(...args) {
199
219
  return startOwned(() => sequence(...args))
200
220
  },
@@ -204,6 +224,19 @@ export function motionScope(): MotionScope {
204
224
  drag(...args) {
205
225
  return startOwned(() => drag(...args))
206
226
  },
227
+ gradient(target, options) {
228
+ assertActive()
229
+ const made = gradient(target, options)
230
+ scope.add({
231
+ get paused() {
232
+ return made.suspended
233
+ },
234
+ pause: () => made.suspend(),
235
+ play: () => made.resume(),
236
+ dispose: () => made.remove(),
237
+ })
238
+ return made
239
+ },
207
240
  states(targets, definitions, options) {
208
241
  return startOwned(() => motionStates(targets, definitions, options))
209
242
  },
@@ -1,10 +1,12 @@
1
- import { prepareAnimation, toView } from './animate.js'
1
+ import { endingValues, prepareAnimation, set, toView } from './animate.js'
2
2
  import { isColorProperty, type ColorValue } from './color.js'
3
3
  import { isProperty } from './properties.js'
4
4
  import type { Animation } from './engine.js'
5
5
  import type { PlaybackAnimation } from './playback.js'
6
- import type { KeyframeProperty, Keyframes, Target } from './types.js'
7
- import type { Spring, Tween, SpringName } from './transition.js'
6
+ import type { KeyframeProperty, Keyframes, Target, Values } from './types.js'
7
+ import type { View } from '@nativescript/core'
8
+ import { mergeTransitions, springs } from './transition.js'
9
+ import type { Gravity, Spring, Tween, SpringName } from './transition.js'
8
10
  import type { MotionScope } from './motion-scope.js'
9
11
 
10
12
  /** Absolute endpoints only; keyframe arrays, paths and relative offsets are not states. */
@@ -20,21 +22,34 @@ export type MotionDefinitions<T, S> = S & {
20
22
  [K in keyof S[N]]: Record<Exclude<keyof S[N][K], KeyframeProperty>, never>
21
23
  }
22
24
  }
23
- export type StateTransition =
25
+ type StateCurve =
24
26
  | SpringName
25
27
  | Omit<Spring, 'repeat' | 'repeatType'>
26
28
  | Omit<Tween, 'repeat' | 'repeatType'>
27
- export interface MotionStatesOptions {
28
- transition?: StateTransition
29
+ | Omit<Gravity, 'repeat' | 'repeatType'>
30
+ /** One transition for every target, or a main one with some targets set apart by name. */
31
+ export type StateTransition<T extends string = string> =
32
+ | StateCurve
33
+ | (Exclude<StateCurve, SpringName> &
34
+ (string extends T ? unknown : { [K in T]?: StateCurve }))
35
+ export interface MotionStatesOptions<T extends string = string> {
36
+ transition?: StateTransition<T>
29
37
  scope?: MotionScope
30
38
  }
31
- export interface MotionStates<S extends string = string> {
39
+ export interface MotionStates<S extends string = string, T extends string = string> {
32
40
  /** Latest requested state, not a claim that playback has finished. */
33
41
  readonly current: S | undefined
34
42
  readonly settled: S | undefined
35
43
  readonly disposed: boolean
36
44
  readonly paused: boolean
37
- to(state: S, transition?: StateTransition): Animation
45
+ to(state: S, transition?: StateTransition<T>): Animation
46
+ /**
47
+ * Point a target at a new view, or at none with `null`. The new view takes the current
48
+ * state at once, or joins the transition in progress from where it is.
49
+ */
50
+ attach(target: T, view: Target | null): void
51
+ /** A stable callback for a template ref: attaches the element and detaches it on unmount. */
52
+ ref(target: T): (view: Target | null) => void
38
53
  pause(): void
39
54
  play(): void
40
55
  stop(): void
@@ -43,28 +58,38 @@ export interface MotionStates<S extends string = string> {
43
58
 
44
59
  /** Coordinated named targets. Omitted properties freeze when leaving their previous state. */
45
60
  export function motionStates<
46
- T extends Record<string, Target>,
61
+ T extends Record<string, Target | null>,
47
62
  const S extends Record<string, MotionState<keyof T>>,
48
63
  >(
49
64
  targets: T,
50
65
  definitions: MotionDefinitions<T, S>,
51
- options: MotionStatesOptions = {},
52
- ): MotionStates<Extract<keyof S, string>> {
66
+ options: MotionStatesOptions<Extract<keyof T, string>> = {},
67
+ ): MotionStates<Extract<keyof S, string>, Extract<keyof T, string>> {
53
68
  type Name = Extract<keyof S, string>
54
- const views = new Map(
55
- Object.entries(targets).map(([name, target]) => [name, toView(target)]),
69
+ type Slot = Extract<keyof T, string>
70
+ const views = new Map<string, View | null>(
71
+ Object.entries(targets).map(([name, target]) => [
72
+ name,
73
+ target === null ? null : toView(target),
74
+ ]),
56
75
  )
57
- if (new Set(views.values()).size !== views.size)
76
+ const assigned = [...views.values()].filter(Boolean)
77
+ if (new Set(assigned).size !== assigned.length)
58
78
  throw new TypeError('Motion state targets must refer to distinct views.')
59
- const states = new Map<string, [Target, Keyframes][]>()
60
- const defaults = normalize(options.transition)
79
+ for (const name of views.keys())
80
+ if (curveKeys.has(name))
81
+ throw new TypeError(
82
+ `A motion target can't be named "${name}", like a transition option.`,
83
+ )
84
+ const states = new Map<string, [string, Keyframes][]>()
85
+ const defaults = normalize(options.transition, views)
61
86
  for (const [name, state] of Object.entries(definitions)) {
62
87
  if (!state || typeof state !== 'object' || Array.isArray(state))
63
88
  throw new TypeError(`Invalid motion state "${name}".`)
64
- const rows: [Target, Keyframes][] = []
89
+ const rows: [string, Keyframes][] = []
65
90
  for (const [target, values] of Object.entries(state)) {
91
+ if (!views.has(target)) throw new TypeError(`Unknown motion target "${target}".`)
66
92
  const view = views.get(target)
67
- if (!view) throw new TypeError(`Unknown motion target "${target}".`)
68
93
  if (!values || typeof values !== 'object' || Array.isArray(values))
69
94
  throw new TypeError(`Invalid motion values for "${target}".`)
70
95
  const frames: Keyframes = {}
@@ -82,8 +107,9 @@ export function motionStates<
82
107
  Object.assign(frames, { [property]: value })
83
108
  }
84
109
  // Validate every definition up front without claiming any native property.
85
- prepareAnimation(view, frames, defaults)
86
- rows.push([view, frames])
110
+ if (view) prepareAnimation(view, frames, timingFor(defaults, target))
111
+ else endingValues(frames, timingFor(defaults, target))
112
+ rows.push([target, frames])
87
113
  }
88
114
  states.set(name, rows)
89
115
  }
@@ -91,8 +117,14 @@ export function motionStates<
91
117
  let settled: Name | undefined
92
118
  let disposed = false
93
119
  let paused = false
94
- let active: { handle: Animation; children: PlaybackAnimation[] } | undefined
95
- const controller: MotionStates<Name> = {
120
+ let active:
121
+ { handle: Animation; children: PlaybackAnimation[]; timing: Timing } | undefined
122
+ const refs = new Map<string, (view: Target | null) => void>()
123
+ const framesFor = (state: Name | undefined, target: string) =>
124
+ state === undefined
125
+ ? undefined
126
+ : states.get(state)!.find(([slot]) => slot === target)?.[1]
127
+ const controller: MotionStates<Name, Slot> = {
96
128
  get current() {
97
129
  return current
98
130
  },
@@ -109,10 +141,11 @@ export function motionStates<
109
141
  if (disposed) throw new Error('Motion states controller is disposed.')
110
142
  const rows = states.get(name)
111
143
  if (!rows) throw new TypeError(`Unknown motion state "${name}".`)
112
- const timing = transition === undefined ? defaults : normalize(transition)
113
- const prepared = rows.map(([view, frames]) =>
114
- prepareAnimation(view, frames, timing),
115
- )
144
+ const timing = normalize(transition, views, defaults)
145
+ const prepared = rows.flatMap(([target, frames]) => {
146
+ const view = views.get(target)
147
+ return view ? [prepareAnimation(view, frames, timingFor(timing, target))] : []
148
+ })
116
149
  const previous = active
117
150
  const children: PlaybackAnimation[] = []
118
151
  // Start replacements first: the engine transfers visible position AND velocity.
@@ -148,12 +181,45 @@ export function motionStates<
148
181
  },
149
182
  then: (resolve, reject) => finished.then(resolve, reject),
150
183
  }
151
- active = { handle, children }
184
+ active = { handle, children, timing }
152
185
  current = name
153
186
  // Also cancels old, omitted properties, without touching the new owners.
154
187
  previous?.handle.stop()
155
188
  return handle
156
189
  },
190
+ attach(target, next) {
191
+ if (disposed) throw new Error('Motion states controller is disposed.')
192
+ if (!views.has(target)) throw new TypeError(`Unknown motion target "${target}".`)
193
+ const view = next === null ? null : toView(next)
194
+ if (views.get(target) === view) return
195
+ if (view)
196
+ for (const [other, assignedView] of views)
197
+ if (other !== target && assignedView === view)
198
+ throw new TypeError('Motion state targets must refer to distinct views.')
199
+ if (view)
200
+ for (const [, rows] of states)
201
+ for (const [slot, frames] of rows)
202
+ if (slot === target)
203
+ prepareAnimation(view, frames, timingFor(defaults, target))
204
+ views.set(target, view)
205
+ const frames = view ? framesFor(current, target) : undefined
206
+ if (!view || !frames) return
207
+ if (active) {
208
+ const child = prepareAnimation(view, frames, timingFor(active.timing, target))()
209
+ active.children.push(child)
210
+ if (paused) child.pause()
211
+ } else set(view, frames as Values)
212
+ },
213
+ ref(target) {
214
+ let callback = refs.get(target)
215
+ if (!callback) {
216
+ callback = (view) => {
217
+ if (!disposed) controller.attach(target, view)
218
+ }
219
+ refs.set(target, callback)
220
+ }
221
+ return callback
222
+ },
157
223
  pause() {
158
224
  if (disposed || paused) return
159
225
  paused = true
@@ -177,8 +243,61 @@ export function motionStates<
177
243
  return options.scope ? options.scope.add(controller) : controller
178
244
  }
179
245
 
180
- function normalize(transition: StateTransition | undefined): StateTransition {
181
- if (transition === undefined) return 'snappy'
246
+ const curveKeys = new Set([
247
+ 'type',
248
+ 'delay',
249
+ 'duration',
250
+ 'ease',
251
+ 'times',
252
+ 'stiffness',
253
+ 'damping',
254
+ 'mass',
255
+ 'bounce',
256
+ 'velocity',
257
+ 'acceleration',
258
+ 'restitution',
259
+ ])
260
+
261
+ type Curve = Exclude<StateCurve, SpringName>
262
+ interface Timing {
263
+ readonly main: StateCurve
264
+ readonly targets: ReadonlyMap<string, StateCurve>
265
+ }
266
+
267
+ /** The transition one target plays: its own merged over the main one, or the main one. */
268
+ function timingFor(timing: Timing, target: string): StateCurve {
269
+ const own = timing.targets.get(target)
270
+ if (own === undefined) return timing.main
271
+ const main = typeof timing.main === 'string' ? springs[timing.main] : timing.main
272
+ return mergeTransitions(main, typeof own === 'string' ? springs[own] : own) as Curve
273
+ }
274
+
275
+ const snappy: Timing = { main: 'snappy', targets: new Map() }
276
+
277
+ /** A transition that only names targets keeps the fallback for everything else. */
278
+ function normalize(
279
+ transition: StateTransition | undefined,
280
+ targets: ReadonlyMap<string, unknown>,
281
+ fallback = snappy,
282
+ ): Timing {
283
+ if (transition === undefined) return fallback
284
+ if (typeof transition === 'string')
285
+ return { main: curve(transition), targets: new Map() }
286
+ if (!transition || typeof transition !== 'object')
287
+ throw new TypeError('Invalid state transition.')
288
+ const main: Record<string, unknown> = {}
289
+ const own = new Map<string, StateCurve>()
290
+ for (const [key, value] of Object.entries(transition)) {
291
+ if (targets.has(key)) {
292
+ if (value !== undefined) own.set(key, curve(value as StateCurve))
293
+ } else main[key] = value
294
+ }
295
+ if (own.size && !Object.keys(main).length)
296
+ return { main: fallback.main, targets: new Map([...fallback.targets, ...own]) }
297
+ return { main: curve(main as Curve), targets: own }
298
+ }
299
+
300
+ function curve(transition: StateCurve): StateCurve {
182
301
  if (typeof transition === 'string') {
183
302
  if (!['smooth', 'snappy', 'bouncy'].includes(transition))
184
303
  throw new TypeError('Unknown state spring.')
@@ -186,20 +305,8 @@ function normalize(transition: StateTransition | undefined): StateTransition {
186
305
  }
187
306
  if (!transition || typeof transition !== 'object')
188
307
  throw new TypeError('Invalid state transition.')
189
- const allowed = new Set([
190
- 'type',
191
- 'delay',
192
- 'duration',
193
- 'ease',
194
- 'times',
195
- 'stiffness',
196
- 'damping',
197
- 'mass',
198
- 'bounce',
199
- 'velocity',
200
- ])
201
308
  for (const key of Object.keys(transition))
202
- if (!allowed.has(key))
309
+ if (!curveKeys.has(key))
203
310
  throw new TypeError(`State transitions do not support "${key}".`)
204
311
  if (
205
312
  transition.duration !== undefined &&