132 lines
3.2 KiB
JavaScript
132 lines
3.2 KiB
JavaScript
// 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)
|
||
}
|