首页 > 解决方案 > 画布线清除并从数组中重新绘制

问题描述

我遇到了一个问题,我尝试从数组的画布上画线。
我试图在绘制第一行之前清除一次画布。
如果我清除画布,我只会绘制最后一行而不是全部。

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();
    }
}

难道我做错了什么?

https://jsfiddle.net/1tgcd9xu/

标签: javascriptcanvashtml5-canvas

解决方案


您的问题不在绘图部分,而是在行更新中(顺便说一句,您可能希望将其包含在您的问题中)。

您正在使用一个也是唯一的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>


推荐阅读