@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,217 @@
1
+ package org.rafaelaugusto.jolt;
2
+
3
+ import android.app.Activity;
4
+ import android.app.Application;
5
+ import android.content.Context;
6
+ import android.hardware.Sensor;
7
+ import android.hardware.SensorEvent;
8
+ import android.hardware.SensorEventListener;
9
+ import android.hardware.SensorManager;
10
+ import android.os.Bundle;
11
+ import android.os.Handler;
12
+ import android.os.Looper;
13
+ import android.os.SystemClock;
14
+ import android.view.Choreographer;
15
+ import android.view.Surface;
16
+ import android.view.WindowManager;
17
+ import java.util.ArrayList;
18
+ import java.util.Arrays;
19
+ import org.json.JSONArray;
20
+ import org.json.JSONException;
21
+ import org.json.JSONObject;
22
+
23
+ /** Shared hardware subscriptions, native display coalescing and native-only live-value delivery. */
24
+ public final class SensorSource {
25
+ public interface Listener { void changed(); }
26
+ private static final ArrayList<SensorSource> sources=new ArrayList<>();
27
+ private static SensorManager manager;
28
+ private static WindowManager window;
29
+ private static Sensor rotationHardware, gravityHardware;
30
+ private static boolean scheduled, background;
31
+ private static int rotationRate, gravityRate;
32
+ private static final Handler main=new Handler(Looper.getMainLooper());
33
+ private static final SensorEventListener hardware=new SensorEventListener() {
34
+ @Override public void onAccuracyChanged(Sensor sensor,int accuracy) {}
35
+ @Override public void onSensorChanged(SensorEvent event) {
36
+ if(background) return;
37
+ boolean rotation=event.sensor.getType()==Sensor.TYPE_GAME_ROTATION_VECTOR;
38
+ double[] values;
39
+ if(rotation) {
40
+ if(event.values.length<4)return;
41
+ values=new double[]{event.values[0],event.values[1],event.values[2],event.values[3]};
42
+ } else {
43
+ if(event.values.length<3)return;
44
+ // Android reports proper acceleration against gravity; canonical gravity points down.
45
+ values=new double[]{-event.values[0],-event.values[1],-event.values[2]};
46
+ }
47
+ for(SensorSource source:new ArrayList<>(sources))
48
+ if(source.enabled && source.trace==null && source.error==null && source.rotation==rotation)
49
+ source.receive(values,event.timestamp/1e6);
50
+ }
51
+ };
52
+ private static final Choreographer.FrameCallback clock=new Choreographer.FrameCallback() {
53
+ @Override public void doFrame(long nanos) {
54
+ scheduled=false;
55
+ for(SensorSource source:new ArrayList<>(sources)) if(source.enabled&&!background)source.frame(nanos/1e6);
56
+ schedule();
57
+ }
58
+ };
59
+ private static void initialize(Context context) {
60
+ if(manager!=null)return;
61
+ Context app=context.getApplicationContext();
62
+ manager=(SensorManager)app.getSystemService(Context.SENSOR_SERVICE);
63
+ window=(WindowManager)app.getSystemService(Context.WINDOW_SERVICE);
64
+ rotationHardware=manager.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR);
65
+ gravityHardware=manager.getDefaultSensor(Sensor.TYPE_GRAVITY);
66
+ if(app instanceof Application)((Application)app).registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
67
+ @Override public void onActivityPaused(Activity activity) {
68
+ background=true;
69
+ for(SensorSource s:sources) s.holdReplay();
70
+ refresh();
71
+ }
72
+ @Override public void onActivityResumed(Activity activity) {
73
+ background=false;
74
+ for(SensorSource s:sources) {s.rebase=true;s.receivedAt=SystemClock.uptimeMillis();s.replayStart=0;}
75
+ refresh();
76
+ }
77
+ @Override public void onActivityCreated(Activity a,Bundle b){}
78
+ @Override public void onActivityStarted(Activity a){}
79
+ @Override public void onActivityStopped(Activity a){}
80
+ @Override public void onActivitySaveInstanceState(Activity a,Bundle b){}
81
+ @Override public void onActivityDestroyed(Activity a){}
82
+ });
83
+ }
84
+ private static boolean ticking() {
85
+ if(background)return false;
86
+ for(SensorSource s:sources)if(s.enabled && !s.disposed && (s.trace!=null || (s.available && s.error==null)))return true;
87
+ return false;
88
+ }
89
+ private static void schedule() {
90
+ if(ticking()) {
91
+ if(!scheduled){scheduled=true;Choreographer.getInstance().postFrameCallback(clock);}
92
+ } else if(scheduled){Choreographer.getInstance().removeFrameCallback(clock);scheduled=false;}
93
+ }
94
+ private static void refresh() {
95
+ if(manager==null)return;
96
+ int rotation=0, gravity=0;
97
+ if(!background)for(SensorSource s:sources)if(s.enabled && s.trace==null && s.available && s.error==null) {
98
+ Sensor hardware=s.rotation?rotationHardware:gravityHardware;
99
+ int rate=Math.max(5000,Math.max(hardware.getMinDelay(),(int)(s.interval*1000)));
100
+ if(s.rotation)rotation=rotation==0?rate:Math.min(rotation,rate);
101
+ else gravity=gravity==0?rate:Math.min(gravity,rate);
102
+ }
103
+ rotationRate=register(rotationHardware,rotationRate,rotation,true);
104
+ gravityRate=register(gravityHardware,gravityRate,gravity,false);
105
+ schedule();
106
+ }
107
+ private static int register(Sensor sensor,int previous,int next,boolean rotation) {
108
+ if(previous==next)return previous;
109
+ // A fusion implementation may reset its game-reference frame on re-registration.
110
+ if(rotation)for(SensorSource s:sources)if(s.rotation&&s.enabled&&s.trace==null)s.rebase=true;
111
+ if(previous>0)manager.unregisterListener(hardware,sensor);
112
+ if(next==0)return 0;
113
+ String error=null;
114
+ try { if(!manager.registerListener(hardware,sensor,next,0,main))error="registration-failed"; }
115
+ catch(SecurityException denied){error="access-denied";}
116
+ catch(RuntimeException failure){error="sensor-start-failed";}
117
+ if(error==null)return next;
118
+ for(SensorSource s:new ArrayList<>(sources))if(s.rotation==rotation&&s.enabled&&s.trace==null){s.error=error;s.state("error");}
119
+ return 0;
120
+ }
121
+ public static int activeCount(){return (rotationRate>0?1:0)+(gravityRate>0?1:0);}
122
+ public static int sourceCount(){return sources.size();}
123
+ private final boolean rotation, interfaceCoordinates, available;
124
+ private final double interval;
125
+ private final LiveSpring[] nodes;
126
+ private Listener listener;
127
+ private boolean enabled,disposed,dirty,rebase=true,reset;
128
+ private String status,error;
129
+ private double timestamp=-1,pendingTimestamp,receivedAt,committedAt,processingMs;
130
+ private long samples,frames,callbacks;
131
+ private double[] reference={0,0,0,1},relative={0,0,0,1},output,pending;
132
+ private JSONArray trace;
133
+ private int replayIndex;
134
+ private double replayStart,replayElapsed,replayOrientation;
135
+ public SensorSource(Context context,String kind,String options,Listener listener) {
136
+ initialize(context);
137
+ rotation=kind.equals("rotation");this.listener=listener;
138
+ try {
139
+ JSONObject config=new JSONObject(options);
140
+ interfaceCoordinates=config.optString("coordinates").equals("interface");
141
+ double requested=config.optDouble("interval",0);
142
+ if(requested==0)requested=1000/Math.max(60,window.getDefaultDisplay().getRefreshRate());
143
+ interval=Math.max(5,Math.min(1000,requested));
144
+ } catch(JSONException e){throw new IllegalArgumentException(e);}
145
+ available=(rotation?rotationHardware:gravityHardware)!=null;
146
+ output=new double[rotation?7:3];if(rotation)output[6]=1;
147
+ nodes=new LiveSpring[output.length];status=available?"idle":"unavailable";
148
+ sources.add(this);
149
+ }
150
+ public void connect(LiveSpring node,int index){if(index>=0&&index<nodes.length)nodes[index]=node;}
151
+ private void state(String next){if(status.equals(next))return;status=next;if(listener!=null){callbacks++;listener.changed();}}
152
+ private void holdReplay(){if(trace!=null&&replayStart>0){replayElapsed=Math.max(0,SystemClock.uptimeMillis()-replayStart);replayStart=0;}}
153
+ public void setEnabled(boolean active,boolean paused) {
154
+ if(disposed)return;
155
+ boolean changed=enabled!=active;enabled=active;
156
+ if(changed){dirty=false;committedAt=0;rebase=true;if(active){receivedAt=SystemClock.uptimeMillis();error=null;replayStart=0;}else holdReplay();}
157
+ if(!active)state(paused?"paused":(available?"idle":"unavailable"));
158
+ else if(changed)state(trace!=null?"replaying":(available?"starting":"unavailable"));
159
+ refresh();
160
+ }
161
+ public void recenter(){if(!disposed&&rotation){reset=true;rebase=true;}}
162
+ public void replay(String input) {
163
+ if(disposed)return;
164
+ try {JSONArray next=new JSONArray(input);if(next.length()<2)return;trace=next;}catch(JSONException e){throw new IllegalArgumentException(e);}
165
+ replayIndex=0;replayStart=0;replayElapsed=0;error=null;reset=true;rebase=true;dirty=false;committedAt=0;
166
+ if(enabled)state("replaying");refresh();
167
+ }
168
+ private void receive(double[] values,double time) {
169
+ if(!Double.isFinite(time)||time<0)return;
170
+ if(trace==null&&timestamp>=0&&time<=pendingTimestamp)return;
171
+ for(double v:values)if(!Double.isFinite(v))return;
172
+ double[] copy=values.clone();if(rotation&&!SensorMath.normalize(copy))return;
173
+ pending=copy;pendingTimestamp=time;samples++;dirty=true;receivedAt=SystemClock.uptimeMillis();
174
+ }
175
+ private double orientation() {
176
+ if(!interfaceCoordinates)return 0;
177
+ if(trace!=null)return replayOrientation;
178
+ switch(window.getDefaultDisplay().getRotation()){
179
+ case Surface.ROTATION_90:return 90;case Surface.ROTATION_180:return 180;case Surface.ROTATION_270:return 270;default:return 0;
180
+ }
181
+ }
182
+ private void frame(double now) {
183
+ if(disposed||error!=null)return;
184
+ if(trace!=null) {
185
+ if(replayStart==0)replayStart=now-replayElapsed;
186
+ double elapsed=now-replayStart;
187
+ try {
188
+ while(replayIndex<trace.length()&&trace.getJSONObject(replayIndex).getDouble("time")<=elapsed){
189
+ JSONObject sample=trace.getJSONObject(replayIndex++);JSONArray values=sample.getJSONArray("values");
190
+ if(values.length()!=(rotation?4:3))continue;
191
+ double[] input=new double[values.length()];for(int i=0;i<input.length;i++)input[i]=values.getDouble(i);
192
+ replayOrientation=sample.optDouble("orientation",0);receive(input,sample.getDouble("time"));
193
+ }
194
+ }catch(JSONException e){error="invalid-test-input";trace=null;state("error");refresh();return;}
195
+ } else if(available&&now-receivedAt>Math.max(3000,interval*3)){error="no-data";state("error");refresh();return;}
196
+ if(dirty&&(committedAt==0||now-committedAt>=interval-.5)) {
197
+ long start=System.nanoTime();
198
+ if(rotation) {
199
+ if(rebase){if(reset)relative=new double[]{0,0,0,1};reference=SensorMath.multiply(pending,SensorMath.inverse(relative));rebase=false;reset=false;}
200
+ relative=SensorMath.multiply(SensorMath.inverse(reference),pending);
201
+ output=SensorMath.rotation(relative,orientation(),Arrays.copyOfRange(output,3,7));
202
+ } else output=SensorMath.vector(pending,orientation());
203
+ for(int i=0;i<nodes.length;i++)if(nodes[i]!=null)nodes[i].setSensorInput(output[i]);
204
+ dirty=false;timestamp=pendingTimestamp;frames++;committedAt=now;processingMs+=(System.nanoTime()-start)/1e6;
205
+ if(trace==null)state("active");
206
+ }
207
+ if(trace!=null&&replayIndex>=trace.length()&&!dirty){trace=null;replayStart=0;replayElapsed=0;rebase=true;receivedAt=now;state(available?"starting":"unavailable");refresh();}
208
+ }
209
+ public String snapshot() {
210
+ try {
211
+ JSONObject result=new JSONObject();result.put("status",status);result.put("available",available);result.put("error",error==null?JSONObject.NULL:error);
212
+ result.put("timestamp",timestamp<0?JSONObject.NULL:timestamp);result.put("samples",samples);result.put("frames",frames);result.put("callbacks",callbacks);
213
+ result.put("processingMs",processingMs);result.put("interval",interval);JSONArray values=new JSONArray();for(double v:output)values.put(v);result.put("values",values);return result.toString();
214
+ }catch(JSONException e){throw new IllegalStateException(e);}
215
+ }
216
+ public void dispose(){if(disposed)return;disposed=true;enabled=false;status="disposed";listener=null;trace=null;Arrays.fill(nodes,null);sources.remove(this);refresh();}
217
+ }
@@ -0,0 +1,120 @@
1
+ package org.rafaelaugusto.jolt;
2
+
3
+ import android.animation.Animator;
4
+ import android.animation.AnimatorListenerAdapter;
5
+ import android.animation.ValueAnimator;
6
+ import android.graphics.Canvas;
7
+ import android.graphics.ColorFilter;
8
+ import android.graphics.Paint;
9
+ import android.graphics.Path;
10
+ import android.graphics.PathMeasure;
11
+ import android.graphics.PixelFormat;
12
+ import android.graphics.Rect;
13
+ import android.graphics.RectF;
14
+ import android.graphics.drawable.Drawable;
15
+ import android.view.animation.LinearInterpolator;
16
+ import org.json.JSONArray;
17
+ import org.json.JSONException;
18
+ import org.json.JSONObject;
19
+
20
+ /** Owned vector surface. JS submits geometry/curves once; all drawing and playback stays native. */
21
+ public final class ShapeLayer extends Drawable {
22
+ private static int live, active;
23
+ public static int liveCount(){return live;}
24
+ public static int activeCount(){return active;}
25
+ private final Paint fill=new Paint(Paint.ANTI_ALIAS_FLAG), stroke=new Paint(Paint.ANTI_ALIAS_FLAG);
26
+ private final Path path=new Path(), trimmed=new Path();
27
+ private final PathMeasure measure=new PathMeasure();
28
+ private final float[] box=new float[4];
29
+ private String commands="";
30
+ // start/end fractions followed by normalized path coordinates.
31
+ private float[] current=new float[0], from, to, times, samples;
32
+ private float length;
33
+ private double duration, delay, repeats;
34
+ private boolean reverse, disposed;
35
+ private ValueAnimator animator;
36
+ public ShapeLayer(String options){
37
+ try {
38
+ JSONObject o=new JSONObject(options);JSONArray b=o.getJSONArray("viewBox");
39
+ for(int i=0;i<4;i++)box[i]=(float)b.getDouble(i);
40
+ fill.setColor((int)o.getLong("fill"));fill.setStyle(Paint.Style.FILL);
41
+ stroke.setColor((int)o.getLong("stroke"));stroke.setStyle(Paint.Style.STROKE);stroke.setStrokeWidth((float)o.getDouble("width"));
42
+ stroke.setStrokeCap(Paint.Cap.valueOf(o.getString("cap").toUpperCase(java.util.Locale.ROOT)));
43
+ stroke.setStrokeJoin(Paint.Join.valueOf(o.getString("join").toUpperCase(java.util.Locale.ROOT)));
44
+ path.setFillType(o.getString("rule").equals("evenodd")?Path.FillType.EVEN_ODD:Path.FillType.WINDING);
45
+ }catch(JSONException e){throw new IllegalArgumentException(e);}
46
+ live++;
47
+ }
48
+ public void paint(String commands,float[] points,float start,float end){
49
+ if(disposed)return;cancel();this.commands=commands;current=new float[points.length+2];current[0]=start;current[1]=end;System.arraycopy(points,0,current,2,points.length);rebuild();invalidateSelf();
50
+ }
51
+ public float[] values(){return current.clone();}
52
+ public float[] geometryBounds(){RectF b=new RectF();path.computeBounds(b,false);return new float[]{b.left,b.top,b.width(),b.height()};}
53
+ public boolean isPlaying(){return animator!=null;}
54
+ public void play(String commands,float[] from,float[] to,float[] times,float[] samples,double duration,double delay,int repeats,boolean reverse){
55
+ if(disposed)return;cancel();
56
+ this.commands=commands;this.from=from;this.to=to;this.times=times;this.samples=samples;
57
+ this.duration=duration;this.delay=delay;this.repeats=repeats;this.reverse=reverse;
58
+ current=from.clone();rebuild();apply(0);
59
+ final ValueAnimator a=ValueAnimator.ofFloat(0f,1f);
60
+ a.setDuration(repeats<0?60000:Math.max(1,(long)Math.ceil(delay+duration*(repeats+1))));
61
+ a.setRepeatCount(repeats<0?ValueAnimator.INFINITE:0);a.setInterpolator(new LinearInterpolator());
62
+ a.addUpdateListener(v->apply(v.getCurrentPlayTime()));
63
+ a.addListener(new AnimatorListenerAdapter(){@Override public void onAnimationEnd(Animator ended){if(animator==a){animator=null;active--;}}});
64
+ animator=a;active++;a.start();
65
+ }
66
+ public void control(double time,boolean paused){
67
+ if(animator==null)return;
68
+ animator.setCurrentPlayTime(Math.max(0,(long)time));
69
+ if(paused)animator.pause();else animator.resume();
70
+ apply(time);
71
+ }
72
+ private void apply(double elapsed){
73
+ double t=Math.max(0,elapsed-delay), fraction;
74
+ if(repeats>=0&&t>=duration*(repeats+1))fraction=reverse&&((int)repeats%2==1)?0:1;
75
+ else {long cycle=(long)(t/duration);fraction=t/duration-cycle;if(reverse&&(cycle%2==1))fraction=1-fraction;}
76
+ int low=0,high=times.length-1;
77
+ while(high-low>1){int mid=(low+high)/2;if(times[mid]<=fraction)low=mid;else high=mid;}
78
+ double span=times[high]-times[low], mix=span>0?Math.max(0,Math.min(1,(fraction-times[low])/span)):1;
79
+ double progress=samples[low]+(samples[high]-samples[low])*mix;
80
+ boolean changed=false;
81
+ for(int i=0;i<current.length;i++){
82
+ float v=(float)(from[i]+(to[i]-from[i])*progress);
83
+ if(i<2)v=Math.max(0,Math.min(1,v));else if(v!=current[i])changed=true;
84
+ current[i]=v;
85
+ }
86
+ if(changed)rebuild();invalidateSelf();
87
+ }
88
+ private void rebuild(){
89
+ path.rewind();int i=2;
90
+ for(int c=0;c<commands.length();c++)switch(commands.charAt(c)){
91
+ case 'M':path.moveTo(current[i],current[i+1]);i+=2;break;
92
+ case 'L':path.lineTo(current[i],current[i+1]);i+=2;break;
93
+ case 'C':path.cubicTo(current[i],current[i+1],current[i+2],current[i+3],current[i+4],current[i+5]);i+=6;break;
94
+ case 'Q':path.quadTo(current[i],current[i+1],current[i+2],current[i+3]);i+=4;break;
95
+ case 'Z':path.close();break;
96
+ }
97
+ measure.setPath(path,false);length=measure.getLength();
98
+ }
99
+ @Override public void draw(Canvas canvas){
100
+ Rect b=getBounds();if(disposed||current.length<4||b.width()<=0||b.height()<=0)return;
101
+ float scale=Math.min(b.width()/box[2],b.height()/box[3]);
102
+ int save=canvas.save();canvas.clipRect(b);
103
+ canvas.translate(b.exactCenterX()-box[2]*scale/2,b.exactCenterY()-box[3]*scale/2);canvas.scale(scale,scale);canvas.translate(-box[0],-box[1]);
104
+ canvas.drawPath(path,fill);
105
+ if(stroke.getStrokeWidth()>0&&current[1]>current[0]){
106
+ if(current[0]<=0&&current[1]>=1)canvas.drawPath(path,stroke);
107
+ else{trimmed.rewind();measure.getSegment(length*current[0],length*current[1],trimmed,true);canvas.drawPath(trimmed,stroke);}
108
+ }
109
+ canvas.restoreToCount(save);
110
+ }
111
+ public void cancel(){
112
+ ValueAnimator a=animator;animator=null;
113
+ if(a!=null){active--;a.removeAllUpdateListeners();a.removeAllListeners();a.cancel();}
114
+ from=to=times=samples=null;
115
+ }
116
+ public void dispose(){if(disposed)return;cancel();disposed=true;live--;path.rewind();trimmed.rewind();current=new float[0];setCallback(null);}
117
+ @Override public void setAlpha(int alpha){fill.setAlpha(alpha);stroke.setAlpha(alpha);invalidateSelf();}
118
+ @Override public void setColorFilter(ColorFilter filter){fill.setColorFilter(filter);stroke.setColorFilter(filter);invalidateSelf();}
119
+ @Override public int getOpacity(){return PixelFormat.TRANSLUCENT;}
120
+ }
@@ -0,0 +1,287 @@
1
+ package org.rafaelaugusto.jolt;
2
+
3
+ import android.graphics.*;
4
+ import android.graphics.drawable.BitmapDrawable;
5
+ import android.widget.ImageView;
6
+ import android.view.*;
7
+ import android.webkit.WebView;
8
+ import org.json.*;
9
+ import java.util.*;
10
+
11
+ /** Window-relative snapshots; frame evaluation and drawing never call JavaScript. */
12
+ public final class SharedLayoutFlight extends View implements Choreographer.FrameCallback {
13
+ public interface Listener { void onEnd(boolean completed); }
14
+ private final ViewGroup root;
15
+ private final float density;
16
+ private final Map<View,Integer> hidden = new WeakHashMap<>();
17
+ private static final PorterDuffXfermode ADD = new PorterDuffXfermode(PorterDuff.Mode.ADD);
18
+ private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
19
+ private Bitmap source, target, pageBitmap;
20
+ private RectF pageFrame;
21
+ private boolean fading, clippedImage;
22
+ private float sourceWidth, sourceHeight, targetWidth, targetHeight;
23
+ private boolean sourceImage, targetImage, disposed, running, navigationImage, borrowedTarget;
24
+ private double[] interactiveStart, interactiveEnd;
25
+ private View destination;
26
+ private final double[] pose = new double[14], velocity = new double[14];
27
+ private double[][] times, values;
28
+ private double duration, started;
29
+ private RectF destinationFrame;
30
+ private int rootWidth, rootHeight;
31
+ private Listener listener;
32
+ private static int active;
33
+
34
+ private SharedLayoutFlight(View view) {
35
+ super(view.getContext()); root = (ViewGroup)view.getRootView();
36
+ density = view.getResources().getDisplayMetrics().density;
37
+ setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
38
+ setWillNotDraw(false); rootWidth = root.getWidth(); rootHeight = root.getHeight();
39
+ layout(0,0,rootWidth,rootHeight);
40
+ }
41
+ public static int activeCount() { return active; }
42
+ private static boolean unsupported(View view) {
43
+ return unsupported(view, false);
44
+ }
45
+ private static boolean unsupported(View view, boolean allowScrolling) {
46
+ if (view instanceof SurfaceView || view instanceof TextureView || view instanceof WebView || (!allowScrolling && (view instanceof android.widget.AbsListView || view instanceof android.widget.ScrollView))) return true;
47
+ if (view instanceof ViewGroup) {
48
+ ViewGroup group = (ViewGroup)view;
49
+ for (int i=0;i<group.getChildCount();i++) if (unsupported(group.getChildAt(i), allowScrolling)) return true;
50
+ }
51
+ return false;
52
+ }
53
+ private RectF geometry(View view) {
54
+ if (view == null || !view.isAttachedToWindow() || view.getRootView()!=root || view.getWidth()<=0 || view.getHeight()<=0) return null;
55
+ float sx=1,sy=1;
56
+ for (View p=view;p!=null;p=p.getParent() instanceof View ? (View)p.getParent() : null) {
57
+ if (p!=view && p.getVisibility()!=VISIBLE) return null;
58
+ if (Math.abs(p.getRotation())>.01 || Math.abs(p.getRotationX())>.01 || Math.abs(p.getRotationY())>.01 || p.getScaleX()<=0 || p.getScaleY()<=0 || Math.abs(p.getAlpha()-1)>.001 || Math.abs(p.getScaleX()-p.getScaleY())>.0001) return null;
59
+ sx*=p.getScaleX(); sy*=p.getScaleY();
60
+ }
61
+ int[] origin=new int[2], local=new int[2]; root.getLocationOnScreen(origin); view.getLocationOnScreen(local);
62
+ return new RectF(local[0]-origin[0],local[1]-origin[1],local[0]-origin[0]+view.getWidth()*sx,local[1]-origin[1]+view.getHeight()*sy);
63
+ }
64
+ private boolean visibleBounds(View view, RectF frame) {
65
+ if (frame==null || frame.left<-.5 || frame.top<-.5 || frame.right>rootWidth+.5 || frame.bottom>rootHeight+.5) return false;
66
+ for (ViewParent p=view.getParent();p instanceof View;p=p.getParent()) {
67
+ if (p instanceof ViewGroup && ((ViewGroup)p).getClipChildren()) {
68
+ RectF clip=geometry((View)p);
69
+ if (clip==null || frame.left<clip.left-.5 || frame.top<clip.top-.5 || frame.right>clip.right+.5 || frame.bottom>clip.bottom+.5) return false;
70
+ }
71
+ }
72
+ return true;
73
+ }
74
+ private RectF visibleClip(View view, RectF frame) {
75
+ if(frame==null)return null;
76
+ RectF clip=new RectF(frame);if(!clip.intersect(0,0,rootWidth,rootHeight))return null;
77
+ for(ViewParent p=view.getParent();p instanceof View;p=p.getParent())if(p instanceof ViewGroup && ((ViewGroup)p).getClipChildren()) {
78
+ RectF parent=geometry((View)p);if(parent==null || !clip.intersect(parent))return null;
79
+ }
80
+ return clip;
81
+ }
82
+ private Bitmap snapshot(View view, long budget) {
83
+ long pixels=(long)view.getWidth()*view.getHeight();
84
+ if (pixels<=0 || pixels>budget || unsupported(view)) return null;
85
+ Bitmap bitmap;
86
+ try { bitmap=Bitmap.createBitmap(view.getWidth(),view.getHeight(),Bitmap.Config.ARGB_8888); }
87
+ catch (OutOfMemoryError error) { return null; }
88
+ int visibility=view.getVisibility();
89
+ try { view.setVisibility(VISIBLE); view.draw(new Canvas(bitmap)); }
90
+ catch (RuntimeException | OutOfMemoryError error) { bitmap.recycle(); return null; }
91
+ finally { view.setVisibility(visibility); }
92
+ return bitmap;
93
+ }
94
+ private void hide(View view) {
95
+ if (!hidden.containsKey(view)) hidden.put(view,view.getVisibility());
96
+ view.setVisibility(INVISIBLE);
97
+ }
98
+ public static SharedLayoutFlight capture(View view, boolean image, double radius, double maxPixels) {
99
+ if (!(view.getRootView() instanceof ViewGroup)) return null;
100
+ SharedLayoutFlight f=new SharedLayoutFlight(view);
101
+ RectF rect=f.geometry(view);
102
+ if (!f.visibleBounds(view,rect) || view.getVisibility()!=VISIBLE) return null;
103
+ Bitmap bitmap=f.snapshot(view,(long)maxPixels); if (bitmap==null) return null;
104
+ f.source=bitmap; f.sourceWidth=rect.width(); f.sourceHeight=rect.height(); f.sourceImage=image;
105
+ f.pose[0]=rect.left/f.density; f.pose[1]=rect.top/f.density; f.pose[2]=rect.width()/f.density; f.pose[3]=rect.height()/f.density; f.pose[4]=radius*rect.width()/view.getWidth();
106
+ f.hide(view); f.root.getOverlay().add(f); active++; return f;
107
+ }
108
+
109
+ private double[] navigationGeometry(View view, double radius) {
110
+ if(!(view instanceof ImageView)) return null;
111
+ ImageView image=(ImageView)view;
112
+ if(!(image.getDrawable() instanceof BitmapDrawable) || image.getColorFilter()!=null || image.getPaddingLeft()!=0 || image.getPaddingTop()!=0 || image.getPaddingRight()!=0 || image.getPaddingBottom()!=0) return null;
113
+ if(image.getScaleType()!=ImageView.ScaleType.FIT_CENTER && image.getScaleType()!=ImageView.ScaleType.CENTER_CROP) return null;
114
+ Bitmap bitmap=((BitmapDrawable)image.getDrawable()).getBitmap(); if(bitmap==null || bitmap.isRecycled())return null;
115
+ RectF rect=geometry(view), clip=clippedImage?visibleClip(view,rect):rect;
116
+ if(clippedImage?clip==null:!visibleBounds(view,rect))return null;
117
+ double scale=image.getScaleType()==ImageView.ScaleType.CENTER_CROP?Math.max(rect.width()/bitmap.getWidth(),rect.height()/bitmap.getHeight()):Math.min(rect.width()/bitmap.getWidth(),rect.height()/bitmap.getHeight());
118
+ double w=bitmap.getWidth()*scale,h=bitmap.getHeight()*scale;
119
+ double[] pose=new double[]{rect.left/density,rect.top/density,rect.width()/density,rect.height()/density,radius*rect.width()/view.getWidth(),(rect.width()-w)/2/density,(rect.height()-h)/2/density,w/density,h/density};
120
+ if(!clippedImage)return pose;
121
+ double[] clipped=Arrays.copyOf(pose,13);clipped[9]=clip.left/density;clipped[10]=clip.top/density;clipped[11]=clip.width()/density;clipped[12]=clip.height()/density;return clipped;
122
+ }
123
+ public static SharedLayoutFlight captureNavigationImage(View view, double radius, double maxPixels) {
124
+ return captureNavigationImage(view,radius,maxPixels,false);
125
+ }
126
+ public static SharedLayoutFlight captureClippedNavigationImage(View view, double radius, double maxPixels) {
127
+ return captureNavigationImage(view,radius,maxPixels,true);
128
+ }
129
+ private static SharedLayoutFlight captureNavigationImage(View view, double radius, double maxPixels, boolean clipped) {
130
+ if(!(view.getRootView() instanceof ViewGroup) || view.getVisibility()!=VISIBLE)return null;
131
+ SharedLayoutFlight f=new SharedLayoutFlight(view);
132
+ f.clippedImage=clipped;
133
+ double[] pose=f.navigationGeometry(view,radius); if(pose==null)return null;
134
+ Bitmap image=((BitmapDrawable)((ImageView)view).getDrawable()).getBitmap();
135
+ if((long)image.getWidth()*image.getHeight()>maxPixels)return null;
136
+ f.navigationImage=true; f.source=image;
137
+ for(int i=0;i<pose.length;i++)f.pose[i<5?i:i+1]=pose[i];
138
+ f.hide(view); f.root.getOverlay().add(f); active++; return f;
139
+ }
140
+ public String prepareNavigationImage(View view, double radius, double maxPixels) {
141
+ if(disposed || !navigationImage || view.getVisibility()!=VISIBLE)return null;
142
+ double[] geometry=navigationGeometry(view,radius); if(geometry==null)return null;
143
+ Bitmap image=((BitmapDrawable)((ImageView)view).getDrawable()).getBitmap();
144
+ if((long)image.getWidth()*image.getHeight()+pixels()>maxPixels || Math.abs((double)image.getWidth()/image.getHeight()-(double)source.getWidth()/source.getHeight())>.001)return null;
145
+ target=image; destination=view; destinationFrame=geometry(view); hide(view);
146
+ try { return new JSONArray(geometry).toString(); } catch(JSONException error) { throw new IllegalStateException(error); }
147
+ }
148
+
149
+ public boolean holdPage(View page,double maxPixels) {
150
+ if(disposed || pageBitmap!=null || page==null || unsupported(page, true))return false;
151
+ RectF frame=geometry(page);if(frame==null)return false;
152
+ long pixels=(long)page.getWidth()*page.getHeight();if(pixels<=0 || pixels+pixels()>maxPixels)return false;
153
+ try {pageBitmap=Bitmap.createBitmap(page.getWidth(),page.getHeight(),Bitmap.Config.ARGB_8888);page.draw(new Canvas(pageBitmap));}
154
+ catch(RuntimeException | OutOfMemoryError error){if(pageBitmap!=null)pageBitmap.recycle();pageBitmap=null;return false;}
155
+ pageFrame=frame;return true;
156
+ }
157
+ public void fade(double milliseconds,Listener callback) {
158
+ if(disposed){if(callback!=null)callback.onEnd(false);return;}
159
+ Choreographer.getInstance().removeFrameCallback(this);fading=true;running=true;duration=Math.max(1,Math.min(500,milliseconds));started=android.os.SystemClock.uptimeMillis();listener=callback;
160
+ Choreographer.getInstance().postFrameCallback(this);
161
+ }
162
+ public double pixels() { return (pageBitmap==null?0:(long)pageBitmap.getWidth()*pageBitmap.getHeight())+(source==null?0:(long)source.getWidth()*source.getHeight())+(target==null?0:(long)target.getWidth()*target.getHeight()); }
163
+ public String state() {
164
+ try { JSONObject out=new JSONObject(); out.put("pose",new JSONArray(java.util.Arrays.copyOf(pose,navigationImage?(clippedImage?14:10):6))); out.put("velocity",new JSONArray(java.util.Arrays.copyOf(velocity,navigationImage?(clippedImage?14:10):5))); return out.toString(); }
165
+ catch (JSONException error) { throw new IllegalStateException(error); }
166
+ }
167
+ public String prepare(View view, boolean image, double radius, double maxPixels) {
168
+ if (disposed || (view.getVisibility()!=VISIBLE && !hidden.containsKey(view))) return null;
169
+ RectF rect=geometry(view);
170
+ if (!visibleBounds(view,rect)) return null;
171
+ Bitmap bitmap=snapshot(view,(long)(maxPixels-pixels())); if(bitmap==null) return null;
172
+ if(target!=null) target.recycle(); target=bitmap; targetWidth=rect.width(); targetHeight=rect.height(); targetImage=image;
173
+ destination=view; destinationFrame=rect; hide(view);
174
+ try { return new JSONArray(new double[]{rect.left/density,rect.top/density,rect.width()/density,rect.height()/density,radius*rect.width()/view.getWidth()}).toString(); } catch(JSONException error) { throw new IllegalStateException(error); }
175
+ }
176
+ static final class Anchor {
177
+ Bitmap bitmap; boolean image; double[] geometry; float width,height;
178
+ void dispose() { if(!image && bitmap!=null)bitmap.recycle(); bitmap=null; }
179
+ long pixels() { return bitmap==null?0:(long)bitmap.getWidth()*bitmap.getHeight(); }
180
+ }
181
+ static Anchor anchor(View view, boolean image, double radius, double budget) {
182
+ if(view==null || !(view.getRootView() instanceof ViewGroup) || view.getVisibility()!=VISIBLE)return null;
183
+ SharedLayoutFlight probe=new SharedLayoutFlight(view);
184
+ RectF rect=probe.geometry(view); if(!probe.visibleBounds(view,rect))return null;
185
+ Anchor a=new Anchor(); a.image=image; a.width=rect.width(); a.height=rect.height();
186
+ if(image) {
187
+ a.geometry=probe.navigationGeometry(view,radius); if(a.geometry==null)return null;
188
+ a.bitmap=((BitmapDrawable)((ImageView)view).getDrawable()).getBitmap();
189
+ if(a.pixels()>budget)return null;
190
+ } else {
191
+ a.bitmap=probe.snapshot(view,(long)budget); if(a.bitmap==null)return null;
192
+ a.geometry=new double[]{rect.left/probe.density,rect.top/probe.density,rect.width()/probe.density,rect.height()/probe.density,radius*rect.width()/view.getWidth()};
193
+ }
194
+ return a;
195
+ }
196
+ boolean prepareAnchor(Anchor anchor, double budget) {
197
+ if(disposed || anchor==null || anchor.bitmap==null || navigationImage!=anchor.image || pixels()+anchor.pixels()>budget)return false;
198
+ if(navigationImage && Math.abs((double)source.getWidth()/source.getHeight()-(double)anchor.bitmap.getWidth()/anchor.bitmap.getHeight())>.001)return false;
199
+ target=anchor.bitmap; borrowedTarget=true; targetWidth=anchor.width; targetHeight=anchor.height; targetImage=false;
200
+ interactiveStart=pose.clone(); interactiveEnd=pose.clone();
201
+ for(int i=0;i<anchor.geometry.length;i++)interactiveEnd[i<5?i:i+1]=anchor.geometry[i];
202
+ interactiveEnd[5]=1; return true;
203
+ }
204
+ void updateInteractive(double progress) {
205
+ if(disposed || interactiveStart==null)return;
206
+ double p=Math.max(0,Math.min(1,Double.isFinite(progress)?progress:0));
207
+ for(int i=0;i<pose.length;i++)pose[i]=interactiveStart[i]+(interactiveEnd[i]-interactiveStart[i])*p;
208
+ invalidate();
209
+ }
210
+ public boolean freeze(double maxPixels) {
211
+ if(disposed) return false;
212
+ if(running) evaluate(android.os.SystemClock.uptimeMillis());
213
+ running=false; Choreographer.getInstance().removeFrameCallback(this); listener=null;
214
+ int w=Math.max(1,(int)Math.ceil(pose[2]*density)),h=Math.max(1,(int)Math.ceil(pose[3]*density));
215
+ if((long)w*h+pixels()>maxPixels) return false;
216
+ Bitmap bitmap;
217
+ try { bitmap=Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888); } catch(OutOfMemoryError error) { return false; }
218
+ Canvas canvas=new Canvas(bitmap); canvas.translate((float)-pose[0]*density,(float)-pose[1]*density); render(canvas);
219
+ if(source!=null && !navigationImage) source.recycle(); if(target!=null && !borrowedTarget) target.recycle();
220
+ source=bitmap; target=null; sourceWidth=(float)pose[2]*density; sourceHeight=(float)pose[3]*density; sourceImage=false; pose[5]=0;
221
+ destination=null; invalidate(); return true;
222
+ }
223
+ public void play(String json, Listener callback) {
224
+ if(disposed) return;
225
+ try {
226
+ JSONObject config=new JSONObject(json); JSONArray tracks=config.getJSONArray("tracks");
227
+ int count=navigationImage?(clippedImage?14:10):6; times=new double[count][]; values=new double[count][]; duration=0;
228
+ for(int k=0;k<(navigationImage?(clippedImage?14:10):6);k++) {
229
+ JSONObject track=tracks.getJSONObject(k); JSONArray t=track.getJSONArray("times"),v=track.getJSONArray("values");
230
+ times[k]=new double[t.length()]; values[k]=new double[v.length()];
231
+ for(int j=0;j<t.length();j++){times[k][j]=t.getDouble(j);values[k][j]=v.getDouble(j);}
232
+ duration=Math.max(duration,times[k][t.length()-1]);
233
+ }
234
+ } catch(JSONException error) { throw new IllegalArgumentException(error); }
235
+ listener=callback; started=android.os.SystemClock.uptimeMillis(); running=true;
236
+ Choreographer.getInstance().postFrameCallback(this);
237
+ }
238
+ private void evaluate(double now) {
239
+ double elapsed=Math.max(0,now-started);
240
+ for(int k=0;k<(navigationImage?(clippedImage?14:10):6);k++) {
241
+ double[] t=times[k],v=values[k]; int j=1;
242
+ while(j<t.length-1 && t[j]<elapsed)j++;
243
+ double span=t[j]-t[j-1], fraction=span<=0?1:Math.max(0,Math.min(1,(elapsed-t[j-1])/span));
244
+ pose[k]=v[j-1]+(v[j]-v[j-1])*fraction;
245
+ if(k!=5) velocity[k]=elapsed>=t[t.length-1]||span<=0?0:(v[j]-v[j-1])*1000/span;
246
+ }
247
+ }
248
+ @Override public void doFrame(long nanos) {
249
+ if(!running || disposed)return;
250
+ if(fading){double p=Math.min(1,(android.os.SystemClock.uptimeMillis()-started)/duration);setAlpha((float)(1-p));if(p>=1)end(true);else Choreographer.getInstance().postFrameCallback(this);return;}
251
+ RectF frame=geometry(destination);
252
+ if(root.getWidth()!=rootWidth || root.getHeight()!=rootHeight || frame==null || Math.abs(frame.left-destinationFrame.left)>1 || Math.abs(frame.top-destinationFrame.top)>1 || Math.abs(frame.width()-destinationFrame.width())>1 || Math.abs(frame.height()-destinationFrame.height())>1) { end(false); return; }
253
+ double now=android.os.SystemClock.uptimeMillis(); evaluate(now); invalidate();
254
+ if(now-started>=duration)end(true); else Choreographer.getInstance().postFrameCallback(this);
255
+ }
256
+ private void end(boolean completed) { Listener callback=listener; listener=null; running=false; Choreographer.getInstance().removeFrameCallback(this); if(callback!=null)callback.onEnd(completed); }
257
+ private void bitmap(Canvas canvas,Bitmap bitmap,float width,float height,boolean image,float alpha,RectF box) {
258
+ if(bitmap==null || alpha<=0)return;
259
+ float scale=image?Math.max(box.width()/width,box.height()/height):1;
260
+ float w=width*scale,h=height*scale;
261
+ paint.setAlpha(Math.round(alpha*255)); canvas.drawBitmap(bitmap,null,new RectF(box.centerX()-w/2,box.centerY()-h/2,box.centerX()+w/2,box.centerY()+h/2),paint);
262
+ }
263
+ private void render(Canvas canvas) {
264
+ if(pageBitmap!=null){paint.setAlpha((int)Math.round((1-Math.max(0,Math.min(1,pose[5])))*255));canvas.drawBitmap(pageBitmap,null,pageFrame,paint);}
265
+ RectF box=new RectF((float)pose[0]*density,(float)pose[1]*density,(float)(pose[0]+Math.max(.1,pose[2]))*density,(float)(pose[1]+Math.max(.1,pose[3]))*density);
266
+ float radius=(float)Math.max(0,Math.min(pose[4]*density,Math.min(box.width(),box.height())/2));
267
+ Path path=new Path(); path.addRoundRect(box,radius,radius,Path.Direction.CW); int save=canvas.save(); canvas.clipPath(path);
268
+ if(navigationImage) {
269
+ if(clippedImage)canvas.clipRect((float)pose[10]*density,(float)pose[11]*density,(float)(pose[10]+Math.max(0,pose[12]))*density,(float)(pose[11]+Math.max(0,pose[13]))*density);
270
+ paint.setAlpha(255);
271
+ canvas.drawBitmap(source,null,new RectF(box.left+(float)pose[6]*density,box.top+(float)pose[7]*density,box.left+(float)(pose[6]+Math.max(.1,pose[8]))*density,box.top+(float)(pose[7]+Math.max(.1,pose[9]))*density),paint);
272
+ canvas.restoreToCount(save); return;
273
+ }
274
+ int composite=canvas.saveLayer(box,null);
275
+ float mix=(float)Math.max(0,Math.min(1,pose[5]));
276
+ bitmap(canvas,source,sourceWidth,sourceHeight,sourceImage,1-mix,box);
277
+ paint.setXfermode(ADD); bitmap(canvas,target,targetWidth,targetHeight,targetImage,mix,box); paint.setXfermode(null);
278
+ canvas.restoreToCount(composite); canvas.restoreToCount(save);
279
+ }
280
+ @Override protected void onDraw(Canvas canvas) { render(canvas); }
281
+ public void dispose() {
282
+ if(disposed)return; disposed=true; running=false; listener=null;
283
+ Choreographer.getInstance().removeFrameCallback(this); root.getOverlay().remove(this); active--;
284
+ for(Map.Entry<View,Integer> entry:hidden.entrySet()) if(entry.getKey().getVisibility()==INVISIBLE)entry.getKey().setVisibility(entry.getValue()); hidden.clear();
285
+ if(!navigationImage) { if(source!=null)source.recycle(); if(target!=null && !borrowedTarget)target.recycle(); } source=null;target=null;destination=null;if(pageBitmap!=null)pageBitmap.recycle();pageBitmap=null;
286
+ }
287
+ }