Search code examples
javascripthtmlcanvasdrawing

Incorrect line position with HTML Canvas when lineWidth is not set to 1


  function drawModule() {
    const lineWidth = 1
    context.lineWidth = lineWidth
    context.translate(0.5, 0.5)

    for (let k = 0; k < self.geometryParsed.length; k++) {
      const geometry = self.geometryParsed[k].geom
      const type = self.geometryParsed[k].typ

      context.beginPath()
      context.strokeStyle = self.unitMixTable[type]
      context.moveTo(
        Math.round(geometry[0].x),
        Math.round(geometry[0].y)
      )
      for (let i = 1; i < geometry.length; i++) {
        context.lineTo(
          Math.round(geometry[i].x),
          Math.round(geometry[i].y)
        )
        context.stroke()
      }
      context.closePath()
      context.fillStyle = 'white'
      context.fill()
    }
    context.translate(-0.5, -0.5)
  }

Here is the code I use for drawing some polygons in the canvas, and it works as expected without problem. But when the lineWidth is 2, for example, the positions and opacity of the lines are slightly distorted.

picture of the result:

lineWidth = 1

lineWidth = 2

As you can see in red circle of the figure when lineWidth is 2, the lines are not aligned even if they share same x point. And in the rightmost rectange of each group, colors of the lines are not same.

What might the problem be? is there any point am I missing? thanks in advance!

reproduce: https://codepen.io/coldsewoo/pen/mdeZBev


Solution

  • The fill is the root cause of your problems

    const geometryParsed = [
      {
        geom: [{ x:78, y:132 }, { x:59, y:132 }, { x:59, y:183 }, { x:78, y:183 }, { x:78, y:132 }]
      },
      {
        geom: [{ x:97, y:132 }, { x:78, y:132 }, { x:78, y:166 }, { x:97, y:166 }, { x:97, y:132 }]
      },
    ];
    
    const canv = document.getElementById("canvas");
    const context = canv.getContext("2d");
    
    context.translate(-50, -100)
    context.lineWidth = 2;
    for (let k = 0; k < geometryParsed.length; k++) {
      const geometry = geometryParsed[k].geom;
      context.beginPath();
      context.moveTo(geometry[0].x, geometry[0].y);
      for (let i = 1; i < geometry.length; i++) {
        context.lineTo(geometry[i].x, geometry[i].y);    
      }
      context.stroke();
    }
    
    context.translate(80, 0)
    context.lineWidth = 4;
    for (let k = 0; k < geometryParsed.length; k++) {
      const geometry = geometryParsed[k].geom;
      context.beginPath();
      context.moveTo(geometry[0].x, geometry[0].y);
      for (let i = 1; i < geometry.length; i++) {
        context.lineTo(geometry[i].x, geometry[i].y);
      }
      context.stroke();
      context.fillStyle = "white";
      context.fill();
    }
    <canvas id="canvas" width="476px" height="170px"></canvas>