I'm trying to create a drawing tool with angular. I created a tool that you can draw a rectangle on a canvas element, the tool is working ok, but I can only draw one rectangle at a time, I just can't figure out how to "not clear" the previous rectangle and keep multiples drawings on my canvas. I cannot clear many canvas because i'm gonna have more drawings, not just rectangles.
rectangleDrawing() {
// first coordinates when clicked
let startX = 0;
let startY = 0;
const rect = this.canvasEl.getBoundingClientRect();
fromEvent(this.canvasEl, "mousedown")
.pipe(
switchMap((e:MouseEvent) => {
startX = e.clientX - rect.left;
startY = e.clientY - rect.top;
return fromEvent(this.canvasEl, 'mousemove').pipe(
takeUntil(fromEvent(this.canvasEl, 'mouseup')),
takeUntil(fromEvent(this.canvasEl, 'mouseleave'))
)
})
).subscribe((event:MouseEvent) => {
let x = event.clientX - rect.left;
let y = event.clientY - rect.top;
let width = x - startX;
let height = y - startY;
this.setCanvasProperties(10, 'square', 'rgba(255,158,43,0.6)');
this.cx.beginPath();
// if I comment this line, the rectangles will stay, but they
// won't be clear, making multiples rectangles inside the
// main rectangle
this.cx.clearRect(0,0, this.canvasEl.width, this.canvasEl.height);
this.cx.rect(startX, startY, width, height);
this.cx.stroke();
});
}
setCanvasProperties(lineWidth, lineCap, strokeStyle) {
this.cx = this.canvasEl.getContext('2d');
this.cx.lineWidth = lineWidth;
this.cx.lineCap = lineCap;
this.cx.strokeStyle = strokeStyle;
}
This link is a good example: https://jsfiddle.net/richardcwc/ukqhf54k/, if you comment the clear line, you can see main problem. Many examples seems to permit only one rectangle at a time.
On mouse up, you could store the drawn rect in an array, and then draw that array and the current rect.
First, lets set the array and keep the width and height as a global variable:
var width;
var height;
var drawItems = [];
Then, the mouseup
function will be like this:
$(canvas).on('mouseup', function(e) {
mousedown = false;
drawItems.push({
x0: last_mousex,
x1: width,
y0: last_mousey,
y1: height
});
});
And this is the mousemove
function:
$(canvas).on('mousemove', function(e) {
mousex = parseInt(e.clientX-canvasx);
mousey = parseInt(e.clientY-canvasy);
if(mousedown) {
ctx.clearRect(0,0,canvas.width,canvas.height); //clear canvas
ctx.strokeStyle = 'black';
ctx.lineWidth = 10;
for(var i=0; i<drawItems.length; i++) {
ctx.beginPath();
ctx.rect(drawItems[i].x0, drawItems[i].y0, drawItems[i].x1, drawItems[i].y1);
ctx.stroke();
}
width = mousex-last_mousex;
height = mousey-last_mousey;
ctx.beginPath();
ctx.rect(last_mousex,last_mousey,width,height);
ctx.stroke();
}
//Output
$('#output').html('current: '+mousex+', '+mousey+'<br/>last: '+last_mousex+', '+last_mousey+'<br/>mousedown: '+mousedown);
});
Here is the updated fiddle
I hope it helps