Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
28
rated 0 times [  32] [ 4]  / answers: 1 / hits: 6894  / 6 Years ago, fri, december 28, 2018, 12:00:00

I have a canvas HTML5 drawing pad.



I would like to create a button with an undo function.



How can I do it?



My idea was to have one array stack. Anytime you draw and release the mouse, it saves the canvas image to the undo array stack by push. But as I tried it, it doesn't really work... Is there a better idea?



Thank you in advance!



var canvas = document.getElementById('paint');
var ctx = canvas.getContext('2d');
var sketch = document.getElementById('sketch');
var sketch_style = getComputedStyle(sketch);

var mouse = {x: 0, y: 0};

canvas.addEventListener('mousemove', function(e) {
mouse.x = e.pageX - this.offsetLeft;
mouse.y = e.pageY - this.offsetTop;
}, false);

ctx.lineJoin = 'round';
ctx.lineCap = 'round';

ctx.strokeStyle = red;
function getColor(colour){ctx.strokeStyle = colour;}

function getSize(size){ctx.lineWidth = size;}

canvas.addEventListener('mousedown', function(e) {
ctx.beginPath();
ctx.moveTo(mouse.x, mouse.y);

canvas.addEventListener('mousemove', onPaint, false);
}, false);

canvas.addEventListener('mouseup', function() {
canvas.removeEventListener('mousemove', onPaint, false);
}, false);

var onPaint = function() {
ctx.lineTo(mouse.x, mouse.y);
ctx.stroke();
};

More From » html

 Answers
4

This is how I would do it:



The main idea is: on mouseup I'm saving the last drawn path in an array. When I click the undo button I remove the last path from the paths array. I'm deleting everything and next I draw all the paths in the paths array.



I'm using a variable drawing that at the beginning is false.
When I click on the canvas drawing is true.
on mouseup drawing is false.
Only if drawing == true I can draw.





const canvas = document.getElementById('paint');
const ctx = canvas.getContext('2d');
canvas.width = 600;
canvas.height=200;
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
ctx.strokeStyle = red;
let drawing = false;
let pathsry = [];
let points = [];

var mouse = {x: 0, y: 0};
var previous = {x: 0, y: 0};

canvas.addEventListener('mousedown', function(e) {
drawing = true;
previous = {x:mouse.x,y:mouse.y};
mouse = oMousePos(canvas, e);
points = [];
points.push({x:mouse.x,y:mouse.y})
});

canvas.addEventListener('mousemove', function(e) {
if(drawing){
previous = {x:mouse.x,y:mouse.y};
mouse = oMousePos(canvas, e);
// saving the points in the points array
points.push({x:mouse.x,y:mouse.y})
// drawing a line from the previous point to the current point
ctx.beginPath();
ctx.moveTo(previous.x,previous.y);
ctx.lineTo(mouse.x,mouse.y);
ctx.stroke();
}
}, false);


canvas.addEventListener('mouseup', function() {
drawing=false;
// Adding the path to the array or the paths
pathsry.push(points);
}, false);


undo.addEventListener(click,Undo);

function drawPaths(){
// delete everything
ctx.clearRect(0,0,canvas.width,canvas.height);
// draw all the paths in the paths array
pathsry.forEach(path=>{
ctx.beginPath();
ctx.moveTo(path[0].x,path[0].y);
for(let i = 1; i < path.length; i++){
ctx.lineTo(path[i].x,path[i].y);
}
ctx.stroke();
})
}

function Undo(){
// remove the last path from the paths array
pathsry.splice(-1,1);
// draw all the paths in the paths array
drawPaths();
}


// a function to detect the mouse position
function oMousePos(canvas, evt) {
var ClientRect = canvas.getBoundingClientRect();
return { //objeto
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
}
}

canvas{border:1px solid}

<button id=undo>undo</button><br>
<canvas id=paint></canvas>




[#9656] Thursday, December 27, 2018, 6 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
ryderalfonsos

Total Points: 655
Total Questions: 88
Total Answers: 91

Location: Nauru
Member since Thu, Feb 2, 2023
1 Year ago
ryderalfonsos questions
Mon, Sep 9, 19, 00:00, 5 Years ago
Wed, Feb 13, 19, 00:00, 5 Years ago
Tue, Feb 12, 19, 00:00, 5 Years ago
;