1. Create a new canvas

The canvas is blank first, we first set the width and height of the canvas and find the rendering context

<body>
    <! Create a new Canvas element -->
    <canvas id="canvas"></canvas>
  </body>
Copy the code
window.onload = () = > {
   / / get canvasDom
  const canvas = document.getElementById("canvas");
  // Manually set the width and height
  canvas.width = 800;
  canvas.height = 800;
  // Get the context
  const ctx = canvas.getContext("2d");
};
Copy the code

2. Draw borders

Now that the page is visible to the canvas, we can draw a border more clearly

window.onload = () = >{...// Get the canvas context
  const ctx = canvas.getContext("2d");
  // Draw the border
  renderBorder(ctx);
};
function renderBorder(ctx{
  // First get the width of the canvas
  const width = ctx.canvas.width;
  const height = ctx.canvas.height;
  ctx.beginPath(); // Start a new path
  ctx.moveTo(0.0); // Move the starting point of the path to the upper-left corner
  ctx.lineTo(width, 0); // Use a straight line to connect to the upper right corner (not drawn)
  ctx.lineTo(width, height); / /... The lower right corner
  ctx.lineTo(0, height); / /... The lower left corner
  ctx.closePath(); // End a new path
  ctx.stroke(); // Draw the current known path
}
Copy the code

3. Draw the ball

Now we can see the border, first we need to create a “ball” object, the ball object has the following properties, and then realize how to draw this “ball” object, which involves the method of drawing the arc path of canvas, especially radians

void ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);

  • X: X-axis coordinates of the center point of the arc
  • Y: Y-axis coordinates of the center point of the arc
  • The radius: the radius
  • StartAngle: indicates the start point of the arc
  • EndAngle: indicates the end point of an arc
  • Anticlockwis (Optional) : Boolean if true, anticlockwis is drawn counterclockwise, if true, anticlockwis is drawn clockwise
window.onload = () = >{.../ / draw the ball
  let ball = {
    x0.// Current x coordinates
    y0.// The current y coordinate
    radius10./ / radius
    g0.1.// Gravitational acceleration
    vx8.// X-axis moving speed
    vy4.// Y-axis moving speed
    color"blue"./ / color
  };
  renderBall(ctx, ball);
};
// Draw a ball
function renderBall(ctx, ball{
  const x = ball.x + ball.radius; // The X-axis coordinates of the center of the arc.
  const y = ball.y + ball.radius; // The Y-axis coordinates of the center of the arc.
  const radius = ball.radius; / / radius
  const startAngle = 0// The starting point of the arc
  const endAngle = 2 * Math.PI; // The end of the arc
  ctx.beginPath(); // Start a new path
  ctx.arc(x, y, radius, startAngle, endAngle);
  ctx.closePath(); // End a new path
  ctx.fillStyle = ball.color; / / color
  ctx.fill(); / / fill
}
Copy the code

4. Get the ball moving

We have drawn a ball, and then we move it according to the speed of the ball on the x and y axes, and add the acceleration of gravity to the Y axis. It should be noted that the canvas needs to be cleaned again every time it is drawn. The essence of canvas animation is to clean the canvas every time and paint again

window.onload = () = > {
    / /...
     
    let ball = {
            x0.// Current x coordinates
            y0.// The current y coordinate
            radius10./ / radius
            g0.1.// Gravitational acceleration
            vx8.// X-axis moving speed
            vy4.// Y-axis moving speed
            color"blue"./ / color
          };

      setInterval(() = > {
        // Erase the previous drawing
        ctx.clearRect(0.0, ctx.canvas.width, ctx.canvas.height);
        // Draw the border
        renderBorder(ctx);
        / / draw the ball
        renderBall(ctx, ball);
        ball = updateBall(ball);
      }, 20);
  }


/ / update the ball
function updateBall(ball{
  ball.x += ball.vx;
  ball.y += ball.vy;
  ball.vy += ball.g;
  return ball;
}
Copy the code

5, to optimize

Now that the ball is moving, let’s optimize the updateBall function to make it realistic. For example, the ball will bounce back when it hits the border, and each bounce will slow down the acceleration


function updateBall(ctx, ball{
      const width = ctx.canvas.width;
      const height = ctx.canvas.height;
      ball.x += ball.vx;
      ball.y += ball.vy;
      ball.vy += ball.g;
      if (ball.y + ball.radius >= height) {
        ball.y = height - ball.radius;
        ball.vy = -ball.vy * 0.5;
      }
      if (ball.y + ball.radius <= 0) {
        ball.y = 0 - ball.radius;
        ball.vy = -ball.vy * 0.5;
      }
      if (ball.x + ball.radius >= width) {
        ball.x = width - ball.radius;
        ball.vx = -ball.vx * 0.5;
      }
      if (ball.x + ball.radius <= 0) {
        ball.x = 0 - ball.radius;
        ball.vx = -ball.vx * 0.5;
      }
      return ball;
    }
Copy the code

The overall code


<! DOCTYPEhtml>
<html lang="zh-cn">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0" />
    <title>Canvas ball</title>
  </head>
  <body>
    <! Create a new Canvas element -->
    <canvas id="canvas"></canvas>
  </body>
  <script>
    window.onload = () = > {
      / / get canvasDom
      const canvas = document.getElementById("canvas");
      // Manually set the width and height
      canvas.width = 800;
      canvas.height = 800;
      // Get the canvas context
      const ctx = canvas.getContext("2d");
      let ball = {
        x0.// Current x coordinates
        y0.// The current y coordinate
        radius10./ / radius
        g0.1.// Gravitational acceleration
        vx8.// X-axis moving speed
        vy4.// Y-axis moving speed
        color"blue"./ / color
      };
      setInterval(() = > {
        // Erase the previous drawing
        ctx.clearRect(0.0, ctx.canvas.width, ctx.canvas.height);
        // Draw the border
        renderBorder(ctx);
        / / draw the ball
        renderBall(ctx, ball);
        ball = updateBall(ctx, ball);
      }, 20);
    };
    // Draw the border
    function renderBorder(ctx{
      // First get the width of the canvas
      const width = ctx.canvas.width;
      const height = ctx.canvas.height;
      ctx.beginPath(); // Start a new path
      ctx.moveTo(0.0); // Move the starting point of the path to the upper-left corner
      ctx.lineTo(width, 0); // Use a straight line to connect to the upper right corner (not drawn)
      ctx.lineTo(width, height); / /... The lower right corner
      ctx.lineTo(0, height); / /... The lower left corner
      ctx.closePath(); // End a new path
      ctx.stroke(); // Draw the current known path
    }
    // Draw a ball
    function renderBall(ctx, ball{
      const x = ball.x + ball.radius; // The X-axis coordinates of the center of the arc.
      const y = ball.y + ball.radius; // The Y-axis coordinates of the center of the arc.
      const radius = ball.radius; / / radius
      const startAngle = 0// The starting point of the arc
      const endAngle = 2 * Math.PI; // The end of the arc
      ctx.beginPath(); // Start a new path
      ctx.arc(x, y, radius, startAngle, endAngle);
      ctx.closePath(); // End a new path
      ctx.fillStyle = ball.color; / / color
      ctx.fill(); / / fill
    }
    / / update the ball
    function updateBall(ctx, ball{
      const width = ctx.canvas.width;
      const height = ctx.canvas.height;
      ball.x += ball.vx;
      ball.y += ball.vy;
      ball.vy += ball.g;
      if (ball.y + ball.radius >= height) {
        ball.y = height - ball.radius;
        ball.vy = -ball.vy * 0.5;
      }
      if (ball.y + ball.radius <= 0) {
        ball.y = 0 - ball.radius;
        ball.vy = -ball.vy * 0.5;
      }
      if (ball.x + ball.radius >= width) {
        ball.x = width - ball.radius;
        ball.vx = -ball.vx * 0.5;
      }
      if (ball.x + ball.radius <= 0) {
        ball.x = 0 - ball.radius;
        ball.vx = -ball.vx * 0.5;
      }
      return ball;
    }
  </script>
</html>



Copy the code

Reference documentation

Baidu Baike: Radians

MDN: canvas

Moocs: Canvas tutorials by Liuyubobobo