Skip to content

动画插件

transition

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

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

动画插件:某些数字,在一段时间内,从一个值变化到另一个值

思路

本质就是数值的变化:

  • 运动次数 = (总时间 / 间隔时间duration);
  • 每次运动距离 = (总距离 / 运动次数);
  • 每次运动的时候,把当前的值记录,传递给用户。(只处理数据,dom的绑定交给使用者)
js
if (!this.myPlugin) {
    this.myPlugin = {};
}
/**
 * 动画
 * @param {object} option 配置对象
 */
this.myPlugin.Animate = function (option) {
    //默认配置
    var defaultOption = {
        duration: 16, //默认间隔时间,单位毫秒
        total: 1000, //默认总时间
        begin: {}, //初始值
        end: {} //终止值
    };
    this.option = myPlugin.mixin(defaultOption, option);
    this.timer = null; //计时器的id
    //运动总次数
    this.number = Math.ceil(this.option.total / this.option.duration);
    //当前运动次数
    this.curNumber = 0;
    //当前状态
    this.curData = myPlugin.clone(this.option.begin);
    //所有属性运动的总距离
    this.distance = {};
    //所有属性每次运动的距离
    this.everyDistance = {};
    for (var prop in this.option.begin) {
        this.distance[prop] = this.option.end[prop] - this.option.begin[prop];
        this.everyDistance[prop] = this.distance[prop] / this.number;
    }
}
/**
 * 开始动画
 */
this.myPlugin.Animate.prototype.start = function () {
    if (this.timer || this.curNumber === this.number) {
        return; //如果之前已经存在计时器,则不做任何处理
    }
    if (this.option.onstart) {
        this.option.onstart.call(that);
    }
    var that = this;
    this.timer = setInterval(function () {
        //改变that.curData
        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);
        }
        if (that.curNumber === that.number) {
            //等于了总次数
            that.stop();
            if (that.option.onover) {
                that.option.onover.call(that);
            }
        }
    }, this.option.duration);
}

/**
 * 停止动画
 */
this.myPlugin.Animate.prototype.stop = function () {
    clearInterval(this.timer);
    this.timer = null;
}

使用

html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .item {
            width: 100px;
            height: 100px;
            position: absolute;
            left: 100px;
            top: 100px;
            border: 2px solid;
            background: #000;
        }
    </style>
</head>

<body>
    <div class="item">

    </div>
    <p>
        <button id="btnBegin">开始</button>
        <button id="btnStop">停止</button>
    </p>
    <script src="../../plugin/helpers.js"></script>
    <script src="../../plugin/animate.js"></script>
    <script>
        var div = document.querySelector("div");
        var animate = new this.myPlugin.Animate({
            duration: 30,
            total: 5000,
            begin: {
                left: 100,
                top: 100,
                r: 0,
                g: 0,
                b: 0
            },
            end: {
                left: 1000,
                top: 500,
                r: 200,
                g: 200,
                b: 200
            },
            onstart: function() {
                console.log("开始");
            },
            //当每次发生变化时
            onmove: function() {
                div.style.left = this.curData.left + "px";
                div.style.top = this.curData.top + "px";
                div.style.background = `rgb(${this.curData.r},${this.curData.g},${this.curData.b})`;
            },
            //结束事件
            onover: function() {
                console.log("结束");
            }
        });

        btnBegin.onclick = function() {
            animate.start();
        }

        btnStop.onclick = function() {
            animate.stop();
        }
    </script>
</body>

</html>

MIT License