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)
|
|||
|
}
|