React Native Animated动画

在React Native中,我们可以通过两种方式实现一个动画效果:

  • LayoutAnimation
  • Animated

关于LayoutAnimation,我之前写过一篇学习博客(React Native LayoutAnimation动画)。此主要用于在页面布局改变的时候添加一些动画效果,但如果想要实现一些更精细,复杂的动画,LayoutAnimation就会比较困难,所以React Native还为我们提供了Animated组件,用来实现一些复杂的动画效果。

一、单个动画

Animated为我们提供了三种类型的动画:spring,timing,decay。

1、Spring 弹跳效果动画

  • friction 摩擦系数,默认40
  • tension 张力系数,默认7
  • bounciness
  • speed

Spring支持 friction与tension 或者 bounciness与speed 两种组合模式,这两种模式不能并存。 其中friction与tension模型来源于origami,一款F家自制的动画原型设计工具,而bounciness与speed则是传统的弹簧模型参数。

2、timing 带有时间的渐变动画

  • duration 动画运行时间
  • easing 动画曲线函数,可以从Easing模块中获取更多预定义的函数
  • delay: 动画执行延迟时间(单位:毫秒).默认为0ms

3、decay 带有加速度值的动画,类似于正弦值

  • velocity:初始速度,必须要填写
  • deceleration:速度减小的比例,加速度。默认为0.997

4、另外,现在RN只为我们提供Animated.View,Animated.Image,Animated.Text三种动画组件,但是可以通过Animated.createAnimatedComponent(component)创建动画组件。

有了上面的知识,我们就可以简单实现一个淡入的动画效果:
React Native Animated动画_第1张图片

具体实现步骤如下:

1、引入Animated组件

import {
    StyleSheet,
    Animated,//要实现Animated 动画,首先要引入Animated组件
    Easing,
    View,
    Image,
    Text,
}from 'react-native';

2、 在构造方法中初始化一个Animated对象

// 构造
    constructor(props) {
        super(props);
        // 初始状态
        this.state = {
            anim: new Animated.Value(0),//初始化一个动画对象
        };
    }

3、添加动画组件,并将要改变的动画组件样式属性值设为动画对象

render() {
        return (
            <View style={styles.container}>
                <Animated.Image source={require('../../res/girl.jpg')}
                 style={[styles.image,{
                 opacity:this.state.anim,//将动画对象赋值给需要改变的样式属性
                 }]}/>
            View>
        )
    }

4、执行动画

componentDidMount() {
         //timing动画
        Animated.timing(//使用timin过度动画
            this.state.anim,//要改变的动画对象
            {
                toValue: 1,//动画结束值
                duration: 3000,//动画运行时间
                easing: Easing.linear,//动画过渡曲线函数
            }
        ).start();//动画开始执行

随着动画的执行,样式属性的值会一直变化,即实现动画效果。

二、插值函数

我们可以只初始化一个动画对象,然后给多个样式属性赋值,通过interpolate()方法,我们可以将一个区间映射到另一个区间。

render() {
        return (
            container}>
                '../../res/girl.jpg')}
                               style={[styles.image,{
                               opacity:this.state.anim,//组件的opacity样式属性
                               transform:[//组件的transform样式属性
                               {scale:this.state.anim.interpolate({//组件的scale样式属性,将[0,1]区间映射到[1,2]区间
                               inputRange:[0,1],//输入区间
                               outputRange:[1,2]//输出区间
                               })},
                               {rotate:this.state.anim.interpolate({//组件的rotate样式属性,将[0,1]区间映射到['0deg','360deg]区间
                               inputRange:[0,1],//输入区间
                               outputRange:['0deg','360deg'],//输出区间
                               })},
                               ]
                               }]}
                />
            
        )
    }

其它代码不变,则随着动画的执行,图片的opacity,scale,rotate都会更改,产生一个淡入,放大,旋转同时进行的动画效果:
React Native Animated动画_第2张图片

三、组合动画

RN为我们提供了三种组合动画方法:

  • sequence 顺序执行
  • parallel 同时执行
  • stagger 每隔一段时间开始执行行一个动画

例如一个弹出字幕的效果:
React Native Animated动画_第3张图片

代码实现如下:

/**
 * Created by gyg on 2017/5/19.
 * Animated学习demo
 */
'use strict'
import React, {Component} from 'react';
import {
    StyleSheet,
    Animated,
    Easing,
    View,
    Image,
    Text,
    Dimensions,
}from 'react-native';
var deviceWidth=Dimensions.get('window').width;
export default class AnimatedDemo extends Component {

    // 构造
    constructor(props) {
        super(props);
        // 初始状态
        this.state = {
            data: ['工行大公司都会', '好噶或更多更好的嘎', '规划i哈哈打开建行', '黑啊好的是根据卡号开个会看到个', '嘎机会更多机会关机定时关机'],
            initAnims:[],//存放初始化的动画对象
            anims: [],//存放动画函数
        };
        for(let i=0;i<this.state.data.length;i++){//遍历数据
            this.state.initAnims.push(new Animated.Value(-250));//每条数据对应一个动画对象
            this.state.anims.push(Animated.timing(this.state.initAnims[i],{//每条数据对应一个动画函数
                duration:3500,
                toValue:deviceWidth+250,
                easing:Easing.linear,
            }));
        }
    }

    componentDidMount() {
        Animated.stagger(1000,this.state.anims).start();//每隔1000ms开始执行动画数组中的一个动画
    }

    render() {
        const views=this.state.data.map((text,i)=>{//每条数据映射一个动画组件
            return(
                this.state.initAnims[i],//设置translateX为动画值,这样动画执行的时候,translateX的值也会随之改变
                    },
                    {
                    translateY:Math.floor(Math.random()*10),//产生0-9的一个随机数
                    },
                    ]}]}
                >
                    {text}
                
            )
        });
        return (
            
                {views}
            
        )
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: 'white',
        justifyContent: 'center',
    },
    textview:{
        width:200,
        paddingTop:10,
        paddingBottom:10,
        paddingLeft:20,
        paddingRight:20,
        backgroundColor:'rgba(0,0,0,0.5)',
        borderRadius:10,
        justifyContent:'center',
        alignItems:'center',
        fontSize:16,
        color:'white',
    },
});

你可能感兴趣的:(react-native,Animated,弹出字幕,React,Native学习笔记)