javascript - 画布线清除并从数组中重新绘制
问题描述
我遇到了一个问题,我尝试从数组的画布上画线。
我试图在绘制第一行之前清除一次画布。
如果我清除画布,我只会绘制最后一行而不是全部。
function drawAll() {
for (var i = 0; i < lines.length; i++) {
if (i == 0) {
ctx2.clearRect(0, 0, canvas.width, canvas.height); // clears canvas
}
ctx2.beginPath(); // needed to clear canvas if drawing lines
ctx2.moveTo(lines[i].start.x, lines[i].start.y);
ctx2.lineTo(lines[i].end.x, lines[i].end.y);
ctx2.stroke();
}
}
难道我做错了什么?
解决方案
您的问题不在绘图部分,而是在行更新中(顺便说一句,您可能希望将其包含在您的问题中)。
您正在使用一个也是唯一的lineObj
对象。
您更新的始终是相同的,您在 Array 中推送的始终是相同的 Object。
因此,当您来到 时drawAll
,您的代码将正确地遍历对它的所有引用lineObj
,并且将正确地绘制其当前状态,就像您在 Array 中推送对它的新引用一样多次。
要修复它,您至少需要在每次将其推送到阵列时创建一个新对象。
但是您可能也有兴趣对这些行进行原型设计,以便您可以使用辅助方法,一旦您的项目发展壮大,这些方法可能会派上用场。
var canvas = document.getElementById("myCanvas");
var canvas2 = document.getElementById("myCanvas2");
var ctx = canvas.getContext("2d");
var ctx2 = canvas2.getContext("2d");
var rect = canvas.getBoundingClientRect();
var xPos;
var yPos;
var pressed = 0;
var lines = [];
var line = [];
function drawCanvas() {
ctx.fillStyle = "rgb(255, 0, 0)";
ctx.fillRect(0, 0, 150, 75);
ctx2.fillStyle = "rgb(255, 0, 0)";
ctx2.fillRect(0, 0, 150, 75);
}
function drawLine() {
if (pressed != 0) { // stops from drawing a line after two mouse presses
ctx.clearRect(0, 0, canvas.width, canvas.height); // clears canvas
ctx.beginPath(); // needed to clear canvas if drawing lines
ctx.moveTo(xPos, yPos); // line start
endXPos = event.clientX - rect.left;
endYPos = event.clientY - rect.top;
ctx.lineTo(endXPos, endYPos);
ctx.stroke();
writeMessage();
}
}
function drawAll() {
// better to move it out of the loop
if (lines.length) {
ctx2.clearRect(0, 0, canvas.width, canvas.height); // clears canvas
}
for (var i = 0; i < lines.length; i++) {
ctx2.beginPath(); // needed to clear canvas if drawing lines
ctx2.moveTo(lines[i].start.x, lines[i].start.y);
ctx2.lineTo(lines[i].end.x, lines[i].end.y);
ctx2.stroke();
}
}
function writeMessage() {
document.getElementById("coordinates").innerHTML =
"Mouse Position: " +
(event.clientX - rect.left) + ", " +
(event.clientY - rect.top);
}
function mouseDownFunction(event) {
pressed++;
xPos = event.clientX - rect.left; // x and y cordinates of mouse on canvas
yPos = event.clientY - rect.top;
if (pressed == 1) { // reset our global lineObj
lineObj.reset(xPos, yPos);
ctx.moveTo(xPos, yPos);
} else if (pressed == 2) { // update our global lineObj
lineObj.update(xPos, yPos);
ctx.lineTo(xPos, yPos)
// push a clone of the current status
lines.push(lineObj.clone());
pressed = 0;
drawAll();
}
}
// LineObject Constructor
/**
* @method reset(xPos, yPos) ::resets both `start` and `end` positions
* @method update(xPos, yPos) ::Updates `end`
* @method clone() ::Returns a new LineObject with this current positions
*
* Feel free to add more, like `draw`, `setColor`...
*
*/
function LineObject(xPos, yPos) {
this.start = {
x: xPos,
y: yPos
};
this.end = {
x: xPos,
y: yPos
}
}
LineObject.prototype = {
reset: function(xPos, yPos) {
this.start.x = this.end.x = xPos;
this.start.y = this.end.y = yPos;
},
update: function(xPos, yPos) {
this.end.x = xPos;
this.end.y = yPos;
},
clone: function() {
var clone = new LineObject(this.start.x, this.start.y);
clone.update(this.end.x, this.end.y);
return clone;
}
};
var lineObj = new LineObject();
canvas.addEventListener("mousemove", drawLine)
// on mouse move inside canvas execute writeMessage
canvas.addEventListener("mousedown", mouseDownFunction)
// on left click inside canvas execute setLineStart
<canvas id="myCanvas"></canvas>
<h1 id="coordinates"></h1>
<h1 id="hehe"></h1>
<canvas id="myCanvas2">
Your browser does not support the canvas element.
</canvas>
推荐阅读
- c# - 如何在 C# 中按国家/地区获取语言
- excel - 如何使用 powershell 修改 Excel COM 中的对象?
- html - 调整浏览器大小时,如何在元素被另一个元素部分覆盖时使元素滚动?(CSS)
- javascript - 整理列表中的重复号码
- java - 如何使用 Maven 配置在 jOOQ 中使用自定义转换器?
- excel - 维护图表中的系列格式:MDX 图例更改的 VBA 事件
- python-3.x - 在 Python Cartopy 地图中突出显示地点
- nestjs - 如何在 NestJS 中发布到 Kafka 客户端?
- html - 如何使用 Nokogiri 替换文本字符串的“inner_html”
- swift - 从一个接口控制器移动到另一个