3000ms で、800pixcel を水平移動する。その2か3
正直なところ遅延など多くないだろうと高をくくっていた。
setInterval よりも setTimeout の遅延があるどろうとおもい、それで実験。
そして遅延は、思いのほか大きい。
必要なパラメータは、把握した。
<!DOCTYPE html> <title>遅延時間を考えて移動する</title> <meta charset="UTF-8"> <style> #invader { list-style : none; position: absolute; margin : 0; padding: 0; top : 0px; left: 3px; } #invader li { margin : 0; padding : 0; display : none; } </style> <ol id ="invader"> <li class="type1 v"> <img id ="inv3" alt="インベーダ" src="data:image/gif;base64, R0lGODlhMAAYAIAAAP8ntf///yH5BAEAAAEALAAAAAAwABgAAAJijI95wO2sopzqWUCzXtft 34Vi8yHjeZUcymJgC3tZTLtUHWth9fDp3PGREjvgz9QjBo04lK7JekJPKkMReaxiLcKkdutd cb+BMdgmhlTNabQ1/JKdu24VW3L/5unkOVNNUQAAOw=="> <li class="type2"> <img id="inv3o" alt="インベーダ" src="data:image/gif;base64, R0lGODlhMAAYAIAAAP8ntf///yH5BAEAAAEALAAAAAAwABgAAAJmjI95wO2sopzqWUCzXtft 34Vi8yHjeZUcymJgC3tZTLtUHWth9fDp3PGREjvgz9QjBo04lK7JekJPKqUMea3ektihdps1 WL6SMRNCXnkn5nSgzeaW4NZ1HQ22d/FCfll+Z9MnaFAAADs="> </ol> <canvas id="hoge" width="800" height="200"></canvas> <p>遅延時間:<input type="text" value="0" id="fuga"></p> <script> var changePattern = (function () { var pattern = document.querySelectorAll ('#invader > li'); var state = 0; var max = 2; Array.prototype.forEach.call ( pattern, function (e) { e.style.display = 'none'; } ); function change () { pattern[state].style.display = 'none'; state = (state + 1) % max; pattern[state].style.display = 'inline'; } change (); return change; }) (); setInterval (changePattern, 200); var moveInvader = (function (time, distance, interval) { var style = document.querySelector ('#invader').style; var x = 0; var y = 30; var max_jump = 3; //遅延があった場合の最大間引き回数 var step = (distance / time) * interval; //移動量 var err = 0; //1回の移動ででる端数移動量 var count = 0; // コールバックされた回数(遅延時間を計算するため) var startTime = null; //スタート時間(遅延時間を計算するため) // 移動する function move (timeStamp) { var mv = step + err; // 端数も含める var ix = Math.floor (mv); // 移動量(整数) var jump; // 遅延が発生した場合に飛び越す回数 var delay = (timeStamp - startTime) - interval * count; //遅延時間の計算 // 遅延がある場合 if (0 < delay) { jump = Math.floor (delay / interval); //何回分のコールバックが不足していたか if (max_jump < jump) {//遅延が大きすぎる場合、抑制する jump = max_jump; } count += jump; //コールバックを間引きしたことにする err += jump * step; //誤差に含めてしまう } document.getElementById('fuga').value = delay; err = mv % 1; x += ix; count++; return (distance < x) ? true: setPosition (); } function setPosition () { style.left = x + 'px'; style.top = y + 'px'; } function loop () { var timeStamp = (new Date).getTime (); if (! move (timeStamp)) setTimeout (loop, interval); } setPosition (); startTime = (new Date).getTime (); loop (); }) (3000, 800, 10); </script>