【问题标题】:Canvas line clear and re-draw from array画布线清除并从数组中重新绘制
【发布时间】:2019-02-01 09:30:37
【问题描述】:

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

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/

【问题讨论】:

    标签: javascript canvas html5-canvas


    【解决方案1】:

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

    您正在使用一个且唯一的 lineObj 对象。

    你更新的总是一样的,你在Array中推送的总是相同的Object。

    因此,当您访问drawAll 时,您的代码将正确地遍历对同一lineObj 的所有引用,并正确绘制其当前状态,次数与您在数组中推送对它的新引用一样多。

    要修复它,您至少需要在每次将其推送到数组时创建一个新对象。
    但是您可能也有兴趣对这些行进行原型设计,以便您可以使用辅助方法,一旦您的项目发展壮大,这些方法可能会派上用场。

    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>

    【讨论】:

      猜你喜欢
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      • 2022-11-20
      • 2016-08-22
      • 1970-01-01
      • 2020-07-16
      • 2015-04-02
      • 2012-07-19
      相关资源
      最近更新 更多