@react-navigation/stack 8.0.0-alpha.51 → 8.0.0-alpha.52
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/lib/module/TransitionConfigs/CardStyleInterpolators.js +241 -83
- package/lib/module/TransitionConfigs/CardStyleInterpolators.js.map +1 -1
- package/lib/module/TransitionConfigs/HeaderStyleInterpolators.js +11 -44
- package/lib/module/TransitionConfigs/HeaderStyleInterpolators.js.map +1 -1
- package/lib/module/TransitionConfigs/TransitionEasings.js +71 -0
- package/lib/module/TransitionConfigs/TransitionEasings.js.map +1 -0
- package/lib/module/TransitionConfigs/TransitionPresets.js +50 -10
- package/lib/module/TransitionConfigs/TransitionPresets.js.map +1 -1
- package/lib/module/TransitionConfigs/TransitionSpecs.js +69 -34
- package/lib/module/TransitionConfigs/TransitionSpecs.js.map +1 -1
- package/lib/module/navigators/createStackNavigator.js +25 -16
- package/lib/module/navigators/createStackNavigator.js.map +1 -1
- package/lib/module/views/Header/Header.js +2 -0
- package/lib/module/views/Header/Header.js.map +1 -1
- package/lib/module/views/Header/HeaderContainer.js +8 -3
- package/lib/module/views/Header/HeaderContainer.js.map +1 -1
- package/lib/module/views/Header/HeaderSegment.js +3 -6
- package/lib/module/views/Header/HeaderSegment.js.map +1 -1
- package/lib/module/views/Stack/Card.js +57 -32
- package/lib/module/views/Stack/Card.js.map +1 -1
- package/lib/module/views/Stack/CardContainer.js +17 -2
- package/lib/module/views/Stack/CardContainer.js.map +1 -1
- package/lib/module/views/Stack/CardStack.js +24 -13
- package/lib/module/views/Stack/CardStack.js.map +1 -1
- package/lib/typescript/src/TransitionConfigs/CardStyleInterpolators.d.ts +19 -11
- package/lib/typescript/src/TransitionConfigs/CardStyleInterpolators.d.ts.map +1 -1
- package/lib/typescript/src/TransitionConfigs/HeaderStyleInterpolators.d.ts +3 -3
- package/lib/typescript/src/TransitionConfigs/HeaderStyleInterpolators.d.ts.map +1 -1
- package/lib/typescript/src/TransitionConfigs/TransitionEasings.d.ts +38 -0
- package/lib/typescript/src/TransitionConfigs/TransitionEasings.d.ts.map +1 -0
- package/lib/typescript/src/TransitionConfigs/TransitionPresets.d.ts +14 -2
- package/lib/typescript/src/TransitionConfigs/TransitionPresets.d.ts.map +1 -1
- package/lib/typescript/src/TransitionConfigs/TransitionSpecs.d.ts +43 -14
- package/lib/typescript/src/TransitionConfigs/TransitionSpecs.d.ts.map +1 -1
- package/lib/typescript/src/navigators/createStackNavigator.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +44 -28
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/views/Header/Header.d.ts +1 -1
- package/lib/typescript/src/views/Header/Header.d.ts.map +1 -1
- package/lib/typescript/src/views/Header/HeaderContainer.d.ts.map +1 -1
- package/lib/typescript/src/views/Header/HeaderSegment.d.ts +1 -0
- package/lib/typescript/src/views/Header/HeaderSegment.d.ts.map +1 -1
- package/lib/typescript/src/views/Stack/Card.d.ts +9 -3
- package/lib/typescript/src/views/Stack/Card.d.ts.map +1 -1
- package/lib/typescript/src/views/Stack/CardContainer.d.ts +3 -1
- package/lib/typescript/src/views/Stack/CardContainer.d.ts.map +1 -1
- package/lib/typescript/src/views/Stack/CardStack.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/TransitionConfigs/CardStyleInterpolators.tsx +351 -100
- package/src/TransitionConfigs/HeaderStyleInterpolators.tsx +15 -46
- package/src/TransitionConfigs/TransitionEasings.tsx +90 -0
- package/src/TransitionConfigs/TransitionPresets.tsx +56 -10
- package/src/TransitionConfigs/TransitionSpecs.tsx +68 -34
- package/src/navigators/createStackNavigator.tsx +33 -24
- package/src/types.tsx +46 -29
- package/src/views/Header/Header.tsx +2 -0
- package/src/views/Header/HeaderContainer.tsx +10 -4
- package/src/views/Header/HeaderSegment.tsx +4 -4
- package/src/views/Stack/Card.tsx +82 -37
- package/src/views/Stack/CardContainer.tsx +17 -2
- package/src/views/Stack/CardStack.tsx +69 -14
|
@@ -5,6 +5,16 @@ import type {
|
|
|
5
5
|
StackCardInterpolationProps,
|
|
6
6
|
} from '../types';
|
|
7
7
|
import { conditional } from '../utils/conditional';
|
|
8
|
+
import {
|
|
9
|
+
accelerate,
|
|
10
|
+
ACTIVITY_CLOSE_DIM,
|
|
11
|
+
clamp,
|
|
12
|
+
decelerate,
|
|
13
|
+
FAST_OUT_EXTRA_SLOW_IN,
|
|
14
|
+
FAST_OUT_SLOW_IN,
|
|
15
|
+
LINEAR_OUT_SLOW_IN,
|
|
16
|
+
timeline,
|
|
17
|
+
} from './TransitionEasings';
|
|
8
18
|
|
|
9
19
|
const { add, multiply } = Animated;
|
|
10
20
|
|
|
@@ -39,13 +49,7 @@ export function forHorizontalIOS({
|
|
|
39
49
|
|
|
40
50
|
const overlayOpacity = current.progress.interpolate({
|
|
41
51
|
inputRange: [0, 1],
|
|
42
|
-
outputRange: [0, 0.
|
|
43
|
-
extrapolate: 'clamp',
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
const shadowOpacity = current.progress.interpolate({
|
|
47
|
-
inputRange: [0, 1],
|
|
48
|
-
outputRange: [0, 0.3],
|
|
52
|
+
outputRange: [0, 0.1],
|
|
49
53
|
extrapolate: 'clamp',
|
|
50
54
|
});
|
|
51
55
|
|
|
@@ -59,23 +63,10 @@ export function forHorizontalIOS({
|
|
|
59
63
|
],
|
|
60
64
|
},
|
|
61
65
|
overlayStyle: { opacity: overlayOpacity },
|
|
62
|
-
shadowStyle: { shadowOpacity },
|
|
66
|
+
shadowStyle: { shadowOpacity: 0.04 },
|
|
63
67
|
};
|
|
64
68
|
}
|
|
65
69
|
|
|
66
|
-
/**
|
|
67
|
-
* iOS-style slide in from the left.
|
|
68
|
-
*/
|
|
69
|
-
export function forHorizontalIOSInverted({
|
|
70
|
-
inverted,
|
|
71
|
-
...rest
|
|
72
|
-
}: StackCardInterpolationProps): StackCardInterpolatedStyle {
|
|
73
|
-
return forHorizontalIOS({
|
|
74
|
-
...rest,
|
|
75
|
-
inverted: Animated.multiply(inverted, -1),
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
|
|
79
70
|
/**
|
|
80
71
|
* Standard iOS-style slide in from the bottom (used for modals).
|
|
81
72
|
*/
|
|
@@ -242,9 +233,9 @@ export function forModalPresentationIOS({
|
|
|
242
233
|
*/
|
|
243
234
|
export function forFadeFromBottomAndroid({
|
|
244
235
|
current,
|
|
236
|
+
next,
|
|
245
237
|
inverted,
|
|
246
238
|
layouts: { screen },
|
|
247
|
-
closing,
|
|
248
239
|
}: StackCardInterpolationProps): StackCardInterpolatedStyle {
|
|
249
240
|
const translateY = multiply(
|
|
250
241
|
current.progress.interpolate({
|
|
@@ -256,13 +247,24 @@ export function forFadeFromBottomAndroid({
|
|
|
256
247
|
);
|
|
257
248
|
|
|
258
249
|
const opacity = conditional(
|
|
259
|
-
closing,
|
|
260
|
-
current.progress
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
250
|
+
current.closing,
|
|
251
|
+
current.progress.interpolate(
|
|
252
|
+
timeline({
|
|
253
|
+
duration: 250,
|
|
254
|
+
easing: (value) => accelerate(4, value),
|
|
255
|
+
closing: true,
|
|
256
|
+
stops: [100],
|
|
257
|
+
output: (time) => 1 - clamp((time - 100) / 150),
|
|
258
|
+
})
|
|
259
|
+
),
|
|
260
|
+
current.progress.interpolate(
|
|
261
|
+
timeline({
|
|
262
|
+
duration: 350,
|
|
263
|
+
easing: (value) => decelerate(5, value),
|
|
264
|
+
stops: [200],
|
|
265
|
+
output: (time) => decelerate(4, clamp(time / 200)),
|
|
266
|
+
})
|
|
267
|
+
)
|
|
266
268
|
);
|
|
267
269
|
|
|
268
270
|
return {
|
|
@@ -270,6 +272,29 @@ export function forFadeFromBottomAndroid({
|
|
|
270
272
|
opacity,
|
|
271
273
|
transform: [{ translateY }],
|
|
272
274
|
},
|
|
275
|
+
dimStyle: next
|
|
276
|
+
? {
|
|
277
|
+
opacity: conditional(
|
|
278
|
+
next.closing,
|
|
279
|
+
next.progress.interpolate(
|
|
280
|
+
timeline({
|
|
281
|
+
duration: 250,
|
|
282
|
+
easing: (value) => accelerate(4, value),
|
|
283
|
+
closing: true,
|
|
284
|
+
output: (time) => 0.3 * (1 - LINEAR_OUT_SLOW_IN(time / 250)),
|
|
285
|
+
})
|
|
286
|
+
),
|
|
287
|
+
next.progress.interpolate(
|
|
288
|
+
timeline({
|
|
289
|
+
duration: 350,
|
|
290
|
+
easing: (value) => decelerate(5, value),
|
|
291
|
+
stops: [217],
|
|
292
|
+
output: (time) => 0.3 * FAST_OUT_SLOW_IN(clamp(time / 217)),
|
|
293
|
+
})
|
|
294
|
+
)
|
|
295
|
+
),
|
|
296
|
+
}
|
|
297
|
+
: undefined,
|
|
273
298
|
};
|
|
274
299
|
}
|
|
275
300
|
|
|
@@ -282,40 +307,80 @@ export function forRevealFromBottomAndroid({
|
|
|
282
307
|
inverted,
|
|
283
308
|
layouts: { screen },
|
|
284
309
|
}: StackCardInterpolationProps): StackCardInterpolatedStyle {
|
|
310
|
+
const translationOpenRanges = timeline({
|
|
311
|
+
duration: 425,
|
|
312
|
+
easing: FAST_OUT_EXTRA_SLOW_IN,
|
|
313
|
+
output: (time) => FAST_OUT_SLOW_IN(time / 425),
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
const translationCloseRanges = timeline({
|
|
317
|
+
duration: 425,
|
|
318
|
+
easing: FAST_OUT_EXTRA_SLOW_IN,
|
|
319
|
+
closing: true,
|
|
320
|
+
output: (time) => 1 - FAST_OUT_SLOW_IN(time / 425),
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
const clipProgress = current.progress.interpolate({
|
|
324
|
+
inputRange: [0, 1],
|
|
325
|
+
outputRange: [0, 1],
|
|
326
|
+
extrapolate: 'clamp',
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
const translationProgress = conditional(
|
|
330
|
+
current.closing,
|
|
331
|
+
current.progress.interpolate(translationCloseRanges),
|
|
332
|
+
current.progress.interpolate(translationOpenRanges)
|
|
333
|
+
);
|
|
334
|
+
|
|
285
335
|
const containerTranslateY = multiply(
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
336
|
+
multiply(
|
|
337
|
+
add(
|
|
338
|
+
add(1, multiply(clipProgress, -0.959)),
|
|
339
|
+
multiply(translationProgress, -0.041)
|
|
340
|
+
),
|
|
341
|
+
screen.height
|
|
342
|
+
),
|
|
291
343
|
inverted
|
|
292
344
|
);
|
|
293
345
|
|
|
294
346
|
const cardTranslateYFocused = multiply(
|
|
295
|
-
|
|
296
|
-
inputRange: [0, 1],
|
|
297
|
-
outputRange: [screen.height * (95.9 / 100) * -1, 0],
|
|
298
|
-
extrapolate: 'clamp',
|
|
299
|
-
}),
|
|
347
|
+
multiply(add(clipProgress, -1), screen.height * 0.959),
|
|
300
348
|
inverted
|
|
301
349
|
);
|
|
302
350
|
|
|
303
351
|
const cardTranslateYUnfocused = next
|
|
304
352
|
? multiply(
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
353
|
+
multiply(
|
|
354
|
+
conditional(
|
|
355
|
+
next.closing,
|
|
356
|
+
next.progress.interpolate(translationCloseRanges),
|
|
357
|
+
next.progress.interpolate(translationOpenRanges)
|
|
358
|
+
),
|
|
359
|
+
screen.height * -0.02
|
|
360
|
+
),
|
|
310
361
|
inverted
|
|
311
362
|
)
|
|
312
363
|
: 0;
|
|
313
364
|
|
|
314
|
-
const overlayOpacity =
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
365
|
+
const overlayOpacity = conditional(
|
|
366
|
+
current.closing,
|
|
367
|
+
current.progress.interpolate(
|
|
368
|
+
timeline({
|
|
369
|
+
duration: 425,
|
|
370
|
+
easing: FAST_OUT_EXTRA_SLOW_IN,
|
|
371
|
+
closing: true,
|
|
372
|
+
output: (time) => 0.1 * (1 - ACTIVITY_CLOSE_DIM(time / 425)),
|
|
373
|
+
})
|
|
374
|
+
),
|
|
375
|
+
current.progress.interpolate(
|
|
376
|
+
timeline({
|
|
377
|
+
duration: 425,
|
|
378
|
+
easing: FAST_OUT_EXTRA_SLOW_IN,
|
|
379
|
+
stops: [117],
|
|
380
|
+
output: (time) => 0.1 * clamp(time / 117),
|
|
381
|
+
})
|
|
382
|
+
)
|
|
383
|
+
);
|
|
319
384
|
|
|
320
385
|
return {
|
|
321
386
|
containerStyle: {
|
|
@@ -333,62 +398,94 @@ export function forRevealFromBottomAndroid({
|
|
|
333
398
|
}
|
|
334
399
|
|
|
335
400
|
/**
|
|
336
|
-
* Standard Android-style
|
|
401
|
+
* Standard Android-style scale from center for Android 10.
|
|
337
402
|
*/
|
|
338
403
|
export function forScaleFromCenterAndroid({
|
|
339
404
|
current,
|
|
340
405
|
next,
|
|
341
|
-
closing,
|
|
342
406
|
}: StackCardInterpolationProps): StackCardInterpolatedStyle {
|
|
343
|
-
const
|
|
344
|
-
current.
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
407
|
+
const opacity = conditional(
|
|
408
|
+
current.closing,
|
|
409
|
+
current.progress.interpolate(
|
|
410
|
+
timeline({
|
|
411
|
+
duration: 400,
|
|
412
|
+
easing: FAST_OUT_EXTRA_SLOW_IN,
|
|
413
|
+
closing: true,
|
|
414
|
+
stops: [33, 83],
|
|
415
|
+
output: (time) => 1 - clamp((time - 33) / 50),
|
|
416
|
+
})
|
|
417
|
+
),
|
|
418
|
+
current.progress.interpolate(
|
|
419
|
+
timeline({
|
|
420
|
+
duration: 400,
|
|
421
|
+
easing: FAST_OUT_EXTRA_SLOW_IN,
|
|
422
|
+
stops: [50, 100],
|
|
423
|
+
output: (time) => clamp((time - 50) / 50),
|
|
424
|
+
})
|
|
425
|
+
)
|
|
426
|
+
);
|
|
427
|
+
|
|
428
|
+
const scale = next
|
|
429
|
+
? conditional(
|
|
430
|
+
next.closing,
|
|
431
|
+
next.progress.interpolate({
|
|
351
432
|
inputRange: [0, 1],
|
|
352
|
-
outputRange: [
|
|
433
|
+
outputRange: [1, 1.1],
|
|
434
|
+
extrapolate: 'clamp',
|
|
435
|
+
}),
|
|
436
|
+
next.progress.interpolate({
|
|
437
|
+
inputRange: [0, 1],
|
|
438
|
+
outputRange: [1, 1.05],
|
|
353
439
|
extrapolate: 'clamp',
|
|
354
440
|
})
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
}),
|
|
370
|
-
progress.interpolate({
|
|
371
|
-
inputRange: [0, 1, 2],
|
|
372
|
-
outputRange: [0.85, 1, 1.075],
|
|
373
|
-
})
|
|
374
|
-
);
|
|
441
|
+
)
|
|
442
|
+
: conditional(
|
|
443
|
+
current.closing,
|
|
444
|
+
current.progress.interpolate({
|
|
445
|
+
inputRange: [0, 1],
|
|
446
|
+
outputRange: [0.9, 1],
|
|
447
|
+
extrapolate: 'clamp',
|
|
448
|
+
}),
|
|
449
|
+
current.progress.interpolate({
|
|
450
|
+
inputRange: [0, 1],
|
|
451
|
+
outputRange: [0.85, 1],
|
|
452
|
+
extrapolate: 'clamp',
|
|
453
|
+
})
|
|
454
|
+
);
|
|
375
455
|
|
|
376
456
|
return {
|
|
377
457
|
cardStyle: {
|
|
378
458
|
opacity,
|
|
379
459
|
transform: [{ scale }],
|
|
380
460
|
},
|
|
461
|
+
dimStyle: next
|
|
462
|
+
? {
|
|
463
|
+
opacity: multiply(
|
|
464
|
+
next.closing.interpolate({
|
|
465
|
+
inputRange: [0, 1],
|
|
466
|
+
outputRange: [1, 0],
|
|
467
|
+
}),
|
|
468
|
+
next.progress.interpolate(
|
|
469
|
+
timeline({
|
|
470
|
+
duration: 400,
|
|
471
|
+
easing: FAST_OUT_EXTRA_SLOW_IN,
|
|
472
|
+
stops: [83, 250],
|
|
473
|
+
output: (time) => 0.6 * clamp((time - 83) / 167),
|
|
474
|
+
})
|
|
475
|
+
)
|
|
476
|
+
),
|
|
477
|
+
}
|
|
478
|
+
: undefined,
|
|
381
479
|
};
|
|
382
480
|
}
|
|
383
481
|
|
|
384
482
|
/**
|
|
385
|
-
* Standard Android-style fade from right for Android 14.
|
|
483
|
+
* Standard Android-style fade from right for Android 14 and later.
|
|
386
484
|
*/
|
|
387
485
|
export function forFadeFromRightAndroid({
|
|
388
486
|
current,
|
|
389
487
|
next,
|
|
390
488
|
inverted,
|
|
391
|
-
closing,
|
|
392
489
|
}: StackCardInterpolationProps): StackCardInterpolatedStyle {
|
|
393
490
|
const translateFocused = multiply(
|
|
394
491
|
current.progress.interpolate({
|
|
@@ -411,13 +508,24 @@ export function forFadeFromRightAndroid({
|
|
|
411
508
|
: 0;
|
|
412
509
|
|
|
413
510
|
const opacity = conditional(
|
|
414
|
-
closing,
|
|
415
|
-
current.progress.interpolate(
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
511
|
+
current.closing,
|
|
512
|
+
current.progress.interpolate(
|
|
513
|
+
timeline({
|
|
514
|
+
duration: 450,
|
|
515
|
+
easing: FAST_OUT_EXTRA_SLOW_IN,
|
|
516
|
+
closing: true,
|
|
517
|
+
stops: [35, 118],
|
|
518
|
+
output: (time) => 1 - clamp((time - 35) / 83),
|
|
519
|
+
})
|
|
520
|
+
),
|
|
521
|
+
current.progress.interpolate(
|
|
522
|
+
timeline({
|
|
523
|
+
duration: 450,
|
|
524
|
+
easing: FAST_OUT_EXTRA_SLOW_IN,
|
|
525
|
+
stops: [50, 133],
|
|
526
|
+
output: (time) => clamp((time - 50) / 83),
|
|
527
|
+
})
|
|
528
|
+
)
|
|
421
529
|
);
|
|
422
530
|
|
|
423
531
|
return {
|
|
@@ -440,20 +548,27 @@ export function forBottomSheetAndroid({
|
|
|
440
548
|
current,
|
|
441
549
|
inverted,
|
|
442
550
|
layouts: { screen },
|
|
443
|
-
closing,
|
|
444
551
|
}: StackCardInterpolationProps): StackCardInterpolatedStyle {
|
|
445
552
|
const translateY = multiply(
|
|
446
553
|
current.progress.interpolate({
|
|
447
554
|
inputRange: [0, 1],
|
|
448
|
-
outputRange: [screen.height * 0.
|
|
555
|
+
outputRange: [screen.height * 0.2, 0],
|
|
449
556
|
extrapolate: 'clamp',
|
|
450
557
|
}),
|
|
451
558
|
inverted
|
|
452
559
|
);
|
|
453
560
|
|
|
454
561
|
const opacity = conditional(
|
|
455
|
-
closing,
|
|
456
|
-
current.progress
|
|
562
|
+
current.closing,
|
|
563
|
+
current.progress.interpolate(
|
|
564
|
+
timeline({
|
|
565
|
+
duration: 350,
|
|
566
|
+
easing: FAST_OUT_EXTRA_SLOW_IN,
|
|
567
|
+
closing: true,
|
|
568
|
+
stops: [300],
|
|
569
|
+
output: (time) => 1 - FAST_OUT_EXTRA_SLOW_IN(clamp(time / 300)),
|
|
570
|
+
})
|
|
571
|
+
),
|
|
457
572
|
current.progress.interpolate({
|
|
458
573
|
inputRange: [0, 1],
|
|
459
574
|
outputRange: [0, 1],
|
|
@@ -461,23 +576,107 @@ export function forBottomSheetAndroid({
|
|
|
461
576
|
})
|
|
462
577
|
);
|
|
463
578
|
|
|
464
|
-
|
|
579
|
+
// We follow Android's window dim timing for the 0.32 scrim.
|
|
580
|
+
// This makes it reach full opacity after 128 ms and clear after 112 ms.
|
|
581
|
+
// See https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-17.0.0_r1/services/core/java/com/android/server/wm/DimmerAnimationHelper.java
|
|
582
|
+
const overlayOpacity = conditional(
|
|
583
|
+
current.closing,
|
|
584
|
+
current.progress.interpolate(
|
|
585
|
+
timeline({
|
|
586
|
+
duration: 350,
|
|
587
|
+
easing: FAST_OUT_EXTRA_SLOW_IN,
|
|
588
|
+
closing: true,
|
|
589
|
+
stops: [112],
|
|
590
|
+
output: (time) => 0.32 * (1 - clamp(time / 112)),
|
|
591
|
+
})
|
|
592
|
+
),
|
|
593
|
+
current.progress.interpolate(
|
|
594
|
+
timeline({
|
|
595
|
+
duration: 400,
|
|
596
|
+
easing: FAST_OUT_EXTRA_SLOW_IN,
|
|
597
|
+
stops: [128],
|
|
598
|
+
output: (time) => 0.32 * clamp(time / 128),
|
|
599
|
+
})
|
|
600
|
+
)
|
|
601
|
+
);
|
|
602
|
+
|
|
603
|
+
return {
|
|
604
|
+
cardStyle: {
|
|
605
|
+
opacity,
|
|
606
|
+
transform: [{ translateY }],
|
|
607
|
+
},
|
|
608
|
+
overlayStyle: { opacity: overlayOpacity },
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* Standard Android dialog transition.
|
|
614
|
+
*/
|
|
615
|
+
export function forDialogAndroid({
|
|
616
|
+
current: { progress, closing },
|
|
617
|
+
}: StackCardInterpolationProps): StackCardInterpolatedStyle {
|
|
618
|
+
const opacity = conditional(
|
|
619
|
+
closing,
|
|
620
|
+
progress.interpolate(
|
|
621
|
+
timeline({
|
|
622
|
+
duration: 220,
|
|
623
|
+
easing: (value) => decelerate(5, value),
|
|
624
|
+
closing: true,
|
|
625
|
+
stops: [150],
|
|
626
|
+
output: (time) => 1 - decelerate(3, clamp(time / 150)),
|
|
627
|
+
})
|
|
628
|
+
),
|
|
629
|
+
progress.interpolate(
|
|
630
|
+
timeline({
|
|
631
|
+
duration: 220,
|
|
632
|
+
easing: (value) => decelerate(5, value),
|
|
633
|
+
stops: [150],
|
|
634
|
+
output: (time) => decelerate(3, clamp(time / 150)),
|
|
635
|
+
})
|
|
636
|
+
)
|
|
637
|
+
);
|
|
638
|
+
|
|
639
|
+
const scale = progress.interpolate({
|
|
465
640
|
inputRange: [0, 1],
|
|
466
|
-
outputRange: [0,
|
|
641
|
+
outputRange: [0.9, 1],
|
|
467
642
|
extrapolate: 'clamp',
|
|
468
643
|
});
|
|
469
644
|
|
|
645
|
+
// We follow Android's window dim timing for the 0.6 dialog dim.
|
|
646
|
+
// This makes it reach or clear full opacity after 132 ms.
|
|
647
|
+
// See https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-17.0.0_r1/services/core/java/com/android/server/wm/DimmerAnimationHelper.java
|
|
648
|
+
const overlayOpacity = conditional(
|
|
649
|
+
closing,
|
|
650
|
+
progress.interpolate(
|
|
651
|
+
timeline({
|
|
652
|
+
duration: 220,
|
|
653
|
+
easing: (value) => decelerate(5, value),
|
|
654
|
+
closing: true,
|
|
655
|
+
stops: [132],
|
|
656
|
+
output: (time) => 0.6 * (1 - clamp(time / 132)),
|
|
657
|
+
})
|
|
658
|
+
),
|
|
659
|
+
progress.interpolate(
|
|
660
|
+
timeline({
|
|
661
|
+
duration: 220,
|
|
662
|
+
easing: (value) => decelerate(5, value),
|
|
663
|
+
stops: [132],
|
|
664
|
+
output: (time) => 0.6 * clamp(time / 132),
|
|
665
|
+
})
|
|
666
|
+
)
|
|
667
|
+
);
|
|
668
|
+
|
|
470
669
|
return {
|
|
471
670
|
cardStyle: {
|
|
472
671
|
opacity,
|
|
473
|
-
transform: [{
|
|
672
|
+
transform: [{ scale }],
|
|
474
673
|
},
|
|
475
674
|
overlayStyle: { opacity: overlayOpacity },
|
|
476
675
|
};
|
|
477
676
|
}
|
|
478
677
|
|
|
479
678
|
/**
|
|
480
|
-
* Simple fade animation
|
|
679
|
+
* Simple fade animation.
|
|
481
680
|
*/
|
|
482
681
|
export function forFadeFromCenter({
|
|
483
682
|
current: { progress },
|
|
@@ -487,15 +686,67 @@ export function forFadeFromCenter({
|
|
|
487
686
|
opacity: progress.interpolate({
|
|
488
687
|
inputRange: [0, 0.5, 0.9, 1],
|
|
489
688
|
outputRange: [0, 0.25, 0.7, 1],
|
|
689
|
+
extrapolate: 'clamp',
|
|
490
690
|
}),
|
|
491
691
|
},
|
|
492
|
-
|
|
493
|
-
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* Standard iOS cross-dissolve transition.
|
|
697
|
+
*/
|
|
698
|
+
export function forCrossDissolveIOS({
|
|
699
|
+
current,
|
|
700
|
+
next,
|
|
701
|
+
}: StackCardInterpolationProps): StackCardInterpolatedStyle {
|
|
702
|
+
// UIKit cross-dissolve darkens identical light screens at the midpoint.
|
|
703
|
+
// Dimming the outgoing card reproduces this without exposing earlier screens.
|
|
704
|
+
return {
|
|
705
|
+
cardStyle: {
|
|
706
|
+
opacity: current.progress.interpolate({
|
|
494
707
|
inputRange: [0, 1],
|
|
495
|
-
outputRange: [0,
|
|
708
|
+
outputRange: [0, 1],
|
|
496
709
|
extrapolate: 'clamp',
|
|
497
710
|
}),
|
|
498
711
|
},
|
|
712
|
+
dimStyle: next
|
|
713
|
+
? {
|
|
714
|
+
opacity: next.progress.interpolate({
|
|
715
|
+
inputRange: [0, 1],
|
|
716
|
+
outputRange: [0, 1],
|
|
717
|
+
extrapolate: 'clamp',
|
|
718
|
+
}),
|
|
719
|
+
}
|
|
720
|
+
: undefined,
|
|
721
|
+
};
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
/**
|
|
725
|
+
* Standard iOS horizontal flip transition.
|
|
726
|
+
*/
|
|
727
|
+
export function forFlipIOS({
|
|
728
|
+
current,
|
|
729
|
+
next,
|
|
730
|
+
inverted,
|
|
731
|
+
}: StackCardInterpolationProps): StackCardInterpolatedStyle {
|
|
732
|
+
const progress = add(current.progress, next ? next.progress : 0);
|
|
733
|
+
|
|
734
|
+
const rotateY = multiply(
|
|
735
|
+
progress.interpolate({
|
|
736
|
+
inputRange: [0, 1, 2],
|
|
737
|
+
outputRange: [180, 0, -180],
|
|
738
|
+
}),
|
|
739
|
+
inverted
|
|
740
|
+
).interpolate({
|
|
741
|
+
inputRange: [-180, 0, 180],
|
|
742
|
+
outputRange: ['-180deg', '0deg', '180deg'],
|
|
743
|
+
});
|
|
744
|
+
|
|
745
|
+
return {
|
|
746
|
+
cardStyle: {
|
|
747
|
+
backfaceVisibility: 'hidden',
|
|
748
|
+
transform: [{ perspective: 1000 }, { rotateY }],
|
|
749
|
+
},
|
|
499
750
|
};
|
|
500
751
|
}
|
|
501
752
|
|
|
@@ -14,11 +14,9 @@ const { add, multiply } = Animated;
|
|
|
14
14
|
export function forUIKit({
|
|
15
15
|
current,
|
|
16
16
|
next,
|
|
17
|
-
|
|
17
|
+
inverted,
|
|
18
18
|
layouts,
|
|
19
19
|
}: StackHeaderInterpolationProps): StackHeaderInterpolatedStyle {
|
|
20
|
-
const multiplier = direction === 'rtl' ? -1 : 1;
|
|
21
|
-
|
|
22
20
|
const progress = add(
|
|
23
21
|
current.progress.interpolate({
|
|
24
22
|
inputRange: [0, 1],
|
|
@@ -45,7 +43,7 @@ export function forUIKit({
|
|
|
45
43
|
});
|
|
46
44
|
|
|
47
45
|
const translateX = multiply(
|
|
48
|
-
|
|
46
|
+
inverted,
|
|
49
47
|
progress.interpolate({
|
|
50
48
|
inputRange: [0, 1, 2],
|
|
51
49
|
outputRange: [layouts.screen.width, 0, -layouts.screen.width * 0.3],
|
|
@@ -128,10 +126,9 @@ export function forFade({
|
|
|
128
126
|
export function forSlideLeft({
|
|
129
127
|
current,
|
|
130
128
|
next,
|
|
131
|
-
|
|
129
|
+
inverted,
|
|
132
130
|
layouts: { screen },
|
|
133
131
|
}: StackHeaderInterpolationProps): StackHeaderInterpolatedStyle {
|
|
134
|
-
const isRTL = direction === 'rtl';
|
|
135
132
|
const progress = add(
|
|
136
133
|
current.progress.interpolate({
|
|
137
134
|
inputRange: [0, 1],
|
|
@@ -147,12 +144,13 @@ export function forSlideLeft({
|
|
|
147
144
|
: 0
|
|
148
145
|
);
|
|
149
146
|
|
|
150
|
-
const translateX =
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
: [screen.width, 0, -screen.width],
|
|
155
|
-
|
|
147
|
+
const translateX = multiply(
|
|
148
|
+
inverted,
|
|
149
|
+
progress.interpolate({
|
|
150
|
+
inputRange: [0, 1, 2],
|
|
151
|
+
outputRange: [screen.width, 0, -screen.width],
|
|
152
|
+
})
|
|
153
|
+
);
|
|
156
154
|
|
|
157
155
|
const transform = [{ translateX }];
|
|
158
156
|
|
|
@@ -168,42 +166,13 @@ export function forSlideLeft({
|
|
|
168
166
|
* Simple translate animation to translate the header to right.
|
|
169
167
|
*/
|
|
170
168
|
export function forSlideRight({
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
direction,
|
|
174
|
-
layouts: { screen },
|
|
169
|
+
inverted,
|
|
170
|
+
...rest
|
|
175
171
|
}: StackHeaderInterpolationProps): StackHeaderInterpolatedStyle {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
inputRange: [0, 1],
|
|
180
|
-
outputRange: [0, 1],
|
|
181
|
-
extrapolate: 'clamp',
|
|
182
|
-
}),
|
|
183
|
-
next
|
|
184
|
-
? next.progress.interpolate({
|
|
185
|
-
inputRange: [0, 1],
|
|
186
|
-
outputRange: [0, 1],
|
|
187
|
-
extrapolate: 'clamp',
|
|
188
|
-
})
|
|
189
|
-
: 0
|
|
190
|
-
);
|
|
191
|
-
|
|
192
|
-
const translateX = progress.interpolate({
|
|
193
|
-
inputRange: [0, 1, 2],
|
|
194
|
-
outputRange: isRTL
|
|
195
|
-
? [screen.width, 0, -screen.width]
|
|
196
|
-
: [-screen.width, 0, screen.width],
|
|
172
|
+
return forSlideLeft({
|
|
173
|
+
...rest,
|
|
174
|
+
inverted: inverted === 1 ? -1 : 1,
|
|
197
175
|
});
|
|
198
|
-
|
|
199
|
-
const transform = [{ translateX }];
|
|
200
|
-
|
|
201
|
-
return {
|
|
202
|
-
leftButtonStyle: { transform },
|
|
203
|
-
rightButtonStyle: { transform },
|
|
204
|
-
titleStyle: { transform },
|
|
205
|
-
backgroundStyle: { transform },
|
|
206
|
-
};
|
|
207
176
|
}
|
|
208
177
|
|
|
209
178
|
/**
|