React Native 入门

React Native 动画

刚看到RN动画时一头懵, 怎么实现, 这些参数属性是什么? 那里有这些参数文档.
后来发现原来是CSS3时提供的, 先了解一下CSS3的动画就不难理解了.

1. 基本知识

1.1 CSS动画介络

CSS3动画相关的几个属性是:transition, transform, animation;我分别理解为过渡,变换,动画。虽意义相近,但具体角色不一。

1.2 transition

作用: 当元素从一种样式变换为另一种样式时为元素添加效果

属性 描述 CSS
transition 简写属性,用于在一个属性中设置四个过渡属性。 3
transition-property 规定应用过渡的 CSS 属性的名称。比如transition-property:backgrond 就是指backgound参与这个过渡 3
transition-duration 定义过渡效果花费的时间。默认是 0。 3
transition-timing-function 规定过渡效果的时间曲线。默认是 “ease”。 3
transition-delay 规定过渡效果何时开始。默认是 0。 3

transition-timing-function: 类型如下:

函数名 解释 实例
ease 移动距离 -moz-transition-timing-function:ease;
linear 线性过度 -moz-transition-timing-function:linear;
ease-in 由慢到快
ease-out 由快到慢
ease-in-out 由慢到快在到慢, ease-in-ease-out
cubic-bezier 贝塞尔曲线

实例:

1
2
3
4
5
6
7
8
9
10
11
12
div {
/* Safari and Chrome */
-webkit-transition-property:width;
-webkit-transition-duration:1s;
-webkit-transition-timing-function:linear;
-webkit-transition-delay:2s;
}
等价下面:
div {
/* Safari and Chrome */
-webkit-transition: width 1s linear 2s;
}

1.3 transform

作用: 对元素进行移动、缩放、转动、拉长或拉伸
2D变换:

3D变换:

实例:

1
transform: rotateY(130deg);

1.4 animation

创建能够取代动画图片、Flash 动画以及 JavaScript的动画。

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
div {
animation-name: myfirst;
animation-duration: 5s;
animation-timing-function: linear;
animation-delay: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-play-state: running;
}
// 等效
div {
animation: myfirst 5s linear 2s infinite alternate;
}

2. React-Native动画

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
transform: 
[
{perspective: number},
{rotate: string},
{rotateX: string},
{rotateY: string},
{rotateZ: string},
{scale: number},
{scaleX: number},
{scaleY: number},
{translateX: number},
{translateY: number},
{skewX: string},
{skewY: string}
]

2.1 Animated

Animated库使得开发者可以非常容易地实现各种各样的动画和交互方式,并且具备极高的性能。

  • 两个值类型: Value用于单个的值,而ValueXY用于向量值;

三种动画类型:

  1. spring: 基础的单次弹跳物理模型,符合Origami设计标准

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    type SpringAnimationConfig = AnimationConfig & {
    toValue: number | AnimatedValue | {x: number, y: number} | AnimatedValueXY,
    overshootClamping?: bool,
    restDisplacementThreshold?: number,
    restSpeedThreshold?: number,
    velocity?: number | {x: number, y: number},
    bounciness?: number,
    speed?: number,
    tension?: number, // 张力,默认40。
    friction?: number, // 摩擦力,默认为7.
    };

    var spring = function(
    value: AnimatedValue | AnimatedValueXY,
    config: SpringAnimationConfig,
    ): CompositeAnimation {
    ......
    };
  2. decay: 以一个初始速度开始并且逐渐减慢停止。
    velocity: 起始速度,必填参数。
    deceleration: 速度衰减比例,默认为0.997。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    type DecayAnimationConfig = AnimationConfig & {
    velocity: number | {x: number, y: number},
    deceleration?: number,
    };

    var decay = function(
    value: AnimatedValue | AnimatedValueXY,
    config: DecayAnimationConfig,
    ): CompositeAnimation {
    ......
    };
  3. timing: 从时间范围映射到渐变的值。
    duration: 动画持续的时间(毫秒),默认为500。
    easing:一个用于定义曲线的渐变函数。阅读Easing模块可以找到许多预定义的函数。iOS默认为E asing.inOut(Easing.ease)。
    delay: 在一段时间之后开始动画(单位是毫秒),默认为0。
    原型: react-native/Libraries/Animated/src/AnimatedImplementagion.js -> Line: 1951

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    type TimingAnimationConfig =  AnimationConfig & {
    toValue: number | AnimatedValue | {x: number, y: number} | AnimatedValueXY,
    easing?: (value: number) => number,
    duration?: number,
    delay?: number,
    };

    var timing = function(
    value: AnimatedValue | AnimatedValueXY,
    config: TimingAnimationConfig,
    ): CompositeAnimation {
    ......
    };
  • 三种组件: View,Text和Image, 可以使用Animated.createAnimatedComponent方法来对其它类型的组件创建动画

2.2 插值函数interpolate

interpolate原型

interpolate插值函数。它可以接受一个输入区间,然后将其映射到另一个的输出区间。

1
2
3
4
5
6
7
8
9
10
11
// extend-允许超出, clamp-固定输入, identity-?
type ExtrapolateType = 'extend' | 'identity' | 'clamp';

export type InterpolationConfigType = {
inputRange: Array<number>, // 输入范围
outputRange: (Array<number> | Array<string>), // 输出范围
easing?: ((input: number) => number), // 任意的渐变函数;
extrapolate?: ExtrapolateType, // 限制输出区间
extrapolateLeft?: ExtrapolateType,
extrapolateRight?: ExtrapolateType,
};

问题: 下面代码设置scale属性是从什么值变到什么值? 0200? 01?

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
class FadeInView extends React.Component {
state: any;

constructor(props) {
super(props);
this.state = {
fadeAnim: new Animated.Value(0), // 声明Animated.Value
};
}
componentDidMount() {
Animated.timing( // Uses easing functions
this.state.fadeAnim, // The value to drive
{
toValue: 200, // 目标值
duration: 2000, // 动画持续的时间(毫秒)
},
).start(); // Don't forget start!
}

render() {
this.state.fadeAnim.setValue(0); // 设置一个较大的初始值, [0,toValue]
return (
<Animated.View // 指定动画View;
style={{
transform: [{scale: this.state.fadeAnim.interpolate({
inputRange: [0, 100, 150], // 输义输入
outputRange: [0, 1, 1], // 对应输出区间, scale最终是在[0, 1]之间变化;
})}]
}}>
{this.props.children}
</Animated.View>
);
}
}

0~1之间缩放效果:

注意: 两元素跟三个元素是有区别的:

inputRange outoutRange extrapolate 实例(输入:输出)
[0, 100] [0, 1] ‘extend’ 0:0, 50:0.5, 100:1, 150:1.5, 200:2
[0, 100] [0, 1] ‘clamp’ 0:0, 50:0.5, 100:1, 150:1, 200:1
[0, 100, 200] [0, 1, 1] ‘extend’ 0:0, 50:0.5, 100:1, 150:1, 200:1
[0, 100, 200] [0, 1, 1] ‘clamp’ 0:0, 50:0.5, 100:1, 150:1, 200:1

动画组合:

parallel(同时执行), sequence(顺序执行), stagger(交错), delay(延时)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Animated.sequence([            // 首先执行decay动画,结束后同时执行spring和twirl动画
Animated.decay(position, { // 滑行一段距离后停止
velocity: {x: gestureState.vx, y: gestureState.vy}, // 根据用户的手势设置速度
deceleration: 0.997,
}),
Animated.parallel([ // 在decay之后并行执行:
Animated.spring(position, {
toValue: {x: 0, y: 0} // 返回到起始点开始
}),
Animated.timing(twirl, { // 同时开始旋转
toValue: 360,
}),
]),
]).start(); // 执行这一整套动画序列

默认情况下,如果任何一个动画被停止或中断了,组内所有其它的动画也会被停止。Parallel有一个stopTogether属性,如果设置为false,可以禁用自动停止。

LayoutAnimation

名词解释

名词 解释 实例
rotate 旋转 -webkit-transform:rotate(10deg);
scale 尺寸放大缩小
skew 倾斜角度
translate 移动距离
linear 线性过度
ease-in 由慢到快
ease-out 由快到慢
ease-in-out 由慢到快在到慢

参考:

  1. CSS3 Transitions, Transforms和Animation使用简介与应用展示
  2. 好吧,CSS3 3D transform变换,不过如此
  3. W3School CSS3 transition
  4. W3School CSS3 2D 转换
  5. W3School CSS3 3D 转换
  6. React Native API Animated