按照国际惯例,先放效果图
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文件中