Skip to content

Instantly share code, notes, and snippets.

@wcandillon
Created February 10, 2020 08:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wcandillon/508a480be6839acc2a1ee05e4acc49ae to your computer and use it in GitHub Desktop.
Save wcandillon/508a480be6839acc2a1ee05e4acc49ae to your computer and use it in GitHub Desktop.
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