mrdeadi
mrdeadi

Reputation: 13

Circle moving around the edge of the canvas

I need a circle moving around the edge of the canvas. Moving right then down is working properly, but when it needs to go left it's jumping to the bottom-right and starts moving right again and again. I don't exactly know how to fix that.

  var can = document.getElementById('C4');
  var ctx = can.getContext('2d');
  var x = 5, y = 20;
  ctx.fillStyle = "black";
  ctx.fillRect(700, 100, 100, 100);
  function draw() {
      ctx.beginPath();
      ctx.arc(x, y, 20, 0, 2 * Math.PI);
      ctx.fillStyle = 'rgba(250,0,0,0.4)';
      ctx.fill();
      do {//moving right
          x += 2;
      } while (x <! 281);
      if (x >= 280){//down
          do {
              x = 280;
              y += 2;
          } while (y <! 130);
      }
      if(y >= 130 && x >= 280){//left
          do {
              x = x - 2;
              y = 130;
          } while (x >! 20);
      }
      if (x <= 20) {//up
          do {
              x = 20;
              y = y-2;
          } while (y <! 20);
      }

      ctx.fillStyle = "rgba(34,45,23,0.4)";
      ctx.fillRect(0, 0, can.width, can.height);
      requestAnimationFrame(draw);
  }
  draw();
canvas { border: 1px solid black}
<canvas id="C4"></canvas>

Upvotes: 1

Views: 203

Answers (2)

Blindman67
Blindman67

Reputation: 54128

  • Isolate the ball as an object.
  • Use the balls direction to check for change in direction.
  • Clear the canvas first line inside the draw function rather than create a path at the end of the draw function.

Example.

  var ctx = canvas.getContext('2d');
  const radius = 20;
  const speed = 2;
  const ball = {
    style: "rgba(250,0,0,0.4)",
    radius: radius,
    pos: {x: radius, y: radius},
    vel: {x: speed, y: 0},
    step() {
        const w = ctx.canvas.width, h = ctx.canvas.height, r = ball.radius;
        var x = ball.pos.x, y = ball.pos.y
        
        if(ball.vel.x === speed && x >= w - r ) {
            ball.vel.x = 0;
            ball.vel.y = speed;
            ball.pos.x = w - r;
        } else if(ball.vel.y === speed && y >= h - r) {
            ball.vel.x = -speed;
            ball.vel.y = 0;
            ball.pos.y = h - r;
        } else if(ball.vel.x === -speed && x <= r) {
            ball.vel.x = 0;
            ball.vel.y = -speed;
            ball.pos.x = r;
        } else if(ball.vel.y === -speed && y <= r) {        
            ball.vel.x = speed;
            ball.vel.y = 0;
            ball.pos.y = r;
        }
        ball.pos.x += ball.vel.x;
        ball.pos.y += ball.vel.y;
    },
    draw() {
        ctx.fillStyle = ball.style;
        ctx.beginPath();
        ctx.arc(ball.pos.x, ball.pos.y, ball.radius, 0, 2 * Math.PI);
        ctx.fill();    
    },
}

             
        
           
  

  function draw() {
      ctx.fillStyle = "rgba(34,45,23,0.4)";
      ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
      ball.step();
      ball.draw();
      requestAnimationFrame(draw);
  }
  draw();
canvas { border: 1px solid black}
<canvas id="canvas"></canvas>

Upvotes: 0

Claudio
Claudio

Reputation: 5203

Since you're using a recursion you don't need the do while, the loops are just making the circle jump from one edge to another. You can achive your goal with if conditions, like this:

var can = document.getElementById('C4');
  var ctx = can.getContext('2d');
  var x = 5, y = 20;
  ctx.fillStyle = "black";
  ctx.fillRect(700, 100, 100, 100);
  function draw() {
      ctx.beginPath();
      ctx.arc(x, y, 20, 0, 2 * Math.PI);
      ctx.fillStyle = 'rgba(250,0,0,0.4)';
      ctx.fill();

      if (x < 280 && y == 20) {
        x += 2;
      }

      if (x >= 280 && y < 130){//down
          x = 280;
          y += 2;
      }

      if(y >= 130 && x > 20){//left
        x = x - 2;
        y = 130;
      }

      if (x == 20 && y > 20) {//up
        x = 20;
        y = y-2;
      }

      ctx.fillStyle = "rgba(34,45,23,0.4)";
      ctx.fillRect(0, 0, can.width, can.height);
      requestAnimationFrame(draw);
  }
  
  draw();
canvas { border: 1px solid black}
<canvas id="C4"></canvas>

Upvotes: 1

Related Questions