1、新建画布

canvas首先是空白的,咱们首先设置canvas的宽高,并找到渲染上下文

<body>    <!-- 新建canvas元素 -->    <canvas id="canvas"></canvas>  </body>
window.onload = () => {   // 获取canvasDom  const canvas = document.getElementById("canvas");  // 手动设置宽高  canvas.width = 800;  canvas.height = 800;  // 获取上下文  const ctx = canvas.getContext("2d");};

2、绘制边框

此时页面曾经能够看到画布了,咱们能够更显著的一些绘制一个边框

window.onload = () => {   .....  // 获取canvas上下文  const ctx = canvas.getContext("2d");  // 绘制边框  renderBorder(ctx);};function renderBorder(ctx) {  // 首先获取画布的宽高  const width = ctx.canvas.width;  const height = ctx.canvas.height;  ctx.beginPath(); // 开始一个新的门路  ctx.moveTo(0, 0); // 将门路的起始点挪动到左上角  ctx.lineTo(width, 0); // 应用直线连贯到右上角(并不绘制)  ctx.lineTo(width, height); // ...右下角  ctx.lineTo(0, height); // ...左下角  ctx.closePath(); // 完结一个新的门路  ctx.stroke(); // 绘制以后已知门路}

3、绘制球

此时咱们曾经能够看到边框了,首先须要新建一个“球”对象,球对象有如下一些属性,再实现如何绘制这个“球”对象,这里波及到canvas绘制圆弧门路的办法,比拟非凡的这里是弧度

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

x:圆弧中心点x轴坐标
y: 圆弧中心点y轴坐标
radius: 半径
startAngle:圆弧起始点
endAngle: 圆弧完结点
anticlockwis(可选):Boolean类型,如果为true,则逆时针方向绘制,反之,顺时针方向绘制

window.onload = () => {    .....  // 绘制球  let ball = {    x: 0, // 以后x轴坐标    y: 0, // 以后y轴坐标    radius: 10, // 半径    g: 0.1, // 重力加速度    vx: 8, // x轴挪动速度    vy: 4, // y轴挪动速度    color: "blue", // 色彩  };  renderBall(ctx, ball);};// 绘制一个球function renderBall(ctx, ball) {  const x = ball.x + ball.radius; // 圆弧核心(圆心)的 x 轴坐标。  const y = ball.y + ball.radius; // 圆弧核心(圆心)的 y 轴坐标。  const radius = ball.radius; // 半径  const startAngle = 0; // 圆弧的起始点  const endAngle = 2 * Math.PI; // 圆弧的完结点  ctx.beginPath(); // 开始一个新的门路  ctx.arc(x, y, radius, startAngle, endAngle);  ctx.closePath(); // 完结一个新的门路  ctx.fillStyle = ball.color; // 色彩  ctx.fill(); // 填充}

4、让球动起来

这是咱们曾经绘制了一个球,接下来依据球在x轴与y轴上的速度挪动起来,并给y轴加上重力加速度,这里须要留神的是每次绘制都须要从新革除一下画布,canvas动画实质就是每次都革除一遍画布从新绘画

window.onload = () => {    // .....         let ball = {            x: 0, // 以后x轴坐标            y: 0, // 以后y轴坐标            radius: 10, // 半径            g: 0.1, // 重力加速度            vx: 8, // x轴挪动速度            vy: 4, // y轴挪动速度            color: "blue", // 色彩          };      setInterval(() => {        // 先将之前绘制的擦除        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);        // 绘制边框        renderBorder(ctx);        // 绘制球        renderBall(ctx, ball);        ball = updateBall(ball);      }, 20);  }// 更新ballfunction updateBall(ball) {  ball.x += ball.vx;  ball.y += ball.vy;  ball.vy += ball.g;  return ball;}

5、优化

当初小球曾经能够动起来了,再优化一下updateBall函数,实在一点,例如当小球调到边框的时候能够反弹回来,且每次反弹都会让加速度变慢

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;    }

整体代码

<!DOCTYPE html><html lang="zh-cn">  <head>    <meta charset="UTF-8" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Canvas小球</title>  </head>  <body>    <!-- 新建canvas元素 -->    <canvas id="canvas"></canvas>  </body>  <script>    window.onload = () => {      // 获取canvasDom      const canvas = document.getElementById("canvas");      // 手动设置宽高      canvas.width = 800;      canvas.height = 800;      // 获取canvas上下文      const ctx = canvas.getContext("2d");      let ball = {        x: 0, // 以后x轴坐标        y: 0, // 以后y轴坐标        radius: 10, // 半径        g: 0.1, // 重力加速度        vx: 8, // x轴挪动速度        vy: 4, // y轴挪动速度        color: "blue", // 色彩      };      setInterval(() => {        // 先将之前绘制的擦除        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);        // 绘制边框        renderBorder(ctx);        // 绘制球        renderBall(ctx, ball);        ball = updateBall(ctx, ball);      }, 20);    };    // 绘制边框    function renderBorder(ctx) {      // 首先获取画布的宽高      const width = ctx.canvas.width;      const height = ctx.canvas.height;      ctx.beginPath(); // 开始一个新的门路      ctx.moveTo(0, 0); // 将门路的起始点挪动到左上角      ctx.lineTo(width, 0); // 应用直线连贯到右上角(并不绘制)      ctx.lineTo(width, height); // ...右下角      ctx.lineTo(0, height); // ...左下角      ctx.closePath(); // 完结一个新的门路      ctx.stroke(); // 绘制以后已知门路    }    // 绘制一个球    function renderBall(ctx, ball) {      const x = ball.x + ball.radius; // 圆弧核心(圆心)的 x 轴坐标。      const y = ball.y + ball.radius; // 圆弧核心(圆心)的 y 轴坐标。      const radius = ball.radius; // 半径      const startAngle = 0; // 圆弧的起始点      const endAngle = 2 * Math.PI; // 圆弧的完结点      ctx.beginPath(); // 开始一个新的门路      ctx.arc(x, y, radius, startAngle, endAngle);      ctx.closePath(); // 完结一个新的门路      ctx.fillStyle = ball.color; // 色彩      ctx.fill(); // 填充    }    // 更新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>

参考文档

[百度百科:弧度](
https://baike.baidu.com/item/...

[MDN:canvas](
https://developer.mozilla.org...

[慕课网: liuyubobobo老师的canvas教程](
https://www.imooc.com/learn/133)