reactnative 动画实现
来源:互联网 发布:知乎招聘 编辑:程序博客网 时间:2024/06/07 21:26
先看一个示例
class Playground extends React.Component { constructor(props) { super(props); this.state = { bounceValue: new Animated.Value(0), }; } render() { return ( <Animated.Image // Base: Image, Text, View source={{uri: 'http://i.imgur.com/XMKOH81.jpg'}} style={{ flex: 1, transform: [ // `transform` is an ordered array {scale: this.state.bounceValue}, // Map `bounceValue` to `scale` ] }} /> ); } componentDidMount() { this.state.bounceValue.setValue(1.5); // Start large Animated.spring( // Base: spring, decay, timing this.state.bounceValue, // Animate `bounceValue` { toValue: 0.8, // Animate to smaller size friction: 1, // Bouncier spring } ).start(); // Start the animation }}
动画是从 Animated.spring开始的
找到对应实现
var spring = function( value: AnimatedValue | AnimatedValueXY, config: SpringAnimationConfig,): CompositeAnimation { return maybeVectorAnim(value, config, spring) || { start: function(callback?: ?EndCallback): void { callback = _combineCallbacks(callback, config); var singleValue: any = value; var singleConfig: any = config; singleValue.stopTracking(); if (config.toValue instanceof Animated) { singleValue.track(new AnimatedTracking( singleValue, config.toValue, SpringAnimation, singleConfig, callback )); } else { singleValue.animate(new SpringAnimation(singleConfig), callback); } }, stop: function(): void { value.stopAnimation(); }, };};
看来目标值存在singleValue,然后结束值和动画实现放在singleConfig
这里start函数都直接有的
最重要的是singleValue.animate(new SpringAnimation(singleConfig), callback);
singlevalue是一个Animated.Value 类型。调用这里面的animate方法。然后传入的类型是SpringAnimation。
Animated.Value
下面研究Animated.Value类型(这个类型我找不到) 但是从函数定义上来来说 是AnimatedValue类型
下面是value 的实现
animate(animation: Animation, callback: ?EndCallback): void { var handle = null; if (animation.__isInteraction) { handle = InteractionManager.createInteractionHandle(); } var previousAnimation = this._animation; this._animation && this._animation.stop(); this._animation = animation; animation.start( this._value, (value) => { // Natively driven animations will never call into that callback, therefore we can always // pass flush = true to allow the updated value to propagate to native with setNativeProps this._updateValue(value, true /* flush */); }, (result) => { this._animation = null; if (handle !== null) { InteractionManager.clearInteractionHandle(handle); } callback && callback(result); }, previousAnimation, this ); }
看来是调用
SpringAnimation的start方法给了一个初始值 然后穿了两个函数。
主要是的是把_updateValue 也传了进去。
先把_updateValue放在这里。
_updateValue(value: number, flush: bool): void { this._value = value; if (flush) { _flush(this); } for (var key in this._listeners) { this._listeners[key]({value: this.__getValue()}); } }
class SpringAnimation extends Animation
SpringAnimation 在构造的时候就知道动画结束值和动画的持续时间
constructor( config: SpringAnimationConfigSingle, ) { super(); this._overshootClamping = withDefault(config.overshootClamping, false); this._restDisplacementThreshold = withDefault(config.restDisplacementThreshold, 0.001); this._restSpeedThreshold = withDefault(config.restSpeedThreshold, 0.001); this._initialVelocity = config.velocity; this._lastVelocity = withDefault(config.velocity, 0); this._toValue = config.toValue; this._useNativeDriver = shouldUseNativeDriver(config); this.__isInteraction = config.isInteraction !== undefined ? config.isInteraction : true;
结束值在this._toValue里面
start函数
start( fromValue: number, onUpdate: (value: number) => void, onEnd: ?EndCallback, previousAnimation: ?Animation, animatedValue: AnimatedValue ): void { this.__active = true; this._startPosition = fromValue; this._lastPosition = this._startPosition; this._onUpdate = onUpdate; this.__onEnd = onEnd; this._lastTime = Date.now(); if (previousAnimation instanceof SpringAnimation) { var internalState = previousAnimation.getInternalState(); this._lastPosition = internalState.lastPosition; this._lastVelocity = internalState.lastVelocity; this._lastTime = internalState.lastTime; } if (this._initialVelocity !== undefined && this._initialVelocity !== null) { this._lastVelocity = this._initialVelocity; } if (this._useNativeDriver) { this.__startNativeAnimation(animatedValue); } else { this.onUpdate(); } }
start里面有个重点
if (this._useNativeDriver) { this.__startNativeAnimation(animatedValue); } else { this.onUpdate(); }
非native
这里会区分是本地动画还是自己的动画。
先分析onUpdate
opUpdate会计算出当前时间动画的值
然后调用this._onUpdate
这个就是AnimatedValue传进来的回调函数。执行的是AnimatedValue的 this._updateValue(value, true /* flush */);
这个函数会大flush标记 和 通知监听者 todo
看来SpringAnimation只是用于计算动画的当前的值。并没有涉及到原理性的东西。
native
下面看一下native的实现
__startNativeAnimation
__startNativeAnimation(animatedValue: AnimatedValue): void { animatedValue.__makeNative(); this.__nativeId = NativeAnimatedHelper.generateNewAnimationId(); NativeAnimatedAPI.startAnimatingNode( this.__nativeId, animatedValue.__getNativeTag(), this.__getNativeAnimationConfig(), this.__debouncedOnEnd.bind(this) ); }
现在要去看NativeAnimatedHelper.js
下面就是要做分平台处理了
ios RCTNativeAnimatedModule.m
Android NativeAnimatedModule.java
RCTNativeAnimatedModule.m
这个类对外提供接口
RCT_EXPORT_METHOD(startAnimatingNode:(nonnull NSNumber *)animationId
nodeTag:(nonnull NSNumber *)nodeTag
config:(NSDictionary
- reactnative 动画实现
- ReactNative动画(上)
- ReactNative动画(下)
- ReactNative Animated动画详解
- ReactNative Art 动画
- (十七)ReactNative 中动画详解
- ReactNative——动画学习
- ReactNative 实现图片轮播器
- reactnative Animated 插值动画(interpolate)
- ReactNative导航设计与实现
- ReactNative 广告轮播页的实现
- (七)ReactNative实现二维码扫描
- ReactNative实现通知监听事件
- reactNative底部导航菜单栏实现
- ReactNative实现图集功能
- ReactNative
- ReactNative
- ReactNative
- Antenna Placement poj 3020 二分图
- 日期转换错误
- spark-环境配置出错
- scala-环境安装出错
- 传入的表格格式数据流(TDS)远程过…
- reactnative 动画实现
- Can not cast from List…
- 程序员如何学习新的技术
- sqlserver数据库数据类型与java数…
- mybatis的mapper-*.xml文件编写语…
- java各种反射方式的性能问题
- 数据库性能优化详解
- Android Studio常见错误_持续…
- Android Studio 编译程序太慢