【译】React Native 动画 API 入门实例

前端之家收集整理的这篇文章主要介绍了【译】React Native 动画 API 入门实例前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

翻译自 React-native Animated API Basic Example
翻译过程中有删改


简介

本文是探索 react-native 中实现的的 Animated API,Web 版本上的 React 没有该 API,不过可以使用在 react-europe 大会上发布的 react-motion
本文中将会完成一个动画例子,效果如下图

原理

Animated API的原理并非通过 setState 方法使 react 重渲染,而是使用 setNativeProps 方法更新 native 视图。
Animated API 导出了几个特殊的 components:Animated.View,Animated.Text,和 Animated.Image。Animated API 直接在 Objective-C 的 native 环境中调整这些 components 的外观样式,跳过了 JS 环境中 react 的 diff 与 reconciliation 过程,从而获得流畅、高效的动画。
简而言之,它将对动画中变化的属性数值做插值运算并且刷新 native 视图。

动画效果:沿屏幕移动的方块

我们将实现一个简单的动画效果:沿手机屏幕四个边,按照左上角 -> 左下角 -> 右下角 -> 右上角的顺序,移动一个正方形。示意图大概如下

@H_404_40@< -- < | | V -- ^

开始

导入依赖

@H_404_40@import React,{ AppRegistry,Component,Dimensions,StyleSheet,View,Animated } from 'react-native'; const { width,height } = Dimensions.get('window'); const SQUARE_DIMENSIONS = 30;

样式

@H_404_40@const styles = StyleSheet.create({ container: { flex: 1 },square: { width: SQUARE_DIMENSIONS,height: SQUARE_DIMENSIONS,backgroundColor: 'blue' } });

基本逻辑

@H_404_40@class AnimatedSquare extends Component { constructor(props) { super(props); this.state = { pan: new Animated.ValueXY() } } getStyle() { return [styles.square,{ transform: this.state.pan.getTranslateTransform() }]; } render() { return ( <View style={styles.container}> <Animated.View style={this.getStyle()} /> </View> ); } }

上面代码中有几个需要解释的地方。
注意我们所建立的 componentstateAnimated.ValueXY 的一个实例。这个 API 将在 XY 两个值上进行插值。

getStyle() 方法,返回一个样式对象数组。包括描述了方块宽高大小的 square 基本样式,以及最为重要的,一个 transform 样式对象。
我们使用 getTranslateTransform 这个 Animated API 中的 helper 方法,来返回一个适合 transform 属性结构的值。
这个返回值的结构类似于[{ translateX: xValue},{translateY: yValue}],xValue 和 yValue 是计算后的插值。

最后我们使用 Animated.View,表示这个组件是可动画组件。

移动正方形

一开始正方形是静止在左上角的,现在我们把它从左上角(x = 0,y = 0)移动到左下角(x = 0,y = (屏幕高 - 正方形高)

@H_404_40@const SPRING_CONFIG = {tension: 2,friction: 3}; //Soft spring //... componentDidMount() { Animated.spring(this.state.pan,{ ...SPRING_CONFIG,toValue: {x: 0,y: height - SQUARE_DIMENSIONS} // return to start }).start(); }

在组件装载后,我们通过 Animated.spring 进行 Spring(弹性)动画 ,我们给弹性动画设置了 SPRING_CONFIG 配置,包括 tension(张力)和 friction(摩擦)值,所以正方形到达左下角后,会有一个小小回弹动画。

再动,又动,还动

我们会建立一个顺序的动画序列,让动画一个接一个进行。当然除了 sequence(顺序),你还可以按 parallel(并行)组合动画效果,让动画同时进行。

@H_404_40@componentDidMount() { Animated.sequence([ Animated.spring(this.state.pan,{ ...SPRING_CONFIG,y: height - SQUARE_DIMENSIONS} //animate to bottom left }),Animated.spring(this.state.pan,toValue: {x: width - SQUARE_DIMENSIONS,y: height - SQUARE_DIMENSIONS} // animated to bottom right }),y: 0} //animate to top right }),y: 0} // return to start }) ]).start(); }

如之前设想的一样,我们定义了4个弹性动画。注释解释了动画移动方向。

一直不停动

@H_404_40@Animated.sequence(animtionList: Arrary).start(cb: Function);

动画序列的start方法可以传一个回调函数,在动画全部执行完时触发。在我们的例子中,这时候正方形回到了起点,我们可以重新开始一遍动画。

@H_404_40@componentDidMount() { this.startAndRepeat(); } startAndRepeat() { this.triggerAnimation(this.startAndRepeat); } triggerAnimation(cb) { Animated.sequence([ Animated.spring(this.state.pan,{ ...SPRING_CONFIG,y: height - SQUARE_DIMENSIONS} //animate to bottom left }),y: height - SQUARE_DIMENSIONS} // animated to bottom right }),y: 0} //animate to top right }),y: 0} // return to start }) ]).start(cb); }

我们把动画逻辑提取为一个方法,在完成回调函数中触发它。

全部代码

@H_404_40@import React,height } = Dimensions.get('window'); const SQUARE_DIMENSIONS = 30; const SPRING_CONFIG = {tension: 2,friction: 3}; class AnimatedSquare extends Component { constructor(props) { super(props); this.state = { pan: new Animated.ValueXY() } } componentDidMount() { this.startAndRepeat(); } startAndRepeat() { this.triggerAnimation(this.startAndRepeat); } triggerAnimation(cb) { Animated.sequence([ Animated.spring(this.state.pan,{ ...SPRING_CONFIG,y: height - SQUARE_DIMENSIONS} //animate to bottom left }),y: height - SQUARE_DIMENSIONS} // animated to bottom right }),y: 0} //animate to top right }),y: 0} // return to start }) ]).start(cb); } getStyle() { return [styles.square,{ transform: this.state.pan.getTranslateTransform() }]; } render() { return ( <View style={styles.container}> <Animated.View style={this.getStyle()} /> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1 },backgroundColor: 'blue' } }); AppRegistry.registerComponent('AnimatedSquare',() => AnimatedSquare);

其它一些范例

react-native-animated-demo-tinder
UIExplorer Animated example

相关资源

Cheng Lou – The State of Animation in React at react-europe 2015
react-motion – Github
React Native Animation API
Spencer Ahrens – React Native: Building Fluid User Experiences at react-europe 2015

原文链接:https://www.f2er.com/react/307047.html

猜你在找的React相关文章