@rafaelaugusto/jolt 0.1.0-beta.0 → 0.1.0-beta.10

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 (307) hide show
  1. package/README.md +441 -25
  2. package/dist/animate.d.ts +21 -5
  3. package/dist/animate.d.ts.map +1 -1
  4. package/dist/animate.js +205 -25
  5. package/dist/animate.js.map +1 -1
  6. package/dist/color.d.ts +11 -0
  7. package/dist/color.d.ts.map +1 -0
  8. package/dist/color.js +73 -0
  9. package/dist/color.js.map +1 -0
  10. package/dist/config.d.ts +31 -0
  11. package/dist/config.d.ts.map +1 -0
  12. package/dist/config.js +73 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/decay.d.ts +11 -0
  15. package/dist/decay.d.ts.map +1 -0
  16. package/dist/decay.js +22 -0
  17. package/dist/decay.js.map +1 -0
  18. package/dist/decoration.d.ts +18 -0
  19. package/dist/decoration.d.ts.map +1 -0
  20. package/dist/decoration.js +155 -0
  21. package/dist/decoration.js.map +1 -0
  22. package/dist/drag-input.d.ts +15 -0
  23. package/dist/drag-input.d.ts.map +1 -0
  24. package/dist/drag-input.js +66 -0
  25. package/dist/drag-input.js.map +1 -0
  26. package/dist/drag-physics.d.ts +20 -0
  27. package/dist/drag-physics.d.ts.map +1 -0
  28. package/dist/drag-physics.js +75 -0
  29. package/dist/drag-physics.js.map +1 -0
  30. package/dist/drag.d.ts +58 -0
  31. package/dist/drag.d.ts.map +1 -0
  32. package/dist/drag.js +324 -0
  33. package/dist/drag.js.map +1 -0
  34. package/dist/driver/android-color.d.ts +20 -0
  35. package/dist/driver/android-color.d.ts.map +1 -0
  36. package/dist/driver/android-color.js +136 -0
  37. package/dist/driver/android-color.js.map +1 -0
  38. package/dist/driver/android-decoration.d.ts +22 -0
  39. package/dist/driver/android-decoration.d.ts.map +1 -0
  40. package/dist/driver/android-decoration.js +139 -0
  41. package/dist/driver/android-decoration.js.map +1 -0
  42. package/dist/driver/android-playback.d.ts +13 -0
  43. package/dist/driver/android-playback.d.ts.map +1 -0
  44. package/dist/driver/android-playback.js +141 -0
  45. package/dist/driver/android-playback.js.map +1 -0
  46. package/dist/driver/android.d.ts +1 -1
  47. package/dist/driver/android.d.ts.map +1 -1
  48. package/dist/driver/android.js +165 -13
  49. package/dist/driver/android.js.map +1 -1
  50. package/dist/driver/index.d.ts +25 -2
  51. package/dist/driver/index.d.ts.map +1 -1
  52. package/dist/driver/index.js.map +1 -1
  53. package/dist/driver/ios-color.d.ts +16 -0
  54. package/dist/driver/ios-color.d.ts.map +1 -0
  55. package/dist/driver/ios-color.js +392 -0
  56. package/dist/driver/ios-color.js.map +1 -0
  57. package/dist/driver/ios-decoration.d.ts +17 -0
  58. package/dist/driver/ios-decoration.d.ts.map +1 -0
  59. package/dist/driver/ios-decoration.js +271 -0
  60. package/dist/driver/ios-decoration.js.map +1 -0
  61. package/dist/driver/ios-layout.d.ts +9 -0
  62. package/dist/driver/ios-layout.d.ts.map +1 -0
  63. package/dist/driver/ios-layout.js +52 -0
  64. package/dist/driver/ios-layout.js.map +1 -0
  65. package/dist/driver/ios-playback.d.ts +10 -0
  66. package/dist/driver/ios-playback.d.ts.map +1 -0
  67. package/dist/driver/ios-playback.js +47 -0
  68. package/dist/driver/ios-playback.js.map +1 -0
  69. package/dist/driver/ios-shadow.d.ts +6 -0
  70. package/dist/driver/ios-shadow.d.ts.map +1 -0
  71. package/dist/driver/ios-shadow.js +52 -0
  72. package/dist/driver/ios-shadow.js.map +1 -0
  73. package/dist/driver/ios.d.ts.map +1 -1
  74. package/dist/driver/ios.js +164 -20
  75. package/dist/driver/ios.js.map +1 -1
  76. package/dist/engine.d.ts +76 -5
  77. package/dist/engine.d.ts.map +1 -1
  78. package/dist/engine.js +303 -23
  79. package/dist/engine.js.map +1 -1
  80. package/dist/haptics.d.ts +21 -0
  81. package/dist/haptics.d.ts.map +1 -0
  82. package/dist/haptics.js +120 -0
  83. package/dist/haptics.js.map +1 -0
  84. package/dist/image-effect-native.d.ts +26 -0
  85. package/dist/image-effect-native.d.ts.map +1 -0
  86. package/dist/image-effect-native.js +73 -0
  87. package/dist/image-effect-native.js.map +1 -0
  88. package/dist/image-effect.d.ts +50 -0
  89. package/dist/image-effect.d.ts.map +1 -0
  90. package/dist/image-effect.js +290 -0
  91. package/dist/image-effect.js.map +1 -0
  92. package/dist/image-owner.d.ts +3 -0
  93. package/dist/image-owner.d.ts.map +1 -0
  94. package/dist/image-owner.js +11 -0
  95. package/dist/image-owner.js.map +1 -0
  96. package/dist/index.d.ts +45 -4
  97. package/dist/index.d.ts.map +1 -1
  98. package/dist/index.js +21 -2
  99. package/dist/index.js.map +1 -1
  100. package/dist/interaction-surface.d.ts +12 -0
  101. package/dist/interaction-surface.d.ts.map +1 -0
  102. package/dist/interaction-surface.js +36 -0
  103. package/dist/interaction-surface.js.map +1 -0
  104. package/dist/items.d.ts +20 -0
  105. package/dist/items.d.ts.map +1 -0
  106. package/dist/items.js +109 -0
  107. package/dist/items.js.map +1 -0
  108. package/dist/keyboard.d.ts +41 -0
  109. package/dist/keyboard.d.ts.map +1 -0
  110. package/dist/keyboard.js +256 -0
  111. package/dist/keyboard.js.map +1 -0
  112. package/dist/label.d.ts +7 -0
  113. package/dist/label.d.ts.map +1 -0
  114. package/dist/label.js +60 -0
  115. package/dist/label.js.map +1 -0
  116. package/dist/layout.d.ts +13 -0
  117. package/dist/layout.d.ts.map +1 -0
  118. package/dist/layout.js +348 -0
  119. package/dist/layout.js.map +1 -0
  120. package/dist/liquid-grid.d.ts +3 -0
  121. package/dist/liquid-grid.d.ts.map +1 -0
  122. package/dist/liquid-grid.js +24 -0
  123. package/dist/liquid-grid.js.map +1 -0
  124. package/dist/liquid.d.ts +18 -0
  125. package/dist/liquid.d.ts.map +1 -0
  126. package/dist/liquid.js +234 -0
  127. package/dist/liquid.js.map +1 -0
  128. package/dist/loader.d.ts +19 -0
  129. package/dist/loader.d.ts.map +1 -0
  130. package/dist/loader.js +173 -0
  131. package/dist/loader.js.map +1 -0
  132. package/dist/motion-scope.d.ts +39 -0
  133. package/dist/motion-scope.d.ts.map +1 -0
  134. package/dist/motion-scope.js +238 -0
  135. package/dist/motion-scope.js.map +1 -0
  136. package/dist/motion-states.d.ts +36 -0
  137. package/dist/motion-states.d.ts.map +1 -0
  138. package/dist/motion-states.js +165 -0
  139. package/dist/motion-states.js.map +1 -0
  140. package/dist/particles.d.ts +39 -0
  141. package/dist/particles.d.ts.map +1 -0
  142. package/dist/particles.js +265 -0
  143. package/dist/particles.js.map +1 -0
  144. package/dist/path.d.ts +12 -0
  145. package/dist/path.d.ts.map +1 -0
  146. package/dist/path.js +90 -0
  147. package/dist/path.js.map +1 -0
  148. package/dist/playback-group.d.ts +6 -0
  149. package/dist/playback-group.d.ts.map +1 -0
  150. package/dist/playback-group.js +141 -0
  151. package/dist/playback-group.js.map +1 -0
  152. package/dist/playback.d.ts +25 -0
  153. package/dist/playback.d.ts.map +1 -0
  154. package/dist/playback.js +35 -0
  155. package/dist/playback.js.map +1 -0
  156. package/dist/presets.d.ts +16 -1
  157. package/dist/presets.d.ts.map +1 -1
  158. package/dist/presets.js +24 -6
  159. package/dist/presets.js.map +1 -1
  160. package/dist/press.d.ts.map +1 -1
  161. package/dist/press.js +25 -7
  162. package/dist/press.js.map +1 -1
  163. package/dist/properties.d.ts +6 -3
  164. package/dist/properties.d.ts.map +1 -1
  165. package/dist/properties.js +26 -2
  166. package/dist/properties.js.map +1 -1
  167. package/dist/reveal.d.ts +25 -0
  168. package/dist/reveal.d.ts.map +1 -0
  169. package/dist/reveal.js +294 -0
  170. package/dist/reveal.js.map +1 -0
  171. package/dist/roll-diff.d.ts +22 -0
  172. package/dist/roll-diff.d.ts.map +1 -0
  173. package/dist/roll-diff.js +36 -0
  174. package/dist/roll-diff.js.map +1 -0
  175. package/dist/roll.d.ts +29 -0
  176. package/dist/roll.d.ts.map +1 -0
  177. package/dist/roll.js +442 -0
  178. package/dist/roll.js.map +1 -0
  179. package/dist/scroll-linked.d.ts +10 -0
  180. package/dist/scroll-linked.d.ts.map +1 -0
  181. package/dist/scroll-linked.js +58 -0
  182. package/dist/scroll-linked.js.map +1 -0
  183. package/dist/sequence.d.ts +13 -7
  184. package/dist/sequence.d.ts.map +1 -1
  185. package/dist/sequence.js +214 -19
  186. package/dist/sequence.js.map +1 -1
  187. package/dist/shimmer.d.ts +12 -0
  188. package/dist/shimmer.d.ts.map +1 -0
  189. package/dist/shimmer.js +161 -0
  190. package/dist/shimmer.js.map +1 -0
  191. package/dist/svg-path.d.ts +14 -0
  192. package/dist/svg-path.d.ts.map +1 -0
  193. package/dist/svg-path.js +281 -0
  194. package/dist/svg-path.js.map +1 -0
  195. package/dist/symbol-effect.d.ts +23 -0
  196. package/dist/symbol-effect.d.ts.map +1 -0
  197. package/dist/symbol-effect.js +187 -0
  198. package/dist/symbol-effect.js.map +1 -0
  199. package/dist/text-layout.d.ts +30 -0
  200. package/dist/text-layout.d.ts.map +1 -0
  201. package/dist/text-layout.js +185 -0
  202. package/dist/text-layout.js.map +1 -0
  203. package/dist/text.d.ts +17 -0
  204. package/dist/text.d.ts.map +1 -0
  205. package/dist/text.js +263 -0
  206. package/dist/text.js.map +1 -0
  207. package/dist/track.d.ts +3 -1
  208. package/dist/track.d.ts.map +1 -1
  209. package/dist/track.js +266 -13
  210. package/dist/track.js.map +1 -1
  211. package/dist/transition.d.ts +17 -1
  212. package/dist/transition.d.ts.map +1 -1
  213. package/dist/transition.js +41 -6
  214. package/dist/transition.js.map +1 -1
  215. package/dist/types.d.ts +50 -1
  216. package/dist/types.d.ts.map +1 -1
  217. package/dist/vue/index.d.ts +95 -0
  218. package/dist/vue/index.d.ts.map +1 -0
  219. package/dist/vue/index.js +163 -0
  220. package/dist/vue/index.js.map +1 -0
  221. package/dist/zoom-native.d.ts +30 -0
  222. package/dist/zoom-native.d.ts.map +1 -0
  223. package/dist/zoom-native.js +56 -0
  224. package/dist/zoom-native.js.map +1 -0
  225. package/dist/zoomable.d.ts +48 -0
  226. package/dist/zoomable.d.ts.map +1 -0
  227. package/dist/zoomable.js +249 -0
  228. package/dist/zoomable.js.map +1 -0
  229. package/package.json +33 -5
  230. package/platforms/android/include.gradle +7 -0
  231. package/platforms/android/java/org/rafaelaugusto/jolt/ColorTarget.java +102 -0
  232. package/platforms/android/java/org/rafaelaugusto/jolt/DecorationTarget.java +154 -0
  233. package/platforms/android/java/org/rafaelaugusto/jolt/ImageEffect.java +288 -0
  234. package/platforms/android/java/org/rafaelaugusto/jolt/KeyboardFollower.java +91 -0
  235. package/platforms/android/java/org/rafaelaugusto/jolt/KeyboardObserver.java +97 -0
  236. package/platforms/android/java/org/rafaelaugusto/jolt/NumberRoll.java +190 -0
  237. package/platforms/android/java/org/rafaelaugusto/jolt/PhotoZoom.java +250 -0
  238. package/platforms/android/java/org/rafaelaugusto/jolt/TextReveal.java +180 -0
  239. package/platforms/android/proguard-rules.pro +19 -0
  240. package/platforms/ios/build.xcconfig +1 -0
  241. package/platforms/ios/src/JoltImageEffect.h +25 -0
  242. package/platforms/ios/src/JoltImageEffect.mm +242 -0
  243. package/platforms/ios/src/JoltInteractiveAnimation.h +18 -0
  244. package/platforms/ios/src/JoltInteractiveAnimation.m +123 -0
  245. package/platforms/ios/src/JoltPhotoZoom.h +23 -0
  246. package/platforms/ios/src/JoltPhotoZoom.m +229 -0
  247. package/platforms/ios/src/module.modulemap +6 -0
  248. package/src/android-plugin.d.ts +155 -0
  249. package/src/animate.ts +278 -38
  250. package/src/color.ts +101 -0
  251. package/src/config.ts +84 -0
  252. package/src/decay.ts +45 -0
  253. package/src/decoration.ts +180 -0
  254. package/src/drag-input.ts +74 -0
  255. package/src/drag-physics.ts +110 -0
  256. package/src/drag.ts +395 -0
  257. package/src/driver/android-color.ts +170 -0
  258. package/src/driver/android-decoration.ts +182 -0
  259. package/src/driver/android-playback.ts +157 -0
  260. package/src/driver/android.ts +208 -20
  261. package/src/driver/index.ts +37 -2
  262. package/src/driver/ios-color.ts +441 -0
  263. package/src/driver/ios-decoration.ts +332 -0
  264. package/src/driver/ios-layout.ts +63 -0
  265. package/src/driver/ios-playback.ts +51 -0
  266. package/src/driver/ios-shadow.ts +50 -0
  267. package/src/driver/ios.ts +194 -25
  268. package/src/engine.ts +329 -27
  269. package/src/haptics.ts +148 -0
  270. package/src/image-effect-native.ts +129 -0
  271. package/src/image-effect.ts +336 -0
  272. package/src/image-owner.ts +12 -0
  273. package/src/index.ts +61 -4
  274. package/src/interaction-surface.ts +41 -0
  275. package/src/ios-plugin.d.ts +81 -0
  276. package/src/items.ts +140 -0
  277. package/src/keyboard.ts +291 -0
  278. package/src/label.ts +76 -0
  279. package/src/layout.ts +408 -0
  280. package/src/liquid-grid.ts +28 -0
  281. package/src/liquid.ts +287 -0
  282. package/src/loader.ts +202 -0
  283. package/src/motion-scope.ts +279 -0
  284. package/src/motion-states.ts +215 -0
  285. package/src/particles.ts +323 -0
  286. package/src/path.ts +124 -0
  287. package/src/playback-group.ts +143 -0
  288. package/src/playback.ts +62 -0
  289. package/src/presets.ts +31 -7
  290. package/src/press.ts +32 -10
  291. package/src/properties.ts +32 -6
  292. package/src/reveal.ts +374 -0
  293. package/src/roll-diff.ts +57 -0
  294. package/src/roll.ts +515 -0
  295. package/src/scroll-linked.ts +73 -0
  296. package/src/sequence.ts +212 -19
  297. package/src/shimmer.ts +180 -0
  298. package/src/svg-path.ts +355 -0
  299. package/src/symbol-effect.ts +226 -0
  300. package/src/text-layout.ts +228 -0
  301. package/src/text.ts +279 -0
  302. package/src/track.ts +347 -12
  303. package/src/transition.ts +63 -6
  304. package/src/types.ts +51 -1
  305. package/src/vue/index.ts +231 -0
  306. package/src/zoom-native.ts +124 -0
  307. package/src/zoomable.ts +330 -0
package/src/driver/ios.ts CHANGED
@@ -1,13 +1,26 @@
1
- import type { View } from '@nativescript/core'
2
- import type { Property } from '../properties.js'
1
+ import { iosPlayback } from './ios-playback.js'
2
+ import { isDecorationProperty } from '../decoration.js'
3
+ import {
4
+ playIOSDecoration,
5
+ presentedIOSDecoration,
6
+ syncIOSDecoration,
7
+ } from './ios-decoration.js'
8
+ import { Application, type View } from '@nativescript/core'
9
+ import { stopView } from '../engine.js'
10
+ import type { NumericProperty } from '../properties.js'
11
+ import { isColorProperty } from '../color.js'
12
+ import { playIOSColor, presentedIOSColor } from './ios-color.js'
3
13
  import { after, type Driver } from './index.js'
14
+ import { hasInteractionSurface } from '../interaction-surface.js'
15
+ import { retainInteractiveLayout } from './ios-layout.js'
4
16
 
5
17
  interface Handle {
6
- layers: CALayer[]
7
- key: string
18
+ stop(): void
19
+ elapsed(): number
20
+ control(elapsed: number, paused: boolean): void
8
21
  }
9
22
 
10
- const keyPaths: Record<Property, string> = {
23
+ const keyPaths: Record<NumericProperty, string> = {
11
24
  opacity: 'opacity',
12
25
  x: 'transform.translation.x',
13
26
  y: 'transform.translation.y',
@@ -48,41 +61,197 @@ export function createIOSDriver(): Driver {
48
61
  now: () => CACurrentMediaTime() * 1000,
49
62
 
50
63
  play(view, track, startedAt, onEnd): Handle {
64
+ if (isDecorationProperty(track.property))
65
+ return playIOSDecoration(view, track, startedAt, onEnd)
66
+ if (isColorProperty(track.property))
67
+ return playIOSColor(view, track, startedAt, onEnd)
51
68
  const layers = layersOf(view)
52
69
  const key = `jolt:${track.property}`
53
70
  const rotation = track.property.startsWith('rotate')
71
+ if (hasInteractionSurface(view)) {
72
+ if (typeof JoltInteractiveAnimation === 'undefined')
73
+ throw new Error('Rebuild the iOS app to enable Jolt interaction surfaces.')
74
+ if (track.property === 'rotateX' || track.property === 'rotateY')
75
+ ensurePerspective(view, layers)
76
+ const releaseLayout = retainInteractiveLayout(view)
77
+ const suspend = () => stopView(view, [track.property])
78
+ const completed = (finished: boolean) => {
79
+ Application.off(Application.suspendEvent, suspend)
80
+ releaseLayout()
81
+ onEnd(finished)
82
+ }
83
+ let native: JoltInteractiveAnimation
84
+ try {
85
+ native =
86
+ JoltInteractiveAnimation.startViewLayersKeyPathValuesTimesDurationDelayRepeatReverseFinalValueStartedAtCompletion(
87
+ view.nativeViewProtected,
88
+ NSArray.arrayWithArray(layers),
89
+ keyPaths[track.property as NumericProperty],
90
+ NSArray.arrayWithArray(
91
+ track.values.map((value) => (rotation ? radians(value) : value)),
92
+ ),
93
+ NSArray.arrayWithArray(track.times as number[]),
94
+ track.duration,
95
+ track.delay,
96
+ track.repeat,
97
+ track.reverse,
98
+ rotation ? radians(track.to) : track.to,
99
+ startedAt,
100
+ completed,
101
+ )
102
+ } catch (error) {
103
+ releaseLayout()
104
+ throw error
105
+ }
106
+ Application.on(Application.suspendEvent, suspend)
107
+ return {
108
+ elapsed: () => native.elapsed,
109
+ control: (time, paused) => native.controlPaused(time, paused),
110
+ stop: () => native.cancel(),
111
+ }
112
+ }
113
+ const infinite = track.repeat === Infinity
54
114
  if (track.property === 'rotateX' || track.property === 'rotateY') {
55
115
  ensurePerspective(view, layers)
56
116
  }
57
117
 
58
- const animation = CAKeyframeAnimation.animationWithKeyPath(keyPaths[track.property])
59
- animation.values = NSArray.arrayWithArray(
60
- track.values.map((value) => (rotation ? radians(value) : value)),
61
- )
62
- animation.keyTimes = NSArray.arrayWithArray(track.times as number[])
63
- animation.duration = Math.max(track.duration, 1) / 1000
64
- animation.beginTime = (startedAt + track.delay) / 1000
65
- animation.fillMode = kCAFillModeBackwards
66
- if (track.repeat > 0) {
67
- animation.autoreverses = track.reverse
68
- animation.repeatCount = track.reverse ? (track.repeat + 1) / 2 : track.repeat + 1
118
+ const timing = iosPlayback(track, startedAt)
119
+ let stopped = false,
120
+ generation = 0
121
+ const attach = () => {
122
+ const instance = ++generation
123
+ const animation = CAKeyframeAnimation.animationWithKeyPath(
124
+ keyPaths[track.property as NumericProperty],
125
+ )
126
+ // iOS 15+. The app must opt in through CADisableMinimumFrameDurationOnPhone.
127
+ if (animation.respondsToSelector('setPreferredFrameRateRange:')) {
128
+ const nativeView = view.nativeViewProtected as UIView
129
+ const screen = nativeView.window?.screen ?? UIScreen.mainScreen
130
+ const maximum = Math.min(120, screen.maximumFramesPerSecond)
131
+ animation.preferredFrameRateRange = CAFrameRateRangeMake(
132
+ Math.min(80, maximum),
133
+ maximum,
134
+ maximum,
135
+ )
136
+ }
137
+ animation.values = NSArray.arrayWithArray(
138
+ track.values.map((value) => (rotation ? radians(value) : value)),
139
+ )
140
+ animation.keyTimes = NSArray.arrayWithArray(track.times as number[])
141
+ animation.duration = Math.max(track.duration, 1) / 1000
142
+ // Keep infinite loops when iOS removes animations on backgrounding.
143
+ // They are removed explicitly when stopped or replaced.
144
+ if (track.repeat > 0) {
145
+ animation.autoreverses = track.reverse
146
+ animation.repeatCount = track.reverse
147
+ ? (track.repeat + 1) / 2
148
+ : track.repeat + 1
149
+ }
150
+
151
+ CATransaction.begin()
152
+ if (!timing.paused && !infinite)
153
+ CATransaction.setCompletionBlock(() => {
154
+ if (stopped || instance !== generation) return
155
+ stopped = true
156
+ onEnd()
157
+ })
158
+ for (const layer of layers) {
159
+ timing.configure(animation, layer)
160
+ layer.addAnimationForKey(animation, key)
161
+ }
162
+ CATransaction.commit()
69
163
  }
164
+ attach()
165
+ return {
166
+ elapsed: timing.elapsed,
167
+ control(time, paused) {
168
+ if (!stopped) {
169
+ timing.control(time, paused)
170
+ attach()
171
+ }
172
+ },
173
+ stop() {
174
+ if (stopped) return
175
+ stopped = true
176
+ generation++
177
+ for (const layer of layers) layer.removeAnimationForKey(key)
178
+ onEnd(false)
179
+ },
180
+ }
181
+ },
70
182
 
71
- CATransaction.begin()
72
- CATransaction.setCompletionBlock(onEnd)
73
- for (const layer of layers) layer.addAnimationForKey(animation, key)
74
- CATransaction.commit()
183
+ stop(_view, handle) {
184
+ ;(handle as Handle).stop()
185
+ },
186
+ control(_view, handle, elapsed, paused) {
187
+ ;(handle as Handle).control(elapsed, paused)
188
+ },
189
+ elapsed: (handle) => (handle as Handle).elapsed(),
75
190
 
76
- return { layers, key }
191
+ sync(view, excluding) {
192
+ syncIOSDecoration(view, excluding)
193
+ if (view.nativeViewProtected && typeof JoltInteractiveAnimation !== 'undefined')
194
+ JoltInteractiveAnimation.syncViewExcluding(
195
+ view.nativeViewProtected,
196
+ excluding ? (keyPaths[excluding as NumericProperty] ?? null) : null,
197
+ )
77
198
  },
78
199
 
79
- stop(_view, handle) {
80
- const { layers, key } = handle as Handle
81
- for (const layer of layers) layer.removeAnimationForKey(key)
200
+ presented(view, property) {
201
+ if (isDecorationProperty(property)) return presentedIOSDecoration(view, property)
202
+ if (isColorProperty(property)) return presentedIOSColor(view, property)
203
+ if (!view.nativeViewProtected || typeof JoltInteractiveAnimation === 'undefined')
204
+ return undefined
205
+ const value = JoltInteractiveAnimation.valueForViewKeyPath(
206
+ view.nativeViewProtected,
207
+ keyPaths[property],
208
+ )
209
+ if (value === null || value === undefined) return undefined
210
+ return property.startsWith('rotate') ? (value * 180) / Math.PI : Number(value)
82
211
  },
83
212
 
84
- presented: () => undefined,
213
+ layoutFrame(view) {
214
+ const native = view.nativeViewProtected as UIView | undefined
215
+ if (!native) return undefined
216
+ const { width, height } = native.bounds.size
217
+ const { position, anchorPoint } = native.layer
218
+ return {
219
+ x: position.x - width * anchorPoint.x,
220
+ y: position.y - height * anchorPoint.y,
221
+ width,
222
+ height,
223
+ }
224
+ },
225
+
226
+ afterLayout(view, callback) {
227
+ const original = view.layout
228
+ const descriptor = Object.getOwnPropertyDescriptor(view, 'layout')
229
+ let active = true
230
+ const detach = () => {
231
+ active = false
232
+ if (view.layout !== wrapper) return
233
+ if (descriptor) Object.defineProperty(view, 'layout', descriptor)
234
+ else delete (view as Partial<View>).layout
235
+ }
236
+ const wrapper: View['layout'] = function (this: View, ...args) {
237
+ original.apply(this, args)
238
+ if (active) {
239
+ detach()
240
+ callback()
241
+ }
242
+ }
243
+ view.layout = wrapper
244
+ return detach
245
+ },
85
246
 
86
247
  after,
248
+
249
+ reducedMotion: () => UIAccessibilityIsReduceMotionEnabled(),
250
+
251
+ watchReducedMotion(callback) {
252
+ const name = UIAccessibilityReduceMotionStatusDidChangeNotification
253
+ const observer = Application.ios.addNotificationObserver(name, callback)
254
+ return () => Application.ios.removeNotificationObserver(observer, name)
255
+ },
87
256
  }
88
257
  }