iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 21
0

一直以來都以為要用 setTimeout 或 setInterval 來製作動畫,但 setTimeout 最快也只能到 10 毫秒,可能造成畫面遺失的問題,而我們就可以用 requestAnimationFrame 這個方法。 一起來看一下 MicroSoft Developer Network 提供的這個例子,在裡面學到不少東西。

支援度
說明:
window.performance.now 高精準的時間戳,可以取到一毫秒的千分之一
elm.style.left = ((lpos += 3) % 600) + "px"; 利用累加方式調整矩形位置,並用餘數值來限定範圍
requestId = window.requestAFrame(render) 計算 requestAFrame 執行的次數, requestAFrame 的回傳值會從 1 開始持續往上累加

<body onload="init();">

<div id="animated">Hello there.</div>
<button onclick="start()">Start</button>
<button onclick="stop()">Stop</button>
</body>
div { 
  position: absolute;
  left: 10px;
  top:100px;
  padding: 50px;
  background: crimson;
  color: white; 
  }
//多瀏覽器的支援
    window.cancelAFrame = (function () {
        return window.cancelAnimationFrame ||
                window.webkitCancelAnimationFrame ||
                window.mozCancelAnimationFrame ||
                window.oCancelAnimationFrame ||
                function (id) {
                    window.clearTimeout(id);
                };
    })();

    var requestId = 0;
    var startime = 0;
    var lpos = 0;
    var elm;

    function init() {
        elm = document.getElementById("animated");
    }
    
    function render() {
        elm.style.left = ((lpos += 3) % 600) + "px";
        requestId = window.requestAFrame(render);
    }

    function start() {
        if (window.performance.now) {
            startime = window.performance.now();
        } else {
            startime = Date.now();
        }
        requestId = window.requestAFrame(render);
    }
    function stop() {
        if (requestId)
            window.cancelAFrame(requestId);        
    }


    // handle multiple browsers for requestAnimationFrame()
    window.requestAFrame = (function () {
        return window.requestAnimationFrame ||
                window.webkitRequestAnimationFrame ||
                window.mozRequestAnimationFrame ||
                window.oRequestAnimationFrame ||
                // if all else fails, use setTimeout
                function (callback) {
                    return window.setTimeout(callback, 1000 / 60); // shoot for 60 fps
                };
    })();

    // handle multiple browsers for cancelAnimationFrame()
    

參考資料:指令碼式動畫的計時控制項


上一篇
一個 JS 學習者的日常 day 19
下一篇
一個 JS 學習者的日常 day 21
系列文
一個 JS 學習者的日常30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言