React Native学习(Android)——动画

本文深入讲解React Native中Animated API的使用方法,包括decay、spring和timing三种动画类型,以及组合动画的实现方式。通过实例演示如何创建复杂的动画效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Animated使用:

类别:

  1. Animated.decay() 以指定的初始速度开始变化,然后变化速度越来越慢直至停下。
  2. Animated.spring()提供了一个简单的弹簧物理模型.
  3. Animated.timing()使用easing 函数让数值随时间动起来。

源码(AnimatedMock.js):

const spring = function(
    value: AnimatedValue | AnimatedValueXY,
    config: SpringAnimationConfig,
): CompositeAnimation {
    return emptyAnimation;
};

const timing = function(
    value: AnimatedValue | AnimatedValueXY,
    config: TimingAnimationConfig,
): CompositeAnimation {
    return emptyAnimation;
};

const decay = function(
    value: AnimatedValue | AnimatedValueXY,
    config: DecayAnimationConfig,
): CompositeAnimation {
    return emptyAnimation;
};

使用:

1.初始化

看上面可知,无论哪种动画都有value和config,而value是相同的,config根据情况配置
一般我们在constructor中定义动画的初始值,值可以分为两种 AnimatedValue 和 AnimatedValueXY
区别一个是单个值,一个是矢量值(可以理解为二维坐标值)

例如:
constructor(props: any) {
    super(props);
    this.state = {
        //initValue: new Animated.ValueXY(0,0),  //矢量值:初始x=0,y=0
        initValue: new Animated.Value(0),        //单个值:开始值为0
    };
}
2.配置(启动参数、样式)

配置你所需要的动画样式,decay、spring还是timing
一般在组件加载完成后开始动画

componentDidMount() {
    this.state.initValue.setValue(1.5);  // 动画启动参数,设置一个比较大的值,也可以使用默认值0
    Animated.spring(                     // 动画可选类型: spring, decay, timing
        this.state.initValue,            // 动画的初始值
        {
            toValue: 0.8,                // 动画的结束值,即需要达成的目标(从0到0.8)
            friction: 1,                 // Bouncier spring
        }
    ).start();                           // 开始执行动画
}
3.各动画参数(AnimatedImplementation.js)

3.1 decay 动画参数

export type DecayAnimationConfigSingle = AnimationConfig & {
    velocity: number,         // 起始速度,必填参数
    deceleration?: number,    // 速度衰减比例,默认为0.997
};

3.1 Spring 动画参数

export type SpringAnimationConfig = AnimationConfig & {
    toValue: number | AnimatedValue | {x: number, y: number} | AnimatedValueXY,
    overshootClamping?: boolean,                    // 布尔表示弹簧是否应夹紧而不是弹跳,默认为false。
    restDisplacementThreshold?: number,             // 静止位移的阈值,低于该阈值时应考虑弹簧处于静止状态。默认值为0.001。
    restSpeedThreshold?: number,                    // 静止时应考虑弹簧的速度,以每秒像素为单位。默认值为0.001。
    velocity?: number | {x: number, y: number},     // 附着在弹簧上的物体的初始速度。默认值为0(对象处于静止状态)
    delay?: number,                                 // 延迟(毫秒)后启动动画。默认值为0。

    bounciness?: number,                            // 控制弹性,默认8。
    speed?: number,                                 // 控制动画的速度。默认12。

    tension?: number,                               // 张力,默认40
    friction?: number,                              // 摩擦力,默认为7.

    stiffness?: number,                             // 弹簧刚度系数,默认100。
    damping?: number,                               // 定义了由于摩擦力如何阻尼弹簧的运动,默认10。
    mass?: number,                                  // 物体的质量附着在弹簧的末端,默认1。
};
不能同时定义 bounciness/speed、tension/friction 或 stiffness/damping/mass 这三组数据,只能指定其中一组,即三选一

3.2 timing 动画参数

export type TimingAnimationConfigSingle = AnimationConfig & {
    toValue: number | AnimatedValue,      //
    easing?: (value: number) => number,   // 缓动函数。 默认为Easing.inOut(Easing.ease)。
    duration?: number,                    // 动画的持续时间(毫秒)。默认值为 500.
    delay?: number,                       // 开始动画前的延迟时间(毫秒)。默认为 0.
};

以上三个都有两个共同的不常用的参数:
isInteraction: 指定本动画是否在InteractionManager的队列中注册以影响其任务调度。默认值为 true。
useNativeDriver: 启用原生动画驱动。默认不启用(false)。
4.默认导出的动画组件
Animated中默认导出了以下这些可以直接使用的动画组件,当然它们都是通过使用上面这个方法进行了封装:
4.1 Animated.Image
4.2 Animated.ScrollView
4.3 Animated.Text
4.4 Animated.View
5.组合动画

5.1 // 在给定延迟后开始动画 Animated.delay(time)

const delay = function(time: number): CompositeAnimation {
  return emptyAnimation;
};

5.2 // 同时启动多个动画 Animated.parallel(animations, config?)

const parallel = function(
  animations: Array<CompositeAnimation>,
  config?: ?ParallelConfig,
): CompositeAnimation {
  return emptyAnimation;
};
type ParallelConfig = {
  stopTogether?: boolean,
};

5.3 // 按顺序启动动画,等待每一个动画完成后再开始下一个动画 Animated.sequence([array])

const sequence = function(
  animations: Array<CompositeAnimation>,
): CompositeAnimation {
  return emptyAnimation;
};

5.4 // 按照给定的延时间隔,顺序并行的启动动画 Animated.stagger(time,[array])

const stagger = function(
  time: number,
  animations: Array<CompositeAnimation>,
): CompositeAnimation {
  return emptyAnimation;
};
例子:
/**
 * Created by ClearLiang on 2019/4/16
 * Function:
 * Desc:
 */
import React, {Component} from 'react';
import {Animated, Easing, StyleSheet, TouchableOpacity} from 'react-native';

export default class Animation_2 extends Component {

    // 初始化state
    constructor(props) {
        super(props);
        this.state = {
            initValue1: new Animated.Value(0),
            initValue2: new Animated.Value(1),
            initValue3: new Animated.ValueXY({x:0,y:0}),
            initValue4: new Animated.Value(0),
            initValue5: new Animated.Value(0),
        };
        this.myAnimation = Animated.sequence([
            // 从无到有、从小到大,一个匀渐变过程
            Animated.timing(
                this.state.initValue1,
                {
                    toValue: 20,
                    //easing: Easing.back(),
                    duration: 3000,
                }
            ),
            // 弹簧弹性模型
            Animated.spring(
                this.state.initValue2,
                {
                    toValue: 0.8,
                    friction: 1, // 摩擦力,默认为7.
                    tension: 50, // 张力,默认40。
                }
            ),
            // 位移
            Animated.timing(
                this.state.initValue3,
                {
                    toValue: {x: 0, y: 100},
                    duration: 2000,
                }
            ),
            // 旋转
            Animated.timing(
                this.state.initValue4,
                {
                    toValue: 1,
                    duration: 2000,
                }
            ),
            // 斜切旋转
            Animated.timing(
                this.state.initValue5,
                {
                    toValue: 1,
                    duration: 2000,
                }
            ),
        ]);
    }

    // 加载后
    componentDidMount() {
        this.resetAnimation();

        this.myAnimation.start((result) => {
            if (result.finished) {
                this.resetAnimation();
            } else {
                this.setState({
                    isOver: 2,
                });
            }
        });
    }

    render() {

        return (
            <Animated.Text                           // 使用专门的可动画化的Text组件
                style={{
                    ...this.props.style,
                    fontSize: this.state.initValue1,  // 将透明度指定为动画变量值

                    // 这个是透视的概念,在RN中目前还看不到效果
                    // 透视 {perspective: number}

                    // 旋转 {rotate : string}
                    // 旋转 {rotateX: string}
                    // 旋转 {rotateY: string}
                    // 旋转 {rotateZ: string}

                    // 缩放 {scale : number}
                    // 缩放 {scaleX: number}
                    // 缩放 {scaleY: number}

                    // 位移 {translateX: number}
                    // 位移 {translateY: number}

                    // skewX表示的是以X轴为中心在YZ屏幕中旋转,而skewY表示的是以Y轴为中心在XZ屏幕中旋转。
                    // 斜切 {skewX: string}
                    // 斜切 {skewY: string}

                    transform:[
                        {scale:this.state.initValue2},
                        {translateX: this.state.initValue3.x}, // x轴移动
                        {translateY: this.state.initValue3.y}, // y轴移动
                        {rotateX: this.state.initValue4.interpolate({inputRange:[0,1], outputRange:['0deg','360deg']})},
                        {skewY: this.state.initValue5.interpolate({inputRange:[0,1], outputRange:['0deg','360deg']})},
                    ],
                }}
            >
                {this.props.children}
            </Animated.Text>
        );
    }

    resetAnimation() {
        this.state.initValue1.setValue(0);
        this.state.initValue2.setValue(1.5);
        this.state.initValue3.setValue({x:0,y:0});
        this.state.initValue4.setValue(0);
        this.state.initValue5.setValue(0);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值