Pixelate

by kuyabiye

HTML

<canvas id="canvas" width="500" height="400"></canvas>
<br>
<input id="blocks" type="range" min="1" max="50" value="5">
<input id="animate" type="button" value="Animate">

CSS

canvas {
    image-rendering: optimizeSpeed;
    image-rendering: -moz-crisp-edges;
    image-rendering: -webkit-optimize-contrast;
    image-rendering: -o-crisp-edges;
    image-rendering: crisp-edges;
    -ms-interpolation-mode: nearest-neighbor;
}

JavaScript

/// (C) Ken Fyrstenberg Nilsen, Abdias Software, CC3.0-attribute.
var ctx = canvas.getContext('2d'),
    img = new Image(),
    play = false;

/// turn off image smoothing - this will give the pixelated effect
ctx.mozImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;

/// wait until image is actually available
img.onload = pixelate;

/// some image, we are not struck with CORS restrictions as we
/// do not use pixel buffer to pixelate, so any image will do
img.src = 'http://i.imgur.com/w1yg6qo.jpg';

/// MAIN function
function pixelate(v) {

    /// if in play mode use that value, else use slider value
    var size = (play ? v : blocks.value) * 0.01,

        /// cache scaled width and height
        w = canvas.width * size,
        h = canvas.height * size;

    /// draw original image to the scaled size
    ctx.drawImage(img, 0, 0, w, h);

    /// then draw that scaled image thumb back to fill canvas
    /// As smoothing is off the result will be pixelated
    ctx.drawImage(canvas, 0, 0, w, h, 0, 0, canvas.width, canvas.height);
}

/// This runs the demo animation to give an impression of
/// performance.
function toggleAnim() {

    /// limit blocksize as we don't want to animate tiny blocks
    var v = Math.min(25, parseInt(blocks.value, 10)),
        dx = 0.5; /// "speed"

    /// toggle play flag set by button "Animate"
    play = !play;

    /// and update button's text
    animate.value = play ? 'Stop' : 'Animate';

    /// if in play mode start loop
    if (play === true) anim();

    /// animation loop
    function anim() {

        /// increase or decrease value
        v += dx;

        /// if at min or max reverse delta
        if (v <= 1 || v > 25) dx = -dx;

        /// pixelate image with current value
        pixelate(v);

        /// loop
        if (play === true) requestAnimationFrame(anim);
    }
}

/// event listeneners for slider and button
blocks.addEventListener('change', pixelate,...