React Naticw
封装了两个易于使用的动画组件。用于全局的布局动画LayoutAnimation
,和用于创建更精细的交互控制的动画Animated
LayoutAnimation
- 当布局变化时,自动将视图运动到它们新的位置上
LayoutAnimation
动画使用简单,要实现动画效果只需要在setState
前添加LayoutAnimation
动画方法
相关方法
1 2 3 4 5 6 7 8 9 10 11
| configureNext: (config: LayoutAnimationConfig, onAnimationDidEnd?: () => void) => void
create: (duration: number, type?: string, creationProp?: string) => LayoutAnimationConfig
|
LayoutAnimationConfig
LayoutAnimationConfig
的相关参数信息
1 2 3 4 5 6 7 8 9 10 11
| export interface LayoutAnimationConfig { duration: number; create?: LayoutAnimationAnim; update?: LayoutAnimationAnim; delete?: LayoutAnimationAnim; }
|
LayoutAnimationAnim
LayoutAnimationAnim
相关参数格式参考
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| export interface LayoutAnimationAnim { duration?: number; delay?: number; springDamping?: number; initialVelocity?: number; type?: string; property?: string; }
|
常用枚举值
LayoutAnimationTypes
和LayoutAnimationProperties
的取值如下
1 2 3 4 5 6 7 8 9 10 11 12 13
| export interface LayoutAnimationTypes { spring: string; linear: string; easeInEaseOut: string; easeIn: string; easeOut: string; keyboard: string; }
export interface LayoutAnimationProperties { opacity: string; scaleXY: string; }
|
代码示例
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
| export default class SpingAnimated extends Component { constructor(props) { super(props)
this.state = { width: 50, height: 50, } }
_startAnimated() { LayoutAnimation.configureNext({ duration: 500, create: {type: 'linear', property: 'opacity'}, update: {type: 'linear', property: '0.8'} })
this.setState({ width: this.state.width + 20, height: this.state.height + 20, }) }
render(){ return ( <View style={{ width: 414, height: 800, backgroundColor: 'yellow', alignItems: 'center', justifyContent: 'center' }}> <View style={{width: this.state.width, height: this.state.height, backgroundColor: 'red'}}/>
<TouchableOpacity style={{position:'absolute', bottom: 50}} onPress={this._startAnimated.bind(this)}> <Text style={{width:200,height:100,textAlign:'center',lineHeight:100}}>点击开始动画</Text> </TouchableOpacity> </View> ); } }
|
Animated
配置动画
Animated
提供了三种动画类型。每种动画类型都提供了特定的函数曲线,用于控制动画值从初始值变化到最终值的变化过程:
Animated.timing()
:最常用的动画类型,使一个值按照一个过渡曲线而随时间变化。
Animated.spring()
:弹簧效果,基础的单次弹跳物理模型实现的 spring 动画。
Animated.decay()
:衰变效果,以一个初始的速度和一个衰减系数逐渐减慢变为0
组合动画
Animated
实现组合动画的主要方式:
Animated.parallel
:同时开始一个动画数组里的全部动画。默认情况下,如果有任何一个动画停止了,其余的也会被停止。可以通过stopTogether
选项设置为false
来取消这种关联。
Animated.sequence
:按顺序执行一个动画数组里的动画,等待一个完成后再执行下一个。如果当前的动画被中止,后面的动画则不会继续执行
Animated.stagger
:一个动画数组,传入一个时间参数来设置队列动画间的延迟,即在前一个动画开始之后,隔一段指定时间才开始执行下一个动画里面的动画,并不关心前一个动画是否已经完成,所以有可能会出现同时执行(重叠)的情况
自定义动画组件
组件必须经过特殊处理才能用于动画。所谓的特殊处理主要是指把动画值绑定到属性上,并且在一帧帧执行动画时避免反应重新渲染和重新调和的开销。此外还得在组件卸载时做一些清理工作,使得这些组件在使用时是安全的
createAnimatedComponent()
方法正是用来处理组件,使其可以用于动画
Animated
中默认导出了以下这些可以直接使用的动画组件,当然它们都是通过使用上面这个方法进行了封装:
Animated.Image
Animated.ScrollView
Animated.Text
Animated.View
合成动画值
你可以使用加减乘除以及取余等运算来把两个动画值合成为一个新的动画值。
Animated.add()
Animated.divide()
Animated.modulo()
Animated.multiply()
timing动画
常用的线性动画, 使组件随时间变化从一个fromValue
按照一个过渡曲线变化到一个toValue
1
| export const timing: (value: AnimatedValue | AnimatedValueXY, config: TimingAnimationConfig) => CompositeAnimation;
|
config
参数介绍
1 2 3 4 5 6 7 8 9 10
| interface TimingAnimationConfig extends AnimationConfig { toValue: number | AnimatedValue | { x: number; y: number } | AnimatedValueXY; easing?: (value: number) => number; duration?: number; delay?: number; }
|
代码示例
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
| export default class Animation extends Component { constructor(props) { super(props)
this.state = { fadeOutOpacity: new Animated.Value(1), }
this.fadeOutAnimated = Animated.timing( this.state.fadeOutOpacity, { toValue: 0, duration: 3000, easing: Easing.linear, } ); }
_startAnimated() { this.fadeOutAnimated.start(() => this.state.fadeOutOpacity.setValue(1)); }
render(){ return ( <View style={{flex: 1, backgroundColor: '#f7f7f7', marginTop: 88, marginBottom: 34}}> <Animated.View style={{marginTop: 100,width: 200, height: 200, opacity: this.state.fadeOutOpacity}}> <View style={{width:200,height:200,backgroundColor: 'red'}}/> </Animated.View>
<TouchableOpacity style={{marginLeft: 50}} onPress={this._startAnimated.bind(this)}> <Text style={{width:200,height:100,textAlign:'center',lineHeight:100}}>点击开始动画</Text> </TouchableOpacity> </View> ); } }
|
spring
弹簧动画, 基础的单词弹跳物理模型实现的spring
动画
1
| export function spring(value: AnimatedValue | AnimatedValueXY, config: SpringAnimationConfig): CompositeAnimation;
|
config
参数格式介绍
1 2 3 4 5 6 7 8 9 10 11 12
| interface SpringAnimationConfig extends AnimationConfig { toValue: number | AnimatedValue | { x: number; y: number } | AnimatedValueXY; bounciness?: number; speed?: number; tension?: number; friction?: number; }
|
示例代码
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
| export default class SpingAnimated extends Component { constructor(props) { super(props)
this.state = { springValue: new Animated.Value(1) }
this.springAnimated = Animated.spring(this.state.springValue, { toValue: 1, duration: 2000, tension: 10, friction: 2 }) }
_startAnimated() { this.state.springValue.setValue(0.1); this.springAnimated.start(); }
render(){ return ( <View style={{ width: 414, height: 800, backgroundColor: 'yellow', alignItems: 'center', justifyContent: 'center' }}> <Animated.View style={{width: 100, height: 100, backgroundColor: 'red', transform: [{scale: this.state.springValue}]}}/>
<TouchableOpacity style={{position:'absolute', bottom: 50}} onPress={this._startAnimated.bind(this)}> <Text style={{width:200,height:100,textAlign:'center',lineHeight:100}}>点击开始动画</Text> </TouchableOpacity> </View> ); } }
|