Reputation: 1253
I have a canvas that I draw a rect on that I want to clear from the screen when a condition is met, the condition fires but does not clear the rect from the screen. What am I doing wrong? I should also mention that I redraw the rects a couple times because they are draggable, not sure if that makes a difference. So far I have tried:
this.ctx.clearRect(this.ctx.rect.startX, this.ctx.rect.startY, this.ctx.rect.w, this.ctx.rect.h);
this.ctx.clearRect(0, 0, this.ctx.rect.w, this.ctx.rect.h);
dclick: function (e) {
e.preventDefault();
this.ctx.rect = {
startX: 25,
startY: 100,
w: (this.canvas.width - 50),
h: 300,
}
this.draw();
<div class="cv">
<canvas v-on:mousedown="mouseDown" v-on:mousemove="mouseMove" v-on:mouseup="mouseUp" v-on:dblclick="dclick" :id="'cv' + emp.id" class="canvas" width="150" height="700"></canvas>
<canvas class="back" :id="'back' + emp.id" width="150" height="700"></canvas>
</div>
</template>
function () {
for (let i = 0; i < this.st; i+=this.ic) {
this.ctx.beginPath();
this.ctx.moveTo(0, i);
this.ctx.lineTo(500, i);
this.ctx.stroke();
this.ctx.closePath();
this.ctx.fillStyle = "#222222";
this.ctx.fillRect(this.ctx.rect.startX, this.ctx.rect.startY, this.ctx.rect.w, this.ctx.rect.h);
this.drawHandles();
}
},
this.save();
this.ctx.clearRect(0, 0, canvas.width, canvas.height);
this.draw();'
Here is a Pen of whats happening. The rect clears but doesn't stay cleared. The box should be draggable vertically and should clear and stayed cleared when the button is clicked. To make the box appear you must double click the canvas. https://codepen.io/tjquinn/pen/BYZQqo
Upvotes: 0
Views: 2919
Reputation: 1000
To read about the canvas and the different types of context refer to MDN. We are using 2d
context. For more details and available method in CanvasRenderingContext2D
, you can visit the link.
Note: When you run the snippet, make sure to scroll down the output, if not visible properly. There is a "Clear" button to erase.
The key point in your code, I have added is
mounted: function() {
var canvas = document.getElementById("canvasId");
var ctx = canvas.getContext("2d");
this.canvas = canvas;
this.ctx = ctx;
}
new Vue({
el: '#app',
data: {
st: 50,
ic: 10
},
mounted: function() {
var canvas = document.getElementById("canvasId");
var ctx = canvas.getContext("2d");
this.canvas = canvas;
this.ctx = ctx;
},
methods: {
dclick: function(e) {
this.ctx.rect = {
startX: 25,
startY: 100,
w: (this.canvas.width - 50),
h: 300,
}
this.draw();
},
draw: function() {
for (let i = 0; i < this.st; i += this.ic) {
this.ctx.beginPath();
this.ctx.moveTo(0, i);
this.ctx.lineTo(500, i);
this.ctx.stroke();
this.ctx.closePath();
this.ctx.fillStyle = "#222222";
this.ctx.fillRect(this.ctx.rect.startX, this.ctx.rect.startY, this.ctx.rect.w, this.ctx.rect.h);
//this.drawHandles();
}
},
clear: function() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<div id="app">
<div class="cv">
<canvas style='border:1px solid;' v-on:dblclick="dclick" id="canvasId" class="canvas" width="400" height="200"></canvas>
<canvas class="back" width="150" height="700" style="border:1px solid red"></canvas>
<button v-on:click="dclick">
Draw
</button>
<button v-on:click="clear">
Clear
</button>
</div>
<p style='margin-top: 100px'>-- Spacer--</p>
</div>
You can update all your code as per need based upon the above code snippet. Hope this helps!!
Update: Modified code as per your code pen. Added one flag cleared
to redraw control.
<html>
<head>
<title>Test</title>
<script src="vue.min.js"></script>
</head>
<body>
<div id="app">
The CANVAS DEMO
<div class="cv">
<canvas style='border:1px solid;' v-on:mousedown="mouseDown" v-on:mousemove="mouseMove" v-on:mouseup="mouseUp" @dblclick="dclick" id="rect" class="rect" width="150" height="700"></canvas>
<button v-on:click="clear">
Clear
</button>
</div>
</div>
<script>
new Vue({
el: '#app',
data: function() {
return {
rect : {},
drag : false,
closeEnough : 10,
st : 0,
ic : 0,
mouseX : 0,
mouseY : 0,
dragTL : false,
dragBL : false,
dragTR : false,
dragBR : false,
cv2: '',
ln: 0,
cleared: true
}
},
mounted: function () {
this.getVal(10);
this.draw();
},
methods: {
checkCloseEnough: function (p1, p2) {
return Math.abs(p1 - p2) < this.closeEnough;
},
getVal: function (x) {
this.canvas2 = document.getElementById('rect');
this.ctx2 = this.canvas2.getContext('2d');
this.st = this.canvas2.height;
this.ic = (this.st / x);
},
draw: function () {
this.ctx2.fillStyle = "#222222";
this.ctx2.fillRect(this.ctx2.rect.startX, this.ctx2.rect.startY, this.ctx2.rect.w, this.ctx2.rect.h);
this.drawHandles();
},
drawHandles: function () {
this.drawCircle(this.ctx2.rect.startX + this.ctx2.rect.w/2, this.ctx2.rect.startY, this.closeEnough); //top left corner
//drawCircle(rect.startX + rect.w, rect.startY, closeEnough);
//drawCircle(rect.startX + rect.w, rect.startY + rect.h, closeEnough);
this.drawCircle(this.ctx2.rect.startX + this.ctx2.rect.w/2, this.ctx2.rect.startY + this.ctx2.rect.h, this.closeEnough);
},
drawCircle: function (x, y, radius) {
this.ctx2.fillStyle = "#FF0000";
this.ctx2.beginPath();
this.ctx2.arc(x, y, radius, 0, 2 * Math.PI);
this.ctx2.closePath();
this.ctx2.fill();
},
checkCloseEnough: function (p1, p2) {
return Math.abs(p1 - p2) < this.closeEnough;
},
mouseDown: function (event) {
if(this.cleared) return;
this.mouseX = event.pageX - this.canvas2.offsetLeft;
this.mouseY = event.pageY - this.canvas2.offsetTop;
// if there isn't a rect yet
if (this.ctx2.rect.w === undefined) {
this.ctx2.rect.startX = this.mouseY;
this.ctx2.rect.startY = this.mouseX;
this.dragBR = true;
}
if (this.checkCloseEnough(this.mouseX, this.ctx2.rect.startX + this.ctx2.rect.w/2) && this.checkCloseEnough(this.mouseY, this.ctx2.rect.startY)) {
this.dragTL = true;
}
else if (this.checkCloseEnough(this.mouseX, this.ctx2.rect.startX + this.ctx2.rect.w/2) && this.checkCloseEnough(this.mouseY, this.ctx2.rect.startY + this.ctx2.rect.h)) {
this.dragBR = true;
}
else {
// handle not resizing
}
this.ctx2.clearRect(0, 0, this.canvas2.width, this.canvas2.height);
this.draw();
},
mouseMove: function (event) {
if(this.cleared) return;
this.mouseX = event.pageX - this.canvas2.offsetLeft;
this.mouseY = event.pageY - this.canvas2.offsetTop;
if (this.dragTL) {
//rect.w += rect.startX - mouseX;
this.ctx2.rect.h += this.ctx2.rect.startY - this.mouseY;
//rect.startX = mouseX;
this.ctx2.rect.startY = this.mouseY;
}
else if (this.dragBR) {
//rect.w = Math.abs(rect.startX - mouseX);
this.ctx2.rect.h = Math.abs(this.ctx2.rect.startY - this.mouseY);
}
this.ctx2.clearRect(0, 0, this.canvas2.width, this.canvas2.height);
this.draw();
},
mouseUp: function () {
if(this.cleared) return;
this.dragTL = false;
this.dragTR = false;
this.dragBL = false;
this.dragBR = false;
},
dclick: function (e) {
this.cleared = false;
console.log("Fires");
e.preventDefault();
this.ctx2.rect = {
startX: 25,
startY: 100,
w: (this.canvas2.width - 50),
h: 300,
}
this.draw();
this. ln = this.lines;
this.getVal(10);
},
clear: function () {
this.cleared = true;
this.cv2 = 'rect';
this.canvas2 = document.getElementById(this.cv2);
this.ctx2 = this.canvas2.getContext('2d');
console.log(this.ctx2.clearRect(0, 0, this.canvas2.width, this.canvas2.height));
console.log("Clear should run");
},
}
})
</script>
</body>
</html>
Upvotes: 1
Reputation: 301
The correct method is:
context.clearRect(0, 0, canvas.width, canvas.height);
Rather than clearing the rectangle, you need to clear the canvas.
Dealing with transformed coordinates If you have modified the transformation matrix (e.g. using scale, rotate, or translate) then context.clearRect(0,0,canvas.width,canvas.height) will likely not clear the entire visible portion of the canvas.
Here is how to do it:
// Store the current transformation matrix
context.save();
// Use the identity matrix while clearing the canvas
context.setTransform(1, 0, 0, 1, 0, 0);
context.clearRect(0, 0, canvas.width, canvas.height);
// Restore the transform
context.restore();
Hope this helps! ;)
Upvotes: 3