-
Notifications
You must be signed in to change notification settings - Fork 374
Expand file tree
/
Copy pathuseAnimatedGalleryStyle.tsx
More file actions
83 lines (75 loc) · 2.34 KB
/
useAnimatedGalleryStyle.tsx
File metadata and controls
83 lines (75 loc) · 2.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import type { ImageStyle } from 'react-native';
import { SharedValue, useAnimatedStyle } from 'react-native-reanimated';
import { useViewport } from '../../../hooks/useViewport';
type Props = {
index: number;
offsetScale: SharedValue<number>;
previous: boolean;
scale: SharedValue<number>;
screenHeight: number;
selected: boolean;
translateX: SharedValue<number>;
translateY: SharedValue<number>;
};
const oneEighth = 1 / 8;
export const useAnimatedGalleryStyle = ({
index,
offsetScale,
previous,
scale,
screenHeight,
selected,
translateX,
translateY,
}: Props) => {
const { vw } = useViewport();
const screenWidth = vw(100);
const halfScreenWidth = vw(50);
/**
* The current image, designated by selected is scaled and translated
* based on the gestures. The rendered images before and after the
* currently selected image also translated in X if the scale is
* greater than one so they keep the same distance from the selected
* image as it is scaled. If the scale is less than one they stay in
* place as to not come into the screen when the image shrinks.
*/
const animatedGalleryStyle = useAnimatedStyle<ImageStyle>(() => {
const xScaleOffset = -7 * screenWidth * (0.5 + index);
const yScaleOffset = -screenHeight * 3.5;
return {
transform: [
{
translateX: selected
? translateX.value + xScaleOffset
: scale.value < 1 || scale.value !== offsetScale.value
? xScaleOffset
: previous
? translateX.value - halfScreenWidth * (scale.value - 1) + xScaleOffset
: translateX.value + halfScreenWidth * (scale.value - 1) + xScaleOffset,
},
{
translateY: selected ? translateY.value + yScaleOffset : yScaleOffset,
},
{
scale: selected ? scale.value / 8 : oneEighth,
},
{ scaleX: 1 },
],
};
}, [previous, selected]);
const animatedStyles = useAnimatedStyle(() => {
const xScaleOffset = 7 * screenWidth * (0.5 + index);
const yScaleOffset = -screenHeight * 3.5;
return {
transform: [
{ scaleX: 1 },
{ translateY: yScaleOffset },
{
translateX: -xScaleOffset,
},
{ scale: oneEighth },
],
};
}, [index]);
return [animatedGalleryStyle, animatedStyles];
};