按照國際慣例,先放效果圖 index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> <style> .ball{ background:linear-gradient( ...
按照國際慣例,先放效果圖
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文件中