I am currently learning to create React Native Animations with the RN Reanimated and Redash libraries. I've managed to create a simple timing animation which transitions a TextInput placeholder into a label.
import Animated, { Clock, Easing, set, useCode } from 'react-native-reanimated';
import { timing } from 'react-native-redash/lib/module/v1';
const [isFocused, setIsFocused] = useState(false);
const clock = new Clock();
const [animation] = useState(new Animated.Value(0));
const shouldAnimateLabel = isFocused || !!value;
useCode(() =>
set(
animation,
timing({
clock,
animation,
duration: 150,
from: shouldAnimateLabel ? 0 : 1,
to: shouldAnimateLabel ? 1 : 0,
easing: Easing.inOut(Easing.ease),
}),
[shouldAnimateLabel],
),
);
const animatedStyles = {
top: Animated.interpolate(animation, {
inputRange: [0, 1],
outputRange: [20, -5],
}),
fontSize: Animated.interpolate(animation, {
inputRange: [0, 1],
outputRange: [18, 14],
}),
color: Animated.interpolateColors(animation, {
inputRange: [0, 1],
outputColorRange: ['#aaa', '#fff'],
}),
};
This animation is working fine when focusing/blurring the input, but as useCode
runs on mount, I am currently getting the unwanted side effect of the label animating from 1
to 0
before I have interacted with either of the inputs.
Is there a common solution to this using react-native-reanimated
or react-native-redash
? I could add another isMounted
state or something but that seems like a clunky solution?
Maybe something like this: