#
whycq
2022-02-22 ed52313c4a5fa425846d3a67de208c209823916c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// 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
        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)
}