25-动画插件封装

39 阅读1分钟

动画插件

  • transiton
  1. css3的属性,有兼容性问题
  2. 动画难以停止,难以恢复

动画: 一个元素的某些css属性,在一段时间内,从一个值变化到另一个值

  • 动画插件: 某些数字,在一段时间内,从一个值变化到另一个值
/**
 * 动画
 * @param { object } opts 配置对象
*/
function Animate(opts) {
    var defaultOpts = {
        duration: 16,//默认间隔时间
        total: 1000,//默认总时间
        begin: {},//初始值
        end: {}//终止值
    }
    this.option = Object.assign(defaultOpts, opts);
    this.timer = null;//计时器的id
    this.number = Math.ceil(this.option.total / this.option.duration);//运动的总次数
    this.curNumber = 0;//当前运动的次数
    this.curData = {...this.option.begin}//当前状态
    this.distance = {};// 所有属性的运动总距离
    this.everyDistance = {};// 所有属性每次运动的距离
    for(var key in this.option.begin) {
        this.distance[key] = this.option.end[key] - this.option.begin[key];
        this.everyDistance[key] = this.distance[key] / this.number;//每个运动的距离、总次数
    }
}

// 开始动画
Animate.prototype.start = function() {
    console.log(this.timer);
    //之前有动画,不做任何处理 或者达到运动总次数
    if(this.timer || this.curNumber === this.number) return;
    
    if(this.option.onStart) {
        this.option.onStart.call(this);
    }
    let that = this;
    this.timer = setInterval(function() {
        that.curNumber++;//当前运动次数+1
        // 每次运动改变当前状态
        for(var prop in that.curData) {
            if(that.curNumber === that.number) {//最后一次运动了
                // 小数可能不精确,最后处理为最终值
                that.curData[prop] = that.option.end[prop];
            }else {
                that.curData[prop] += that.everyDistance[prop];
            }
        }
        if(that.option.onMove) {
            that.option.onMove.call(that, that.curData);
        }
        if(that.curNumber === that.number) {//如果等于总次数不在运动
            that.stop();  
            that.onEnd && that.onEnd();
        }
    }, this.option.duration);
}
// 停止动画
Animate.prototype.stop = function() {
    clearInterval(this.timer);
    this.timer = null;
}

let div = document.querySelector('.item');
console.log(div);
let animate = new Animate({
    duration: 30,//动画时间
    total: 3000,
    begin: {
        left: 100,
        top: 100
    },
    end: {
        left: 800,
        top: 600
    },
    onStart: function () {
        console.log("开始了")
    },
    onMove: function(data) {
        console.log("变化", this.curData);
        div.style.left = this.curData.left + 'px';
        div.style.top = this.curData.top + 'px';
    },
    onEnd: function() {
        console.log("结束");
    }
});
console.log(animate);
  • index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .item {
            width: 100px;
            height: 100px;
            position: absolute;
            left: 100px;
            top: 100px;
            background-color: aquamarine;
        }
    </style>
</head>
<body>
    <div class="item"></div>
    <script src="./index.js"></script>
</body>
</html>
  • animate.start() 启动
  • animate.stop() 停止