React Native动画更改颜色和移动。

huangapple go评论62阅读模式
英文:

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 &#39;react&#39;
import { Animated, SafeAreaView, StyleSheet } from &#39;react-native&#39;

const duration = 500;

const App = () =&gt; {
    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: [&#39;#007BC0&#39;, &#39;#ED0007&#39;]
    });

    useEffect(() =&gt; {
        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 (
        &lt;SafeAreaView style={{flex:1, justifyContent:&#39;center&#39;, alignSelf:&#39;center&#39;}}&gt;
            &lt;Animated.View style={[styles.indicatorTop, { backgroundColor: color },
            {
                transform: [
                    {
                        translateX: animatedCenterToLeft
                    },
                    {
                        translateY: animatedCenterToTop
                    }
                ]
            }
            ]} /&gt;
           
        &lt;/SafeAreaView&gt;
    )
}

export default App

const styles = StyleSheet.create({
    indicatorTop: {
        height: 15,
        width: 15,
        position: &#39;absolute&#39;
    },
})

huangapple
  • 本文由 发表于 2023年5月29日 16:56:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76355935.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定