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) { //...