- 浏览: 141699 次
- 性别:
- 来自: 北京
文章分类
最新评论
原文链接:http://click.aliyun.com/m/22229/
摘要: 在移动开发中,动画是提高用户体验不可缺少的一个元素。在React Native中,动画API提供了一些现成的组件:Animated.View,Animated.Text和Animated.Image默认支持动画。
在移动开发中,动画是提高用户体验不可缺少的一个元素。在React Native中,动画API提供了一些现成的组件:Animated.View,Animated.Text和Animated.Image默认支持动画。动画API会调用iOS或者Android的本地代码来完成这些组件的位移、大小等动画。
在React Native中,Animated创建过程如下:
创建Animated.Value,设置初始值,比如一个视图的opacity属性,最开始设置Animated.Value(0),来表示动画的开始时候,视图是全透明的。
AnimatedValue绑定到Style的可动画属性,比如透明度,{opacity: this.state.fadeAnim}
使用Animated.timing来创建自动的动画,或者使用Animated.event来根据手势,触摸,Scroll的动态更新动画的状态(本文会侧重讲解Animated.timing)
调用Animated.timeing.start()开始动画
Animated简介
大多数情况下,在 React Native 中创建动画是推荐使用 Animated API 的,其提供了三个主要的方法用于创建动画:
Animated.timing() -- 推动一个值按照一个过渡曲线而随时间变化。Easing 模块定义了很多缓冲曲线函数。
Animated.decay() -- 推动一个值以一个初始的速度和一个衰减系数逐渐变为0。
Animated.spring() -- 产生一个基于 Rebound 和 Origami 实现的Spring动画。它会在 toValue 值更新的同时跟踪当前的速度状态,以确保动画连贯。
除了这三个创建动画的方法,对于每个独立的方法都有三种调用该动画的方式:
Animated.parallel() --同时开始一个动画数组里的全部动画。默认情况下,如果有任何一个动画停止了,其余的也会被停止。你可以通过stopTogether 选项来改变这个效果。
Animated.sequence() --按顺序执行一个动画数组里的动画,等待一个完成后再执行下一个。如果当前的动画被中止,后面的动画则不会继续执行。
Animated.stagger() -- 一个动画数组,里面的动画有可能会同时执行(重叠),不过会以指定的延迟来开始。
Animated.timing()
使用 Animated.timing 创建的旋转动画。Animated.timing()的基本使用方法如下:
Animated.timing(
someValue,
{
toValue: number,
duration: number,
easing: easingFunction,
delay: number
}
)
Easing 也是用React Native创建动画的载体,它允许我们使用已经定义好的各种缓冲函数,例如:linear, ease, quad, cubic, sin, elastic, bounce, back, bezier, in, out, inout 。由于有直线运动,我们将使用 linear。
接下来,需要在构造函数中初始化一个带动画属性的值用于旋转动画的初始值:
constructor () {
super()
this.spinValue = new Animated.Value(0)
}
我们使用 Animated.Value声明了一个 spinValue 变量,并传了一个 0 作为初始值。然后创建了一个名为 spin 的方法,并在 componentDidMount 中调用它,目的是在 app 加载之后运行动画。
componentDidMount () {
this.spin()
}
spin () {
this.spinValue.setValue(0)
原文链接:http://click.aliyun.com/m/22229/
Animated.timing(
this.spinValue,
{
toValue: 1,
duration: 4000,
easing: Easing.linear
}
).start(() => this.spin())
}
现在方法已经创建好了,接下来就是在UI中渲染动画了。
render () {
const spin = this.spinValue.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '360deg']
})
return (
<View style={styles.container}>
<Animated.Image
style={{
width: 227,
height: 200,
transform: [{rotate: spin}] }}
source={{uri: 'https://s3.amazonaws.com/media-p.slid.es/uploads/alexanderfarennikov/images/1198519/reactjs.png'}}
/>
</View>
)
}
实现效果:
这里写图片描述
完整代码:
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, {Component} from 'react';
import {
AppRegistry,
StyleSheet,
Text,
Animated,
TouchableOpacity,
Easing,
View
} from 'react-native';
class AnimationRotateScene extends Component {
constructor(props) {
super(props);
this.spinValue = new Animated.Value(0)
}
componentDidMount () {
this.spin()
}
spin () {
this.spinValue.setValue(0)
Animated.timing(
this.spinValue,
{
toValue: 1,
duration: 4000,
easing: Easing.linear
}
).start(() => this.spin())
}
render() {
const
spin = this.spinValue.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '360deg']
})
return (
<View style={styles.container}>
原文链接:http://click.aliyun.com/m/22229/
<Animated.Image
style={{
width: 227,
height: 200,
transform: [{rotate: spin}] }}
source={{uri: 'https://s3.amazonaws.com/media-p.slid.es/uploads/alexanderfarennikov/images/1198519/reactjs.png'}}
/>
<TouchableOpacity onPress={() => this.spin()} style={styles.button}>
<Text>启动动画</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 20,
justifyContent: 'center',
alignItems: 'center',
},
button: {
marginTop: 20,
backgroundColor:'#808080',
height:35,
width:140,
borderRadius:5,
justifyContent: 'center',
alignItems: 'center',
},
});
export default AnimationRotateScene;
Animated.spring()
使用 Animated.spring() 方法创建一个放大缩小的动画。
这里写图片描述
Animated.spring() 方法使用:
Animated.spring(
someValue,
{
toValue: number,
friction: number
}
)
如上图所示,我们要使用Animated.spring()创建一个放大缩小的动画效果。
在构造函数中,创建一个 springValue 变量,初始化其值为0.3。
constructor () {
super()
this.springValue = new Animated.Value(0.3)
}
然后,删除 animated 方法和componentDidMount方法,创建一个新的 spring 方法。
spring () {
this.springValue.setValue(0.3)
Animated.spring(
this.springValue,
{
toValue: 1,
friction: 1
}
).start()
}
然后我们给View的button添加一个点击事件,出发上面的spring动画。
<View style={styles.container}>
<Text
style={{marginBottom: 100}}
onPress={this.spring.bind(this)}>Spring</Text>
<Animated.Image
style={{ width: 227, height: 200, transform: [{scale: this.springValue}] }}
source={{uri: 'https://s3.amazonaws.com/media-p.slid.es/uploads/alexanderfarennikov/images/1198519/reactjs.png'}}/>
</View>
完整代码如下:
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, {Component} from 'react';
import {
AppRegistry,
StyleSheet,
Text,
Animated,
TouchableOpacity,
Easing,
View
} from 'react-native';
原文链接:http://click.aliyun.com/m/22229/
class AnimationRotateScene extends Component {
constructor(props) {
super(props);
this.spinValue = new Animated.Value(0)
}
componentDidMount () {
this.spin()
}
spin () {
this.spinValue.setValue(0)
Animated.timing(
this.spinValue,
{
toValue: 1,
duration: 4000,
easing: Easing.linear
}
).start(() => this.spin())
}
render() {
const
spin = this.spinValue.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '360deg']
})
return (
<View style={styles.container}>
<Animated.Image
style={{
width: 227,
height: 200,
transform: [{rotate: spin}] }}
source={{uri: 'https://s3.amazonaws.com/media-p.slid.es/uploads/alexanderfarennikov/images/1198519/reactjs.png'}}
/>
<TouchableOpacity onPress={() => this.spin()} style={styles.button}>
<Text>启动动画</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 20,
justifyContent: 'center',
alignItems: 'center',
},
button: {
marginTop: 20,
backgroundColor:'#808080',
height:35,
width:140,
borderRadius:5,
justifyContent: 'center',
alignItems: 'center',
},
});
export default AnimationRotateScene;
Animated.parallel()
Animated.parallel() 会同时开始一个动画数组里的全部动画。parallel()会接受一个动画数组,首先看一下api:
Animated.parallel(arrayOfAnimations)
// In use:
Animated.parallel([
Animated.spring(
animatedValue,
{
//config options
}
),
Animated.timing(
animatedValue2,
{
//config options
}
)
])
所以,我们先创建一个动画数组,并初始化。
constructor () {
super()
this.animatedValue1 = new Animated.Value(0)
this.animatedValue2 = new Animated.Value(0)
this.animatedValue3 = new Animated.Value(0)
}
然后,创建一个 animate 方法并在 componendDidMount() 中调用它。
componentDidMount () {
this.animate()
}
animate () {
this.animatedValue1.setValue(0)
this.animatedValue2.setValue(0)
this.animatedValue3.setValue(0)
const createAnimation = function (value, duration, easing, delay = 0) {
return Animated.timing(
value,
{
toValue: 1,
duration,
easing,
delay
}
)
}
Animated.parallel([
createAnimation(this.animatedValue1, 2000, Easing.ease),
createAnimation(this.animatedValue2, 1000, Easing.ease, 1000),
createAnimation(this.animatedValue3, 1000, Easing.ease, 2000)
]).start()
}
在 animate 方法中,我们将三个动画属性值重置为0。此外,还创建了一个 createAnimation 方法,该方法接受四个参数:value, duration, easing, delay(默认值是0),返回一个新的动画。
然后,调用 Animated.parallel(),并将三个使用 createAnimation 创建的动画作为参数传递给它。在 render 方法中,我们需要设置插值:
原文链接:http://click.aliyun.com/m/22229/
render () {
const scaleText = this.animatedValue1.interpolate({
inputRange: [0, 1],
outputRange: [0.5, 2]
})
const spinText = this.animatedValue2.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '720deg']
})
const introButton = this.animatedValue3.interpolate({
inputRange: [0, 1],
outputRange: [-100, 400]
})
...
}
最后,我们用一个主 View 包裹三个 Animated.Views:
<View style={[styles.container]}>
<Animated.View
style={{ transform: [{scale: scaleText}] }}>
<Text>Welcome</Text>
</Animated.View>
<Animated.View
style={{ marginTop: 20, transform: [{rotate: spinText}] }}>
<Text
style={{fontSize: 20}}>
to the App!
</Text>
</Animated.View>
<Animated.View
style={{top: introButton, position: 'absolute'}}>
<TouchableHighlight
onPress={this.animate.bind(this)}
style={styles.button}>
<Text
style={{color: 'white', fontSize: 20}}>
Click Here To Start
</Text>
</TouchableHighlight>
</Animated.View>
</View>
完整的代码如下:
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow 组动画
*/
import React, {Component} from 'react';
import {
AppRegistry,
StyleSheet,
Text,
Animated,
TouchableOpacity,
TouchableHighlight,
Easing,
View
} from 'react-native';
原文链接:http://click.aliyun.com/m/22229/
class AnimationGroupScene extends Component {
constructor() {
super()
this.animatedValue1 = new Animated.Value(0)
this.animatedValue2 = new Animated.Value(0)
this.animatedValue3 = new Animated.Value(0)
}
componentDidMount() {
this.animate()
}
animate() {
this.animatedValue1.setValue(0)
this.animatedValue2.setValue(0)
this.animatedValue3.setValue(0)
const createAnimation = function (value, duration, easing, delay = 0) {
return Animated.timing(
value,
{
toValue: 1,
duration,
easing,
delay
}
)
}
Animated.parallel([
createAnimation(this.animatedValue1, 2000, Easing.ease),
createAnimation(this.animatedValue2, 1000, Easing.ease, 1000),
createAnimation(this.animatedValue3, 1000, Easing.ease, 2000)
]).start()
}
startAnimation() {
this.state.currentAlpha = this.state.currentAlpha == 1.0 ? 0.0 : 1.0;
Animated.timing(
this.state.fadeAnim,
{toValue: this.state.currentAlpha}
).start();
}
render() {
const scaleText = this.animatedValue1.interpolate({
inputRange: [0, 1],
outputRange: [0.5, 2]
})
const spinText = this.animatedValue2.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '720deg']
})
const introButton = this.animatedValue3.interpolate({
inputRange: [0, 1],
outputRange: [-100, 400]
})
return (
<View style={styles.container}>
<Animated.View
style={{transform: [{scale: scaleText}]}}>
<Text>Welcome</Text>
</Animated.View>
<Animated.View
style={{marginTop: 20, transform: [{rotate: spinText}]}}>
<Text
style={{fontSize: 20}}>
to the App!
</Text>
</Animated.View>
<Animated.View
style={{top: introButton, position: 'absolute'}}>
<TouchableHighlight
onPress={this.animate.bind(this)}
style={styles.button}>
<Text>启动组动画</Text>
</TouchableHighlight>
</Animated.View>
</View>
);
}
}
原文链接:http://click.aliyun.com/m/22229/
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 20,
justifyContent: 'center',
alignItems: 'center',
},
button: {
marginTop: 20,
backgroundColor: '#808080',
height: 35,
width: 140,
borderRadius: 5,
justifyContent: 'center',
alignItems: 'center',
},
});
export default AnimationGroupScene;
示例使用说明
这里写图片描述
这里写图片描述
如图所示,我对动画的代码做了一个简单的整理,大家在使用的时候直接引入AnimationRoot文件即可。
AnimationRoot文件内容如下:
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, {Component} from 'react';
import { StackNavigator } from 'react-navigation';
import AnimationIndex from './AnimationIndex';
import AnimationSpringScene from './AnimationSpringScene';//缩放动画
import AnimationRotateScene from './AnimationRotateScene';//旋转动画
import AnimationAlphaScene from './AnimationAlphaScene';//Alpha动画
import AnimationGroupScene from './AnimationGroupScene';//组动画
import AnimationFrameScene from './AnimationFrameScene';//帧动画
const anim = StackNavigator({
AnimationIndex: { screen: AnimationIndex },
AnimationSpringScene: { screen: AnimationSpringScene },
AnimationRotateScene: { screen: AnimationRotateScene },
AnimationAlphaScene: { screen: AnimationAlphaScene },
AnimationGroupScene: { screen: AnimationGroupScene },
AnimationFrameScene: { screen: AnimationFrameScene },
});
export default anim;
最后是项目实现的最终结果图,代码地址动画源码
原文链接:http://click.aliyun.com/m/22229/
相关推荐
针对 MongoDB 的优化是提高数据库性能的关键,这通常涉及到多个方面,包括内存配置、查询优化、索引管理和集群架构调整等。 首先,我们可以修改 MongoDB 的默认内存配置以适应更大的数据处理需求。在 MongoDB ...
本篇文章将深入探讨MongoDB的优化器执行器,包括慢查询的产生与发现、索引的工作原理、优化器的工作机制以及多键索引的影响和注意事项。 首先,慢查询通常是由于查询读取了过多的文档导致的。MongoDB提供了一个名为...
这涉及到正确配置硬件资源、优化数据库架构、设置合适的复制集以实现高可用性,以及定期维护和监控。 总的来说,MongoDB为JavaScript开发者提供了强大的数据分析和报告工具。通过理解其核心特性,如聚合框架、索引...
本文主要分享了关于MongoDB优化的一些关键心得,旨在帮助开发者更好地管理和优化MongoDB实例。 首先,MongoDB的参数配置至关重要。其中,`storageEngine` 和 `directoryperdb` 是两个重要的设置。`directoryperdb` ...
MongoDB 优化可以通过调整 MongoDB 配置文件、优化查询语句、使用索引、分片、缓存等方式来实现。 MySQL 和 MongoDB 的比较 MySQL 和 MongoDB 都是流行的数据库管理系统,但它们有着不同的设计理念和应用场景。...
3. **高性能**:MongoDB优化了读写操作,提供了高性能的数据访问,特别是在处理大量的读写操作时。 4. **高可用性**:通过副本集(Replica Sets)实现,副本集是一组维护相同数据集的MongoDB服务器,可以提供数据的...
3. **高性能**:MongoDB优化了读写操作,提供了高性能的数据访问,特别是在处理大量的读写操作时。 4. **高可用性**:通过副本集(Replica Sets)实现,副本集是一组维护相同数据集的MongoDB服务器,可以提供数据的...
MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化...
### MongoDB性能优化详解 #### 一、MongoDB性能优化概述 MongoDB作为一种广泛使用的NoSQL数据库,因其灵活性和高扩展性而备受青睐。然而,在实际应用过程中,由于数据量的增长和查询复杂性的增加,可能会遇到性能...
MongoDB 安装与配置主从关系需要考虑多方面的因素,包括安装、配置、创建数据库和用户、创建索引、主从配置和优化等。只有通过合理的配置和优化,才能发挥 MongoDB 的强大功能,提高系统性能和可用性。
在3.4.6版本中,MongoDB优化了存储引擎,如WiredTiger,提供了更好的空间利用率和更快的读写速度。 2. **查询性能**:MongoDB支持丰富的查询语法,包括聚合框架、地理空间索引、正则表达式匹配等。3.4.6版本进一步...
"MongoDB集群性能优化实践" 本文档主要介绍了MongoDB集群性能优化实践,涵盖了从 MongoDB 集群优化到解决方案的分享。通过本文档,我们可以了解到 MongoDB 集群性能优化的重要性,并学习到实际的解决方案。 知识点...
3. **高性能**:MongoDB优化了读写操作,提供了高性能的数据访问,特别是在处理大量的读写操作时。 4. **高可用性**:通过副本集(Replica Sets)实现,副本集是一组维护相同数据集的MongoDB服务器,可以提供数据的...
3. **高性能**:MongoDB优化了读写操作,提供了高性能的数据访问,特别是在处理大量的读写操作时。 4. **高可用性**:通过副本集(Replica Sets)实现,副本集是一组维护相同数据集的MongoDB服务器,可以提供数据的...
3. **高性能**:MongoDB优化了读写操作,提供了高性能的数据访问,特别是在处理大量的读写操作时。 4. **高可用性**:通过副本集(Replica Sets)实现,副本集是一组维护相同数据集的MongoDB服务器,可以提供数据的...