@apexnative/navigation 1.0.0-alpha.4 → 1.0.0-alpha.6
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.
- package/CHANGELOG.md +38 -0
- package/README.md +1 -1
- package/android/CLAUDE.md +23 -14
- package/android/CORE.md +32 -19
- package/android/src/main/java/dev/apexnative/navigation/NavigationActivity.kt +60 -13
- package/android/src/main/java/dev/apexnative/navigation/options/AnimationsOptions.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/BottomTabsOptions.kt +13 -8
- package/android/src/main/java/dev/apexnative/navigation/options/HardwareBackButtonOptions.kt +9 -1
- package/android/src/main/java/dev/apexnative/navigation/options/StackAnimationOptions.kt +40 -2
- package/android/src/main/java/dev/apexnative/navigation/react/CommandAnswer.kt +28 -13
- package/android/src/main/java/dev/apexnative/navigation/react/Hinge.kt +7 -4
- package/android/src/main/java/dev/apexnative/navigation/react/NavigationTurboModule.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/react/ReactView.kt +39 -20
- package/android/src/main/java/dev/apexnative/navigation/react/ReloadCoordinator.kt +7 -6
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenEnvironment.kt +177 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenRegions.kt +19 -51
- package/android/src/main/java/dev/apexnative/navigation/react/ScrollEvents.kt +49 -128
- package/android/src/main/java/dev/apexnative/navigation/react/events/AppearanceDispatcher.kt +30 -39
- package/android/src/main/java/dev/apexnative/navigation/react/events/EventEmitter.kt +34 -7
- package/android/src/main/java/dev/apexnative/navigation/react/events/NavigationState.kt +154 -0
- package/android/src/main/java/dev/apexnative/navigation/safearea/SafeAreaView.kt +12 -10
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotScreenView.kt +12 -12
- package/android/src/main/java/dev/apexnative/navigation/utils/ViewExtensions.kt +0 -13
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/ArrangementController.kt +10 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsCollapseBehavior.kt +5 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsController.kt +22 -21
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowGeometry.kt +22 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabsRoom.kt +0 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentViewController.kt +12 -9
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ContentReadiness.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenReadiness.kt +103 -56
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenSafeArea.kt +29 -11
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/externalcomponent/ExternalComponentViewController.kt +2 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalCoordinator.kt +20 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalSheet.kt +119 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalViews.kt +7 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetBack.kt +42 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackCheck.kt +50 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackState.kt +45 -14
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/Navigator.kt +25 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/RootCoordinator.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ParentController.kt +3 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitViewController.kt +3 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/PreparedFrame.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackCommands.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt +13 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackViews.kt +3 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/ScreenSearch.kt +3 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/StackSearchPresenter.kt +2 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarComponents.kt +5 -51
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarPresenter.kt +4 -9
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ScrollEventListener.kt +6 -9
- package/android/src/main/java/dev/apexnative/navigation/views/animations/AnimationLayer.kt +73 -0
- package/android/src/main/java/dev/apexnative/navigation/views/animations/ValueInterpolation.kt +14 -0
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabsLayout.kt +61 -2
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomBottomTabItemView.kt +0 -5
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomTabRow.kt +72 -10
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementTransitions.kt +9 -2
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ElementPictures.kt +11 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/FlightGeometry.kt +318 -25
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMatrixAnimator.kt +18 -20
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PlainViewAnimator.kt +17 -25
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ReactImageAnimator.kt +15 -22
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/SharedAnimatorFactory.kt +12 -9
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextChangeAnimator.kt +84 -35
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewChangeAnimator.kt +49 -40
- package/cli/doctor/checks/splash.js +4 -22
- package/cli/splash/index.js +3 -1
- package/docs-md/architecture/transitions.md +4 -2
- package/docs-md/containers/modals.md +4 -2
- package/docs-md/containers/overlays.md +1 -1
- package/docs-md/containers/side-menu.md +1 -1
- package/docs-md/containers/tabs.md +2 -0
- package/docs-md/flows/bottom-sheets.md +1 -1
- package/docs-md/fundamentals/starting-the-app.md +1 -1
- package/docs-md/guides/cli.md +1 -2
- package/docs-md/help/glossary.md +2 -2
- package/docs-md/help/troubleshooting.md +23 -2
- package/docs-md/index.json +12 -0
- package/docs-md/migration/from-expo-router.md +1 -1
- package/docs-md/migration/from-react-native-navigation.md +1 -1
- package/docs-md/migration/from-react-navigation.md +2 -2
- package/docs-md/screen-ui/back-and-gestures.md +36 -0
- package/docs-md/screen-ui/bar-buttons.md +4 -4
- package/docs-md/screen-ui/search.md +1 -1
- package/docs-md/screen-ui/system-ui.md +16 -11
- package/docs-md/screen-ui/toolbar-and-fab.md +2 -2
- package/docs-md/screen-ui/top-bar.md +8 -4
- package/docs-md/start/installation.md +1 -1
- package/ios/Animations/ANNFrameDriver.mm +2 -0
- package/ios/Animations/Elements/ANNSharedElementFlight.mm +70 -4
- package/ios/Animations/Interpolators/ANNInterpolate.h +2 -30
- package/ios/Animations/Interpolators/ANNTransformParts.h +48 -0
- package/ios/Animations/Interpolators/ANNTransformParts.mm +507 -0
- package/ios/Animations/Interpolators/ANNViewTracks.h +6 -4
- package/ios/Animations/Interpolators/ANNViewTracks.mm +49 -9
- package/ios/CLAUDE.md +17 -15
- package/ios/CORE.md +30 -26
- package/ios/Contract/ANNCommandAnswer.h +9 -2
- package/ios/Contract/ANNCommandAnswer.mm +25 -12
- package/ios/Contract/ANNCommandRunner.h +8 -7
- package/ios/Contract/ANNCommandRunner.mm +21 -27
- package/ios/Contract/ANNLayoutNode.h +3 -3
- package/ios/Contract/ANNLayoutReader.h +3 -3
- package/ios/Core/ANNAppearanceDispatcher.h +5 -4
- package/ios/Core/ANNAppearanceDispatcher.mm +12 -1
- package/ios/Core/ANNJavaScriptCalls.h +11 -12
- package/ios/Core/ANNJavaScriptCalls.mm +7 -16
- package/ios/Core/ANNNavigationState.h +4 -6
- package/ios/Core/ANNNavigationState.mm +0 -4
- package/ios/Core/ANNReloadCoordinator.mm +4 -8
- package/ios/Core/ApexNavigation+Internal.h +1 -1
- package/ios/Layouts/Arrangement/ANNArrangementState.h +2 -17
- package/ios/Layouts/Arrangement/ANNArrangementState.mm +0 -38
- package/ios/Layouts/Arrangement/ANNArrangementViewController.mm +4 -4
- package/ios/Layouts/Root/ANNSplashViewController.h +5 -3
- package/ios/Layouts/Root/ANNSplashViewController.mm +147 -0
- package/ios/Layouts/Screen/ANNComponentViewController.h +2 -2
- package/ios/Layouts/Screen/ANNComponentViewController.mm +9 -22
- package/ios/Layouts/Screen/ANNPreviewInteraction.h +7 -4
- package/ios/Layouts/Screen/ANNPreviewInteraction.mm +72 -10
- package/ios/Layouts/Screen/ANNScreenEnvironment.h +63 -0
- package/ios/Layouts/Screen/ANNScreenEnvironment.mm +181 -0
- package/ios/Layouts/Screen/ANNScreenRegions.h +3 -18
- package/ios/Layouts/Screen/ANNScreenRegions.mm +0 -38
- package/ios/Layouts/Screen/ANNScreenSafeArea.h +4 -9
- package/ios/Layouts/Screen/ANNScreenSafeArea.mm +14 -16
- package/ios/Layouts/Stack/ANNPreviewPush.h +7 -6
- package/ios/Layouts/Stack/ANNPreviewPush.mm +142 -27
- package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.h +12 -1
- package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.mm +23 -0
- package/ios/Layouts/Tabs/ANNBottomTabsController.mm +2 -1
- package/ios/Layouts/Tabs/ANNBottomTabsCustomRow.mm +8 -3
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.h +4 -0
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.mm +123 -36
- package/ios/Layouts/Tabs/ANNTabsDesign.h +6 -5
- package/ios/Layouts/Tabs/ANNTabsDesign.mm +9 -1
- package/ios/Layouts/Tabs/UITabBar+utils.h +5 -5
- package/ios/Layouts/Tabs/UITabBar+utils.mm +32 -13
- package/ios/Options/ANNBottomTabsOptions.h +2 -0
- package/ios/Options/ANNBottomTabsOptions.mm +1 -0
- package/ios/Options/ANNOptions.h +18 -0
- package/ios/Options/ANNOptions.mm +112 -1
- package/ios/Options/ANNOptionsReader.mm +110 -0
- package/ios/Options/Params/ANNParam.h +15 -0
- package/ios/Options/Params/ANNParam.mm +61 -0
- package/ios/Options/Params/Color.h +3 -0
- package/ios/Options/Params/Color.mm +21 -0
- package/ios/Options/Params/Image.h +4 -0
- package/ios/Options/Params/Image.mm +20 -0
- package/ios/React/ANNReactView.mm +6 -25
- package/ios/React/ANNSafeAreaViewComponentView.mm +26 -15
- package/ios/React/ANNSurfaceHostingView.h +6 -0
- package/ios/React/ANNSurfaceHostingView.mm +116 -0
- package/ios/TopBar/ANNBackButtonPresenter.mm +6 -5
- package/ios/TopBar/ANNBarAppearance.h +2 -1
- package/ios/TopBar/ANNBarAppearance.mm +111 -30
- package/ios/TopBar/ANNBarBackgroundComponent.mm +16 -0
- package/ios/TopBar/ANNBarButtonComponentView.h +4 -4
- package/ios/TopBar/ANNBarButtonComponentView.mm +1 -1
- package/ios/TopBar/ANNBarButtons.h +5 -3
- package/ios/TopBar/ANNBarButtons.mm +186 -17
- package/ios/TopBar/ANNLargeTitlePresenter.mm +24 -4
- package/ios/TopBar/ANNMainList.h +3 -0
- package/ios/TopBar/ANNMainList.mm +4 -0
- package/ios/TopBar/ANNScrollEdgeEffects.h +22 -6
- package/ios/TopBar/ANNScrollEdgeEffects.mm +123 -16
- package/ios/TopBar/ANNSearchPresenter.mm +2 -2
- package/ios/TopBar/ANNSearchResultsViewController.mm +5 -5
- package/ios/TopBar/ANNTopBarPresenter.h +3 -2
- package/ios/TopBar/ANNTopBarPresenter.mm +95 -22
- package/ios/TurboModules/ANNTurboModule.mm +20 -16
- package/lib/module/ARCHITECTURE.md +8 -4
- package/lib/module/api/commands/commands.js +54 -6
- package/lib/module/api/commands/commands.js.map +1 -1
- package/lib/module/api/hooks/useSafeAreaInsets.js +4 -3
- package/lib/module/api/hooks/useSafeAreaInsets.js.map +1 -1
- package/lib/module/api/options/OptionsChain.js +2 -2
- package/lib/module/engine/commands.js +21 -1
- package/lib/module/engine/commands.js.map +1 -1
- package/lib/module/engine/places.js +8 -0
- package/lib/module/engine/places.js.map +1 -1
- package/lib/module/engine/screens.js +29 -4
- package/lib/module/engine/screens.js.map +1 -1
- package/lib/typescript/api/app/createNavigation.d.ts +3 -3
- package/lib/typescript/api/commands/commands.d.ts.map +1 -1
- package/lib/typescript/api/commands/presentation.d.ts +4 -3
- package/lib/typescript/api/commands/presentation.d.ts.map +1 -1
- package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts +4 -3
- package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts.map +1 -1
- package/lib/typescript/api/options/OptionsChain.d.ts +2 -2
- package/lib/typescript/engine/commands.d.ts.map +1 -1
- package/lib/typescript/engine/places.d.ts +2 -0
- package/lib/typescript/engine/places.d.ts.map +1 -1
- package/lib/typescript/engine/screens.d.ts +20 -6
- package/lib/typescript/engine/screens.d.ts.map +1 -1
- package/lib/typescript/interfaces/Options.d.ts +1 -1
- package/lib/typescript/interfaces/Options.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/animations.d.ts +30 -9
- package/lib/typescript/interfaces/options/animations.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/bottomTabs.d.ts +18 -5
- package/lib/typescript/interfaces/options/bottomTabs.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/buttons.d.ts +8 -8
- package/lib/typescript/interfaces/options/stack.d.ts +9 -0
- package/lib/typescript/interfaces/options/stack.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/system.d.ts +8 -5
- package/lib/typescript/interfaces/options/system.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/toolbar.d.ts +2 -2
- package/lib/typescript/interfaces/options/topBar.d.ts +32 -29
- package/lib/typescript/interfaces/options/topBar.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/ARCHITECTURE.md +8 -4
- package/src/api/app/createNavigation.ts +3 -3
- package/src/api/commands/commands.ts +48 -7
- package/src/api/commands/presentation.ts +4 -3
- package/src/api/hooks/useSafeAreaInsets.ts +4 -3
- package/src/api/options/OptionsChain.ts +2 -2
- package/src/engine/commands.ts +30 -6
- package/src/engine/places.ts +9 -0
- package/src/engine/screens.tsx +29 -8
- package/src/interfaces/Options.ts +1 -0
- package/src/interfaces/options/animations.ts +31 -9
- package/src/interfaces/options/bottomTabs.ts +18 -5
- package/src/interfaces/options/buttons.ts +8 -8
- package/src/interfaces/options/stack.ts +9 -0
- package/src/interfaces/options/system.ts +8 -5
- package/src/interfaces/options/toolbar.ts +2 -2
- package/src/interfaces/options/topBar.ts +32 -29
- package/android/src/main/java/dev/apexnative/navigation/react/ArrangementStates.kt +0 -42
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenInsets.kt +0 -70
- package/android/src/main/java/dev/apexnative/navigation/react/events/NavigationStateReporter.kt +0 -62
- package/android/src/main/java/dev/apexnative/navigation/react/events/StateHold.kt +0 -62
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowPlacer.kt +0 -223
- package/ios/Layouts/Screen/ANNScreenInsets.h +0 -30
- package/ios/Layouts/Screen/ANNScreenInsets.mm +0 -70
|
@@ -3,19 +3,25 @@
|
|
|
3
3
|
#import "ANNInterpolate.h"
|
|
4
4
|
#import "ANNSharedElementTransitionOptions.h"
|
|
5
5
|
#import "ANNTrack.h"
|
|
6
|
+
#import "ANNTransformParts.h"
|
|
6
7
|
#import "ANNUtils.h"
|
|
7
8
|
#import <React/RCTViewComponentView.h>
|
|
8
9
|
#import <react/renderer/components/view/ViewProps.h>
|
|
10
|
+
#include <cmath>
|
|
9
11
|
|
|
10
12
|
// How close two rectangles count as the same (points): a visible part that is the whole element needs no mask.
|
|
11
13
|
static const CGFloat ANNSameRectTolerance = 0.5;
|
|
12
14
|
|
|
13
15
|
// One end of a flight: the place, the size, the transform, the corners and the visible part of a React view, in the
|
|
14
|
-
// container's coordinates.
|
|
16
|
+
// container's coordinates. The transform is the whole one the view is drawn with there (its own and its parents'),
|
|
17
|
+
// about its center; once split, its scale goes into the size, the corners and the visible part, so the size the copy
|
|
18
|
+
// shows changes evenly on the way.
|
|
15
19
|
typedef struct {
|
|
16
20
|
CGPoint center;
|
|
17
21
|
CGSize size;
|
|
18
22
|
CATransform3D transform;
|
|
23
|
+
// The transform's parts, which the flight interpolates; their scale is only its sign once the scale is in the size.
|
|
24
|
+
ANNTransformParts parts;
|
|
19
25
|
CGFloat cornerRadius;
|
|
20
26
|
// The part the clipping parents leave visible, in the copy's coordinates, and its corners.
|
|
21
27
|
CGRect visible;
|
|
@@ -71,12 +77,44 @@ static CGFloat ANNCornerRadiusOf(UIView *view) {
|
|
|
71
77
|
return 0;
|
|
72
78
|
}
|
|
73
79
|
|
|
80
|
+
// The anchor of a layer in the coordinates of its bounds.
|
|
81
|
+
static CGPoint ANNAnchorInBounds(CALayer *layer) {
|
|
82
|
+
CGRect bounds = layer.bounds;
|
|
83
|
+
return CGPointMake(bounds.origin.x + layer.anchorPoint.x * bounds.size.width,
|
|
84
|
+
bounds.origin.y + layer.anchorPoint.y * bounds.size.height);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// What takes a point of the layer, counted from its anchor, to the top of its tree: its transform and place, then each
|
|
88
|
+
// superlayer's `sublayerTransform`, transform and place the same way (a layer's transforms turn about its anchor).
|
|
89
|
+
static CATransform3D ANNTransformToTop(CALayer *layer) {
|
|
90
|
+
CATransform3D transform = CATransform3DConcat(
|
|
91
|
+
layer.transform, CATransform3DMakeTranslation(layer.position.x, layer.position.y, 0));
|
|
92
|
+
for (CALayer *parent = layer.superlayer; parent; parent = parent.superlayer) {
|
|
93
|
+
CGPoint anchor = ANNAnchorInBounds(parent);
|
|
94
|
+
transform = CATransform3DConcat(transform,
|
|
95
|
+
CATransform3DMakeTranslation(-anchor.x, -anchor.y, 0));
|
|
96
|
+
transform = CATransform3DConcat(transform, parent.sublayerTransform);
|
|
97
|
+
transform = CATransform3DConcat(transform, parent.transform);
|
|
98
|
+
transform = CATransform3DConcat(
|
|
99
|
+
transform, CATransform3DMakeTranslation(parent.position.x, parent.position.y, 0));
|
|
100
|
+
}
|
|
101
|
+
return transform;
|
|
102
|
+
}
|
|
103
|
+
|
|
74
104
|
static ANNFlightEnd ANNFlightEndOf(UIView *view, UIView *screenRoot, UIView *container) {
|
|
75
105
|
ANNFlightEnd end;
|
|
76
106
|
CALayer *layer = view.layer;
|
|
77
107
|
end.size = layer.bounds.size;
|
|
78
|
-
|
|
79
|
-
|
|
108
|
+
// From the view's center to the container's bounds: up to the top, then down into the container.
|
|
109
|
+
CGPoint containerAnchor = ANNAnchorInBounds(container.layer);
|
|
110
|
+
CATransform3D toContainer =
|
|
111
|
+
CATransform3DConcat(CATransform3DInvert(ANNTransformToTop(container.layer)),
|
|
112
|
+
CATransform3DMakeTranslation(containerAnchor.x, containerAnchor.y, 0));
|
|
113
|
+
CATransform3D whole = CATransform3DConcat(ANNTransformToTop(layer), toContainer);
|
|
114
|
+
// The center is where the view's center lands; the rest of the transform turns about it.
|
|
115
|
+
end.center = CGPointMake(whole.m41 / whole.m44, whole.m42 / whole.m44);
|
|
116
|
+
end.transform = CATransform3DConcat(
|
|
117
|
+
whole, CATransform3DMakeTranslation(-end.center.x, -end.center.y, 0));
|
|
80
118
|
end.cornerRadius = ANNCornerRadiusOf(view);
|
|
81
119
|
// The visible part: the element's bounds cut by every parent that clips (`overflow: hidden`, a scroll view) up to
|
|
82
120
|
// the screen's root, in the element's own coordinates, moved to the copy's (its bounds start at 0, 0).
|
|
@@ -122,6 +160,28 @@ static BOOL ANNFlightEndIsFinite(ANNFlightEnd end) {
|
|
|
122
160
|
ANNIsFiniteRect(end.visible);
|
|
123
161
|
}
|
|
124
162
|
|
|
163
|
+
// The parts of the end's transform, its scale moved into the size, the corners and the visible part (a mirror keeps
|
|
164
|
+
// its sign); NO when the transform flattens the view.
|
|
165
|
+
static BOOL ANNSplitFlightEnd(ANNFlightEnd *end) {
|
|
166
|
+
ANNTransformParts parts;
|
|
167
|
+
if (!ANNTransformPartsOf(end->transform, &parts)) {
|
|
168
|
+
return NO;
|
|
169
|
+
}
|
|
170
|
+
CGFloat scaleX = (CGFloat)std::fabs(parts.scale[0]);
|
|
171
|
+
CGFloat scaleY = (CGFloat)std::fabs(parts.scale[1]);
|
|
172
|
+
CGFloat scale = MIN(scaleX, scaleY);
|
|
173
|
+
parts.scale[0] = std::copysign(1.0, parts.scale[0]);
|
|
174
|
+
parts.scale[1] = std::copysign(1.0, parts.scale[1]);
|
|
175
|
+
end->parts = parts;
|
|
176
|
+
end->size = CGSizeMake(end->size.width * scaleX, end->size.height * scaleY);
|
|
177
|
+
end->cornerRadius *= scale;
|
|
178
|
+
end->visibleRadius *= scale;
|
|
179
|
+
end->visible = CGRectMake(end->visible.origin.x * scaleX, end->visible.origin.y * scaleY,
|
|
180
|
+
end->visible.size.width * scaleX,
|
|
181
|
+
end->visible.size.height * scaleY);
|
|
182
|
+
return YES;
|
|
183
|
+
}
|
|
184
|
+
|
|
125
185
|
// The picture of the view's layer and its sublayers at the screen's scale, in the layer's own coordinates.
|
|
126
186
|
static UIImage *ANNPictureOf(UIView *view) {
|
|
127
187
|
CGSize size = view.bounds.size;
|
|
@@ -251,6 +311,11 @@ static UIImage *ANNPictureOf(UIView *view) {
|
|
|
251
311
|
ANNElementSkipped(name, @"the place of a view of the pair can't be worked out");
|
|
252
312
|
return nil;
|
|
253
313
|
}
|
|
314
|
+
// A transform that flattens the view (a scale of 0) has no parts to fly between.
|
|
315
|
+
if (!ANNSplitFlightEnd(&_from) || !ANNSplitFlightEnd(&_to)) {
|
|
316
|
+
ANNElementSkipped(name, @"the transform of a view of the pair flattens it");
|
|
317
|
+
return nil;
|
|
318
|
+
}
|
|
254
319
|
_text = ANNIsText(from) || ANNIsText(to);
|
|
255
320
|
_grows = _to.size.height >= _from.size.height;
|
|
256
321
|
_rightToLeft =
|
|
@@ -317,7 +382,8 @@ static UIImage *ANNPictureOf(UIView *view) {
|
|
|
317
382
|
_copy.layer.transform = CATransform3DIdentity;
|
|
318
383
|
_copy.bounds = CGRectMake(0, 0, size.width, size.height);
|
|
319
384
|
_copy.center = ANNInterpolatePoint(_from.center, _to.center, f);
|
|
320
|
-
_copy.layer.transform =
|
|
385
|
+
_copy.layer.transform =
|
|
386
|
+
ANNTransformOfParts(ANNInterpolateTransformParts(_from.parts, _to.parts, f));
|
|
321
387
|
if (_text) {
|
|
322
388
|
[self placeTextPicturesAtTime:time size:size];
|
|
323
389
|
return;
|
|
@@ -5,7 +5,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
5
5
|
|
|
6
6
|
// The interpolation of values: from + f·(to − from) per component, where f is the share of the way a track gives
|
|
7
7
|
// (`ANNTrack fractionAt:`); exactly `from` at f = 0 and exactly `to` at f = 1, whatever the floating point would give.
|
|
8
|
-
// iOS never interpolates colors: a shared element flies as pictures.
|
|
8
|
+
// iOS never interpolates colors: a shared element flies as pictures. A transform goes by its parts
|
|
9
|
+
// (`ANNTransformParts`).
|
|
9
10
|
|
|
10
11
|
/// A number.
|
|
11
12
|
static inline CGFloat ANNInterpolateNumber(CGFloat from, CGFloat to, double f) {
|
|
@@ -37,33 +38,4 @@ static inline CGRect ANNInterpolateRect(CGRect from, CGRect to, double f) {
|
|
|
37
38
|
return CGRectMake(origin.x, origin.y, size.width, size.height);
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
/// A 4×4 transform, element by element (a shared element with a `transform` style, as iOS does it now).
|
|
41
|
-
static inline CATransform3D ANNInterpolateTransform(CATransform3D from, CATransform3D to,
|
|
42
|
-
double f) {
|
|
43
|
-
if (f == 0) {
|
|
44
|
-
return from;
|
|
45
|
-
}
|
|
46
|
-
if (f == 1) {
|
|
47
|
-
return to;
|
|
48
|
-
}
|
|
49
|
-
CATransform3D t;
|
|
50
|
-
t.m11 = ANNInterpolateNumber(from.m11, to.m11, f);
|
|
51
|
-
t.m12 = ANNInterpolateNumber(from.m12, to.m12, f);
|
|
52
|
-
t.m13 = ANNInterpolateNumber(from.m13, to.m13, f);
|
|
53
|
-
t.m14 = ANNInterpolateNumber(from.m14, to.m14, f);
|
|
54
|
-
t.m21 = ANNInterpolateNumber(from.m21, to.m21, f);
|
|
55
|
-
t.m22 = ANNInterpolateNumber(from.m22, to.m22, f);
|
|
56
|
-
t.m23 = ANNInterpolateNumber(from.m23, to.m23, f);
|
|
57
|
-
t.m24 = ANNInterpolateNumber(from.m24, to.m24, f);
|
|
58
|
-
t.m31 = ANNInterpolateNumber(from.m31, to.m31, f);
|
|
59
|
-
t.m32 = ANNInterpolateNumber(from.m32, to.m32, f);
|
|
60
|
-
t.m33 = ANNInterpolateNumber(from.m33, to.m33, f);
|
|
61
|
-
t.m34 = ANNInterpolateNumber(from.m34, to.m34, f);
|
|
62
|
-
t.m41 = ANNInterpolateNumber(from.m41, to.m41, f);
|
|
63
|
-
t.m42 = ANNInterpolateNumber(from.m42, to.m42, f);
|
|
64
|
-
t.m43 = ANNInterpolateNumber(from.m43, to.m43, f);
|
|
65
|
-
t.m44 = ANNInterpolateNumber(from.m44, to.m44, f);
|
|
66
|
-
return t;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
41
|
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#import <QuartzCore/QuartzCore.h>
|
|
2
|
+
#import <UIKit/UIKit.h>
|
|
3
|
+
|
|
4
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
5
|
+
|
|
6
|
+
/// A 4×4 transform split into the parts it is made of (the decomposition of CSS Transforms Level 2): applied to a point
|
|
7
|
+
/// in the order scale, skew, rotation, translation, perspective. Two transforms interpolate part by part, the rotation
|
|
8
|
+
/// along the shorter arc between the two (a quaternion's slerp), so a rotation never collapses on the way.
|
|
9
|
+
typedef struct {
|
|
10
|
+
double translate[3];
|
|
11
|
+
double scale[3];
|
|
12
|
+
/// The shears xy, xz, yz.
|
|
13
|
+
double skew[3];
|
|
14
|
+
double perspective[4];
|
|
15
|
+
/// x, y, z, w.
|
|
16
|
+
double quaternion[4];
|
|
17
|
+
} ANNTransformParts;
|
|
18
|
+
|
|
19
|
+
/// The parts of no transform.
|
|
20
|
+
FOUNDATION_EXPORT ANNTransformParts ANNTransformPartsIdentity(void);
|
|
21
|
+
|
|
22
|
+
/// The parts of `transform` into `parts`; NO when it can't be split (a scale of 0 flattens it).
|
|
23
|
+
FOUNDATION_EXPORT BOOL ANNTransformPartsOf(CATransform3D transform, ANNTransformParts *parts);
|
|
24
|
+
|
|
25
|
+
/// The transform the parts make.
|
|
26
|
+
FOUNDATION_EXPORT CATransform3D ANNTransformOfParts(ANNTransformParts parts);
|
|
27
|
+
|
|
28
|
+
/// The parts at `f` of the way: each number from + f·(to − from), the rotation by slerp along the shorter arc; exactly
|
|
29
|
+
/// `from` at f = 0 and `to` at f = 1. Two rotations half a turn apart go either way.
|
|
30
|
+
FOUNDATION_EXPORT ANNTransformParts ANNInterpolateTransformParts(ANNTransformParts from,
|
|
31
|
+
ANNTransformParts to, double f);
|
|
32
|
+
|
|
33
|
+
/// The rotation of the parts as the turns about x, then y, then z (degrees, each in −180…180), the order a view's
|
|
34
|
+
/// tracks compose them in (`ANNViewTracks`).
|
|
35
|
+
FOUNDATION_EXPORT void ANNRotationDegreesOf(ANNTransformParts parts, double *x, double *y,
|
|
36
|
+
double *z);
|
|
37
|
+
|
|
38
|
+
/// The shears of the parts as a transform of their own (the scale, rotation and the rest aside).
|
|
39
|
+
FOUNDATION_EXPORT CATransform3D ANNSkewTransformOf(ANNTransformParts parts);
|
|
40
|
+
|
|
41
|
+
#if DEBUG
|
|
42
|
+
/// Development only (there is no iOS test target): splits and rebuilds known transforms and checks the rotations a
|
|
43
|
+
/// shared element takes (0° → 90°, 0° → 180°, 45° → −45°, 270°, 170° → −170°, a scale, a tilt), once; a mismatch is
|
|
44
|
+
/// logged.
|
|
45
|
+
FOUNDATION_EXPORT void ANNTransformPartsSelfCheck(void);
|
|
46
|
+
#endif
|
|
47
|
+
|
|
48
|
+
NS_ASSUME_NONNULL_END
|