使用策略模式设计一个动画模块DEMO

171 阅读1分钟

使用策略模式封装一个动画模块,启动动画时可以指定缓动函数,从而达到不通效果

//缓动函数
var easingFunc = {
    linear(t, b, c, d) {
        return c*t/d + b
    },
    easeIn(t, b, c, d) {
        return c * (t /= d) * t + b
    }
}

class Animate{
    constructor(dom) {
        this.dom = dom
        this.startTime = 0
        this.startPos = 0
        this.endPos = 0
        this.propertyName = null //动态改变的属性
        this.easing = null  //缓动函数
        this.duration = null
    }
    start(propertyName, endPos, duration, easing) {
        this.startTime = +new Date()
        this.startPos = this.dom.getBoundingClientRect()[propertyName]
        this.propertyName = propertyName
        this.endPos = endPos
        this.duration = duration
        this.easing = easingFunc[easing] //数据计算委托算法
        var timer = setInterval(() => {
            if (this.step() === false) {
                clearInterval(timer)    //动画结束,清除
            }
        }, 19)
    }
    //处理数据委托给算法
    step() {
        var t = +new Date()
        if (t >= this.duration + this.startTime) {
            this.update(this.endPos)
            return false
        }
        var pos = this.easing(t - this.startTime, this.startPos,
            this.endPos - this.startPos, this.duration)
        this.update(pos)    //更新动画
    }
    update(pos) {
        this.dom.style[this.propertyName] = pos + 'px'
    }
}
var ele = document.querySelector('div')
var animate = new Animate(ele)
animate.start('left', 500, 1000, 'easeIn')