Created
February 10, 2020 08:59
-
-
Save wcandillon/508a480be6839acc2a1ee05e4acc49ae to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Animated, {Easing} from 'react-native-reanimated'; | |
// These are functions that we should ship from redash normally | |
// But we are not able to because the reanimated version supported by | |
// redash has bugs in proc() when used with clocks. | |
const { | |
Clock, | |
Value, | |
block, | |
clockRunning, | |
startClock, | |
cond, | |
set, | |
not, | |
timing: reTiming, | |
proc, | |
stopClock, | |
round, | |
interpolate, | |
Extrapolate, | |
color, | |
} = Animated; | |
export const red = (color: number) => (color >> 16) & 255; | |
export const green = (color: number) => (color >> 8) & 255; | |
export const blue = (color: number) => color & 255; | |
export const bInterpolate = proc(( | |
value: Animated.Node<number>, | |
from: Animated.Adaptable<number>, | |
to: Animated.Adaptable<number> | |
) => interpolate(value, { | |
inputRange: [0, 1], | |
outputRange: [from, to] | |
})); | |
export const bInterpolateColor = ( | |
value: Animated.Node<number>, | |
r1: Animated.Adaptable<number>, | |
g1: Animated.Adaptable<number>, | |
b1: Animated.Adaptable<number>, | |
r2: Animated.Adaptable<number>, | |
g2: Animated.Adaptable<number>, | |
b2: Animated.Adaptable<number> | |
) => interpolateColor(value, 0, 1, r1, g1, b1, r2, g2, b2); | |
export const interpolateColor = proc( | |
( | |
value: Animated.Adaptable<number>, | |
from: Animated.Adaptable<number>, | |
to: Animated.Adaptable<number>, | |
r1: Animated.Adaptable<number>, | |
g1: Animated.Adaptable<number>, | |
b1: Animated.Adaptable<number>, | |
r2: Animated.Adaptable<number>, | |
g2: Animated.Adaptable<number>, | |
b2: Animated.Adaptable<number>, | |
) => { | |
const inputRange = [from, to]; | |
const red = round( | |
interpolate(value, { | |
inputRange, | |
outputRange: [r1, r2], | |
extrapolate: Extrapolate.CLAMP, | |
}), | |
); | |
const green = round( | |
interpolate(value, { | |
inputRange, | |
outputRange: [g1, g2], | |
extrapolate: Extrapolate.CLAMP, | |
}), | |
); | |
const blue = round( | |
interpolate(value, { | |
inputRange, | |
outputRange: [b1, b2], | |
extrapolate: Extrapolate.CLAMP, | |
}), | |
); | |
return color(red, green, blue); | |
}, | |
); | |
export interface LoopProps { | |
duration?: number; | |
} | |
const internalLoop = proc( | |
( | |
clock: Animated.Clock, | |
toValue: Animated.Value<number>, | |
duration: Animated.Adaptable<number>, | |
finished: Animated.Value<number>, | |
time: Animated.Value<number>, | |
frameTime: Animated.Value<number>, | |
position: Animated.Value<number>, | |
) => { | |
const config = { | |
duration, | |
easing: Easing.ease, | |
toValue, | |
}; | |
const state = { | |
finished, | |
time, | |
frameTime, | |
position, | |
}; | |
return block([ | |
cond(not(clockRunning(clock)), startClock(clock)), | |
reTiming(clock, state, config), | |
cond(state.finished, [ | |
set(state.finished, 0), | |
set(state.time, 0), | |
set(state.frameTime, 0), | |
set(config.toValue, cond(config.toValue, 0, 1)), | |
]), | |
state.position, | |
]); | |
}, | |
); | |
export const loop = (loopConfig: LoopProps) => { | |
const {clock, easing, duration} = { | |
clock: new Clock(), | |
easing: Easing.linear, | |
duration: 200, | |
...loopConfig, | |
}; | |
const state = { | |
finished: new Value(0), | |
position: new Value(0), | |
time: new Value(0), | |
frameTime: new Value(0), | |
}; | |
const config = { | |
toValue: new Value(1), | |
duration, | |
easing, | |
}; | |
return internalLoop( | |
clock, | |
config.toValue, | |
config.duration, | |
state.finished, | |
state.time, | |
state.frameTime, | |
state.position, | |
); | |
}; | |
const internalTiming = proc( | |
( | |
clock: Animated.Clock, | |
from: Animated.Adaptable<number>, | |
to: Animated.Adaptable<number>, | |
toValue: Animated.Value<number>, | |
duration: Animated.Adaptable<number>, | |
finished: Animated.Value<number>, | |
time: Animated.Value<number>, | |
position: Animated.Value<number>, | |
frameTime: Animated.Value<number>, | |
) => { | |
const config = { | |
toValue, | |
duration, | |
easing: Easing.linear, | |
}; | |
const state = { | |
finished, | |
time, | |
frameTime, | |
position, | |
}; | |
return block([ | |
cond(not(clockRunning(clock)), [set(config.toValue, to), set(state.frameTime, 0)]), | |
block([ | |
cond(not(clockRunning(clock)), [ | |
set(state.finished, 0), | |
set(state.time, 0), | |
set(state.position, from), | |
startClock(clock), | |
]), | |
reTiming(clock, state, config), | |
cond(state.finished, stopClock(clock)), | |
state.position, | |
]), | |
]); | |
}, | |
); | |
export interface TimingParams { | |
clock?: Animated.Clock; | |
from?: Animated.Adaptable<number>; | |
to?: Animated.Adaptable<number>; | |
duration?: Animated.Adaptable<number>; | |
} | |
export const timing = (params: TimingParams) => { | |
const {clock, duration, from, to} = { | |
clock: new Clock(), | |
duration: 250, | |
from: 0, | |
to: 1, | |
...params, | |
}; | |
const state: Animated.TimingState = { | |
finished: new Value(0), | |
position: new Value(0), | |
time: new Value(0), | |
frameTime: new Value(0), | |
}; | |
const config = { | |
toValue: new Value(0), | |
duration, | |
}; | |
return internalTiming( | |
clock, | |
from, | |
to, | |
config.toValue, | |
config.duration, | |
state.finished, | |
state.time, | |
state.position, | |
state.frameTime, | |
); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment