Перемещение изображений по холсту

by SerGen

HTML

<canvas></canvas>

<!--
В Хромах края передвигаемого изображения не сдвигаются субпиксельно, при этом его содержимое сглаживается нормально.

Чтобы этого избежать, можно оставлять один прозрачный пиксель вокруг передвигаемой картинки.

Эта проблема незаметна, если форма залитой части изображения сложнее прямоугольной.
-->

CSS

html, body {
  background-color: #1e2124;
  height: 100%;
}

canvas {
  position: fixed;
}

JavaScript

window.raf = (function(){
  return  window.requestAnimationFrame       ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    ||
          window.oRequestAnimationFrame      ||
          window.msRequestAnimationFrame     ||
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();

(function(win, d) {

  var i1 = new Image();
  var i2 = new Image();

  var canvas = document.getElementsByTagName('canvas')[0];
  var ctx = canvas.getContext('2d');

  var delta = 0;

  init();
  onResize();

  win.addEventListener('load', onResize, false);
  win.addEventListener('resize', onResize, false);

  function init() {
    i1.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6AgMAAAD1grKuAAAACVBMVEX///8AAADy8vK9KB7sAAAAYklEQVRo3u3bIREAIAAEQQwR8Wj6UIKUGBK8gWH2/Ea4It2ttrRH/FhZ8/hesnie53me53me53me53me53me53me53me53me53me53me53me53me53n+Zx//e4/8h7mX7rYB7eeVnBk8RgoAAAAASUVORK5CYII=';
    i2.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPwAAAD8AgMAAAAuxSH0AAAADFBMVEUAAAD///8AAADy8vILosC6AAAAAXRSTlMAQObYZgAAAHNJREFUaN7t2zERgDAQAEFM4IwgBh+YYIbBHw00UfDf/CR7/Uq4JdvaMm08n/T7Fe2s4Z8v1tv93WIdPM/zPM/zPM/zPM/zPM/zPM/zPM/zPM/zPM/zPM/zPM/zPM/zPM/zPD+wD/97Rf7DuC/xf/Iz+2Q/RPGSpNhdTh4AAAAASUVORK5CYII=';

    raf(update);
  }

  function update() {
    delta = delta + 0.1;

    ctx.fillRect(0, 0, canvas.width, canvas.height);

    ctx.fillStyle = "#1e2124";
    ctx.drawImage(i1, pos(0, delta, 0.25), pos(0, delta, 0.25));
    ctx.drawImage(i2, pos(-1, delta, 0.25), pos(269, delta, 0.25));

    raf(update);
  }

  function pos(base, delta, speed) {
    return base + delta * speed;
  }

  function onResize() {
    canvas.width = win.innerWidth;
    canvas.height = win.innerHeight;
  }

})(window, document);