// const defaultOption = { // duration: 300, // timingFunction: 'linear', // delay: 0, // transformOrigin: '50% 50% 0' // } // #ifdef APP-NVUE const nvueAnimation = uni.requireNativePlugin('animation') // #endif class MPAnimation { constructor(options, _this) { this.options = options // 在iOS10+QQ小程序平台下,传给原生的对象一定是个普通对象而不是Proxy对象,否则会报parameter should be Object instead of ProxyObject的错误 this.animation = uni.createAnimation({ ...options }) this.currentStepAnimates = {} this.next = 0 this.$ = _this } _nvuePushAnimates(type, args) { let aniObj = this.currentStepAnimates[this.next] let styles = {} if (!aniObj) { styles = { styles: {}, config: {} } } else { styles = aniObj } if (animateTypes1.includes(type)) { if (!styles.styles.transform) { styles.styles.transform = '' } let unit = '' if(type === 'rotate'){ unit = 'deg' } styles.styles.transform += `${type}(${args+unit}) ` } else { styles.styles[type] = `${args}` } this.currentStepAnimates[this.next] = styles } _animateRun(styles = {}, config = {}) { let ref = this.$.$refs['ani'].ref if (!ref) return return new Promise((resolve, reject) => { nvueAnimation.transition(ref, { styles, ...config }, res => { resolve() }) }) } _nvueNextAnimate(animates, step = 0, fn) { let obj = animates[step] if (obj) { let { styles, config } = obj this._animateRun(styles, config).then(() => { step += 1 this._nvueNextAnimate(animates, step, fn) }) } else { this.currentStepAnimates = {} typeof fn === 'function' && fn() this.isEnd = true } } step(config = {}) { // #ifndef APP-NVUE this.animation.step(config) // #endif // #ifdef APP-NVUE this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config) this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin this.next++ // #endif return this } run(fn) { // #ifndef APP-NVUE this.$.animationData = this.animation.export() this.$.timer = setTimeout(() => { typeof fn === 'function' && fn() }, this.$.durationTime) // #endif // #ifdef APP-NVUE this.isEnd = false let ref = this.$.$refs['ani'] && this.$.$refs['ani'].ref if(!ref) return this._nvueNextAnimate(this.currentStepAnimates, 0, fn) this.next = 0 // #endif } } const animateTypes1 = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d', 'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY', 'translateZ' ] const animateTypes2 = ['opacity', 'backgroundColor'] const animateTypes3 = ['width', 'height', 'left', 'right', 'top', 'bottom'] animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => { MPAnimation.prototype[type] = function(...args) { // #ifndef APP-NVUE this.animation[type](...args) // #endif // #ifdef APP-NVUE this._nvuePushAnimates(type, args) // #endif return this } }) export function createAnimation(option, _this) { if(!_this) return clearTimeout(_this.timer) return new MPAnimation(option, _this) }