meskens.simongmail.com / Crisp Pixel Zoom

// ==UserScript==
// @name       Crisp Pixel Zoom
// @namespace  http://game-designer.org/
// @version    2.12
// @description  crispy pixel goodness
// @match http://wayofthepixel.net/*
// @match http://www.wayofthepixel.net/*
// @match http://www.pixeljoint.com/pixelart/*
// @match http://pixeljoint.com/pixelart/*
// ==/UserScript==

/*global window, document, Image, requestAnimationFrame, $ */

var isPixelation = window.location.host.indexOf('wayofthepixel') > -1;
var isPixeljoint = window.location.host.indexOf('pixeljoint') > -1;
var isImageTab = document.getElementsByTagName('img').length === 1 && document.body.children.length === 1;

window.addEventListener('load', function () {
    var zoomClass = 'GDPxZoom';
    var defaultZoom = 1;
    var renderList = [];

    /**
     * Initialize the canvas
     */
    function init() {
        //Create the wrapper
        var wrapper = document.createElement('div');
        wrapper.style.display = 'inline-block';
        wrapper.style.position = 'relative';
        wrapper.style.verticalAlign = 'baseline';

        this.parentElement.insertBefore(wrapper, this);
        wrapper.appendChild(this);

        //Make the image invisible
        this.style.opacity = 0;
        this.style.display = 'block';
        this.scale = defaultZoom;

        //Render the canvas underneath
        this.canvas = document.createElement('canvas');
        this.parentElement.insertBefore(this.canvas, this);
        this.canvas.style.position = 'absolute';
        this.canvas.style.top = 0;
        this.canvas.style.left = 0;

        this.width = this.canvas.width = this.naturalWidth * this.scale;
        this.height = this.canvas.height = this.naturalHeight * this.scale;
    }

    function render() {
        this.canvas.width = this.width;
        this.canvas.height = this.height;

        var ctx = this.canvas.getContext('2d');
        ctx.mozImageSmoothingEnabled = false;
        ctx.webkitImageSmoothingEnabled = false;
        ctx.msImageSmoothingEnabled = false;
        ctx.imageSmoothingEnabled = false;
        ctx.scale(this.width / this.naturalWidth, this.height / this.naturalHeight);
        ctx.drawImage(this, 0, 0);
    }

    function zoom(ev) {
        click.call(this);

        if (ev.ctrlKey || ev.shiftKey) {
            this.scale = Math.max(1, this.scale - 1);
        } else if (ev.altKey) {
            this.scale = 1;
        } else {
            this.scale += 1;
        }

        this.width = this.canvas.width = this.naturalWidth * this.scale;
        this.height = this.canvas.height = this.naturalHeight * this.scale;
    }

    function click() {
        if (renderList.indexOf(this) < 0) {
            renderList.push(this);
            init.call(this);
        }
    }

    var elements = [];
    if (isImageTab) {
        elements = document.getElementsByTagName('img');
    } else if (isPixelation) {
        elements = document.body.getElementsByClassName('zoom');
    } else if (isPixeljoint) {
        elements = [document.getElementById('mainimg'), document.getElementById('smallimg')];
    } else {
        elements = document.body.getElementsByClassName(zoomClass);
    }

    [].forEach.call(elements, function (img) {
        if (isPixeljoint) {
            click.call(img);
        } else if (!isPixelation || isImageTab) {
            img.addEventListener('click', zoom);
        } else {
            img.addEventListener('click', click);
        }
    });

    var loop = function () {
        renderList.forEach(function (img) {
            render.call(img);
        });

        requestAnimationFrame(loop);
    };

    requestAnimationFrame(loop);
});