前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >canvas 系列学习笔记二《绘制图形》

canvas 系列学习笔记二《绘制图形》

作者头像
星宇大前端
发布2022-09-08 11:18:53
2370
发布2022-09-08 11:18:53
举报
文章被收录于专栏:大宇笔记大宇笔记

canvas 可以获取上下文,2d 部分是CanvasRenderingContext2D,它用于绘制形状,文本,图像和其他对象。

画矩形


canvas提供了三种方法绘制矩形:

fillRect(x, y, width, height) 绘制一个填充的矩形

strokeRect(x, y, width, height) 绘制一个矩形的边框

clearRect(x, y, width, height) 清除指定矩形区域,让清除部分完全透明。

代码:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>绘制矩形</title>
</head>
<body>
   <canvas id="canvas2d" width="200" height="200" style="background:red"></canvas>
</body>
<script>
    let canvas2d = document.getElementById('canvas2d')
    console.log(canvas2d);
    if (canvas2d.getContext) {
      var ctx = canvas2d.getContext('2d');
        ctx.fillRect(25, 25, 100, 100);
        ctx.clearRect(45, 45, 60, 60);
        ctx.strokeRect(50, 50, 50, 50);
    }
</script>
</html>

结果:

在这里插入图片描述
在这里插入图片描述

绘制圆形


画圆形api

代码语言:javascript
复制
void ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);

参数:

x 圆弧中心(圆心)的 x 轴坐标。

y 圆弧中心(圆心)的 y 轴坐标。

radius 圆弧的半径。

startAngle 圆弧的起始点, x轴方向开始计算,单位以弧度表示。

endAngle 圆弧的终点, 单位以弧度表示。

anticlockwise 可选 可选的Boolean值 ,如果为 true,逆时针绘制圆弧,反之,顺时针绘制。

例子代码:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>绘制圆形</title>
</head>
<body>
   <canvas id="canvas2d" width="200" height="200"></canvas>
</body>
<style>
  #canvas2d{
    border: 1px solid;
    display: block;
    margin: 0 auto;
  }
</style>

<script>
    let canvas2d = document.getElementById('canvas2d')
    canvas2d.width = window.innerWidth/2
    canvas2d.height = window.innerHeight
    if (canvas2d.getContext) {
      var ctx = canvas2d.getContext('2d');
      ctx.beginPath();
      ctx.arc(75, 75, 50, 0, 2 * Math.PI);
      ctx.stroke();  

      ctx.beginPath();
      ctx.moveTo(260,75)
      ctx.arc(200, 75, 60, 0, 2 * Math.PI);
      ctx.fill()
    }
</script>
</html>

显示:

在这里插入图片描述
在这里插入图片描述

绘制五角星


首先整理下思路,看了别人一个图比较好,拿来一下。

在这里插入图片描述
在这里插入图片描述

思路:

  1. 两个圆各自五个点,每个点相差72度
  2. 点可以根据半径和度数求出x,y 坐标
  3. 循环点,canvans 连线
代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>绘制五角星</title>
  </head>
  <body>
    <canvas id="canvas2d" width="200" height="200"></canvas>
  </body>
  <style>
    #canvas2d {
      border: 1px solid;
      display: block;
      margin: 0 auto;
    }
  </style>

  <script>
    let canvas2d = document.getElementById("canvas2d");
    canvas2d.width = window.innerWidth / 2;
    canvas2d.height = window.innerHeight;
    if (canvas2d.getContext) {
      var ctx = canvas2d.getContext("2d");
      ctx.beginPath();
      // 将坐标移动到画布中央
      ctx.translate(canvas2d.width / 2, canvas2d.height / 2);
      // 设置大圆、小圆半径
      let R = 200;
      let r = 100;
      let x;
      let y;
      // 逆时针计算五角星外围10个点的坐标
      for (let i = 0; i < 5; i++) {
        // 外围凸出的每个点坐标
        x = Math.cos(((18 + 72 * i) / 180) * Math.PI) * R;
        y = -Math.sin(((18 + 72 * i) / 180) * Math.PI) * R; // canvas中y轴的正向方向与直角坐标系相反
        ctx.lineTo(x, y);
        // 外围凹下去的每个点坐标
        x = Math.cos(((54 + 72 * i) / 180) * Math.PI) * r;
        y = -Math.sin(((54 + 72 * i) / 180) * Math.PI) * r; // canvas中y轴的正向方向与直角坐标系相反
        ctx.lineTo(x, y);
      }
      ctx.closePath();
      ctx.stroke();
    }
  </script>
</html>
在这里插入图片描述
在这里插入图片描述

绘制笑脸


官方示例,这是相比于五角星,会有一个移动画笔的动作。

代码:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>绘制五角星</title>
  </head>
  <body>
    <canvas id="canvas2d" width="200" height="200"></canvas>
  </body>
  <style>
    #canvas2d {
      border: 1px solid;
      display: block;
      margin: 0 auto;
    }
  </style>

  <script>
    let canvas2d = document.getElementById("canvas2d");
    // canvas2d.width = window.innerWidth / 2;
    // canvas2d.height = window.innerHeight;
    if (canvas2d.getContext) {
      var ctx = canvas2d.getContext("2d");
      ctx.beginPath();
      ctx.arc(75, 75, 50,  0, Math.PI * 2, false); // 绘制
      ctx.moveTo(110, 75);
      ctx.arc(75, 75, 35, 0, Math.PI, false); // 口 (顺时针)
      ctx.moveTo(65, 65);
      ctx.arc(60, 65, 5, 0, Math.PI * 2, true); // 左眼
      ctx.moveTo(95, 65);
      ctx.arc(90, 65, 5, 0, Math.PI * 2, true); // 右眼
      ctx.stroke();
    }
  </script>
</html>

效果:

在这里插入图片描述
在这里插入图片描述

二次贝塞尔曲线

贝塞尔曲线一般用来画曲线,波浪等图形,依赖于贝塞尔曲线公式。可借助在线工具帮助获取想要的曲线控制点。

贝塞尔画线工具

API 说明

quadraticCurveTo(cp1x, cp1y, x, y)

绘制二次贝塞尔曲线,cp1x,cp1y为一个控制点,x,y为结束点。

下面例子是用二次贝塞尔曲线画一个提示框

示例代码

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>二次贝塞尔曲线</title>
  </head>
  <body>
    <canvas id="canvas2d" width="500" height="500"></canvas>
  </body>
  <style>
    #canvas2d {
      border: 1px solid;
      display: block;
      margin: 0 auto;
    }
  </style>

  <script>
    let canvas2d = document.getElementById("canvas2d");
    if (canvas2d.getContext) {
      var ctx = canvas2d.getContext("2d");
      // 二次贝塞尔曲线
      ctx.beginPath();
      ctx.moveTo(75, 25);
      ctx.quadraticCurveTo(25, 25, 25, 62.5);
      ctx.quadraticCurveTo(25, 100, 50, 100);
      ctx.quadraticCurveTo(50, 120, 30, 125);
      ctx.quadraticCurveTo(60, 120, 65, 100);
      ctx.quadraticCurveTo(125, 100, 125, 62.5);
      ctx.quadraticCurveTo(125, 25, 75, 25);
      ctx.stroke();
    }
  </script>
</html>

效果展示

在这里插入图片描述
在这里插入图片描述

三次贝塞尔曲线


API 说明

bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)

绘制三次贝塞尔曲线,cp1x,cp1y为控制点一,cp2x,cp2y为控制点二,x,y为结束点。

下面利用三次贝塞尔曲线画一个心形

效果演示

在这里插入图片描述
在这里插入图片描述

代码示例

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>三次贝塞尔曲线</title>
  </head>
  <body>
    <canvas id="canvas2d" width="200" height="200"></canvas>
  </body>
  <style>
    #canvas2d {
      border: 1px solid;
      display: block;
      margin: 0 auto;
    }
  </style>

  <script>
    let canvas2d = document.getElementById("canvas2d");
    if (canvas2d.getContext) {
      var ctx = canvas2d.getContext("2d");
      // 三次贝塞尔曲线
      ctx.beginPath();
      ctx.moveTo(75, 40);
      ctx.bezierCurveTo(75, 37, 70, 25, 50, 25);
      ctx.bezierCurveTo(20, 25, 20, 62.5, 20, 62.5);
      ctx.bezierCurveTo(20, 80, 40, 102, 75, 120);
      ctx.bezierCurveTo(110, 102, 130, 80, 130, 62.5);
      ctx.bezierCurveTo(130, 62.5, 130, 25, 100, 25);
      ctx.bezierCurveTo(85, 25, 75, 37, 75, 40);
      ctx.fill();
    }
  </script>
</html>

综合应用


把以上图形综合应用到项目里,添加

效果演示

在这里插入图片描述
在这里插入图片描述

代码示例

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>综合示例</title>
  </head>
  <body>
    <canvas id="canvas2d" width="500" height="500"></canvas>
  </body>
  <style>
    #canvas2d {
      border: 1px solid;
      display: block;
      margin: 0 auto;
    }
  </style>

  <script>
    let canvas2d = document.getElementById("canvas2d");
    if (canvas2d.getContext) {
      var ctx = canvas2d.getContext("2d");
      // 将坐标移动到画布中央
      ctx.translate(160, 160);

      //大石块障碍物
      roundedRect(ctx, 12, 12, 200, 200, 15);
      roundedRect(ctx, 19, 19, 200, 200, 9);
      roundedRect(ctx, 53, 53, 49, 33, 10);
      roundedRect(ctx, 53, 119, 49, 16, 6);
      roundedRect(ctx, 135, 53, 49, 33, 10);
      roundedRect(ctx, 135, 119, 25, 49, 10);

      ctx.beginPath();
      // 开始角度和结束角度限制形成缺口
      ctx.arc(37, 37, 13, Math.PI / 7, -Math.PI / 7, false);
      ctx.lineTo(31, 37);
      ctx.fill();

      // 小方块黑点
      for (var i = 0; i < 8; i++) {
        ctx.fillRect(51 + i * 16, 35, 4, 4);
      }

      for (i = 0; i < 6; i++) {
        ctx.fillRect(115, 51 + i * 16, 4, 4);
      }

      for (i = 0; i < 8; i++) {
        ctx.fillRect(51 + i * 16, 99, 4, 4);
      }

      // 怪物,从左下角开始画
      ctx.beginPath();
      ctx.moveTo(83, 116);
      ctx.lineTo(83, 102);
      ctx.bezierCurveTo(83, 94, 89, 88, 97, 88);
      ctx.bezierCurveTo(105, 88, 111, 94, 111, 102);
      ctx.lineTo(111, 116);
      ctx.lineTo(106.333, 111.333);
      ctx.lineTo(101.666, 116);
      ctx.lineTo(97, 111.333);
      ctx.lineTo(92.333, 116);
      ctx.lineTo(87.666, 111.333);
      ctx.lineTo(83, 116);
      ctx.fill();

      // 怪兽眼睛,是贝塞尔曲线不是圆
      ctx.fillStyle = "white";
      ctx.beginPath();
      ctx.moveTo(91, 96);
      ctx.bezierCurveTo(88, 96, 87, 99, 87, 101);
      ctx.bezierCurveTo(87, 103, 88, 106, 91, 106);
      ctx.bezierCurveTo(94, 106, 95, 103, 95, 101);
      ctx.bezierCurveTo(95, 99, 94, 96, 91, 96);
      ctx.moveTo(103, 96);
      ctx.bezierCurveTo(100, 96, 99, 99, 99, 101);
      ctx.bezierCurveTo(99, 103, 100, 106, 103, 106);
      ctx.bezierCurveTo(106, 106, 107, 103, 107, 101);
      ctx.bezierCurveTo(107, 99, 106, 96, 103, 96);
      ctx.fill();

      // 怪兽黑眼珠
      ctx.fillStyle = "black";
      ctx.beginPath();
      ctx.arc(101, 102, 2, 0, Math.PI * 2, true);
      ctx.fill();

      ctx.beginPath();
      ctx.arc(89, 102, 2, 0, Math.PI * 2, true);
      ctx.fill();
    }

    // 封装的一个用于绘制圆角矩形的函数。
    // 方块从左上角弧度下开始化
    function roundedRect(ctx, x, y, width, height, radius) {
      ctx.beginPath();
      ctx.moveTo(x, y + radius);
      ctx.lineTo(x, y + height - radius);
      ctx.quadraticCurveTo(x, y + height, x + radius, y + height);
      ctx.lineTo(x + width - radius, y + height);
      ctx.quadraticCurveTo(
        x + width,
        y + height,
        x + width,
        y + height - radius
      );
      ctx.lineTo(x + width, y + radius);
      ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
      ctx.lineTo(x + radius, y);
      ctx.quadraticCurveTo(x, y, x, y + radius);
      ctx.stroke();
    }
  </script>
</html>

Path2D


Path2D 看这个名字已经明白了这个对象的意义,就是路径,我们可以把路径看做对象,路径对象可以添加多条轨迹集合。这样高效在画布上进行复用。

以三维贝塞尔曲线画心型为例,可以缓存心形路径达到复用路径的目的。

代码示例

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>path2d</title>
  </head>
  <body>
    <canvas id="canvas2d" width="500" height="500"></canvas>
  </body>
  <style>
    #canvas2d {
      border: 1px solid;
      display: block;
      margin: 0 auto;
    }
  </style>

  <script>
    let canvas2d = document.getElementById("canvas2d");
    if (canvas2d.getContext) {
      var ctx = canvas2d.getContext("2d");
      // 用path 对象画图

      let heart = new Path2D();
      heart.moveTo(75, 40);
      heart.bezierCurveTo(75, 37, 70, 25, 50, 25);
      heart.bezierCurveTo(20, 25, 20, 62.5, 20, 62.5);
      heart.bezierCurveTo(20, 80, 40, 102, 75, 120);
      heart.bezierCurveTo(110, 102, 130, 80, 130, 62.5);
      heart.bezierCurveTo(130, 62.5, 130, 25, 100, 25);
      heart.bezierCurveTo(85, 25, 75, 37, 75, 40);
      ctx.stroke(heart);
      ctx.translate(30,10)
      ctx.fill(heart)
    }
  </script>
</html>

效果演示

在这里插入图片描述
在这里插入图片描述

path2d svg 路径支持

新的 Path2D API 有另一个强大的特点,就是使用 SVG path data 来初始化 canvas 上的路径。这将使你获取路径时可以以 SVG 或 canvas 的方式来重用它们。

这条路径将先移动到点 (M10 10) 然后再水平移动 80 个单位(h 80),然后下移 80 个单位 (v 80),接着左移 80 个单位 (h -80),再回到起点处 (z)。你可以在Path2D constructor 查看这个例子。

代码示例

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>path2d</title>
  </head>
  <body>
    <canvas id="canvas2d" width="500" height="500"></canvas>
  </body>
  <style>
    #canvas2d {
      border: 1px solid;
      display: block;
      margin: 0 auto;
    }
  </style>

  <script>
    let canvas2d = document.getElementById("canvas2d");
    if (canvas2d.getContext) {
      var ctx = canvas2d.getContext("2d");
      var p = new Path2D("M10 10 h 80 v 80 h -80 Z");
      ctx.strokeStyle = 'red'
      ctx.stroke(p);
    }
  </script>
</html>

效果演示

在这里插入图片描述
在这里插入图片描述
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-07-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 画矩形
  • 绘制圆形
  • 绘制五角星
  • 绘制笑脸
  • 二次贝塞尔曲线
    • API 说明
      • 示例代码
        • 效果展示
        • 三次贝塞尔曲线
          • API 说明
            • 效果演示
              • 代码示例
              • 综合应用
                • 效果演示
                  • 代码示例
                  • Path2D
                    • 代码示例
                      • 效果演示
                      • path2d svg 路径支持
                        • 代码示例
                          • 效果演示
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档