JSFiddle - React, Tailwind, and code Playground
CSS
body{ background-color: ivory; }
canvas{border:1px solid red;}
JavaScript
function test(src){
var canvas=document.createElement("canvas");
var ctx=canvas.getContext("2d");
var img=new Image();
img.onload=function(){
var n_w = 400,
n_h = Math.round(img.height * (n_w/img.width));
var det = Math.ceil(Math.log(img.width/n_w) / Math.log(2));
canvas.width=n_w
canvas.height=n_h
var cx = step(img, det, img.width, img.height, n_w, n_h)
ctx.drawImage(cx, 0, 0, n_w, n_h)
document.body.appendChild(canvas)
}
img.src=src
}
// 3 large images
test("http://openwalls.com/image/17342/colored_lines_on_blue_background_1920x1200.jpg")
test('http://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Equus_quagga_%28Namutoni%2C_2012%29.jpg/1280px-Equus_quagga_%28Namutoni%2C_2012%29.jpg')
test('http://i.imgur.com/BqOquPn.jpg')
function step(img, num, w, h, nw, nh){
if ( nw/w >= 1 && nh/h >= 1 ) return img;
var oc = document.createElement('canvas'),
octx = oc.getContext('2d'),
can = document.createElement('canvas'),
ctx = can.getContext('2d'),
mult = 1;
num = Math.max(0, num-1);
oc.width = w * 0.5;
oc.height = h * 0.5;
octx.drawImage(img, 0, 0, oc.width, oc.height);
if ( num ) {
for ( var i = 1; i<num; i++ ) {
octx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5);
mult = mult * 0.5;
}
}
can.width=nw;
can.height=nh;
ctx.drawImage(oc, 0, 0, oc.width * mult, oc.height * mult, 0, 0, nw, nh);
return can;
}