原生js 動畫

咱們常常經過setInterval或setTimeout定時修改DOM、CSS實現動畫,瀏覽器

利用seTimeout實現的動畫在某些低端機上會出現卡頓、抖動的現象。 這種現象的產生有兩個緣由:

  • setTimeout的執行時間並非肯定的。在Javascript中, setTimeout 任務被放進了異步隊列中,只有當主線程上的任務執行完之後,纔會去檢查該隊列裏的任務是否須要開始執行,所以 setTimeout 的實際執行時間通常要比其設定的時間晚一些。
  • 刷新頻率受屏幕分辨率和屏幕尺寸的影響,所以不一樣設備的屏幕刷新頻率可能會不一樣,而 setTimeout只能設置一個固定的時間間隔,這個時間不必定和屏幕的刷新時間相同。

不過實現動畫還可使用requestAnimationFrame

requestAnimationFrame的方式的優點以下:

1.通過瀏覽器優化,動畫更流暢異步

2.窗口沒激活時,動畫將中止,省計算資源函數

3.更省電,尤爲是對移動終端優化

requestAnimationFrame最大的優點是

由系統來決定回調函數的執行時機。具體一點講,若是屏幕刷新率是60Hz,那麼回調函數就每16.7ms被執行一次,若是刷新率是75Hz,那麼這個時間間隔就變成了1000/75=13.3ms,換句話說就是,requestAnimationFrame的步伐跟着系統的刷新步伐走。它能保證回調函數在屏幕每一次的刷新間隔中只被執行一次,這樣就不會引發丟幀現象,也不會致使動畫出現卡頓的問題。動畫

實現一個div滑動的動畫,由快至慢5s結束

.sj{
    width:50px;
    height:50px;
    border:1px solid red;
    position:absolute;
    left:0
}
<div class="sj" id="sj"></div>
//ele爲要移動的盒子,target爲目標位置(像素),spd爲計數器的頻率
var ele = document.getElementById('sj')
function animate(ele,spd){
    var start = Date.now(); // remember start time
    var timer = setInterval(function() {
        var timePassed = Date.now() - start;
        var step = Math.ceil(Math.abs(timePassed - 5000)/10)
        console.log(step)
        if (timePassed >= 5000) {
            clearInterval(timer); // finish the animation after 2 seconds
            return;
        }
        ele.style.left = ele.offsetLeft + step + 'px'
    }, spd);
}
複製代碼

實現一個div滑動的動畫,由快至慢到500px結束

function animate1(ele,target,spd){
    var timer = setInterval(function() {
        var step = (target-ele.offsetLeft)/10;
        //對步長進行二次加工(大於0向上取整,小於0向下取整)
        step = step>0?Math.ceil(step):Math.floor(step);
        //動畫原理: 目標位置 = 當前位置 + 步長
        ele.style.left = ele.offsetLeft + step + "px";
        //檢測緩動動畫有沒有中止
        if(Math.abs(target-ele.offsetLeft)<=Math.abs(step)){
            //處理小數賦值
            ele.style.left = target + "px";
            clearInterval(timer);
        }
    }, spd);
}
複製代碼
相關文章
相關標籤/搜索