1 | import { Animated, I18nManager } from 'react-native';
|
2 |
|
3 | import type {
|
4 | StackHeaderInterpolatedStyle,
|
5 | StackHeaderInterpolationProps,
|
6 | } from '../types';
|
7 |
|
8 | const { add } = Animated;
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | export function forUIKit({
|
14 | current,
|
15 | next,
|
16 | layouts,
|
17 | }: StackHeaderInterpolationProps): StackHeaderInterpolatedStyle {
|
18 | const defaultOffset = 100;
|
19 | const leftSpacing = 27;
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 | const leftLabelOffset = layouts.leftLabel
|
27 | ? (layouts.screen.width - layouts.leftLabel.width) / 2 - leftSpacing
|
28 | : defaultOffset;
|
29 | const titleLeftOffset = layouts.title
|
30 | ? (layouts.screen.width - layouts.title.width) / 2 - leftSpacing
|
31 | : defaultOffset;
|
32 |
|
33 |
|
34 |
|
35 | const rightOffset = layouts.screen.width / 4;
|
36 |
|
37 | const progress = add(
|
38 | current.progress.interpolate({
|
39 | inputRange: [0, 1],
|
40 | outputRange: [0, 1],
|
41 | extrapolate: 'clamp',
|
42 | }),
|
43 | next
|
44 | ? next.progress.interpolate({
|
45 | inputRange: [0, 1],
|
46 | outputRange: [0, 1],
|
47 | extrapolate: 'clamp',
|
48 | })
|
49 | : 0
|
50 | );
|
51 |
|
52 | return {
|
53 | leftButtonStyle: {
|
54 | opacity: progress.interpolate({
|
55 | inputRange: [0.3, 1, 1.5],
|
56 | outputRange: [0, 1, 0],
|
57 | }),
|
58 | },
|
59 | leftLabelStyle: {
|
60 | transform: [
|
61 | {
|
62 | translateX: progress.interpolate({
|
63 | inputRange: [0, 1, 2],
|
64 | outputRange: I18nManager.getConstants().isRTL
|
65 | ? [-rightOffset, 0, leftLabelOffset]
|
66 | : [leftLabelOffset, 0, -rightOffset],
|
67 | }),
|
68 | },
|
69 | ],
|
70 | },
|
71 | rightButtonStyle: {
|
72 | opacity: progress.interpolate({
|
73 | inputRange: [0.3, 1, 1.5],
|
74 | outputRange: [0, 1, 0],
|
75 | }),
|
76 | },
|
77 | titleStyle: {
|
78 | opacity: progress.interpolate({
|
79 | inputRange: [0, 0.4, 1, 1.5],
|
80 | outputRange: [0, 0.1, 1, 0],
|
81 | }),
|
82 | transform: [
|
83 | {
|
84 | translateX: progress.interpolate({
|
85 | inputRange: [0.5, 1, 2],
|
86 | outputRange: I18nManager.getConstants().isRTL
|
87 | ? [-titleLeftOffset, 0, rightOffset]
|
88 | : [rightOffset, 0, -titleLeftOffset],
|
89 | }),
|
90 | },
|
91 | ],
|
92 | },
|
93 | backgroundStyle: {
|
94 | transform: [
|
95 | {
|
96 | translateX: progress.interpolate({
|
97 | inputRange: [0, 1, 2],
|
98 | outputRange: I18nManager.getConstants().isRTL
|
99 | ? [-layouts.screen.width, 0, layouts.screen.width]
|
100 | : [layouts.screen.width, 0, -layouts.screen.width],
|
101 | }),
|
102 | },
|
103 | ],
|
104 | },
|
105 | };
|
106 | }
|
107 |
|
108 |
|
109 |
|
110 |
|
111 | export function forFade({
|
112 | current,
|
113 | next,
|
114 | }: StackHeaderInterpolationProps): StackHeaderInterpolatedStyle {
|
115 | const progress = add(
|
116 | current.progress.interpolate({
|
117 | inputRange: [0, 1],
|
118 | outputRange: [0, 1],
|
119 | extrapolate: 'clamp',
|
120 | }),
|
121 | next
|
122 | ? next.progress.interpolate({
|
123 | inputRange: [0, 1],
|
124 | outputRange: [0, 1],
|
125 | extrapolate: 'clamp',
|
126 | })
|
127 | : 0
|
128 | );
|
129 |
|
130 | const opacity = progress.interpolate({
|
131 | inputRange: [0, 1, 2],
|
132 | outputRange: [0, 1, 0],
|
133 | });
|
134 |
|
135 | return {
|
136 | leftButtonStyle: { opacity },
|
137 | rightButtonStyle: { opacity },
|
138 | titleStyle: { opacity },
|
139 | backgroundStyle: {
|
140 | opacity: progress.interpolate({
|
141 | inputRange: [0, 1, 1.9, 2],
|
142 | outputRange: [0, 1, 1, 0],
|
143 | }),
|
144 | },
|
145 | };
|
146 | }
|
147 |
|
148 |
|
149 |
|
150 |
|
151 | export function forSlideLeft({
|
152 | current,
|
153 | next,
|
154 | layouts: { screen },
|
155 | }: StackHeaderInterpolationProps): StackHeaderInterpolatedStyle {
|
156 | const progress = add(
|
157 | current.progress.interpolate({
|
158 | inputRange: [0, 1],
|
159 | outputRange: [0, 1],
|
160 | extrapolate: 'clamp',
|
161 | }),
|
162 | next
|
163 | ? next.progress.interpolate({
|
164 | inputRange: [0, 1],
|
165 | outputRange: [0, 1],
|
166 | extrapolate: 'clamp',
|
167 | })
|
168 | : 0
|
169 | );
|
170 |
|
171 | const translateX = progress.interpolate({
|
172 | inputRange: [0, 1, 2],
|
173 | outputRange: I18nManager.getConstants().isRTL
|
174 | ? [-screen.width, 0, screen.width]
|
175 | : [screen.width, 0, -screen.width],
|
176 | });
|
177 |
|
178 | const transform = [{ translateX }];
|
179 |
|
180 | return {
|
181 | leftButtonStyle: { transform },
|
182 | rightButtonStyle: { transform },
|
183 | titleStyle: { transform },
|
184 | backgroundStyle: { transform },
|
185 | };
|
186 | }
|
187 |
|
188 |
|
189 |
|
190 |
|
191 | export function forSlideRight({
|
192 | current,
|
193 | next,
|
194 | layouts: { screen },
|
195 | }: StackHeaderInterpolationProps): StackHeaderInterpolatedStyle {
|
196 | const progress = add(
|
197 | current.progress.interpolate({
|
198 | inputRange: [0, 1],
|
199 | outputRange: [0, 1],
|
200 | extrapolate: 'clamp',
|
201 | }),
|
202 | next
|
203 | ? next.progress.interpolate({
|
204 | inputRange: [0, 1],
|
205 | outputRange: [0, 1],
|
206 | extrapolate: 'clamp',
|
207 | })
|
208 | : 0
|
209 | );
|
210 |
|
211 | const translateX = progress.interpolate({
|
212 | inputRange: [0, 1, 2],
|
213 | outputRange: I18nManager.getConstants().isRTL
|
214 | ? [screen.width, 0, -screen.width]
|
215 | : [-screen.width, 0, screen.width],
|
216 | });
|
217 |
|
218 | const transform = [{ translateX }];
|
219 |
|
220 | return {
|
221 | leftButtonStyle: { transform },
|
222 | rightButtonStyle: { transform },
|
223 | titleStyle: { transform },
|
224 | backgroundStyle: { transform },
|
225 | };
|
226 | }
|
227 |
|
228 |
|
229 |
|
230 |
|
231 | export function forSlideUp({
|
232 | current,
|
233 | next,
|
234 | layouts: { header },
|
235 | }: StackHeaderInterpolationProps): StackHeaderInterpolatedStyle {
|
236 | const progress = add(
|
237 | current.progress.interpolate({
|
238 | inputRange: [0, 1],
|
239 | outputRange: [0, 1],
|
240 | extrapolate: 'clamp',
|
241 | }),
|
242 | next
|
243 | ? next.progress.interpolate({
|
244 | inputRange: [0, 1],
|
245 | outputRange: [0, 1],
|
246 | extrapolate: 'clamp',
|
247 | })
|
248 | : 0
|
249 | );
|
250 |
|
251 | const translateY = progress.interpolate({
|
252 | inputRange: [0, 1, 2],
|
253 | outputRange: [-header.height, 0, -header.height],
|
254 | });
|
255 |
|
256 | const transform = [{ translateY }];
|
257 |
|
258 | return {
|
259 | leftButtonStyle: { transform },
|
260 | rightButtonStyle: { transform },
|
261 | titleStyle: { transform },
|
262 | backgroundStyle: { transform },
|
263 | };
|
264 | }
|
265 |
|
266 | export function forNoAnimation(): StackHeaderInterpolatedStyle {
|
267 | return {};
|
268 | }
|