Resize in steps

by Ed Bulikyan

HTML

<span id="info"></span>
<br>
<table>
  <tr>
    <th>Browser</th>
    <th>Canvas Downsampling</th>
    <th>Stepped</th>
  </tr>
  <tr>
    <td><img id="browser"></td>
    <td><img id="canvas"></td>
    <td><img id="stepped"></td>
  </tr>
  <tr>
    <td></td>
    <td id="time-canvas"></td>
    <td id="time-stepped"></td>
  </tr>
</table>
<h2>
Scaling Canvas:
</h2>
<img id="scale-canvas" width="100%">

JavaScript

window.performance = (window.performance || {
  offset: Date.now(),
  now: function now() {
    return Date.now() - this.offset;
  }
});

img = new Image();
img.crossOrigin = "Anonymous";
img.onload = function() {
  var width = 200;
  source_info(img, width);

  browser_scale(img, width);
  canvas_scale(img, width)
  stepped_scale(img, width, 0.5)
}
img.src = "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/A_woman_with_red_hair.jpg/685px-A_woman_with_red_hair.jpg";

function browser_scale(img, width) {
  // -- browser scaling --
  var browser = document.getElementById("browser");
  browser.width = width;
  browser.src = img.src;
}

function canvas_scale(img, width) {
  var canvas = document.createElement('canvas'),
    ctx = canvas.getContext("2d");

  // -- canvas scaling --
  var start = window.performance.now();

  canvas.width = width;
  canvas.height = canvas.width * (img.height / img.width);
  ctx.drawImage(img, 0, 0, canvas.width, canvas.height);

  document.getElementById("time-canvas").innerHTML = time_diff(start) + ' ms';
  document.getElementById("canvas").src = canvas.toDataURL();
}

function stepped_scale(img, width, step) {
  var canvas = document.createElement('canvas'),
    ctx = canvas.getContext("2d"),
    oc = document.createElement('canvas'),
    octx = oc.getContext('2d');

  // -- stepped scaling --
  var start = window.performance.now();

  canvas.width = width; // destination canvas size
  canvas.height = canvas.width * img.height / img.width;

  if (img.width * step > width) { // For performance avoid unnecessary drawing
    var mul = 1 / step;
    var cur = {
      width: Math.floor(img.width * step),
      height: Math.floor(img.height * step)
    }

    oc.width = cur.width;
    oc.height = cur.height;

    octx.drawImage(img, 0, 0, cur.width, cur.height);

    while (cur.width * step > width) {
      cur = {
      	width: Math.floor(cur.width * step),
        height: Math.floor(cur.height * step)
      };
     ...