React Native animation works only if state is true with useEffect - react-native

I'm trying to make accordion component with animated api and useEffect hook but animation only works if expanded state is true. When expanded state false component closes itself but with no animation. How can i make this animation work at both state?
const [expanded, setExpanded] = useState(false);
useEffect(() => {
console.log(expanded ? "150" : "0",);
Animated.parallel([
Animated.timing(animatedBGColor, {
toValue: expanded ? 150 : 0,
easing: Easing.linear,
duration: 200,
}),
Animated.spring(animatedRotation, {
toValue: expanded ? 1 : 0,
tension: 100,
friction: 9,
}),
Animated.timing(animatedHeight, {
toValue: expanded ? (lineHeight + (scaleHeight(15) * 2)) : 0,
easing: Easing.linear,
duration: 200,
}),
Animated.timing(animatedMargin, {
toValue: expanded ? scaleHeight(15) : 0,
duration: 200,
})
]).start()
}, [expanded]);
I'm changing state with this button
<AnimatedTouchable onPress={() => setExpanded(!expanded)}

Related

How to animate shrinking and growing of two elements at the same time?

I want to create a weekly plan and the user should be able to "select" a day which should then grow in the ui (example below).
I am using the Animated class from react-native and noticed I am not able to animate the flex-property, so I believe I have to do this using width and height.
I tried the following after reading #M.N.s awnser:
selectDay = (i: number) => {
const {selected, grow, shrink} = this.state;
this.setState({selected: i, latestSelected: selected});
grow.setValue(0.5);
shrink.setValue(1);
Animated.parallel(
[
Animated.timing(grow, {
toValue: 1,
duration: 200,
useNativeDriver: false,
easing: Easing.cubic,
}),
Animated.timing(shrink, {
toValue: 0.5,
duration: 200,
useNativeDriver: false,
easing: Easing.cubic,
}),
],
{stopTogether: false},
).start();
};
// In my render:
const growInterpolate = grow.interpolate({
inputRange: [0, 1],
outputRange: ['0%', '25%'],
});
const shrinkInterpolate = shrink.interpolate({
inputRange: [0, 1],
outputRange: ['0%', '25%'],
});
But it still behaves very laggy:
Video of the animation
In such case you need to use parallel animation:
Animated.parallel([
Animated.timing(animatedHeight, {
toValue: newHeight,
duration: 200,
}),
Animated.timing(animatedWidth, {
toValue: newWidth,
duration: 200,
})
], { stopTogether: false }).start()
More information:
https://reactnative.dev/docs/animated#parallel

My React Native Animation Duration Isn't Working

I have an animation in my login screen which is supposed to slide down the buttons when the sign in button is clicked and slide up the email and password input boxes at the same time, i have a duration of 2000 milliseconds but the positions change instantly instead of smoothly sliding.
The Animation is in a functional component, so to stop the animation from reverting back before i click to reverse it so i am using useState() to hold the position.( Previously before i was using useState(), when i changed the text in the input boxes, the animation would reset back to the original position)
Here is the Animation
const [Buttons, setButtons] = useState(200);
const [Input, setInput] = useState(800);
const AnimatedButtons = new Animated.ValueXY({ x: 0, y: Buttons })
const AnimatedInputs = new Animated.ValueXY({ x: 0, y: Input })
const StartAnmation = () => {
setButtons(800);
Animated.timing(
AnimatedButtons, {
toValue: { x: AnimatedButtons.x, y: AnimatedButtons.y },
duration: 2000,
useNativeDriver: true,
}).start()
setInput(-100);
Animated.timing(AnimatedInputs, {
toValue: { x: AnimatedInputs.x, y: AnimatedButtons.y },
duration: 2000,
useNativeDriver: true,
}).start()
}
const ReverseAnimation = () => {
setButtons(200)
Animated.timing(
AnimatedButtons, {
toValue: { x: AnimatedButtons.x, y: AnimatedButtons.y },
duration: 2000,
useNativeDriver: true,
}).start()
setInput(800)
Animated.timing(AnimatedInputs, {
toValue: { x: AnimatedInputs.x, y: AnimatedInputs.y },
duration: 2000,
useNativeDriver: true,
}).start()
}
I have 2 button onPress() that call the animations and have 2 Views which change positions, The positions change alright but i doesnt slide out gradually , just instantly change
Thanks

React-Native animation has a small pause

animate() {
Animated.loop(
Animated.timing(this.spinValue, {
toValue: 360,
duration: 1000
})
).start();
}
I call this function in componentDidMount and its clearly looping the animation however, on every loop there is a slight delay before it starts. Trying to figure out how that can just become a smooth 0 -> 360 loop
Adding Easing.linear was the solution.
animate() {
Animated.loop(
Animated.timing(this.spinValue, {
fromValue:0,
toValue: 360,
duration: 1000,
easing: Easing.linear,
useNativeDriver: true
}),
{useNativeDriver: true}
).start();
}

React Native Animated - How do you disable default easing?

How do you remove the default easing (easeInOut) that is applied to the Animated.timing function? For some reason, setting ease: Easing.linear does not remove the default easeInOut timing.
Animated.timing(this.state.positionX, {
toValue: 1,
duration:1000,
ease: Easing.linear,
useNativeDriver: true,
}),
Your config object should read easing not ease.
Animated.timing(this.state.positionX, {
toValue: 1,
duration: 1000,
easing: Easing.linear,
useNativeDriver: true
});

detected a division by zero in animated.divide node in react native ios

I get the above error in react native 0.49. I'm using Animated for simple animation. and I don't use Animated.divide, I don't get the why I get this error , here's my code:
_ChangeAvatarScale() {
if (ProfileStore.avatarScaleStatus) {
Animated.sequence([Animated.timing(ProfileStore.avatarScale, {
toValue: 0.7,
duration: 120,
useNativeDriver: true
}),
Animated.parallel([
Animated.timing(ProfileStore.avatarPosition, {
toValue: -20,
duration: 120,
useNativeDriver: true
}),
Animated.timing(ProfileStore.cameraPickIcons, {
toValue: 1,
duration: 100,
useNativeDriver: true
})
])
]).start();
ProfileStore.avatarScaleStatusChange();
}
else {
Animated.sequence([Animated.timing(ProfileStore.avatarScale, {
toValue: 1,
duration: 120,
useNativeDriver: true
}),
Animated.parallel([
Animated.timing(ProfileStore.avatarPosition, {
toValue: 1,
duration: 120,
useNativeDriver: true
}),
Animated.timing(ProfileStore.cameraPickIcons, {
toValue: -350,
duration: 100,
useNativeDriver: true
})
])
]).start();
ProfileStore.avatarScaleStatusChange();
}
}
and the mobx store :
#observable avatarScale = new Animated.Value(1);
#observable avatarPosition = new Animated.Value(1);
#observable avatarScaleStatus = true;
#action avatarScaleStatusChange(){
this.avatarScaleStatus = !this.avatarScaleStatus;
}
#observable cameraPickIcons = new Animated.Value(-350);
and I get this problem only in ios, the related file is RCTDivisionAnimatedNode.m