美文网首页React Native开发技巧
React Native 初步学习之动画

React Native 初步学习之动画

作者: wfunny | 来源:发表于2017-05-01 14:25 被阅读75次

    概述

    目前,ReactNative的版本是0.43,主要的动画分为两大类
    1、Animated 更加精确的交互式的动画
    2、LayoutAnimation 用来实现布局切换的动画
    今天首先介绍一下Animated

    Animated动画的创建原理

    一个最基本的Animated创建过程

    1、创建Animated.Value,设置初始值,比如一个视图的opacity属性,最开始设置Animated.Value(0),来表示动画的开始时候,视图是全透明的。

    2、AnimatedValue绑定到Style的可动画属性,比如透明度,{opacity: this.state.fadeAnim}。

    3、使用Animated.timing来创建自动的动画,或者使用Animated.event来根据手势,触摸,Scroll的动态更新动画的状态(本文会侧重讲解Animated.timing)。

    4、调用Animated.timeing.start()开始动画。

    根据上述原理,下面我们就创建一个简单的动画(给这个默认的视图创建fade in动画,效果如下):

    代码如下:

    import React, { Component } from 'react';
    import {
        AppRegistry,
        Text,
        View,
        StyleSheet,
        Animated,
    } from 'react-native';
    
    class SimpleAnimatedDemo extends React.Component {
      state: { //可以不写,我这里写是为了去除flow的warning
        fadeIn: Object,
      };
      constructor(props) {
         super(props);
         this.state = {
             fadeIn: new Animated.Value(0), //设置初始值
         };
       }
       componentDidMount() {
       Animated.timing(
         this.state.fadeIn,//初始值
         {toValue: 1}//结束值
       ).start();//开始
       }
      render() {
        return (
          <View style={styles.container}>
          <Animated.Text style={{opacity: this.state.fadeIn}}>//绑定到属性
              Welcome to React Native Animated!
          </Animated.Text>
          </View>
        );
      }
    }
    
    

    从代码可以看出来,简单的动画就是用Animated.Value指定初始值,然后在Animated.timing中设置结束值,其他的直接交给React native让它自动创建,我们只需要调用start开始动画即可。

    运行的效果图是动态图,插入不进来,想看效果的直接在手机上或模拟器上运行一下就知道啦~

    可动画的视图一般有View、Text、Image、createAnimatedComponent(自定义)

    Animated详解

    方法
    static decay(value, config) 阻尼,将一个值根据阻尼系数动画到 0
    static timing(value, config 根据时间函数来处理,常见的比如线性,加速开始减速结束等等,支持自定义时间函数
    static spring(value, config) 弹性动画
    static add(a, b) 将两个Animated.value相加,返回一个新的
    static multiply(a, b) 将两个Animated.value相乘,返回一个新的
    static modulo(a, modulus),将a对modulus取余,类似操作符%
    static delay(time)延迟一段时间
    static sequence(animations) 依次开始一组动画,后一个在前一个结束后才会开始,如果其中一个动画中途停止,则整个动画组停止
    static parallel(animations, config?),同时开始一组动画,默认一个动画中途停止,则全都停止。可以通过设置stopTogether来重写这一特性
    static stagger(time, animations),一组动画可以同时执行,但是会按照延迟依次开始
    static event(argMapping, config?),利用手势,Scroll来手动控制动画的状态
    static createAnimatedComponent(Component),自定义的让某一个Component支持动画
    
    属性
    Value,类型是AnimatedValue,驱动基本动画
    AnimatedValueXY,类型是AnimatedValueXY,驱动二维动画
    

    AnimatedValue类型

    一个AnimatedValue一次可以驱动多个可动画属性,但是一个AnimatedValue一次只能由一个机制驱动。比如,一个Value可以同时动画View的透明度和位置,但是一个Value一次只能采用线性时间函数

    方法
    constructor(value) 构造器
    setValue(value) 直接设置值,会导致动画终止
    setOffset(offset) 设置当前的偏移量
    flattenOffset() 将偏移量合并到最初值中,并把偏移量设为0,
    addListener(callback) ,removeListener(id),removeAllListeners(),增加一个异步的动画监听者
    stopAnimation(callback?) 终止动画,并在动画结束后执行callback
    interpolate(config) 插值,在更新可动画属性前用插值函数对当前值进行变换
    animate(animation, callback) 通常在React Native内部使用
    stopTracking(),track(tracking) 通常在React Native内部使用
    

    AnimatedValueXY

    它和AnimatedValue类似,用在二维动画,使用起来和AnimatedValue类似,这里不在介绍,这里是文档

    手势驱动

    React Native最常用的手势就是PanResponser,
    由于本文侧重讲解动画,所以不会特别详细的介绍PanResponser,想深入了解可以看官方文档,这里仅仅介绍用到的几个属性和回调方法

    onStartShouldSetPanResponder: (event, gestureState) => {}//是否相应pan手势
    onPanResponderMove: (event, gestureState) => {}//在pan移动的时候进行的回调
    onPanResponderRelease: (event, gestureState) => {}//手离开屏幕
    onPanResponderTerminate: (event, gestureState) => {}//手势中断
    
    

    其中,通过event可以获得触摸的位置,时间戳等信息。通过gestureState可以获取移动的距离,速度等
    下面写了一个拖动的动画,通过手指拖动小蓝球,移动小篮球.

    代码如下:

    // View随着手拖动而移动,手指离开会到原点

    import {
        AppRegistry,
        Text,
        View,
        StyleSheet,
        Animated,
        PanResponder,
    } from 'react-native';
    class TransAnimatedDemo extends Component {
        state: {
            trans: AnimatedValueXY, //可以不定义,只是为了除去警告
        }
        _panResponder: PanResponder;
    
        constructor(props) {
            super(props);
            this.state = {
                trans: new Animated.ValueXY(),
            };
    
            this._panResponder = PanResponder.create({
                onStartShouldSetPanResponder: () => true, //响应手势
                onPanResponderMove: Animated.event(
                    [null, {dx: this.state.trans.x, dy: this.state.trans.y}] // 绑定动画值
                ),
                onPanResponderRelease: () => {//手松开是回调,回到原始位置
                    Animated.spring(this.state.trans, {toValue: {x: 0, y: 0}}
                    ).start();
                },
                onPanResponderTerminate: () => {//手势中断时回调,回到原始位置
                    Animated.spring(this.state.trans, {toValue: {x: 0, y: 0}}
                    ).start();
                },
            });
        }
        render(){
            return(
                <View>
                    <Animated.View style={
                        {
                            width:100,
                            height:100,
                            backgroundColor:'blue',
                            borderRadius:50,
                            transform:[
                                {translateX:this.state.trans.x},
                                {translateY:this.state.trans.y},
                            ],
                        }
                    } {...this._panResponder.panHandlers}>
    
                    </Animated.View>
                </View>
            );
        }
    }
    

    以上代码通过回调PanResponder的各个函数 实现移动的动画效果,具体的运行效果,请自行在模拟器或者真机上运行(因为动态图片插不进来,请谅解)。

    参考资料:

    官方关于动画的介绍
    官方给出的复杂动画的示例

    相关文章

      网友评论

        本文标题:React Native 初步学习之动画

        本文链接:https://www.haomeiwen.com/subject/bfmftxtx.html