Canvas学习笔记一 - 图形的绘制

一、替换内容

<!-- 当前浏览器如果不支持 canvas 标签时,会打印 canvas 内部的html标签 -->
<canvas id="stockGraph" width="150" height="150">
  current stock price: $3.15 +0.15
</canvas>

<canvas id="clock" width="150" height="150">
  <img src="images/clock.png" width="150" height="150" alt=""/>
</canvas>

在这里插入图片描述
(左图:IE8,右图:谷歌 89.0.0)

二、渲染上下文

  • getContext(),只有一个参数,上下文的格式‘2d’
  • CanvasRenderingContext2D,2D图像处理

三、检查支持性

if (canvas.getContext) {
	var ctx = canvas.getContext('2d');
}

模板骨架

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Canvas学习笔记</title>
    <style>
      canvas {
        border: 1px solid black;
      }
    </style>
  </head>
  <body onload="draw()">
    <canvas id="canvas" width="150" height="150"></canvas>
  </body>
  <script>
    function draw() {
      var canvas = document.getElementById('canvas');

      if (canvas.getContext) {
        var ctx = canvas.getContext('2d');

        // 代码编写
      }
    }
  </script>
</html>

四、属性与方法

1. 绘制矩形

属性、方法说明
fillRect(x, y, width, height)绘制一个填充的矩形
strokeRect(x, y, width, height)绘制一个矩形的边框
clearRect(x, y, width, height)清除指定矩形区域,让清除部分完全透明。
rect(x, y, width, height)绘制一个左上角坐标为(x,y),宽高为width以及height的矩形。(画完之后是空白的,没有边框显示,需要配合 stroke() 使用)
draw = () => {
  var canvas = document.getElementById('canvas');

  if (canvas.getContext) {
    var ctx = canvas.getContext('2d');

    ctx.fillRect(25, 25, 100, 100);
    ctx.clearRect(35, 35, 40, 40)
    ctx.strokeRect(45, 45, 20, 20);
    ctx.clearRect(75, 75, 40, 40);
    ctx.strokeRect(85, 85, 20, 20);
  }
};

2. 绘制路径

  1. 首先,你需要创建路径起始点。
  2. 然后你使用画图命令去画出路径。
  3. 之后你把路径封闭。
  4. 一旦路径生成,你就能通过描边或填充路径区域来渲染图形。

注意:当前路径为空,即调用beginPath()之后,或者canvas刚建的时候,第一条路径构造命令通常被视为是moveTo(),无论实际上是什么。出于这个原因,你几乎总是要在设置路径之后专门指定你的起始位置。

方法说明
beginPath()新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。
closePath()闭合路径之后图形绘制命令又重新指向到上下文中。
stroke()通过线条来绘制图形轮廓。
fill()通过填充路径的内容区域生成实心的图形。
// 绘制一个三角形
draw = () => {
  var canvas = document.getElementById('canvas');

  if (canvas.getContext) {
    var ctx = canvas.getContext('2d');
    
    ctx.beginPath();
    ctx.moveTo(25, 25);
    ctx.lineTo(25, 100);
    ctx.lineTo(125, 100);
    ctx.fill( )
  }
};

3. 移动笔触

一个非常有用的函数,而这个函数实际上并不能画出任何东西,也是上面所描述的路径列表的一部分,这个函数就是moveTo()。或者你可以想象一下在纸上作业,一支钢笔或者铅笔的笔尖从一个点到另一个点的移动过程。

方法说明
moveTo(x, y)将笔触移动到指定的坐标x以及y上。
// 画一个笑脸
draw = () => {
  var canvas = document.getElementById('canvas');

  if (canvas.getContext) {
    var ctx = canvas.getContext('2d');

    ctx.beginPath();
    ctx.arc(75, 75, 50, 0, Math.PI * 2, true);
    ctx.moveTo(115, 75);
    ctx.arc(75, 75, 40, 0, Math.PI, false);
    ctx.moveTo(70, 60)
    ctx.arc(60, 60, 10, 0, Math.PI * 2, true);
    ctx.moveTo(100, 60)
    ctx.arc(90, 60, 10, 0, Math.PI * 2, true);

    ctx.stroke();
  }
};

效果图如下:前者没有使用moverTo属性,后者则是使用了。
在这里插入图片描述

4. 线

方法说明
lineTo(x, y)绘制一条从当前位置到指定x以及y位置的直线。
draw = () => {
  var canvas = document.getElementById('canvas');

  if (canvas.getContext) {
    var ctx = canvas.getContext('2d');
    // 填充三角形
    ctx.beginPath();
    ctx.moveTo(25, 25);
    ctx.lineTo(25, 75);
    ctx.lineTo(60, 50);
    ctx.fill(); // 填充图形,可以直接使用fill方法,路径会自动闭合。

	// 描边三角形
    ctx.beginPath();
    ctx.moveTo(100, 80);
    ctx.lineTo(100, 130);
    ctx.lineTo(50, 105);
    ctx.closePath(); // 描边图形,需要手动闭合路径,否则边框会缺失。
    ctx.stroke();
  }
};

5. 圆

方法说明
arc(x, y, radius, startAngle, endAngle, anticlockwise)画一个以(x,y)为圆心的以radius为半径的圆弧(圆),从startAngle开始到endAngle结束,按照anticlockwise给定的方向(默认为顺时针)来生成。
arcTo(x1, y1, x2, y2, radius)根据给定的控制点和半径画一段圆弧,再以直线连接两个控制点。

这里详细介绍一下arc方法,该方法有六个参数:x,y为绘制圆弧所在圆上的圆心坐标。radius为半径。startAngle以及endAngle参数用弧度定义了开始以及结束的弧度。这些都是以x轴为基准参数anticlockwise为一个布尔值。为true时,是逆时针方向,否则顺时针方向

注意:arc()函数中表示角的单位是弧度,不是角度。角度与弧度的js表达式: 弧度=(Math.PI/180)*角度。1弧度约等于57度。

draw = () => {
  let canvas = document.getElementById('canvas');

  if (canvas.getContext) {
    let ctx = canvas.getContext('2d');
    for (var i = 0; i < 4; i++) {
      for (var j = 0; j < 3; j++) {
        ctx.beginPath();
        var x = 25 + j * 50; // x 坐标值
        var y = 25 + i * 50; // y 坐标值
        var radius = 20; // 圆弧半径
        var startAngle = 0; // 开始点
        var endAngle = Math.PI + (Math.PI * j) / 2; // 结束点
        var anticlockwise = i % 2 == 0 ? false : true; // 顺时针或逆时针

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

        if (i > 1) {
          ctx.fill();
        } else {
          ctx.stroke();
        }
      }
    }
  }
};

6. 二次贝塞尔曲线及三次贝塞尔曲线

方法说明
quadraticCurveTo(cp1x, cp1y, x, y)绘制二次贝塞尔曲线,cp1x,cp1y为一个控制点,x,y为结束点。
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)绘制三次贝塞尔曲线,cp1x,cp1y为控制点一,cp2x,cp2y为控制点二,x,y为结束点。

二次贝塞尔曲线及三次贝塞尔曲线的关系:二次贝塞尔曲线有一个开始点(蓝色)、一个结束点(蓝色)以及一个控制点(红色),而三次贝塞尔曲线有两个控制点。
在这里插入图片描述

// 聊天气泡 二次贝塞尔曲线
function draw() {
  var canvas = document.getElementById('canvas');
  if (canvas.getContext) {
    var ctx = canvas.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();
   }
}

// 填充心形 三次贝塞尔曲线
function draw() {
  var canvas = document.getElementById('canvas');
  if (canvas.getContext){
    var ctx = canvas.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();
  }
}

五、Path2D 对象

正如我们在前面例子中看到的,你可以使用一系列的路径和绘画命令来把对象“画”在画布上。为了简化代码和提高性能,Path2D对象已可以在较新版本的浏览器中使用,用来缓存或记录绘画命令,这样你将能快速地回顾路径。
Path2D()会返回一个新初始化的Path2D对象(可能将某一个路径作为变量——创建一个它的副本,或者将一个包含SVG path数据的字符串作为变量)。

方法说明
Path2D.addPath(path [, transform])​添加了一条路径到当前路径(可能添加了一个变换矩阵)。
function draw() {
  var canvas = document.getElementById('canvas');
  if (canvas.getContext){
    var ctx = canvas.getContext('2d');

    var rectangle = new Path2D();
    rectangle.rect(10, 10, 50, 50);

    var circle = new Path2D();
    circle.moveTo(125, 35);
    circle.arc(100, 35, 25, 0, 2 * Math.PI);

    ctx.stroke(rectangle);
    ctx.fill(circle);
  }
}

使用 SVG paths

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

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

var p = new Path2D("M10 10 h 80 v 80 h -80 Z");
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

俊小赞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值