JSFiddle - React, Tailwind, and code Playground

by blparker

HTML

<canvas id='canvas' width='300' height='300'></canvas>

<div onclick='PEN.clear()'>Clear</div>

CSS

canvas { background:gray }
div { width:100px; height:100px; margin-top:100px; border:1px solid black }

JavaScript

// Constructor
// CH: Define methods with prototype to save memory?

function Pen(new_context) {
    var tool = this;
    var context = new_context;
    this.started = false;
    var move_count = 0;
    context.lineWidth = 5;
    context.lineJoin = 'round';
    context.lineCap = 'round';
    var lastx = 0;
    var lasty = 0;
    // create an in-memory canvas
    var memCanvas = document.createElement('canvas');
    memCanvas.width = 300;
    memCanvas.height = 300;
    var memCtx = memCanvas.getContext('2d');
    this.points = [];

    this.mousedown = function(ev) {
        tool.points.push({
            x: ev._x,
            y: ev._y
        });
        tool.started = true;
    };

    this.mousemove = function(ev) {
        if (tool.started) {
            context.clearRect(0, 0, 300, 300);
            // put back the saved content
            context.drawImage(memCanvas, 0, 0);
            tool.points.push({
                x: ev._x,
                y: ev._y
            });
            drawPoints(context, tool.points);
        }
    };

    this.mouseup = function(ev) {
        if (tool.started) {
            tool.started = false;
            // When the pen is done, save the resulting context
            // to the in-memory canvas
            memCtx.clearRect(0, 0, 300, 300);
            memCtx.drawImage(canvas, 0, 0);
            tool.points = [];
        }
    };

    // clear both canvases!
    this.clear = function() {
        context.clearRect(0, 0, 300, 300);
        memCtx.clearRect(0, 0, 300, 300);
    };
}

// The general-purpose event handler. This function determines the mouse position relative to the canvas element.

function ev_canvas(ev) {
    if (false) {
        ev._x = ev.touches[0].clientX;
        ev._y = ev.touches[0].clientY; // CH: Is there a better way to do this?
    }
    else if (ev.layerX || ev.layerX == 0) { // Firefox
        ev._x = ev.layerX;
        ev._y = ev.layerY;
    }
    else if (ev.offsetX || ev.offsetX == 0) { //...