149 lines
4.3 KiB
TypeScript
149 lines
4.3 KiB
TypeScript
// @ts-nocheck
|
||
// nvue 需要在节点上设置ref或在export里传入
|
||
// const animation = createAnimation({
|
||
// ref: this.$refs['xxx'],
|
||
// duration: 0,
|
||
// timingFunction: 'linear'
|
||
// })
|
||
// animation.opacity(1).translate(x, y).step({duration})
|
||
// animation.export(ref)
|
||
|
||
// 抹平nvue 与 uni.createAnimation的使用差距
|
||
// 但是nvue动画太慢~~~无语
|
||
|
||
|
||
|
||
|
||
// #ifdef APP-NVUE
|
||
const nvueAnimation = uni.requireNativePlugin('animation')
|
||
|
||
type AnimationTypes = 'matrix' | 'matrix3d' | 'rotate' | 'rotate3d' | 'rotateX' | 'rotateY' | 'rotateZ' | 'scale' | 'scale3d' | 'scaleX' | 'scaleY' | 'scaleZ' | 'skew' | 'skewX' | 'skewY' | 'translate' | 'translate3d' | 'translateX' | 'translateY' | 'translateZ'
|
||
| 'opacity' | 'backgroundColor' | 'width' | 'height' | 'left' | 'right' | 'top' | 'bottom'
|
||
|
||
interface Styles {
|
||
[key : string] : any
|
||
}
|
||
|
||
interface StepConfig {
|
||
duration?: number
|
||
timingFunction?: string
|
||
delay?: number
|
||
needLayout?: boolean
|
||
transformOrigin?: string
|
||
}
|
||
interface StepAnimate {
|
||
styles?: Styles
|
||
config?: StepConfig
|
||
}
|
||
interface StepAnimates {
|
||
[key: number]: StepAnimate
|
||
}
|
||
interface CreateAnimationOptions extends UniApp.CreateAnimationOptions {
|
||
ref?: string
|
||
}
|
||
|
||
type Callback = (time: number) => void
|
||
const animateTypes1 : AnimationTypes[] = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d',
|
||
'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY',
|
||
'translateZ'
|
||
]
|
||
const animateTypes2 : AnimationTypes[] = ['opacity', 'backgroundColor']
|
||
const animateTypes3 : AnimationTypes[] = ['width', 'height', 'left', 'right', 'top', 'bottom']
|
||
|
||
class LimeAnimation {
|
||
ref : any
|
||
context : any
|
||
options : UniApp.CreateAnimationOptions
|
||
// stack : any[] = []
|
||
next : number = 0
|
||
currentStepAnimates : StepAnimates = {}
|
||
duration : number = 0
|
||
constructor(options : CreateAnimationOptions) {
|
||
const {ref} = options
|
||
this.ref = ref
|
||
this.options = options
|
||
}
|
||
addAnimate(type : AnimationTypes, args: (string | number)[]) {
|
||
let aniObj = this.currentStepAnimates[this.next]
|
||
let stepAnimate:StepAnimate = {}
|
||
if (!aniObj) {
|
||
stepAnimate = {styles: {}, config: {}}
|
||
} else {
|
||
stepAnimate = aniObj
|
||
}
|
||
|
||
if (animateTypes1.includes(type)) {
|
||
if (!stepAnimate.styles.transform) {
|
||
stepAnimate.styles.transform = ''
|
||
}
|
||
let unit = ''
|
||
if (type === 'rotate') {
|
||
unit = 'deg'
|
||
}
|
||
stepAnimate.styles.transform += `${type}(${args.map((v: number) => v + unit).join(',')}) `
|
||
} else {
|
||
stepAnimate.styles[type] = `${args.join(',')}`
|
||
}
|
||
this.currentStepAnimates[this.next] = stepAnimate
|
||
}
|
||
animateRun(styles: Styles = {}, config:StepConfig = {}, ref: any) {
|
||
const el = ref || this.ref
|
||
if (!el) return
|
||
return new Promise((resolve) => {
|
||
const time = +new Date()
|
||
nvueAnimation.transition(el, {
|
||
styles,
|
||
...config
|
||
}, () => {
|
||
resolve(+new Date() - time)
|
||
})
|
||
})
|
||
}
|
||
nextAnimate(animates: StepAnimates, step: number = 0, ref: any, cb: Callback) {
|
||
let obj = animates[step]
|
||
if (obj) {
|
||
let { styles, config } = obj
|
||
// this.duration += config.duration
|
||
this.animateRun(styles, config, ref).then((time: number) => {
|
||
step += 1
|
||
this.duration += time
|
||
this.nextAnimate(animates, step, ref, cb)
|
||
})
|
||
} else {
|
||
this.currentStepAnimates = {}
|
||
cb && cb(this.duration)
|
||
}
|
||
}
|
||
step(config:StepConfig = {}) {
|
||
this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config)
|
||
this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin
|
||
this.next++
|
||
return this
|
||
}
|
||
export(ref: any, cb?: Callback) {
|
||
ref = ref || this.ref
|
||
if(!ref) return
|
||
this.duration = 0
|
||
this.next = 0
|
||
this.nextAnimate(this.currentStepAnimates, 0, ref, cb)
|
||
return null
|
||
}
|
||
}
|
||
|
||
|
||
animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => {
|
||
LimeAnimation.prototype[type] = function(...args: (string | number)[]) {
|
||
this.addAnimate(type, args)
|
||
return this
|
||
}
|
||
})
|
||
// #endif
|
||
export function createAnimation(options : CreateAnimationOptions) {
|
||
// #ifndef APP-NVUE
|
||
// 在iOS10+QQ小程序平台下,传给原生的对象一定是个普通对象而不是Proxy对象,否则会报parameter should be Object instead of ProxyObject的错误
|
||
return uni.createAnimation({ ...options })
|
||
// #endif
|
||
// #ifdef APP-NVUE
|
||
return new LimeAnimation(options)
|
||
// #endif
|
||
} |