英文:
React native animation change colors and moving
问题
I'm from a new family with React Native. I'm now working with react native animation to change components from JSX to react native. Here are the sources:
I am done converting the source from JSX to RN, but it's still not perfect. Sometimes the color gets delayed in updating the new value.
Can anyone give me some advice? Thanks all!!!
英文:
I'm from a new family with React Native. I'm now working with react native animation to change components from JSX to react native. Here are the sources:
I am done converting the source from JSX to RN, but it's still not perfect. Sometimes the color gets delayed in updating the new value.
Can anyone give me some advice? Thanks all!!!
import React, { useEffect, useRef, useState } from 'react'
import { Animated, SafeAreaView, StyleSheet } from 'react-native'
const App = () => {
const animatedCenterToLeft = useRef(new Animated.Value(0)).current;
const animatedCenterToTop = useRef(new Animated.Value(0)).current;
const [duration] = useState(500);
const [value, setValue] = React.useState(0);
React.useEffect(() => {
const timeInterVal = 2080;
const intervalTop = setInterval(() => {
setValue((v) => (v === 1 ? 0 : v + 1));
}, timeInterVal);
return () => {
clearInterval(intervalTop);
}
}, []);
const colors = [
'#007BC0',
'#ED0007',
];
useEffect(() => {
Animated.loop(
Animated.sequence([
Animated.timing(animatedCenterToLeft, {
toValue: -24,
duration,
delay: 0,
useNativeDriver: true,
}),
Animated.timing(animatedCenterToLeft, {
toValue: 0,
duration,
delay: 0,
useNativeDriver: true,
}),
Animated.timing(animatedCenterToTop, {
toValue: -24,
duration,
delay: 0,
useNativeDriver: true,
}),
Animated.timing(animatedCenterToTop, {
toValue: 0,
duration,
delay: 0,
useNativeDriver: true,
})
])
).start();
}, [])
return (
<SafeAreaView style={{flex:1, justifyContent:'center', alignSelf:'center'}}>
<Animated.View style={[styles.indicatorTop, { backgroundColor: colors[value] },
{
transform: [
{
translateX: animatedCenterToLeft
},
{
translateY: animatedCenterToTop
}
]
}
]} />
</SafeAreaView>
)
}
export default App
const styles = StyleSheet.create({
indicatorTop: {
height: 15,
width: 15,
position: 'absolute'
},
})
答案1
得分: 2
以下是翻译好的部分:
"Instead, add your color change to your sequence, and remove your interval. I'm not sure if there's an easy way to reference animated values within animations in the basic React Native Animated; I have done it in Reanimated, which I can recommend if you're looking to do more complex animations.
Changes:
- added new Animated.Value (
animatedColor
), range 0-1 - interpolate animatedColor to your colors (
color
), apply color to object style - start sequence with Animated.timing call to change animatedColor to 1
- double the sequence, set the second Animated.timing call on animatedColor to 0"
"Full code:
import React, { useEffect, useRef } from 'react'
import { Animated, SafeAreaView, StyleSheet } from 'react-native'
const duration = 500;
const App = () => {
const animatedCenterToLeft = useRef(new Animated.Value(0)).current;
const animatedCenterToTop = useRef(new Animated.Value(0)).current;
const animatedColor = useRef(new Animated.Value(0)).current;
const color = animatedColor.interpolate({
inputRange: [0, 1],
outputRange: ['#007BC0', '#ED0007']
});
useEffect(() => {
Animated.loop(
Animated.sequence([
Animated.timing(animatedColor, {
toValue: 1,
duration: 1,
useNativeDriver: true,
}),
Animated.timing(animatedCenterToLeft, {
toValue: -24,
duration,
delay: 0,
useNativeDriver: true,
}),
Animated.timing(animatedCenterToLeft, {
toValue: 0,
duration,
delay: 0,
useNativeDriver: true,
}),
Animated.timing(animatedCenterToTop, {
toValue: -24,
duration,
delay: 0,
useNativeDriver: true,
}),
Animated.timing(animatedCenterToTop, {
toValue: 0,
duration,
delay: 0,
useNativeDriver: true,
}),
Animated.timing(animatedColor, {
toValue: 0,
duration: 1,
useNativeDriver: true,
}),
Animated.timing(animatedCenterToLeft, {
toValue: -24,
duration,
delay: 0,
useNativeDriver: true,
}),
Animated.timing(animatedCenterToLeft, {
toValue: 0,
duration,
delay: 0,
useNativeDriver: true,
}),
Animated.timing(animatedCenterToTop, {
toValue: -24,
duration,
delay: 0,
useNativeDriver: true,
}),
Animated.timing(animatedCenterToTop, {
toValue: 0,
duration,
delay: 0,
useNativeDriver: true,
})
])
).start();
}, [])
return (
<SafeAreaView style={{flex:1, justifyContent:'center', alignSelf:'center'}}>
<Animated.View style={[styles.indicatorTop, { backgroundColor: color },
{
transform: [
{
translateX: animatedCenterToLeft
},
{
translateY: animatedCenterToTop
}
]
}
]} />
</SafeAreaView>
)
}
export default App
const styles = StyleSheet.create({
indicatorTop: {
height: 15,
width: 15,
position: 'absolute'
},
})
"
英文:
There's nothing that binds the color change to the animation sequence - they happen independently. Timeouts/intervals are not guaranteed to an exact length of time, and animations can also be elastic.
Instead, add your color change to your sequence, and remove your interval. I'm not sure if there's an easy way to reference animated values within animations in the basic React Native Animated; I have done it in Reanimated, which I can recommend if you're looking to do more complex animations.
Changes:
- added new Animated.Value (
animatedColor
), range 0-1 - interpolate animatedColor to your colors (
color
), apply color to object style - start sequence with Animated.timing call to change animatedColor to 1
- double the sequence, set the second Animated.timing call on animatedColor to 0
Full code:
import React, { useEffect, useRef } from 'react'
import { Animated, SafeAreaView, StyleSheet } from 'react-native'
const duration = 500;
const App = () => {
const animatedCenterToLeft = useRef(new Animated.Value(0)).current;
const animatedCenterToTop = useRef(new Animated.Value(0)).current;
const animatedColor = useRef(new Animated.Value(0)).current;
const color = animatedColor.interpolate({
inputRange: [0, 1],
outputRange: ['#007BC0', '#ED0007']
});
useEffect(() => {
Animated.loop(
Animated.sequence([
Animated.timing(animatedColor, {
toValue: 1,
duration: 1,
useNativeDriver: true,
}),
Animated.timing(animatedCenterToLeft, {
toValue: -24,
duration,
delay: 0,
useNativeDriver: true,
}),
Animated.timing(animatedCenterToLeft, {
toValue: 0,
duration,
delay: 0,
useNativeDriver: true,
}),
Animated.timing(animatedCenterToTop, {
toValue: -24,
duration,
delay: 0,
useNativeDriver: true,
}),
Animated.timing(animatedCenterToTop, {
toValue: 0,
duration,
delay: 0,
useNativeDriver: true,
}),
Animated.timing(animatedColor, {
toValue: 0,
duration: 1,
useNativeDriver: true,
}),
Animated.timing(animatedCenterToLeft, {
toValue: -24,
duration,
delay: 0,
useNativeDriver: true,
}),
Animated.timing(animatedCenterToLeft, {
toValue: 0,
duration,
delay: 0,
useNativeDriver: true,
}),
Animated.timing(animatedCenterToTop, {
toValue: -24,
duration,
delay: 0,
useNativeDriver: true,
}),
Animated.timing(animatedCenterToTop, {
toValue: 0,
duration,
delay: 0,
useNativeDriver: true,
})
])
).start();
}, [])
return (
<SafeAreaView style={{flex:1, justifyContent:'center', alignSelf:'center'}}>
<Animated.View style={[styles.indicatorTop, { backgroundColor: color },
{
transform: [
{
translateX: animatedCenterToLeft
},
{
translateY: animatedCenterToTop
}
]
}
]} />
</SafeAreaView>
)
}
export default App
const styles = StyleSheet.create({
indicatorTop: {
height: 15,
width: 15,
position: 'absolute'
},
})
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论