React-Native之动画

动画组成

react-native提供了两个互补的动画系统: 用于全局的布局动画(LayoutAnimation), 和用于创建更精细交互的动画(Animated)

animated

Animated旨在以声明的形式来定义动画的输入与输出,在其中建立一个可配置的变化函数,然后使用简单的start/stop方法来控制动画按顺序执行。
Animated仅封装了四个可以动画化的组件:ViewTextImageScrollView
不过可以使用Animated.createAnimatedComponent()来封装你自己的组件。

下面是一个简单的透明渐变动画的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// FadeInView.js
import React, { Component } from 'react';
import {
Animated,
} from 'react-native';

export default class FadeInView extends Component {
constructor(props) {
super(props);
this.state = {
// 透明度初始值设为0
fadeAnim: new Animated.Value(0),
};
}
componentDidMount() {
// 随时间变化而执行的动画类型
Animated.timing(
// 动画中的变量值
this.state.fadeAnim,
{
// 透明度最终变为1,即完全不透明
toValue: 1,
// 变化动画的总执行时间
duration: 3000
}
).start(); // 开始执行动画
}
render() {
return (
// 可动画化的视图组件
<Animated.View
style={{
...this.props.style,
// 将透明度指定为动画变量值
opacity: this.state.fadeAnim,
}}
>
{this.props.children}
</Animated.View>
);
}
}

然后通过引入该组件, 并传入对应的style样式及子组件的方式就可以开始进行使用了

总体来说, 简单的动画就是用Animated.Value指定初始值, 此时要new一个对象,然后在Animated.timing中设置结束值,其他的交给React native让它自动创建,我们只需要调用start开始动画即可。

常用的动画类

方法

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类似,用在二维动画

interpolate

所以一般时间, 我们创建动画的基本流程是:

  1. 在state中使用一个变量来存储我们new出来的动画的对象, 并赋予其初始值
1
2
3
tate = {
anim: new Animated.Value(0)
};
  1. 当需要调用这个动画对象的时候, 我们使用动画对象的对应动画参数来进行调用
1
2
3
4
5
6
7
nimated.timing(
// 传入起始状态下的动画对象
this.state.anim,
// 传入结束状态的值, 当然, 这个值是可以变化的
// 通过变化的结束值, 就可以很方便地进行动画的循环了
{ toValue: this.state.currentAlpha }
).start();
  1. 对页面需要进行控制的动画对象进行处理, 目前可以处理的组件有: Text, View, Image, ScrollView , 我们将其写为Animated对象下面的属性形式以使动画正常生效
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<Animated.Text style={{
// 当前组件的透明度参数, 直接设置为此对象值, 则代表直接获取到了此对象的value
opacity: this.state.anim,
// 这个和css3中的transform是一样的
// 因为只有一个值在变, 所以我们这里需要为对应的内容设置范围值
transform: [
{
// 我们使用anim中的interpolate函数来进行页面数值的转换
translateY: this.state.anim.interpolate({
// 输入值的范围
inputRange: [0, 1],
// 输出值的范围
outputRange: [60, 0] //线性插值,0对应60,0.5对应30,1对应0
}),
},
{
// 同样的, 缩放值也是与anim的value一致
scale: this.state.anim
},
],
}}>

一般作为一个变量, 我们会将其转换为范围值来对页面的样式进行控制

文章目录
  1. 1. 动画组成
    1. 1.1. animated
  2. 2. 常用的动画类
    1. 2.1. 方法
    2. 2.2. 属性
      1. 2.2.1. AnimatedValue类型
      2. 2.2.2. 方法
        1. 2.2.2.1. AnimatedValueXY
        2. 2.2.2.2. interpolate
|