遅延感知しながら移動する。
書いてみてから、今!気づく!
時間から移動位置を決めるのではなく、移動量を得て移動する!
ですね。
アホな考えだった。休むに似たり。
なんだよ〜俺!
あぁ〜。
終了していなかったのでコードを修正。
<!DOCTYPE html> <title>遅延時間を考えて移動する</title> <meta charset="UTF-8"> <style> li { position: relative; left : 0; } </style> <ol id="invader"> <li> ease: <img class ="invader" alt="ease" src="data:image/gif;base64, R0lGODlhMAAYAIAAAP8ntf///yH5BAEAAAEALAAAAAAwABgAAAJijI95wO2sopzqWUCzXtft 34Vi8yHjeZUcymJgC3tZTLtUHWth9fDp3PGREjvgz9QjBo04lK7JekJPKkMReaxiLcKkdutd cb+BMdgmhlTNabQ1/JKdu24VW3L/5unkOVNNUQAAOw=="> <li> liner: <img class ="invader" alt="linear" src="data:image/gif;base64, R0lGODlhMAAYAIAAAP8ntf///yH5BAEAAAEALAAAAAAwABgAAAJijI95wO2sopzqWUCzXtft 34Vi8yHjeZUcymJgC3tZTLtUHWth9fDp3PGREjvgz9QjBo04lK7JekJPKkMReaxiLcKkdutd cb+BMdgmhlTNabQ1/JKdu24VW3L/5unkOVNNUQAAOw=="> <li> ease-in: <img class ="invader" alt="ease-in" src="data:image/gif;base64, R0lGODlhMAAYAIAAAP8ntf///yH5BAEAAAEALAAAAAAwABgAAAJijI95wO2sopzqWUCzXtft 34Vi8yHjeZUcymJgC3tZTLtUHWth9fDp3PGREjvgz9QjBo04lK7JekJPKkMReaxiLcKkdutd cb+BMdgmhlTNabQ1/JKdu24VW3L/5unkOVNNUQAAOw=="> <li> ease-out: <img class ="invader" alt="ease-out" src="data:image/gif;base64, R0lGODlhMAAYAIAAAP8ntf///yH5BAEAAAEALAAAAAAwABgAAAJijI95wO2sopzqWUCzXtft 34Vi8yHjeZUcymJgC3tZTLtUHWth9fDp3PGREjvgz9QjBo04lK7JekJPKkMReaxiLcKkdutd cb+BMdgmhlTNabQ1/JKdu24VW3L/5unkOVNNUQAAOw=="> </ol> <script> // requestAnimationFrame if ('undefined' === typeof this.requestAnimationFrame) { this.requestAnimationFrame = this.requestAnimationFrame || this.webkitRequestAnimationFrame|| this.mozRequestAnimationFrame || this.oRequestAnimationFrame || this.msRequestAnimationFrame || function (callback, that) { var tmpFunc = function () { var timestamp = +(new Date); //(new Date).getTime (); callback (timestamp); //callback.call (that, timestamp); }; win.setTimeout (tmpFunc, Math.floor (1000 / 60)); }; } (function () { //__________ // ベジェ曲線を更に高速化したもの (始点:0・終点限定:1)戻り値は[x,y] //cubic-bezier function cubic_bezier (x1, y1, x2, y2) { if (x1 < 0 || 1 < x1 || x2 < 0 || 1 < x2) throw new Error ('範囲外'); return function (t) { var a = (1 - t); var b = 3 * a * t; var A = b * a; var B = b * t; var C = t * t * t; return [ A * x1 + B * x2 + C, A * y1 + B * y2 + C ]; }; } // 呼び出す関数を1つにまとめる。 function cbFuncCollector (/* cbFunc0, cbFunc1, ..*/) { var cbFuncStock = Array.prototype.slice.call (arguments, 0); return function (i) { for (var n = 0, func; func = cbFuncStock [n++]; ) { func (i); } }; } //_________________ // アニメーションの遅延を感知しながら補う function CompensateInterval (cbFunc, duration, timingFunc, delay, maxCompensate, interval, through) { this.cbFunc = cbFunc; // コールバック this.duration = duration; // 作動時間 this.timingFunc = timingFunc; // ベジェ曲線の関数 this.delay = delay; // ms 秒後に開始 this.maxCompensate = maxCompensate; //最大補間回数 this.interval = interval; // 間隔 this.through = through; // 遅延が発生したならコールバックを呼ばない (default: true) this.step = 1 / (duration / interval); this.count = null; this.startTime = null; this.timeCount = null; //ベジェ曲線に渡す引数(time) } function loop (timeStamp) { var max = this.maxCompensate; var delay = (timeStamp - this.startTime) - this.interval * this.count; var endF = false; var r; do { if (max === this.maxCompensate || ! this.through) { //遅延中&スルーするなら何もしない r = this.timingFunc (this.timeCount); this.cbFunc (r[0], r[1], this.timeCount); } if (endF || this.timeCount ===1) return; this.timeCount += this.step; if (1 < this.timeCount) { //確実に1にして終わらせる this.timeCount = 1; endF = true; } this.count += 1; if (0 === max++) //打ち切り break; delay -= this.interval; } while (0 < delay); // 遅延があれば return requestAnimationFrame (loop.bind (this)); } function CompensateInterval_init () { this.count = 0; this.timeCount = 0; this.startTime = (new Date).getTime (); loop.call (this); } function CompensateInterval_start () { if (this.delay) setTimeout (CompensateInterval_init.bind (this), this.delay); else CompensateInterval_init.call (this); } function CompensateInterval_create (cbFunc, duration, timingFunc, delay, maxCompensate, interval, through) { if (3 > arguments.length) throw new Error; switch (typeof timingFunc) { case 'function' : break; case 'string' : switch (timingFunc) { case 'ease' : timingFunc = cubic_bezier (0.25, 0.1, 0.25, 1.0); break; case 'linear' : timingFunc = cubic_bezier (0.0, 0.0, 1.0, 1.0); break; case 'ease-in' : timingFunc = cubic_bezier (0.42, 0, 1.0, 1.0); break; case 'ease-out' : timingFunc = cubic_bezier (0, 0, 0.58, 1.0); break; default : throw new Error ('Not know name'); } break; default : throw new Error ('Syntax error'); } return new CompensateInterval (cbFunc, duration, timingFunc, delay || 0, maxCompensate || 3, interval || 1000 / 60, through || true); } CompensateInterval.prototype.start = CompensateInterval_start; CompensateInterval.create = CompensateInterval_create; this.CompensateInterval = CompensateInterval; //_________________ this.cubic_bezier = cubic_bezier; this.cbFuncCollect = cbFuncCollector; }) (); //############################################ // 右に移動させる var move = (function (e) { var style = e.style; var max = 800; return function (x, y, t) { style.left = Math.floor (x * max) + 'px'; }; }); Array.prototype.forEach.call ( document.querySelectorAll ('#invader > li'), function (e, i) { (CompensateInterval.create (move(e), 3000, this[i]).start ()); }, ['ease', 'linear', 'ease-in', 'ease-out' ]) </script>