@apexnative/navigation 1.0.0-alpha.6 → 1.0.0-alpha.7

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 (236) hide show
  1. package/ApexNavigation.podspec +2 -1
  2. package/CHANGELOG.md +7 -0
  3. package/android/CLAUDE.md +19 -10
  4. package/android/CORE.md +3 -2
  5. package/android/consumer-rules.pro +6 -0
  6. package/android/src/main/java/dev/apexnative/navigation/options/BottomTabOptions.kt +1 -1
  7. package/android/src/main/java/dev/apexnative/navigation/options/ButtonOptions.kt +1 -1
  8. package/android/src/main/java/dev/apexnative/navigation/options/LargeTitleOptions.kt +1 -1
  9. package/android/src/main/java/dev/apexnative/navigation/options/LayoutAnimation.kt +1 -1
  10. package/android/src/main/java/dev/apexnative/navigation/options/OptionKey.kt +18 -0
  11. package/android/src/main/java/dev/apexnative/navigation/options/OptionPaths.kt +91 -0
  12. package/android/src/main/java/dev/apexnative/navigation/options/SheetOptions.kt +7 -4
  13. package/android/src/main/java/dev/apexnative/navigation/options/TitleOptions.kt +2 -2
  14. package/android/src/main/java/dev/apexnative/navigation/options/TopBarAppearanceOptions.kt +1 -1
  15. package/android/src/main/java/dev/apexnative/navigation/options/TopBarOptions.kt +16 -7
  16. package/android/src/main/java/dev/apexnative/navigation/react/ContentHeights.kt +95 -0
  17. package/android/src/main/java/dev/apexnative/navigation/react/ContentMounts.kt +66 -0
  18. package/android/src/main/java/dev/apexnative/navigation/react/NavigationTurboModule.kt +4 -0
  19. package/android/src/main/java/dev/apexnative/navigation/react/OptionsCommands.kt +41 -3
  20. package/android/src/main/java/dev/apexnative/navigation/react/ReactView.kt +16 -1
  21. package/android/src/main/java/dev/apexnative/navigation/slots/SlotScreenView.kt +27 -7
  22. package/android/src/main/java/dev/apexnative/navigation/slots/SlotView.kt +12 -1
  23. package/android/src/main/java/dev/apexnative/navigation/utils/MaterialTheme.kt +5 -6
  24. package/android/src/main/java/dev/apexnative/navigation/utils/SystemAnimations.kt +36 -0
  25. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalSheet.kt +329 -55
  26. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalViews.kt +26 -5
  27. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetStops.kt +60 -2
  28. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuMotion.kt +8 -2
  29. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/BackPreview.kt +32 -4
  30. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt +46 -7
  31. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackQueue.kt +15 -3
  32. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackViews.kt +7 -4
  33. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabMotion.kt +142 -0
  34. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabPresenter.kt +215 -43
  35. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/StackSearchPresenter.kt +25 -26
  36. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarRowTransition.kt +3 -2
  37. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/ButtonPlaces.kt +11 -5
  38. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarPresenter.kt +36 -38
  39. package/android/src/main/java/dev/apexnative/navigation/views/element/ElementTransitions.kt +124 -181
  40. package/android/src/main/java/dev/apexnative/navigation/views/element/TargetsWait.kt +8 -1
  41. package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionLayer.kt +37 -112
  42. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ElementPictures.kt +56 -3
  43. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/FlightGeometry.kt +170 -153
  44. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMorph.kt +199 -0
  45. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/SharedAnimatorFactory.kt +55 -45
  46. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/{TextChangeAnimator.kt → TextMorph.kt} +79 -129
  47. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewMorph.kt +108 -0
  48. package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabCopy.kt +85 -0
  49. package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabMenu.kt +13 -0
  50. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TitleBar.kt +5 -24
  51. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TopBar.kt +51 -34
  52. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonComponentCell.kt +6 -6
  53. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonView.kt +113 -0
  54. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarMenu.kt +219 -0
  55. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonBar.kt +121 -175
  56. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonMenus.kt +34 -64
  57. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonRow.kt +216 -0
  58. package/android/src/main/jni/ANNContentHeights.cpp +82 -0
  59. package/android/src/main/res/drawable/apex_navigation_ic_arrow_right.xml +14 -0
  60. package/android/src/main/res/layout/apex_navigation_menu_header.xml +19 -0
  61. package/android/src/main/res/layout/apex_navigation_menu_item.xml +68 -0
  62. package/android/src/main/res/values/styles.xml +1 -1
  63. package/android/src/main/res/values-night/styles.xml +1 -1
  64. package/cli/doctor/checks/app.js +16 -1
  65. package/cli/project.js +4 -0
  66. package/cli/setup/index.js +5 -0
  67. package/cli/setup/steps/metro.js +46 -0
  68. package/docs-md/architecture/native-screens.md +4 -0
  69. package/docs-md/architecture/theme-and-context.md +131 -12
  70. package/docs-md/architecture/transitions.md +43 -4
  71. package/docs-md/flows/bottom-sheets.md +4 -2
  72. package/docs-md/fundamentals/screens-and-props.md +9 -1
  73. package/docs-md/guides/cli.md +3 -1
  74. package/docs-md/help/troubleshooting.md +1 -1
  75. package/docs-md/index.json +29 -1
  76. package/docs-md/screen-ui/back-and-gestures.md +3 -1
  77. package/docs-md/screen-ui/bar-buttons.md +1 -1
  78. package/docs-md/screen-ui/toolbar-and-fab.md +2 -0
  79. package/docs-md/start/installation.md +16 -1
  80. package/ios/Animations/ANNFrameDriver.h +55 -15
  81. package/ios/Animations/ANNFrameDriver.mm +214 -60
  82. package/ios/Animations/ANNTransitionAnimator.h +26 -5
  83. package/ios/Animations/ANNTransitionAnimator.mm +49 -3
  84. package/ios/Animations/ANNTransitionPlan.h +2 -2
  85. package/ios/Animations/ANNTransitionPlan.mm +10 -0
  86. package/ios/Animations/Elements/ANNElementFinder.h +2 -2
  87. package/ios/Animations/Elements/ANNElementFinder.mm +2 -2
  88. package/ios/Animations/Elements/ANNElementTransition.h +3 -3
  89. package/ios/Animations/Elements/ANNElementTransition.mm +2 -2
  90. package/ios/Animations/Elements/ANNSharedElementFlight.h +3 -3
  91. package/ios/Animations/Elements/ANNSharedElementFlight.mm +181 -43
  92. package/ios/Animations/Interpolators/ANNViewTracks.h +6 -5
  93. package/ios/Animations/Interpolators/ANNViewTracks.mm +51 -21
  94. package/ios/CLAUDE.md +15 -7
  95. package/ios/CORE.md +1 -1
  96. package/ios/Core/ANNAppDelegate.mm +0 -2
  97. package/ios/Core/ANNDeepLinkQueue.h +6 -5
  98. package/ios/Core/ANNDeepLinkQueue.mm +22 -10
  99. package/ios/Core/ANNSceneDelegate.mm +2 -2
  100. package/ios/Core/ApexNavigation.mm +6 -2
  101. package/ios/Layouts/Root/ANNRootCoordinator.mm +45 -15
  102. package/ios/Layouts/Screen/ANNComponentViewController.mm +4 -1
  103. package/ios/Layouts/Stack/ANNStackAnimatingDelegate.h +11 -2
  104. package/ios/Layouts/Stack/ANNStackAnimatingDelegate.mm +14 -7
  105. package/ios/Layouts/Stack/ANNStackController.h +8 -0
  106. package/ios/Layouts/Stack/ANNStackController.mm +153 -11
  107. package/ios/Layouts/Stack/ANNSwipePopInteraction.h +26 -0
  108. package/ios/Layouts/Stack/ANNSwipePopInteraction.mm +185 -0
  109. package/ios/Layouts/Stack/InteractivePopGestureDelegate.mm +28 -4
  110. package/ios/Options/ANNAnimationOptions.h +2 -1
  111. package/ios/Options/ANNAnimationOptions.mm +1 -1
  112. package/ios/Options/ANNOptions.h +7 -0
  113. package/ios/Options/ANNOptions.mm +45 -0
  114. package/ios/Options/ANNOptionsReader.mm +2 -4
  115. package/ios/Options/ANNStackPopAnimationOptions.h +13 -0
  116. package/ios/Options/ANNStackPopAnimationOptions.mm +11 -0
  117. package/ios/Options/Params/ColorParser.h +4 -3
  118. package/ios/Options/Params/ColorParser.mm +22 -4
  119. package/ios/React/ANNSurfaceHostingView.h +8 -0
  120. package/ios/React/ANNSurfaceHostingView.mm +28 -1
  121. package/ios/React/Slots/ANNSlotScreenView.mm +8 -2
  122. package/ios/TurboModules/ANNTurboModule.mm +46 -0
  123. package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.cpp +20 -0
  124. package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.h +5 -14
  125. package/lib/module/ARCHITECTURE.md +9 -3
  126. package/lib/module/adapters/NativeANNTurboModule.js.map +1 -1
  127. package/lib/module/api/app/AppRegistry.js +14 -2
  128. package/lib/module/api/app/AppRegistry.js.map +1 -1
  129. package/lib/module/api/app/createNavigation.js +188 -66
  130. package/lib/module/api/app/createNavigation.js.map +1 -1
  131. package/lib/module/api/events/navigationEvents.js +6 -2
  132. package/lib/module/api/events/navigationEvents.js.map +1 -1
  133. package/lib/module/api/linking/linking.js +11 -0
  134. package/lib/module/api/linking/linking.js.map +1 -1
  135. package/lib/module/api/screens/defineScreen.js +45 -3
  136. package/lib/module/api/screens/defineScreen.js.map +1 -1
  137. package/lib/module/api/screens/nativeScreens.js +31 -6
  138. package/lib/module/api/screens/nativeScreens.js.map +1 -1
  139. package/lib/module/api/screens/registerScreens.js +172 -35
  140. package/lib/module/api/screens/registerScreens.js.map +1 -1
  141. package/lib/module/api/theme/theme.js +5 -0
  142. package/lib/module/api/theme/theme.js.map +1 -1
  143. package/lib/module/engine/commands.js +21 -1
  144. package/lib/module/engine/commands.js.map +1 -1
  145. package/lib/module/engine/layout.js +7 -2
  146. package/lib/module/engine/layout.js.map +1 -1
  147. package/lib/module/engine/nativeScreens.js +9 -0
  148. package/lib/module/engine/nativeScreens.js.map +1 -1
  149. package/lib/module/engine/options.js +5 -4
  150. package/lib/module/engine/options.js.map +1 -1
  151. package/lib/module/engine/optionsChange.js +102 -0
  152. package/lib/module/engine/optionsChange.js.map +1 -0
  153. package/lib/module/engine/refresh.js +85 -0
  154. package/lib/module/engine/refresh.js.map +1 -0
  155. package/lib/module/engine/rememberedOptions.js +60 -0
  156. package/lib/module/engine/rememberedOptions.js.map +1 -1
  157. package/lib/module/engine/screens.js +26 -0
  158. package/lib/module/engine/screens.js.map +1 -1
  159. package/lib/typescript/adapters/NativeANNTurboModule.d.ts +7 -0
  160. package/lib/typescript/adapters/NativeANNTurboModule.d.ts.map +1 -1
  161. package/lib/typescript/api/app/AppRegistry.d.ts.map +1 -1
  162. package/lib/typescript/api/app/createNavigation.d.ts +5 -0
  163. package/lib/typescript/api/app/createNavigation.d.ts.map +1 -1
  164. package/lib/typescript/api/events/navigationEvents.d.ts +2 -2
  165. package/lib/typescript/api/events/navigationEvents.d.ts.map +1 -1
  166. package/lib/typescript/api/index.d.ts +1 -1
  167. package/lib/typescript/api/index.d.ts.map +1 -1
  168. package/lib/typescript/api/linking/linking.d.ts +8 -0
  169. package/lib/typescript/api/linking/linking.d.ts.map +1 -1
  170. package/lib/typescript/api/screens/defineScreen.d.ts +23 -4
  171. package/lib/typescript/api/screens/defineScreen.d.ts.map +1 -1
  172. package/lib/typescript/api/screens/nativeScreens.d.ts +8 -1
  173. package/lib/typescript/api/screens/nativeScreens.d.ts.map +1 -1
  174. package/lib/typescript/api/screens/registerScreens.d.ts.map +1 -1
  175. package/lib/typescript/api/theme/theme.d.ts +2 -0
  176. package/lib/typescript/api/theme/theme.d.ts.map +1 -1
  177. package/lib/typescript/engine/commands.d.ts +5 -0
  178. package/lib/typescript/engine/commands.d.ts.map +1 -1
  179. package/lib/typescript/engine/layout.d.ts.map +1 -1
  180. package/lib/typescript/engine/nativeScreens.d.ts +5 -0
  181. package/lib/typescript/engine/nativeScreens.d.ts.map +1 -1
  182. package/lib/typescript/engine/optionsChange.d.ts +28 -0
  183. package/lib/typescript/engine/optionsChange.d.ts.map +1 -0
  184. package/lib/typescript/engine/refresh.d.ts +35 -0
  185. package/lib/typescript/engine/refresh.d.ts.map +1 -0
  186. package/lib/typescript/engine/rememberedOptions.d.ts +13 -0
  187. package/lib/typescript/engine/rememberedOptions.d.ts.map +1 -1
  188. package/lib/typescript/engine/screens.d.ts +7 -0
  189. package/lib/typescript/engine/screens.d.ts.map +1 -1
  190. package/lib/typescript/interfaces/ComponentEvents.d.ts +2 -2
  191. package/lib/typescript/interfaces/options/animations.d.ts +40 -15
  192. package/lib/typescript/interfaces/options/animations.d.ts.map +1 -1
  193. package/lib/typescript/interfaces/options/bottomTabs.d.ts +2 -2
  194. package/lib/typescript/interfaces/options/buttons.d.ts +2 -2
  195. package/lib/typescript/interfaces/options/modals.d.ts +6 -7
  196. package/lib/typescript/interfaces/options/modals.d.ts.map +1 -1
  197. package/lib/typescript/interfaces/options/stack.d.ts +8 -3
  198. package/lib/typescript/interfaces/options/stack.d.ts.map +1 -1
  199. package/lib/typescript/interfaces/options/topBar.d.ts +14 -0
  200. package/lib/typescript/interfaces/options/topBar.d.ts.map +1 -1
  201. package/metro/acceptPlugin.js +57 -0
  202. package/metro/babelTransformer.js +45 -0
  203. package/metro/index.js +36 -0
  204. package/package.json +3 -1
  205. package/src/ARCHITECTURE.md +9 -3
  206. package/src/adapters/NativeANNTurboModule.ts +7 -0
  207. package/src/api/app/AppRegistry.ts +16 -2
  208. package/src/api/app/createNavigation.ts +198 -66
  209. package/src/api/events/navigationEvents.ts +9 -3
  210. package/src/api/index.ts +1 -0
  211. package/src/api/linking/linking.ts +22 -1
  212. package/src/api/screens/defineScreen.ts +49 -5
  213. package/src/api/screens/nativeScreens.ts +40 -4
  214. package/src/api/screens/registerScreens.tsx +170 -42
  215. package/src/api/theme/theme.ts +5 -0
  216. package/src/engine/commands.ts +21 -0
  217. package/src/engine/layout.ts +11 -2
  218. package/src/engine/nativeScreens.ts +10 -1
  219. package/src/engine/options.ts +6 -8
  220. package/src/engine/optionsChange.ts +107 -0
  221. package/src/engine/refresh.ts +97 -0
  222. package/src/engine/rememberedOptions.ts +70 -0
  223. package/src/engine/screens.tsx +24 -0
  224. package/src/interfaces/ComponentEvents.ts +2 -2
  225. package/src/interfaces/options/animations.ts +40 -15
  226. package/src/interfaces/options/bottomTabs.ts +2 -2
  227. package/src/interfaces/options/buttons.ts +2 -2
  228. package/src/interfaces/options/modals.ts +6 -7
  229. package/src/interfaces/options/stack.ts +8 -3
  230. package/src/interfaces/options/topBar.ts +14 -0
  231. package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStub.kt +0 -31
  232. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMatrixAnimator.kt +0 -134
  233. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PlainViewAnimator.kt +0 -78
  234. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PropertyAnimatorCreator.kt +0 -33
  235. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ReactImageAnimator.kt +0 -57
  236. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewChangeAnimator.kt +0 -146
@@ -1,57 +0,0 @@
1
- package dev.apexnative.navigation.views.element.animators
2
-
3
- import android.animation.Animator
4
- import android.view.View
5
- import com.facebook.drawee.drawable.ScalingUtils
6
- import com.facebook.react.views.image.ReactImageView
7
- import dev.apexnative.navigation.views.element.TransitionLayer
8
- import kotlin.math.roundToInt
9
-
10
- /**
11
- * A shared React image: from where `from` is drawn to where it is drawn in its screen ([FlightGeometry]), laid out at
12
- * the size of each frame, unscaled and turned about its middle; its content by Fresco's scale type going from `from`'s
13
- * fit to its own (`ScalingUtils.InterpolatingScaleType`); Fresco's own fade off meanwhile. Everything goes back as it
14
- * was at the end. Main thread only.
15
- */
16
- internal class ReactImageAnimator(
17
- private val from: ReactImageView,
18
- private val to: ReactImageView,
19
- /** Where [to] was in its screen: what it flies to. */
20
- private val toStandIn: View?,
21
- private val layer: TransitionLayer,
22
- ) {
23
- /** The animator; none when [to] has no place in the layer or no hierarchy. */
24
- fun create(): Animator? {
25
- if (!from.hasHierarchy() || !to.hasHierarchy()) return null
26
- val geometry = FlightGeometry.of(from, to, toStandIn, layer) ?: return null
27
- val toType = to.hierarchy.actualImageScaleType ?: ScalingUtils.ScaleType.CENTER_CROP
28
- val fromType = from.hierarchy.actualImageScaleType ?: ScalingUtils.ScaleType.CENTER_CROP
29
- val scale = ScalingUtils.InterpolatingScaleType(fromType, toType)
30
- val moved = MovedProperties(to)
31
- var savedFade = 0
32
- return MoveAnimator().apply {
33
- fun frame(time: Float) {
34
- val f = curve.getInterpolation(time)
35
- val at = geometry.at(f, time)
36
- val width = at.width.roundToInt()
37
- val height = at.height.roundToInt()
38
- layer.place(to, geometry.toLeft, geometry.toTop, width, height)
39
- moved.show(geometry, at, width, height)
40
- scale.setValue(if (time >= 1f) 1f else f)
41
- to.invalidate()
42
- }
43
- onStart {
44
- savedFade = to.hierarchy.fadeDuration
45
- to.hierarchy.fadeDuration = 0
46
- to.hierarchy.setActualImageScaleType(scale)
47
- frame(0f)
48
- }
49
- onFrame { frame(it) }
50
- onEnd {
51
- to.hierarchy.setActualImageScaleType(toType)
52
- to.hierarchy.fadeDuration = savedFade
53
- moved.end(geometry, landed) { w, h -> layer.place(to, geometry.toLeft, geometry.toTop, w, h) }
54
- }
55
- }
56
- }
57
- }
@@ -1,146 +0,0 @@
1
- package dev.apexnative.navigation.views.element.animators
2
-
3
- import android.animation.Animator
4
- import android.graphics.Canvas
5
- import android.graphics.ColorFilter
6
- import android.graphics.Paint
7
- import android.graphics.Picture
8
- import android.graphics.PixelFormat
9
- import android.graphics.PorterDuff
10
- import android.graphics.PorterDuffXfermode
11
- import android.graphics.RectF
12
- import android.graphics.drawable.Drawable
13
- import android.view.View
14
- import android.view.ViewGroup
15
- import com.facebook.react.views.view.ReactViewGroup
16
- import dev.apexnative.navigation.options.SharedElementTransitionOptions
17
- import dev.apexnative.navigation.utils.borderRadius
18
- import kotlin.math.roundToInt
19
-
20
- // A view with children moves as two pictures of itself, as on iOS: of the view that goes away and of the one that
21
- // comes, each with its children. The copy goes from where the one is drawn — its center, its size at the scale it is
22
- // drawn at, its angle and corner radius — to where the other is drawn in its screen (FlightGeometry), the angle along
23
- // the shorter arc; both pictures fill it, and the picture of the destination shows over the other on the way. The
24
- // pictures are drawing commands: an avatar's letter grows sharp. They are drawn in the overlay of the transition layer
25
- // while `to` is hidden, and nothing else moves the pair. A view without children moves itself, its outline growing, as
26
- // before.
27
- class ViewChangeAnimator internal constructor(
28
- from: View,
29
- to: View,
30
- // Where `to` was in its screen: what the copy flies to.
31
- private val toStandIn: View?,
32
- ) : PropertyAnimatorCreator<ReactViewGroup>(from, to, ReactViewGroup::class.java) {
33
- private val pictures by lazy { pictures() }
34
-
35
- override fun shouldAnimateProperty(fromChild: ReactViewGroup, toChild: ReactViewGroup): Boolean =
36
- (fromChild.childCount > 0 || toChild.childCount > 0) && pictures != null
37
-
38
- override fun create(options: SharedElementTransitionOptions): Animator {
39
- val (start, end) = checkNotNull(pictures)
40
- val layer = to.parent as ViewGroup
41
- val drawable = ViewMorphDrawable(start, end)
42
- // Everything changes between the start and the end of the animation: a cancelled one ends too.
43
- return MoveAnimator().apply {
44
- onStart {
45
- drawable.setBounds(0, 0, layer.width, layer.height)
46
- layer.overlay.add(drawable)
47
- to.alpha = 0f
48
- }
49
- onFrame {
50
- drawable.update(it, curve.getInterpolation(it))
51
- layer.invalidate()
52
- }
53
- // A flight that landed where `to` shows only in its screen keeps its last picture: the transition takes the
54
- // layer away with it and shows `to` in its place.
55
- val holds = FlightEnd.holdsAtEnd(to, toStandIn, layer)
56
- onEnd {
57
- if (!holds || !landed) {
58
- layer.overlay.remove(drawable)
59
- layer.invalidate()
60
- to.alpha = end.alpha
61
- }
62
- }
63
- }
64
- }
65
-
66
- // `to` is in the transition layer already: the pictures are drawn in its coordinates. `from` is where it is drawn
67
- // on the screen, `to` where it is drawn once back in its screen.
68
- private fun pictures(): Pair<ViewPicture, ViewPicture>? {
69
- val layer = to.parent as? ViewGroup ?: return null
70
- val start = ViewPicture.of(from as ReactViewGroup, LayerPlace.of(from, layer)) ?: return null
71
- val end = ViewPicture.of(to as ReactViewGroup, LayerPlace.of(to, layer, toStandIn)) ?: return null
72
- return start to end
73
- }
74
- }
75
-
76
- // A view's picture, where it is drawn in the transition layer, its corner radius there and its opacity.
77
- private class ViewPicture(val picture: Picture, val end: FlightEnd, val radius: Float, val alpha: Float) {
78
- companion object {
79
- fun of(view: ReactViewGroup, place: LayerPlace): ViewPicture? {
80
- if (view.width <= 0 || view.height <= 0) return null
81
- val picture = recordPicture(view) ?: return null
82
- val end = place.end(view.width, view.height)
83
- return ViewPicture(picture, end, view.borderRadius * end.scale, view.alpha)
84
- }
85
- }
86
- }
87
-
88
- // The copy where the move has brought it: its center, size, angle and corner radius go from the start to the end along
89
- // the transition's curve, and so does the picture of the end over the picture of the start.
90
- private class ViewMorphDrawable(private val start: ViewPicture, private val end: ViewPicture) : Drawable() {
91
- private val flight = FlightGeometry(start.end, end.end, 0, 0)
92
- private var at = start.end
93
- private var progress = 0f
94
- private val rect = RectF()
95
- private val maskPaint = Paint(Paint.ANTI_ALIAS_FLAG)
96
- // What is drawn over the mask keeps only the mask's pixels: the corners stay smooth (a clip path on the hardware
97
- // canvas is not anti-aliased).
98
- private val contentPaint = Paint().apply { xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN) }
99
-
100
- /** The copy at [time] (the part of the time), [progress] the curve's value. */
101
- fun update(time: Float, progress: Float) {
102
- this.progress = progress
103
- at = flight.at(progress, time)
104
- }
105
-
106
- override fun draw(canvas: Canvas) {
107
- rect.set(-at.width / 2, -at.height / 2, at.width / 2, at.height / 2)
108
- if (rect.isEmpty) return
109
- val radius = lerp(start.radius, end.radius)
110
- // The copy turns about its center, mirrored where a view is.
111
- val count = canvas.save()
112
- canvas.translate(at.centerX, at.centerY)
113
- canvas.rotate(at.rotation)
114
- canvas.scale(at.mirrorX, at.mirrorY)
115
- canvas.saveLayer(rect, null)
116
- canvas.drawRoundRect(rect, radius, radius, maskPaint)
117
- canvas.saveLayer(rect, contentPaint)
118
- draw(canvas, start, start.alpha)
119
- draw(canvas, end, end.alpha * progress)
120
- canvas.restoreToCount(count)
121
- }
122
-
123
- // A picture fills the copy, as on iOS.
124
- private fun draw(canvas: Canvas, view: ViewPicture, shown: Float) {
125
- val alpha = (shown * 255).roundToInt().coerceIn(0, 255)
126
- if (alpha == 0) return
127
- val width = view.picture.width.toFloat()
128
- val height = view.picture.height.toFloat()
129
- val count = canvas.save()
130
- canvas.translate(rect.left, rect.top)
131
- canvas.scale(rect.width() / width, rect.height() / height)
132
- // The picture fades as a whole: its children and background don't show through each other.
133
- if (alpha < 255) canvas.saveLayerAlpha(0f, 0f, width, height, alpha)
134
- canvas.drawPicture(view.picture)
135
- canvas.restoreToCount(count)
136
- }
137
-
138
- private fun lerp(from: Float, to: Float) = from + (to - from) * progress
139
-
140
- override fun setAlpha(alpha: Int) = Unit
141
-
142
- override fun setColorFilter(colorFilter: ColorFilter?) = Unit
143
-
144
- @Deprecated("Deprecated in Java")
145
- override fun getOpacity(): Int = PixelFormat.TRANSLUCENT
146
- }