@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
@@ -0,0 +1,663 @@
1
+ import { Application, Trace, isAndroid, isIOS, type View } from '@nativescript/core'
2
+ import { toView } from './animate.js'
3
+ import { colorMixer, parseColor, type ColorValue } from './color.js'
4
+ import { reducedMotion } from './config.js'
5
+ import { getDriver } from './driver/index.js'
6
+ import { androidGradient } from './driver/android-gradient.js'
7
+ import { iosGradient } from './driver/ios-gradient.js'
8
+ import type { Animation } from './engine.js'
9
+ import { createTrack, type Track } from './track.js'
10
+ import {
11
+ resolveTransition,
12
+ springs,
13
+ type SpringName,
14
+ type Transition,
15
+ } from './transition.js'
16
+ import type { Target } from './types.js'
17
+ import { createClock, type PlaybackClock } from './playback.js'
18
+ import {
19
+ cloneFrame,
20
+ gradientPatch,
21
+ gradientProgram,
22
+ put,
23
+ take,
24
+ type GradientBindings,
25
+ type GradientComponent,
26
+ type GradientPatch,
27
+ type GradientSource,
28
+ } from './gradient-binding.js'
29
+ export type { GradientBindings } from './gradient-binding.js'
30
+
31
+ export type GradientType = 'linear' | 'radial' | 'conic'
32
+
33
+ export interface GradientValues {
34
+ /** Two to eight colors. Animating keeps the count. */
35
+ colors?: readonly ColorValue[]
36
+ /** Where each color sits, from 0 to 1. Evenly spaced by default. */
37
+ stops?: readonly number[]
38
+ /** Degrees, like CSS: `linear` points this way (180 runs top to bottom), `conic` starts here (0 is up). */
39
+ angle?: number
40
+ /** `radial` and `conic`: the center, in fractions of the view's width and height. */
41
+ center?: { readonly x: number; readonly y: number }
42
+ /** `radial`: the radius, in fractions of the view's shorter side. */
43
+ radius?: number
44
+ }
45
+
46
+ export interface GradientOptions extends GradientBindings {
47
+ type: GradientType
48
+ colors: NonNullable<GradientBindings['colors']>
49
+ }
50
+
51
+ export interface Gradient {
52
+ readonly type: GradientType
53
+ /** Animates to new values from the ones on screen. Colors and stops keep their count. */
54
+ animate(values: GradientValues, transition?: Transition | SpringName): Animation
55
+ /** Applies values at once, stopping the animation in progress. */
56
+ set(values: GradientValues): void
57
+ /** Holds the current frame and detaches all gradient bindings; sources keep running. */
58
+ stop(): void
59
+ /** Attach mixed static/value components. Cleanup holds their current values; newer owners survive. */
60
+ bind(values: GradientBindings): () => void
61
+ /** Whether this gradient is explicitly suspended (independent of app/view lifecycle). */
62
+ readonly suspended: boolean
63
+ /** Hold and detach source subscriptions until resume; source playback is not paused. */
64
+ suspend(): void
65
+ /** Catch up to current source positions and reattach once. */
66
+ resume(): void
67
+ /** Takes the gradient off the view. */
68
+ remove(): void
69
+ }
70
+
71
+ /** Everything the platform needs to paint one frame. */
72
+ export interface GradientFrame {
73
+ colors: number[]
74
+ stops: number[]
75
+ angle: number
76
+ x: number
77
+ y: number
78
+ radius: number
79
+ }
80
+
81
+ export interface GradientTiming {
82
+ duration: number
83
+ delay: number
84
+ repeat: number
85
+ reverse: boolean
86
+ }
87
+
88
+ export interface GradientPainter {
89
+ paint(frame: GradientFrame): void
90
+ /** Plays sampled frames natively; `onEnd(false)` when cancelled. */
91
+ play(
92
+ frames: readonly GradientFrame[],
93
+ times: readonly number[],
94
+ timing: GradientTiming,
95
+ onEnd: (finished: boolean) => void,
96
+ ): { cancel(): void; control?(elapsed: number, paused: boolean): void }
97
+ remove(): void
98
+ }
99
+
100
+ type PainterFactory = (view: View, type: GradientType) => GradientPainter | undefined
101
+
102
+ let factory: PainterFactory | undefined
103
+
104
+ /** Test seam, like `setDriver`. */
105
+ export function setGradientPainter(next: PainterFactory | undefined) {
106
+ factory = next
107
+ }
108
+
109
+ function platformPainter(view: View, type: GradientType) {
110
+ if (isIOS) return iosGradient(view, type)
111
+ if (isAndroid) return androidGradient(view, type)
112
+ return undefined
113
+ }
114
+
115
+ const types: readonly GradientType[] = ['linear', 'radial', 'conic']
116
+
117
+ /**
118
+ * Paints a native gradient behind a layout's children and animates it.
119
+ *
120
+ * ```ts
121
+ * const glow = gradient(halo, { type: 'radial', colors: ['#FF0080', '#7928CA00'], radius: 0.8 })
122
+ * glow.animate({ center: { x: 0.8, y: 0.2 }, radius: 1.2 }, { duration: 2000 })
123
+ * ```
124
+ */
125
+ export function gradient(target: Target, options: GradientOptions): Gradient {
126
+ const view = toView(target)
127
+ const { frame, patch } = prepareGradient(options)
128
+ return new GradientController(view, options.type, frame, patch)
129
+ }
130
+
131
+ /** Validate declarative replacements before removing their current native layer. */
132
+ export function prepareGradient(options: GradientOptions) {
133
+ if (!options || !types.includes(options.type))
134
+ throw new TypeError(`Gradient type must be 'linear', 'radial' or 'conic'.`)
135
+ if (!options.colors)
136
+ throw new RangeError('A gradient needs between two and eight colors.')
137
+ const base: GradientFrame = {
138
+ colors: [],
139
+ stops: [],
140
+ angle: 180,
141
+ x: 0.5,
142
+ y: 0.5,
143
+ radius: 0.5,
144
+ }
145
+ const patch = gradientPatch(options, 0)
146
+ const prepared = gradientProgram(
147
+ { at: () => base, remaining: 0, elapsed: () => 0 },
148
+ patch,
149
+ )
150
+ return { frame: prepared.current, patch }
151
+ }
152
+
153
+ interface GradientRun {
154
+ from: GradientFrame
155
+ to: GradientFrame
156
+ track: Track
157
+ keys: Set<GradientComponent>
158
+ masked: Set<GradientComponent>
159
+ clock: PlaybackClock
160
+ cancelEnd?: () => void
161
+ settle(finished: boolean): void
162
+ }
163
+
164
+ class GradientController implements Gradient {
165
+ private painter: GradientPainter | undefined
166
+ private player: ReturnType<GradientPainter['play']> | undefined
167
+ private program: ReturnType<typeof gradientProgram> | undefined
168
+ private model: GradientFrame
169
+ private removed = false
170
+ private _suspended = false
171
+ private background = false
172
+ private unloadedView = false
173
+ private running: GradientRun | undefined
174
+ private bindings = new Map<
175
+ GradientComponent,
176
+ { source: GradientSource; owner: object }
177
+ >()
178
+ private releases: (() => void)[] = []
179
+ private cancelWindow?: () => void
180
+ private generation = 0
181
+
182
+ constructor(
183
+ private readonly view: View,
184
+ readonly type: GradientType,
185
+ frame: GradientFrame,
186
+ patch: GradientPatch,
187
+ ) {
188
+ this.model = frame
189
+ const owner = {}
190
+ for (const [key, source] of patch)
191
+ if (typeof source !== 'number') this.bindings.set(key, { source, owner })
192
+ this.painter = (factory ?? platformPainter)(view, type)
193
+ view.on('unloaded', this.unloaded)
194
+ view.on('loaded', this.loaded)
195
+ view.on('layoutChanged', this.resized)
196
+ Application.on(Application.suspendEvent, this.appSuspended)
197
+ Application.on(Application.resumeEvent, this.appResumed)
198
+ this.subscribe()
199
+ this.render()
200
+ }
201
+
202
+ private get inactive() {
203
+ return this.removed || this._suspended || this.background || this.unloadedView
204
+ }
205
+ private patch() {
206
+ return new Map([...this.bindings].map(([key, entry]) => [key, entry.source]))
207
+ }
208
+ private base() {
209
+ const run = this.running
210
+ const elapsed = run?.clock.time() ?? 0
211
+ const model = cloneFrame(this.model)
212
+ return {
213
+ remaining: run ? Math.max(0, run.track.end - elapsed) : 0,
214
+ elapsed: () => (run ? Math.max(0, run.clock.time() - elapsed) : 0),
215
+ at: (delta: number) => {
216
+ const frame = cloneFrame(model)
217
+ if (run) {
218
+ const sample = mix(
219
+ run.from,
220
+ run.to,
221
+ run.track.valueAt(elapsed + delta),
222
+ reducedMotion(),
223
+ )
224
+ for (const key of run.keys)
225
+ if (!run.masked.has(key)) put(frame, key, take(sample, key))
226
+ }
227
+ return frame
228
+ },
229
+ }
230
+ }
231
+ private presented(): GradientFrame {
232
+ if (this.inactive) return cloneFrame(this.model)
233
+ try {
234
+ return gradientProgram(this.base(), this.patch()).current
235
+ } catch {
236
+ return (
237
+ this.program?.at(Math.min(this.program.duration, this.program.elapsed())) ??
238
+ cloneFrame(this.model)
239
+ )
240
+ }
241
+ }
242
+ private clearPlayer() {
243
+ this.generation++
244
+ this.cancelWindow?.()
245
+ this.cancelWindow = undefined
246
+ const player = this.player
247
+ this.player = undefined
248
+ player?.cancel()
249
+ }
250
+ private unsubscribe() {
251
+ for (const release of this.releases) release()
252
+ this.releases = []
253
+ }
254
+ private subscribe() {
255
+ this.unsubscribe()
256
+ if (this.inactive) return
257
+ const sources = new Map<object, GradientSource>()
258
+ for (const { source } of this.bindings.values()) sources.set(source.identity, source)
259
+ this.releases = [...sources.values()].map((source) => source.subscribe(this.changed))
260
+ }
261
+ private changed = () => {
262
+ if (this.inactive) return
263
+ try {
264
+ this.render()
265
+ } catch (error) {
266
+ // A later invalid source must not throw through its other consumers or leave
267
+ // half of a compound frame painted. Hold the last compiled frame and detach.
268
+ this.stop()
269
+ Trace.write(
270
+ `Jolt gradient binding stopped: ${String(error)}`,
271
+ Trace.categories.Error,
272
+ Trace.messageType.error,
273
+ )
274
+ }
275
+ }
276
+ private render() {
277
+ if (this.inactive) return
278
+ const prepared = gradientProgram(this.base(), this.patch())
279
+ this.clearPlayer()
280
+ this.program = prepared
281
+ const painter = this.painter
282
+ if (!painter) return
283
+ const run = this.running
284
+ if (run && !this.bindings.size && !run.masked.size) {
285
+ const generation = this.generation
286
+ this.player = painter.play(
287
+ run.track.values.map((p) => mix(run.from, run.to, p, reducedMotion())),
288
+ run.track.times,
289
+ {
290
+ duration: run.track.duration,
291
+ delay: run.track.delay,
292
+ repeat: run.track.repeat,
293
+ reverse: run.track.reverse,
294
+ },
295
+ (completed) => {
296
+ if (generation === this.generation && this.running === run)
297
+ this.finish(run, completed)
298
+ },
299
+ )
300
+ // Concrete playback retains its existing API; bindings always use native control.
301
+ if (run.clock.time() > 1) this.player.control?.(run.clock.time(), false)
302
+ return
303
+ }
304
+ if (prepared.duration <= 0) {
305
+ painter.paint(prepared.current)
306
+ return
307
+ }
308
+ const generation = this.generation
309
+ this.player = painter.play(
310
+ prepared.frames,
311
+ prepared.times,
312
+ { duration: prepared.duration, delay: 0, repeat: 0, reverse: false },
313
+ () => {},
314
+ )
315
+ this.player.control?.(prepared.elapsed(), false)
316
+ // Only long compound windows need a boundary callback; each source sends its
317
+ // own completion/control notifications. There is no observer frame subscription.
318
+ if (prepared.remaining > prepared.duration)
319
+ this.cancelWindow = getDriver().after(
320
+ Math.max(1, prepared.duration - prepared.elapsed()),
321
+ () => {
322
+ if (generation === this.generation) this.changed()
323
+ },
324
+ )
325
+ }
326
+
327
+ animate(values: GradientValues, transition?: Transition | SpringName): Animation {
328
+ this.assertActive()
329
+ const from = this.presented()
330
+ const to = resolve(from, values, true)
331
+ const patch = gradientPatch(values, from.colors.length)
332
+ const resolved =
333
+ typeof transition === 'string' ? springOf(transition) : (transition ?? {})
334
+ const track = createTrack(
335
+ 'opacity',
336
+ [0, 1],
337
+ resolveTransition(resolved, 'opacity', 2),
338
+ 0,
339
+ )
340
+ this.cancelRunning()
341
+ this.model = from
342
+ for (const key of patch.keys()) this.bindings.delete(key)
343
+ this.subscribe()
344
+ let settle!: (finished: boolean) => void
345
+ const finished = new Promise<boolean>((resolve) => {
346
+ settle = resolve
347
+ })
348
+ const driver = getDriver()
349
+ const run: GradientRun = {
350
+ from,
351
+ to,
352
+ track,
353
+ keys: new Set(patch.keys()),
354
+ masked: new Set(),
355
+ clock: driver.clock?.(track.end) ?? createClock(() => driver.now()),
356
+ settle,
357
+ }
358
+ const animation: Animation = {
359
+ finished,
360
+ stop: () => {
361
+ if (this.running !== run) return
362
+ this.model = this.presented()
363
+ this.cancelRunning()
364
+ this.render()
365
+ },
366
+ then: (onfulfilled, onrejected) => finished.then(onfulfilled, onrejected),
367
+ }
368
+ this.running = run
369
+ if (track.end === 0 || !this.painter) this.finish(run, true)
370
+ else {
371
+ this.render()
372
+ if (Number.isFinite(track.end))
373
+ run.cancelEnd = driver.after(Math.max(1, track.end - run.clock.time()), () =>
374
+ this.finish(run, true),
375
+ )
376
+ }
377
+ return animation
378
+ }
379
+
380
+ private finish(run: GradientRun, completed: boolean) {
381
+ if (this.running !== run) return
382
+ const frame = completed
383
+ ? mix(run.from, run.to, run.track.to, reducedMotion())
384
+ : this.presented()
385
+ for (const key of run.keys)
386
+ if (!run.masked.has(key)) put(this.model, key, take(frame, key))
387
+ this.running = undefined
388
+ run.cancelEnd?.()
389
+ run.clock.cancel()
390
+ this.clearPlayer()
391
+ run.settle(completed)
392
+ this.render()
393
+ }
394
+ private cancelRunning() {
395
+ const run = this.running
396
+ this.running = undefined
397
+ run?.cancelEnd?.()
398
+ run?.clock.cancel()
399
+ this.clearPlayer()
400
+ run?.settle(false)
401
+ }
402
+
403
+ bind(values: GradientBindings): () => void {
404
+ this.assertActive()
405
+ const held = this.presented()
406
+ const patch = gradientPatch(values, held.colors.length)
407
+ const candidate: GradientPatch = this.patch()
408
+ const count = values.colors?.length ?? held.colors.length
409
+ const structural = count !== held.colors.length
410
+ if (structural) {
411
+ held.colors.length = held.stops.length = count
412
+ for (const key of candidate.keys())
413
+ if (key.startsWith('color:') || key.startsWith('stop:')) candidate.delete(key)
414
+ }
415
+ for (const [key, value] of patch) candidate.set(key, value)
416
+ const prepared = gradientProgram(
417
+ { at: () => held, remaining: 0, elapsed: () => 0 },
418
+ candidate,
419
+ )
420
+ // Validation/sampling above is transactional. Only now may ownership change.
421
+ const owner = {}
422
+ if (structural) {
423
+ for (const key of this.bindings.keys())
424
+ if (key.startsWith('color:') || key.startsWith('stop:')) this.bindings.delete(key)
425
+ for (const key of this.running?.keys ?? [])
426
+ if (key.startsWith('color:') || key.startsWith('stop:'))
427
+ this.running!.masked.add(key)
428
+ }
429
+ this.model = prepared.current
430
+ for (const [key, source] of patch) {
431
+ this.running?.masked.add(key)
432
+ if (typeof source === 'number') this.bindings.delete(key)
433
+ else this.bindings.set(key, { source, owner })
434
+ }
435
+ this.subscribe()
436
+ this.render()
437
+ return () => {
438
+ if (this.removed) return
439
+ const keys = [...this.bindings]
440
+ .filter(([, entry]) => entry.owner === owner)
441
+ .map(([key]) => key)
442
+ if (!keys.length) return
443
+ const current = this.presented()
444
+ for (const key of keys) {
445
+ put(this.model, key, take(current, key))
446
+ this.bindings.delete(key)
447
+ }
448
+ this.subscribe()
449
+ this.render()
450
+ }
451
+ }
452
+
453
+ set(values: GradientValues) {
454
+ this.assertActive()
455
+ const from = this.presented()
456
+ resolve(from, values, false)
457
+ gradientPatch(values, from.colors.length)
458
+ this.cancelRunning()
459
+ this.model = from
460
+ this.bind(values)
461
+ }
462
+ stop() {
463
+ if (this.removed) return
464
+ const frame = this.presented()
465
+ this.bindings.clear()
466
+ this.unsubscribe()
467
+ this.cancelRunning()
468
+ this.model = frame
469
+ this.program = undefined
470
+ this.painter?.paint(frame)
471
+ }
472
+ private hold() {
473
+ this.model = this.presented()
474
+ this.cancelRunning()
475
+ this.unsubscribe()
476
+ this.painter?.paint(this.model)
477
+ }
478
+ get suspended() {
479
+ return this._suspended
480
+ }
481
+
482
+ suspend() {
483
+ if (!this._suspended && !this.removed) {
484
+ this.hold()
485
+ this._suspended = true
486
+ }
487
+ }
488
+ resume() {
489
+ if (this._suspended && !this.removed) {
490
+ this._suspended = false
491
+ this.subscribe()
492
+ this.changed()
493
+ }
494
+ }
495
+ private unloaded = () => {
496
+ if (this.removed) return
497
+ this.hold()
498
+ this.unloadedView = true
499
+ this.painter?.remove()
500
+ this.painter = undefined
501
+ }
502
+ private loaded = () => {
503
+ if (this.removed) return
504
+ this.unloadedView = false
505
+ this.painter ??= (factory ?? platformPainter)(this.view, this.type)
506
+ this.subscribe()
507
+ this.changed()
508
+ }
509
+ private resized = () => {
510
+ if (this.bindings.size || this.running) this.changed()
511
+ }
512
+ private appSuspended = () => {
513
+ if (!this.background && !this.removed) {
514
+ this.hold()
515
+ this.background = true
516
+ }
517
+ }
518
+ private appResumed = () => {
519
+ if (this.background && !this.removed) {
520
+ this.background = false
521
+ this.subscribe()
522
+ this.changed()
523
+ }
524
+ }
525
+ remove() {
526
+ if (this.removed) return
527
+ this.unsubscribe()
528
+ this.cancelRunning()
529
+ this.bindings.clear()
530
+ this.removed = true
531
+ this.view.off('unloaded', this.unloaded)
532
+ this.view.off('loaded', this.loaded)
533
+ this.view.off('layoutChanged', this.resized)
534
+ Application.off(Application.suspendEvent, this.appSuspended)
535
+ Application.off(Application.resumeEvent, this.appResumed)
536
+ this.painter?.remove()
537
+ this.painter = undefined
538
+ }
539
+ private assertActive() {
540
+ if (this.removed) throw new Error('This gradient was removed.')
541
+ }
542
+ }
543
+
544
+ function springOf(name: SpringName): Transition {
545
+ const spring = springs[name]
546
+ if (!spring || !Object.hasOwn(springs, name))
547
+ throw new Error(`Unknown spring "${name}".`)
548
+ return spring
549
+ }
550
+
551
+ /** Validates values and fills in what they leave out from `base`. */
552
+ function resolve(
553
+ base: GradientFrame,
554
+ values: GradientValues,
555
+ sameCount: boolean,
556
+ ): GradientFrame {
557
+ if (!values || typeof values !== 'object')
558
+ throw new TypeError('Gradient values must be an object.')
559
+ const colors = values.colors ? values.colors.map(parseColor) : base.colors
560
+ if (colors.length < 2 || colors.length > 8)
561
+ throw new RangeError('A gradient needs between two and eight colors.')
562
+ if (sameCount && values.colors && colors.length !== base.colors.length)
563
+ throw new RangeError(
564
+ `Animating a gradient keeps its ${base.colors.length} colors; use set() to change the count.`,
565
+ )
566
+ const stops = values.stops
567
+ ? [...values.stops]
568
+ : values.colors || base.stops.length !== colors.length
569
+ ? colors.map((_, i) => i / (colors.length - 1))
570
+ : base.stops
571
+ if (
572
+ stops.length !== colors.length ||
573
+ stops.some(
574
+ (stop, i) =>
575
+ !Number.isFinite(stop) || stop < 0 || stop > 1 || stop < (stops[i - 1] ?? 0),
576
+ )
577
+ )
578
+ throw new RangeError(
579
+ 'Gradient stops need one value per color, from 0 to 1, without going back.',
580
+ )
581
+ const angle = values.angle ?? base.angle
582
+ const x = values.center?.x ?? base.x
583
+ const y = values.center?.y ?? base.y
584
+ const radius = values.radius ?? base.radius
585
+ for (const [name, value] of [
586
+ ['angle', angle],
587
+ ['center', x],
588
+ ['center', y],
589
+ ['radius', radius],
590
+ ] as const)
591
+ if (!Number.isFinite(value))
592
+ throw new RangeError(`Invalid gradient ${name}: ${value}.`)
593
+ if (radius < 0)
594
+ throw new RangeError(`Gradient radius must not be negative, got ${radius}.`)
595
+ return { colors, stops, angle, x, y, radius }
596
+ }
597
+
598
+ /** One frame between two states. Geometry follows the curve, overshoot included; colors and stops stay between their ends. */
599
+ export function mix(
600
+ from: GradientFrame,
601
+ to: GradientFrame,
602
+ progress: number,
603
+ reduced = false,
604
+ ): GradientFrame {
605
+ const p = Math.min(Math.max(progress, 0), 1)
606
+ const g = reduced ? 1 : progress
607
+ const lerp = (a: number, b: number, t: number) => a + (b - a) * t
608
+ return {
609
+ colors: to.colors.map((color, i) => colorMixer(from.colors[i] ?? color, color)(p)),
610
+ stops: to.stops.map((stop, i) => lerp(from.stops[i] ?? stop, stop, p)),
611
+ angle: lerp(from.angle, to.angle, g),
612
+ x: lerp(from.x, to.x, g),
613
+ y: lerp(from.y, to.y, g),
614
+ radius: Math.max(0, lerp(from.radius, to.radius, g)),
615
+ }
616
+ }
617
+
618
+ /**
619
+ * The points a platform gradient needs, in unit coordinates of a `width` × `height` box.
620
+ * Linear follows CSS: the line runs through the center at `angle` and is long enough
621
+ * for the corners to get the first and last colors.
622
+ */
623
+ export function gradientPoints(
624
+ type: GradientType,
625
+ frame: GradientFrame,
626
+ width: number,
627
+ height: number,
628
+ ) {
629
+ const radians = (frame.angle * Math.PI) / 180
630
+ const sin = Math.sin(radians)
631
+ const cos = Math.cos(radians)
632
+ if (type === 'linear') {
633
+ // Core Animation keeps an axial gradient's bands square to its line in unit space, so
634
+ // on a box that isn't square the line leans to keep them square to `angle` on screen.
635
+ const ux = height > 0 ? sin / height : 0
636
+ const uy = width > 0 ? -cos / width : 0
637
+ const squared = ux * ux + uy * uy
638
+ const reach = squared > 0 ? (Math.abs(ux) + Math.abs(uy)) / (2 * squared) : 0
639
+ return {
640
+ start: { x: 0.5 - ux * reach, y: 0.5 - uy * reach },
641
+ end: { x: 0.5 + ux * reach, y: 0.5 + uy * reach },
642
+ }
643
+ }
644
+ const center = { x: frame.x, y: frame.y }
645
+ const shorter = Math.min(width, height)
646
+ if (type === 'radial') {
647
+ const r = frame.radius * shorter
648
+ return {
649
+ start: center,
650
+ end: {
651
+ x: center.x + (width > 0 ? r / width : 0),
652
+ y: center.y + (height > 0 ? r / height : 0),
653
+ },
654
+ }
655
+ }
656
+ return {
657
+ start: center,
658
+ end: {
659
+ x: center.x + (width > 0 ? (sin * shorter) / (2 * width) : 0),
660
+ y: center.y + (height > 0 ? (-cos * shorter) / (2 * height) : 0),
661
+ },
662
+ }
663
+ }