我有一个单击eventListener,正在调用静态方法“ clearCanv”,但是 不会调用“ clearCanv”内部的一种方法
this.ctx.clearRect(x,y,this.canv.width,this.canv.width)
正在调用“ clearCanv”,但未调用该方法。
但是,如果我将clickevenetListner传递给一个匿名函数,并且突然从匿名函数内部调用我的静态方法“ clearCanv”。
有人可以解释为什么会这样吗?
问题出在JS的最后几行。 我正在使用Firefox
class Board {
static initalize() {
// Create Canvas
this.canv = document.createElement("canvas");
this.ctx = this.canv.getContext("2d");
this.canv.height = window.innerHeight;
this.canv.width = window.innerWidth;
document.body.appendChild(this.canv);
this.prevX, this.prevY;
this.lineWidth = 25;
this.color = "white"; //Default color
this.prevColor = this.color;
this.erase = false;
// Bindings
this.draw = Board.draw.bind(this);
this.clearCanv = Board.clearCanv.bind(this);
}
static draw({
x,
y
}) {
// Draw a cericle on X, Y
this.ctx.beginPath();
this.ctx.fillStyle = this.color;
this.ctx.arc(x, y, this.lineWidth / 2, 0, Math.PI * 2);
this.ctx.fill();
this.ctx.closePath();
// If we have prevX/Y draw a line from prevX/Y
// To currentX/Y
if (this.prevX && this.prevY) {
this.ctx.beginPath();
this.ctx.moveTo(this.prevX, this.prevY);
this.ctx.strokeStyle = this.color;
this.ctx.lineTo(x, y);
this.ctx.lineWidth = this.lineWidth;
this.ctx.stroke();
this.ctx.closePath();
}
// Recored X/Y
this.prevX = x;
this.prevY = y;
}
static clearCanv(x = 0, y = 0) {
this.ctx.clearRect(x, y, this.canv.width, this.canv.height);
}
}
Board.initalize();
Board.canv.addEventListener("mousedown", function() {
this.addEventListener("mousemove", Board.draw);
});
Board.canv.addEventListener("mouseup", function() {
Board.prevX = null;
Board.prevY = null;
Board.canv.removeEventListener("mousemove", Board.draw);
});
const clearBtn = document.getElementById("clear");
//This does not work
clearBtn.addEventListener("click", Board.clearCanv);
// This works for some reson
//clearBtn.addEventListener("click", function(){
// Board.clearCanv();
//});
html,
body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
overflow: hidden;
position: relative;
}
canvas {
height: 100%;
width: 100%;
background: black;
}
#clear {
position: absolute;
/* z-index: 222; */
}
#erase {
position: absolute;
left: 5.5rem;
}
.erase-selected {
position: absolute;
left: 5.5rem;
opacity: 0.7;
}
#mouseColor {
position: absolute;
left: 11.2rem;
}
.font-size-select {
position: absolute;
left: 15.5rem;
}
.bg-color {
position: absolute;
left: 19.5rem;
}
<button id="clear">Clear</button><button id="erase">erase</button><input type="color" id="mouseColor" />
<select class="font-size-select" id="select-size">
<option selected value="10">10</option>
<option value="15">15</option>
<option value="20">20</option>
<option value="25">25</option>
</select>
<select class="bg-color" id="select-bg">
<option selected value="black">Dark</option>
<option value="white">Light</option>
</select>
答案 0 :(得分:2)
您在这里面临的问题是x=0, y=0
方法的clearCanv
参数被事件侦听器传递的参数(即x= Event
)覆盖。
clearRect()会静默忽略该呼叫,因为x
是NaN
所涉及的内容。
只需在此处删除参数即可解决此问题,因为我想您不希望它不是0
之外的任何东西。
class Board {
static initalize() {
// Create Canvas
this.canv = document.createElement("canvas");
this.ctx = this.canv.getContext("2d");
this.canv.height = window.innerHeight;
this.canv.width = window.innerWidth;
document.body.appendChild(this.canv);
this.prevX, this.prevY;
this.lineWidth = 25;
this.color = "white"; //Default color
this.prevColor = this.color;
this.erase = false;
// Bindings
this.draw = Board.draw.bind(this);
this.clearCanv = Board.clearCanv.bind(this);
}
static draw({
x,
y
}) {
// Draw a cericle on X, Y
this.ctx.beginPath();
this.ctx.fillStyle = this.color;
this.ctx.arc(x, y, this.lineWidth / 2, 0, Math.PI * 2);
this.ctx.fill();
this.ctx.closePath();
// If we have prevX/Y draw a line from prevX/Y
// To currentX/Y
if (this.prevX && this.prevY) {
this.ctx.beginPath();
this.ctx.moveTo(this.prevX, this.prevY);
this.ctx.strokeStyle = this.color;
this.ctx.lineTo(x, y);
this.ctx.lineWidth = this.lineWidth;
this.ctx.stroke();
this.ctx.closePath();
}
// Recored X/Y
this.prevX = x;
this.prevY = y;
}
// here remove the params
// static clearCanv(x = 0, y = 0) {
static clearCanv() {
this.ctx.clearRect(0, 0, this.canv.width, this.canv.height);
}
}
Board.initalize();
Board.canv.addEventListener("mousedown", function() {
this.addEventListener("mousemove", Board.draw);
});
Board.canv.addEventListener("mouseup", function() {
Board.prevX = null;
Board.prevY = null;
Board.canv.removeEventListener("mousemove", Board.draw);
});
const clearBtn = document.getElementById("clear");
clearBtn.addEventListener("click", Board.clearCanv);
// This worked because here the params were not overridden
//clearBtn.addEventListener("click", function(){
// Board.clearCanv();
//});
html,
body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
overflow: hidden;
position: relative;
}
canvas {
height: 100%;
width: 100%;
background: black;
}
#clear {
position: absolute;
/* z-index: 222; */
}
#erase {
position: absolute;
left: 5.5rem;
}
.erase-selected {
position: absolute;
left: 5.5rem;
opacity: 0.7;
}
#mouseColor {
position: absolute;
left: 11.2rem;
}
.font-size-select {
position: absolute;
left: 15.5rem;
}
.bg-color {
position: absolute;
left: 19.5rem;
}
<button id="clear">Clear</button><button id="erase">erase</button><input type="color" id="mouseColor" />
<select class="font-size-select" id="select-size">
<option selected value="10">10</option>
<option value="15">15</option>
<option value="20">20</option>
<option value="25">25</option>
</select>
<select class="bg-color" id="select-bg">
<option selected value="black">Dark</option>
<option value="white">Light</option>
</select>
现在,让您继续走这条路真的很难。您完全滥用这里的语言。
您正在使用这个 class ,就像它是一个实例一样。取而代之的是删除所有这些static
,创建一个真实的 class ,然后创建该 class 的新实例。
class Board {
constructor() {
// Create Canvas
this.canv = document.createElement("canvas");
this.ctx = this.canv.getContext("2d");
this.canv.height = window.innerHeight;
this.canv.width = window.innerWidth;
document.body.appendChild(this.canv);
this.prevX, this.prevY;
this.lineWidth = 25;
this.color = "white"; //Default color
this.prevColor = this.color;
this.erase = false;
// Bindings
this.draw = this.draw.bind(this);
this.clearCanv = this.clearCanv.bind(this);
}
draw({x,y}) {
// Draw a circle on X, Y
this.ctx.beginPath();
this.ctx.fillStyle = this.color;
this.ctx.arc(x, y, this.lineWidth / 2, 0, Math.PI * 2);
this.ctx.fill();
this.ctx.closePath();
// If we have prevX/Y draw a line from prevX/Y
// To currentX/Y
if (this.prevX && this.prevY) {
this.ctx.beginPath();
this.ctx.moveTo(this.prevX, this.prevY);
this.ctx.strokeStyle = this.color;
this.ctx.lineTo(x, y);
this.ctx.lineWidth = this.lineWidth;
this.ctx.stroke();
this.ctx.closePath();
}
// Recored X/Y
this.prevX = x;
this.prevY = y;
}
clearCanv() {
this.ctx.clearRect(0, 0, this.canv.width, this.canv.height);
}
}
// create an instance of Board
const board = new Board();
board.canv.addEventListener("mousedown", function() {
this.addEventListener("mousemove", board.draw);
});
board.canv.addEventListener("mouseup", function() {
board.prevX = null;
board.prevY = null;
board.canv.removeEventListener("mousemove", board.draw);
});
const clearBtn = document.getElementById("clear");
clearBtn.addEventListener("click", board.clearCanv);
html,
body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
overflow: hidden;
position: relative;
}
canvas {
height: 100%;
width: 100%;
background: black;
}
#clear {
position: absolute;
/* z-index: 222; */
}
#erase {
position: absolute;
left: 5.5rem;
}
.erase-selected {
position: absolute;
left: 5.5rem;
opacity: 0.7;
}
#mouseColor {
position: absolute;
left: 11.2rem;
}
.font-size-select {
position: absolute;
left: 15.5rem;
}
.bg-color {
position: absolute;
left: 19.5rem;
}
<button id="clear">Clear</button><button id="erase">erase</button><input type="color" id="mouseColor" />
<select class="font-size-select" id="select-size">
<option selected value="10">10</option>
<option value="15">15</option>
<option value="20">20</option>
<option value="25">25</option>
</select>
<select class="bg-color" id="select-bg">
<option selected value="black">Dark</option>
<option value="white">Light</option>
</select>