git @ Cat's Eye Technologies Art-Restoration-Simulator / master src / art-restoration-simulator.js
master

Tree @master (Download .tar.gz)

art-restoration-simulator.js @masterraw · history · blame

// SPDX-FileCopyrightText: Chris Pressey, the original author of this work, has dedicated it to the public domain.
// For more information, please refer to <https://unlicense.org/>
// SPDX-License-Identifier: Unlicense

function getCanvasCoordinates(event) {
    const rect = event.target.getBoundingClientRect();

    // Calculate the scale ratio in case the size due to application of
    // CSS styling is different from the canvas's internal dimensions
    const scaleX = event.target.width / rect.width;
    const scaleY = event.target.height / rect.height;

    // Adjust coordinates according to the placement of the element
    const x = Math.trunc((event.clientX - rect.left) * scaleX);
    const y = Math.trunc((event.clientY - rect.top) * scaleY);

    return [x, y];
}

var ArtRestorationSimulator = function() {
    var artCanvas;
    var artCtx;
    var filthCanvas;
    var filthCtx;
    var imageData;
    var mouseDown;

    var mask = [
        "   ***    ",
        "  ******  ",
        " ******** ",
        " *********",
        "**********",
        "**********",
        "********* ",
        " ******** ",
        "  ******  ",
        "    ***   "
    ];

    this.init = function(config) {
        /*
         * part 1: artCanvas
         */
        artCanvas = config.artCanvas;
        artCtx = artCanvas.getContext('2d');
        var bgimg = new Image();
        bgimg.onload = function() {
            artCtx.drawImage(bgimg, 0, 0, artCanvas.width, artCanvas.height);
        };
        bgimg.src = config.artUrl;

        /*
         * part 2: filthCanvas
         */
        filthCanvas = config.filthCanvas;
        filthCtx = filthCanvas.getContext('2d');

        filthCtx.clearRect(0, 0, filthCanvas.width, filthCanvas.height);
        filthCtx.fillStyle = "rgba(50,80,100,255)";
        filthCtx.fillRect(0, 0, filthCanvas.width, filthCanvas.height);
        imageData = filthCtx.getImageData(0, 0, filthCanvas.width, filthCanvas.height);

        var $this = this;
        filthCanvas.addEventListener('mousedown', function(e) {
            return $this.onmousedown(e);
        });
        filthCanvas.addEventListener('touchstart', function(e) {
            return $this.onmousedown(e.touches[0]);
        });

        filthCanvas.addEventListener('mousemove', function(e) {
            return $this.onmousemove(e);
        });
        filthCanvas.addEventListener('touchmove', function(e) {
            return $this.onmousemove(e.touches[0]);
        });

        filthCanvas.addEventListener('mouseup', function(e) {
            return $this.onmouseup(e);
        });
        filthCanvas.addEventListener('touchend', function(e) {
            return $this.onmouseup(e.touches[0]);
        });
    };

    this.onmousedown = function(event) {
        mouseDown = true;
    };

    this.onmouseup = function(event) {
        mouseDown = false;
    };

    this.onmousemove = function(event) {
        if (!mouseDown) return;
        var canvasCoords = getCanvasCoordinates(event);
        var canvasX = canvasCoords[0];
        var canvasY = canvasCoords[1];
        var range = 10;
        var w = artCanvas.width;
        for (var dx = 0; dx < range; dx++) {
            var x = canvasX - range + dx;
            for (var dy = 0; dy < range; dy++) {
                if (mask[dy].charAt(dx) !== '*') continue;
                var y = canvasY - range + dy;
                var index = (y * w + x) * 4;
                imageData.data[index + 3] -= 12;
            }
        }
        filthCtx.putImageData(imageData, 0, 0);
    };
}