2017년 1월 3일 화요일

Timing Control For script based Animations

描画のアニメーションは、setInterval, setTimeoutを使っていたが
requestAnimationFrameを使うと
ブラウザの負荷状況によって最も適したタイミングでアニメーションを開始し、
バックグラウンドにある場合は、速度が低くなるため、メモリ消費を抑えることができる
アニメーションを終了したい場合は requestCanselAnimationFrameを呼び出す


https://liginc.co.jp/web/js/130758

requestAnimationFrameの特徴
  • ブラウザの描画更新単位と同じ単位で呼び出される
  • 次の再描画が行われる前に次のアニメーションをする関数を呼び出す
  • タブが非アクティブの時はFPSを落とす
setInteval、setTimeoutの特徴
  • ブラウザで準備ができていなくても必ず実行
  • タブが非アクティブの状態でも常に実行
------------------------------------------
loop();
function loop() {
    console.log('requestAnimationFrame直前');
    requestId = window.requestAnimationFrame(loop);
    var currentTime = new Date().getTime();
    var now = window.performance.now();
    console.log('now() :' + (now));
    //経過時刻を取得
    var status = currentTime - startTime // 描画開始時刻から経過時刻を引く
    // 経過時間が2000ミリ秒すぎたらアニメーション終了
    if (status > 2000) {
        console.log('END!! ');
        console.log('requestId : ' + requestId);
        // loopを終了させる
        window.cancelAnimationFrame(requestId);
    }
    console.log(status);
}
---------------------------------------------------------------
canvasとrequestAnimationFrameを使いサンプル作成
---------------------------------------------------------------

        <div id="info"></div>
        <canvas id="sample" width="500" height="500"></canvas>
        <button id="move">move</button>
        <button id="stop">stop</button>      
        <script type="text/javascript">
            var startTime = new Date().getTime();
            console.log(startTime);
            (function () {
                var sample = document.getElementById('sample');
                sample.width = 500;
                sample.height = 500;
                var ctx = sample.getContext('2d');
                var sizeX = 50;
                var sizeY = 50;
                var _amount = 5;
                var _x = 0;
                var _y = 0;
                var _w = sample.width;
                var _h = sample.height;
                var requestId;

                render(_x, _y);
                document.getElementById('move').addEventListener('click', loop);
                document.getElementById('stop').addEventListener('click', stop);

                var dirX = _amount;
                var dirY = _amount * 5;

                function render(_x, _y) {
                    ctx.clearRect(0, 0, _w, _h);
                    ctx.beginPath();
                    ctx.fillRect(_x, _y, sizeX, sizeY);
                    ctx.closePath();
                }
                var start;
                function loop() {

                    if (!start) {
                        start = window.performance.now();
                    }

                    requestId = window.requestAnimationFrame(loop);

                    if (_x > _w || _x < 0) {
                        dirX *= -1;
                        _y += dirY;
                    }

                    if (_y > _h || _y < 0) {
                        dirY *= -1;
                    }
                    _x += dirX;

                    render(_x, _y);
                }

                function stop() {
                    var end = window.performance.now();
                    document.getElementById('info').innerHTML = floatFormat((end - start) / 1000, 2);
                    start = null;
                    window.cancelAnimationFrame(requestId);
                }
               
                // 小数点n位までを残す関数
                // number=対象の数値
                // n=残したい小数点以下の桁数
                function floatFormat( number, n ) {
                        var _pow = Math.pow( 10 , n ) ;
                        return Math.round( number * _pow ) / _pow ;
                }

            })();
        </script>
--------------------------------------------------------------


댓글 없음:

댓글 쓰기