简体   繁体   中英

Javascript canvas behaving strangely in for loop

I'm trying to create a canvas graphic by rotating ellipses around a central point. When I do this however, the for loop creates a strange image. There are sporadic gaps in between ellipses, and the colors are strange. At first I thought I was calculating the angles wrong, but if that was the case, the gaps should not be sporadic as I am incrementing them in equal increments each iteration of the for loop. Then I thought maybe I was looping around too many times, but if that was the case, only the colors should be off and not the gaps. This makes me think it's an asynchronous problem where maybe the context didn't finish shifting before the next iteration started drawing the next circle, but that's just a guess. What could be wrong and how do I fix it?

Here's a jsfiddle, there's only 6 ellipses when there should be 10, what's happening? https://jsfiddle.net/vj7csL3b/

<!DOCTYPE html>
<html>
  <body>
    <canvas id="canvas" width="200" height="200"></canvas>
    <script>
      const canvas = document.getElementById("canvas");
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
      const ctx = canvas.getContext("2d");

      let color = "#0000ff";
      let numberOfEllipses = 10;
      let lineThickness = 3;
      let middleW = 150;
      let middleL = 150;
      let eWidth = 50;
      let eHeight = 50;
      let fill = "rgba(0,0,255,0.2)";
      let shift = 50;
      let rotate = ((Math.PI / 180) * 360) / 10;
      //console.log(middleW, middleL, dfc);
      for (let i = 1; i < 10 + 1; i++) {
        //translate to point of rotation, rotate and translate back
        ctx.translate(middleW, middleL);
        ctx.rotate(rotate * i);
        ctx.translate(-1 * middleW, -1 * middleL);
        ctx.beginPath();

        // draws ellipse shifted from the middle we are rotating around.
        ctx.ellipse(
          middleW + shift,
          middleL + shift,
          eWidth,
          eHeight,
          0,
          0,
          2 * Math.PI
        );
        ctx.strokeStyle = color;

        ctx.lineWidth = lineThickness;
        ctx.fillStyle = fill;
        ctx.stroke();
        ctx.fill();
      }
    </script>
  </body>
</html>

The circles were actually overlapping over each other.Altering the rotation angle and shift will give the output that u expect.

  const canvas = document.getElementById("canvas");
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  const ctx = canvas.getContext("2d");

  let color = "#0000ff";
  let numberOfEllipses = 10;
  let lineThickness = 3;
  let middleW = 150;
  let middleL = 150;
  let eWidth = 50;
  let eHeight = 50;
  let fill = "rgba(0,0,255,0.2)";
  let shift = 60;
  let rotate = ((Math.PI / 180) * 360) / 60;
  //console.log(middleW, middleL, dfc);
  for (let i = 1; i < 10 + 1; i++) {
    //console.log("paiting circle" + i);
     ctx.translate(middleW, middleL);
    ctx.rotate(rotate * i);
    ctx.translate(-1 * middleW, -1 * middleL);
    ctx.beginPath();
    ctx.ellipse(
      middleW + shift,
      middleL + shift,
      eWidth,
      eHeight,
      0,
      0,
      2 * Math.PI
    );
    ctx.strokeStyle = color;

    ctx.lineWidth = lineThickness;
    ctx.fillStyle = fill;
    ctx.stroke();
    ctx.fill();

  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM