React Native 动画(Animated)

发布时间 2023-09-28 15:08:10作者: ZerlinM

实现效果

代码

从react-native中引入

import {
    Animated,
    Easing,
} from 'react-native';

js实现

const opacity1 = useRef(new Animated.Value(0.2)).current;
const opacity2 = useRef(new Animated.Value(0.2)).current;
const scale1 = useRef(new Animated.Value(1)).current;
const scale2 = useRef(new Animated.Value(1)).current;

useEffect(() => {
    // 图标动画
    startAnimated();
}, [])

const startAnimated = () => {
    const opacityAni1 = Animated.sequence([
        Animated.timing( //随时间变化而执行动画
            opacity1, //动画中的变量值
            {
                toValue: 0.5, // 透明度最终变为0.5
                duration: 1200, //动画时长
                easing: Easing.linear,
                useNativeDriver: true,
            }
        ),
        Animated.timing(
            opacity1,
            {
                toValue: 0.2,
                duration: 1200,
                easing: Easing.linear,
                useNativeDriver: true,
            }
        ),
    ])
    const scaleAni1 = Animated.sequence([
        Animated.timing(
            scale1,
            {
                toValue: 1.02,
                duration: 1200,
                easing: Easing.linear,
                useNativeDriver: true,
            }
        ),
        Animated.timing(
            scale1,
            {
                toValue: 1,
                duration: 1200,
                easing: Easing.linear,
                useNativeDriver: true,
            }
        ),
    ])
    const opacityAni2 = Animated.sequence([
        Animated.timing(
            opacity2,
            {
                toValue: 0.5,
                duration: 1200,
                easing: Easing.linear,
                useNativeDriver: true,
            }
        ),
        Animated.timing(
            opacity2,
            {
                toValue: 0.2,
                duration: 1200,
                easing: Easing.linear,
                useNativeDriver: true,
            }
        ),
    ])
    const scaleAni2 = Animated.sequence([
        Animated.timing(
            scale2,
            {
                toValue: 1.02,
                duration: 1200,
                easing: Easing.linear,
                useNativeDriver: true,
            }
        ),
        Animated.timing(
            scale2,
            {
                toValue: 1,
                duration: 1200,
                easing: Easing.linear,
                useNativeDriver: true,
            }
        ),
    ])
    let animated = Animated.parallel([
        opacityAni1,
        scaleAni1,
        opacityAni2,
        scaleAni2,
    ])

    animated.start(() => startAnimated())
}

render中使用

<View style={styles.warnWrap}>
    <Animated.View style={{
        ...styles.avatarAnimation2,
        backgroundColor: 'rgb(245, 0, 0)',
        opacity: opacity2,
        transform: [{ scale: scale2 }],
    }} />
    <Animated.View style={{
        ...styles.avatarAnimation,
        backgroundColor: 'rgb(245, 0, 0)',
        opacity: opacity1,
        transform: [{ scale: scale1 }],
    }} />
    <View style={{
        ...styles.avatar,
        backgroundColor: 'rgb(245, 0, 0)',
    }}>
        <Image style={{ width: 22, height: 22 }} source={ImageResource.Common.Alarm} />
    </View>
</View>

css

const styles = StyleSheet.create({

    warnWrap: {
        position: 'absolute',
        bottom: 110,
        right: 3,
        zIndex: 9,
        width: deviceSize.scale(100),
        height: deviceSize.scale(100),
        justifyContent: 'center',
        alignItems: 'center',
    },
    avatar: {
        position: 'absolute',

        bottom: deviceSize.scale(15),
        left: deviceSize.scale(15),
        width: deviceSize.scale(70),
        height: deviceSize.scale(70),
        borderRadius: deviceSize.scale(70),
        justifyContent: 'center',
        alignItems: 'center',
    },
    avatarAnimation: {
        position: 'absolute',
        bottom: deviceSize.scale(8),
        left: deviceSize.scale(8),
        width: deviceSize.scale(83),
        height: deviceSize.scale(83),
        borderRadius: deviceSize.scale(83),
    },
    avatarAnimation2: {
        position: 'absolute',
        bottom: 0,
        left: 0,
        width: deviceSize.scale(100),
        height: deviceSize.scale(100),
        borderRadius: deviceSize.scale(100),
    },

})