ES6封装形变类,完成连续动画

按照国际惯例,先放效果图

ES6封装形变类,完成连续动画

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index</title>
    <style>
        .ball{
            background:linear-gradient(pink 50%,lightblue 50%);/*css3线性渐变*/
            width:150px;
            height:150px;
            border-radius:50%;
        }
    </style>
</head>
<body>
    <div class="ball"></div>

    <script>
        //形变类
        class Transform{
            constructor(selector){
                this.el=document.querySelector(selector);
                this.defaultTime=Transform.config.defaultTime;//设置默认动画时长
                this.el.style.transition=`all ${ this.defaultTime }s`;//设置transition才会有动画效果
                this._queue=[];//队列,存放每一条动画
                //每次动画时,保留之前的不同类型的动画结果(直到被同类型的动画覆盖)
                this._transform={
                    rotate:"",
                    translate:"",
                    scale:""
                }
            }

            //位移
            translate(value,time){
                return this._add("translate",value,time);
            }

            //缩放
            scale(value,time){
                return this._add("scale",value,time);
            }

            //旋转
            rotate(value,time){
                return this._add("rotate",value,time);
            }

            //添加动画
            _add(type,value,time=this.defaultTime){
                this._queue.push({type,value,time});
                return this;//方便链式调用
            }

            //运动队列添加完成,开始正式动画
            done(){
                if(!this._queue.length) return;

                //把动画从队列里拿出来,先进先出
                //定时器能够解决因为浏览器渲染机制造成的动画时有时无的情况
                setTimeout(()=>{
                    const info=this._queue.shift();//弹出队列里第一个
                    this.el.style.transition=`all ${ info.time/1000 }s`;
                    this.el.style.transform=this._getTransform(info);

                    setTimeout(()=>{
                        this.done();
                    },info.time);
                },0)
            }

            //获取具体的transform动画
            _getTransform({time,value,type}){
                const _tsf=this._transform;

                switch(type){
                    case "translate":
                        _tsf.translate=`translate(${ value })`;
                        break;
                    case "scale":
                        _tsf.scale=`scale(${ value })`;
                        break;
                    case "rotate":
                        _tsf.rotate=`rotate(${ value }deg)`;
                        break;
                }
                return `${ _tsf.translate } ${ _tsf.scale } ${ _tsf.rotate }`;                
            }
        }

        //静态属性
        Transform.config={
            defaultTime:300//默认动画时长
        }

        //修改默认时长
        Transform.config.defaultTime=1000;

        //继承
        class MultiTransform extends Transform{
            //复合动画
            multi(value,time){
                return this._add("multi",value,time);
            }

            //等待
            sleep(value){
                return this._add("sleep","",value);
            }

            //重写父类中的同名方法
            _getTransform({time, value, type}){
                const _tsf=this._transform;

                switch(type){
                    case "translate":
                        _tsf.translate=`translate(${ value })`;
                        break;
                    case "scale":
                        _tsf.scale=`scale(${ value })`;
                        break;
                    case "rotate":
                        _tsf.rotate=`rotate(${ value }deg)`;
                        break;
                    case "multi":
                        value.forEach(item=>{
                            this._getTransform(item);
                        })
                        break;
                    case "sleep":
                        break;
                }
                return `${ _tsf.translate } ${ _tsf.scale } ${ _tsf.rotate }`;                
            }
        }

        //实例化
        const tf=new MultiTransform(".ball");
        tf
        .translate("100px,100px")
        .scale(2)
        .sleep(500)
        .rotate(180,1000)
        .multi([
            {
                type:"translate",
                value:"0,0"
            },
            {
                type:"scale",
                value:2
            }
        ])
        .done();

        console.log(tf);
    </script>
</body>
</html>

为了演示方便,我把代码都写到一个文件里了,大家要用的话,可以把形变类分离到单独的js文件中