ReactNative动画研究与实践

2016年6月17日 255点热度 0人点赞 0条评论

(点击上方公众号,可快速关注)

作者:Tw93(@Tw93)

链接:https://zhuanlan.zhihu.com/p/21301314?f3fb8ead20=6e93a1a433c8393225432dd3b1d5944b


本次专题文章的题目为《ReactNative动画研究与实践》,既然有研究,那我们就争取一次将ReactNative动画相关的内容都说清楚,提出问题-论证问题-解决问题的方式来弄。ReactNative动画之前在博客上面写过一次,不过感觉写得不是很好,本次重新捋一次思路重写整理下分享给大家。


问题


  • ReactNative动画支持的怎么样?

  • ReactNative的动画使用起来方便吗?

  • ReactNative动画的性能和H5性能相比怎么样?

  • ReactNative动画的综合情况如何?


ReactNative动画支持:


图片


从上面的MineNode我们可以看出ReactNative中有3个地方可以使用动画:


  • 用于创建更精细的交互控制的动画Animated;

  • 用于全局的布局动画LayoutAnimation;

  • 用于构建Navigator不同页面切换的动画;

此篇文章主要是讲Animated相关的内容,平时动画中用得最多的也是它,其他两个通过文档可以很容易的使用。

ReactNative动画的使用

一个老子明天不上班的的动画实现,同时从小变大并且旋转,我们可以从注释中看到ReactNative动画的实现步骤:

代码如下:

import React, { Component } from 'react';

import {

    AppRegistry,

    StyleSheet,

    Text,

    View,

    Animated,   //使用Animated组件

    Easing,     //引入Easing渐变函数

} from 'react-native';

 

class ReactNativeDemo extends Component {

    constructor(props:any) {

        super(props);

        //使用Animated.Value设定初始化值(缩放度,角度等等)

        this.state = {

            bounceValue: new Animated.Value(0),

            rotateValue: new Animated.Value(0),

        };

    }

 

    componentDidMount() {

        //在初始化渲染执行之后立刻调用动画执行函数

        this.startAnimation();

    }

 

    startAnimation() {

        this.state.bounceValue.setValue(0);

        this.state.rotateValue.setValue(0);

        Animated.parallel([

            //通过Animated.spring等函数设定动画参数

            //可选的基本动画类型: spring, decay, timing

            Animated.spring(this.state.bounceValue, {

                toValue: 3,      //变化目标值

                friction: 20,    //friction 摩擦系数,默认40

            }),

            Animated.timing(this.state.rotateValue, {

                toValue: 1,

                duration: 800,

                easing: Easing.out(Easing.quad),

            }),

            //调用start启动动画,start可以回调一个函数,从而实现动画循环

        ]).start(()=>this.startAnimation());

    }

 

    render() {

        return (

            <View style={styles.container}>

                <Animated.Image source={require('./bsb.jpeg')}

                                style={{width: 100,

                                height: 100,

                                transform: [

                                //将初始化值绑定到动画目标的style属性上

                                {scale: this.state.bounceValue},

                                //使用interpolate插值函数,实现了从数值单位的映射转换

                                {rotateZ: this.state.rotateValue.interpolate({

                                inputRange: [0,1],

                                outputRange: ['0deg', '360deg'],

                                })},

                     ]}}>

                </Animated.Image>

 

            </View>

        );

    }

}

const styles = StyleSheet.create({

    container: {

        flex: 1,

        justifyContent: 'center',

        alignItems: 'center',

    }

});

 

AppRegistry.registerComponent('ReactNativeDemo', () =>ReactNativeDemo);

 

从上面demo可以看出,动画的使用逻辑还算清晰,虽然比不上css3动画编写简单,也不需要二次分装,直接向上面使用即可。

具体的效果是这样

图片

ReactNative动画和H5动画对比

  • ReactNative中的的动画均为 JavaScript 动画,即通过 JavaScript 代码控制图像的各种参数值的变化,从而产生时间轴上的动画效果。 通过封装一个Animated的元素,内部通过数据绑定和DOM操作变更元素,结合React的生命周期完善内存管理,解决条件竞争问题,对外表现则与原生组件相同,实现了高效流畅的动画效果。

  • CSS3动画 vs ReactNative动画录制

    图片

  • 上述动画css3使用animation: rotate 0.2s linear infinite实现;

  • ReactNative采用如下实现:

    图片

  • 关于性能测试都采用instruments来测试Time Profiler数据,其中红线是动画开始时候,从图中可以看出两者消耗都低,但是css3动画的性能稍微优于ReactNative的动画。

    图片

综合

React Native的动画支持度还是很广:

  • CSS3可以实现的动画ReactNative基本上可以实现:

  • 支持:3种动画类型(spring、decay、timing)、Interpolation插值函数、4种动画组合(同时、顺序、错峰、延迟)、动画执行回调、跟踪动态值、Animated.event输入事件、响应当前的动画值等功能;

  • 关于ReactNative 支持的Easing类型可以到Easing.js;中去找符合自己项目需求的动画类型;

  • Navigator页面切换的动画也很丰富,我们可以从上面的MindNode找到所支持的切换动画,同样也可以从NavigatorSceneConfigs.js中找到它支持的类型;

  • 对于特别复杂的动画,可以使用react-native-animatable补充多余的动画类型;

  • 对于有些组件的动画,譬如数据图表的绘制,建议直接使用RN绘图库ART实现,同时react-native-svgkit这种思路也很好;

React Native编写起来方便,具有逻辑性:

  1. 使用基本的Animated组件,如Animated.View、Animated.Image、Animated.Text和其他(使用AnimatedImplementation来包装);

  2. 使用Animated.Value设定一个或多个初始化值,如位置属性、透明属性、角度属性等;

  3. 将初始化值绑定到动画目标的属性上,如style;

  4. 通过动画类型Api设定动画参数,如spring、decay、timing三种动画类型;

  5. 调用start启动动画,同时可以在start里面回调相关功能;

React Native动画性能没有那么差,或者说比想象中要好:

For Animated:

  • 通过封装一个Animated的元素;

  • 内部通过数据绑定和DOM操作变更元素;

  • 结合React的生命周期完善内存管理,解决条件竞争问题;

  • 对外表现则与原生组件相同,实现了高效流畅的动画效果;

For Navigator页面切换动画不流畅:

  • 使用InteractionManager在转场动画的过程中,使新页面只渲染必要的少量的内容。

  • InteractionManager.runAfterInteractions只有一个函数类型的参数,当转场动画结束,这个回调函数就会被触发(所有基于AnimatedAPI的动画都会触发InteractionManager.runAfterInteractions)。

参考

  • Animations React Native

  • Navigator React Native

  • LayoutAnimation React Native

  • ReactNative Animated动画详解

  • react-native-animation-book


【今日微信公号推荐↓】

图片

更多推荐请看值得关注的技术和设计公众号


其中推荐了包括技术设计极客 和 IT相亲相关的热门公众号。技术涵盖:Python、Web前端、Java、安卓、iOS、PHP、C/C++、.NET、Linux、数据库、运维、大数据、算法、IT职场等。点击《值得关注的技术和设计公众号》,发现精彩!


图片

37150ReactNative动画研究与实践

这个人很懒,什么都没留下

文章评论