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>
--------------------------------------------------------------