-
Notifications
You must be signed in to change notification settings - Fork 0
/
createInterpolationTransitionAnimation.js
128 lines (106 loc) · 3.46 KB
/
createInterpolationTransitionAnimation.js
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import A from 'react-native-reanimated';
import { ANIMATION_STATE } from './constants';
import { getProperAnimation } from './animations';
export default function createTransitionAnimation(config) {
const valueNames = Object.keys(config.values);
const initialAnimationValues = {
from: {},
to: {},
};
valueNames.forEach((key) => {
const current = config.values[key];
initialAnimationValues.from[key] = current.from;
initialAnimationValues.to[key] = current.to;
});
return () => {
function createAnimation(stateValue) {
const animationState = new A.Value(ANIMATION_STATE.START_POINT);
// interpolator will be used as a position tracker of animation
// using interpolation technique
const interpolator = new A.Value(0);
const animationValues = {};
valueNames.forEach((key, index) => {
const first = index === 0;
const animatedBlock = [];
// add tracking of animationState and running animation
// via animating interpolator only for very first
// animation value to get rid of Animation.Code
if (first) {
const forwardAnimationClock = new A.Clock();
const backwardAnimationClock = new A.Clock();
const forwardAnimationConfig = {
clock: forwardAnimationClock,
oppositeClock: backwardAnimationClock,
value: interpolator,
dest: config.animation.duration,
};
const backwardAnimationConfig = {
clock: backwardAnimationClock,
oppositeClock: forwardAnimationClock,
value: interpolator,
dest: 0,
};
if (first) {
forwardAnimationConfig.onFinish = [
A.set(animationState, ANIMATION_STATE.END_POINT),
];
backwardAnimationConfig.onFinish = [
A.set(animationState, ANIMATION_STATE.START_POINT),
];
}
const forwardTiming = getProperAnimation(
config,
!stateValue
? forwardAnimationConfig
: backwardAnimationConfig,
);
const backwardTiming = getProperAnimation(
config,
!stateValue
? backwardAnimationConfig
: forwardAnimationConfig,
);
animatedBlock.push(
A.cond(
A.eq(animationState, ANIMATION_STATE.PLAY_FORWARD),
forwardTiming,
),
A.cond(
A.eq(animationState, ANIMATION_STATE.PLAY_BACKWARD),
backwardTiming,
),
);
}
const item = config.values[key];
const inputRange = [0, config.animation.duration];
const outputRange = [item.from, item.to];
// reverse input range
// in order to animate value in reverse way
// from `to` to `from`
if (stateValue) {
outputRange.reverse();
}
const valueAnimation = A.interpolate(interpolator, {
inputRange,
outputRange,
extrapolate: A.Extrapolate.CLAMP,
});
animatedBlock.push(valueAnimation);
animationValues[key] = A.block(animatedBlock);
});
return {
animationState,
animationValues,
interpolator,
};
}
return {
valueNames,
lazy: config.animation.lazy,
initialAnimationValues,
operations: {
createAnimation,
},
};
};
}