Reputation: 34109
I am trying to draw multiple rectangles on canvas. I am able to do it except its not clearing rectangles as the mouse moves.
And when i try to clear rectangle using clearRect
then the back image on canvas is also gets cleared. So I have commented out //ctx.clearRect(0, 0, canvas.width, canvas.height);
in the code below
I have gone through several SO posts with similar questions but doesn't seems work
$(function(){
var canvas = document.getElementById('myCanvas');
if (canvas.getContext){
var ctx = canvas.getContext('2d');
ctx.fillText("Sample String", 20, 50);
}
var ctx = canvas.getContext('2d');
//Variables
var canvasx = $(canvas).offset().left;
var canvasy = $(canvas).offset().top;
var last_mousex = last_mousey = 0;
var mousex = mousey = 0;
var mousedown = false;
//Mousedown
$(canvas).on('mousedown', function (e) {
last_mousex = parseInt(e.clientX - canvasx);
last_mousey = parseInt(e.clientY - canvasy);
mousedown = true;
});
//Mouseup
$(canvas).on('mouseup', function (e) {
mousedown = false;
});
//Mousemove
$(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);
var width = mousex - last_mousex;
var height = mousey - last_mousey;
ctx.beginPath();
ctx.rect(last_mousex, last_mousey, width, height);
ctx.strokeStyle = 'black';
ctx.lineWidth = 1;
ctx.stroke();
}
//Output
$('#results').html('current: ' + mousex + ', ' + mousey + '<br/>last: ' + last_mousex + ', ' + last_mousey + '<br/>mousedown: ' + mousedown);
});
})
canvas { border: 1px solid black; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3>
Use mouse to draw multiple rectangles with in the canvas
</h3>
<canvas id="myCanvas"></canvas>
<div id="results">
</div>
Upvotes: 1
Views: 2182
Reputation: 975
I think you can come to another approach
By using mousedown event only then save all rectangle to an array variable
Then you can clear and redraw the whole canvas with the saved variable
var shapes = [];
canva.addEventListener('mousedown', mouseDownListener);
class Rectangle() {
public ctx, x, y, w, h;
public Rectangle(ctx, x, y, w, h) {
this.ctx = ctx;
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
public draw() {
// draw using ctx here
}
}
function mouseDownListener() {
// create rectable
var rectangle = new Rectangle(ctx, x, y, width, height);
// save rectangle to an array
shapes.push(rectangle);
// redraw canvas
redraw();
}
function redraw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// draw all rectangle
shapes.forEach(function(shape) {
// draw shape
shape.draw();
})
}
Upvotes: 0
Reputation: 238
your mistake was you cleared all the canvas:
ctx.clearRect(0, 0, canvas.width, canvas.height);
instead of clearing just the area you drew before:
ctx.clearRect(prev_x-1, prev_y-1, prev_w+2, prev_h+2);
I wrote the basic idea here, but you need to add some code to clear the area depends on the direction the mouse was, and moving to (try to move your mouse to each of the corners and see what happens).
$("#clear").click(function(){
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillText("Sample String", 20, 50);
});
$(function(){
var canvas = document.getElementById('myCanvas');
if (canvas.getContext){
var ctx = canvas.getContext('2d');
ctx.fillText("Sample String", 20, 50);
}
var ctx = canvas.getContext('2d');
//Variables
var canvasx = $(canvas).offset().left;
var canvasy = $(canvas).offset().top;
var last_mousex = last_mousey = w = h = 0;
var prev_x = prev_y = prev_w = prev_h = 0;
var mousex = mousey = 0;
var mousedown = false;
//Mousedown
$(canvas).on('mousedown', function (e) {
last_mousex = parseInt(e.clientX - canvasx);
last_mousey = parseInt(e.clientY - canvasy);
mousedown = true;
});
//Mouseup
$(canvas).on('mouseup', function (e) {
w = h = 0;
mousedown = false;
});
//Mousemove
$(canvas).on('mousemove', function (e) {
mousex = parseInt(e.clientX - canvasx);
mousey = parseInt(e.clientY - canvasy);
if (mousedown) {
prev_x = last_mousex;
prev_y = last_mousey;
prev_w = w;
prev_h = h;
ctx.clearRect(prev_x-1, prev_y-1, prev_w+2, prev_h+2);
w = mousex - last_mousex;
h = mousey - last_mousey;
ctx.beginPath();
ctx.rect(last_mousex, last_mousey, w, h);
ctx.strokeStyle = 'black';
ctx.lineWidth = 1;
ctx.stroke();
}
//Output
$('#results').html('current: ' + mousex + ', ' + mousey + '<br/>last: ' + last_mousex + ', ' + last_mousey + '<br/>mousedown: ' + mousedown);
});
})
canvas { border: 1px solid black; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3>
Use mouse to draw multiple rectangles with in the canvas
</h3>
<button id="clear">clear</button>
<br />
<canvas id="myCanvas"></canvas>
<div id="results">
</div>
Upvotes: 2