Skip to content

简介

https://www.imooc.com/learn/133

简介

作为 HTML5 核心技术之一,Canvas 应用非常广泛,可以用于绘制图形、绘制图表、动画开发以及游戏开发等

很多网页游戏主体就只有一个 canvas 标签,用 javascript 来控制其行为

在 HTML5 之前,为了达到页面绚丽多彩的效果,我们很多情况下都是借助"图片"来实现。不过使用图片这种方式,都是以“低性能”为代价的。
由于图片体积大、下载速度慢等原因,因此为了应对日渐复杂的 Web 应用开发,W3C 在 HTML5 标准中引入了 Canvas 这一门技术

我们都知道,HTML5 新增了一个 Canvas 元素。其实,Canvas 又称为"画布",是 HTML5 的核心技术之一。
我们常说的 Canvas 技术,指的就是使用 Canvas 元素结合 Javascript 来绘制各种图形的技术

既然 Canvas 是 HTML5 核心技术,那它都有哪些厉害之处呢?

1.绘制图形

Canvas 可以用来绘制各种基本图形如矩形、曲线、圆等,也可以绘制各种复杂绚丽的图形

2.绘制图表

很多公司业务的数据展示都离不开图表,使用 Canvas 可以用来绘制满足各种需求的图表

3.动画效果

使用 Canvas,我们也可以制作出各种华丽的动画效果,这也是 Canvas 为大家带来的一大乐趣

4.游戏开发

游戏开发在 HTML5 领域具有举足轻重的地位,现在我们也可以使用 Canvas 来开发各种游戏。这几年非常火的游戏如围住神经猫等,就是使用 HTML5 Canvas 来开发的
此外,Canvas 技术是一门纯 JavaScript 操作的技术,因此大家需要具备 JavaScript 入门知识

在 HTML 文档中,<canvas> 元素本身并不可见,它只是创建了一个绘图表面并向客户端暴露了强大的绘图 API。
<canvas> API 与 SVG 的主要区别在于使用画布(canvas)绘图要调用方法,而使用 SVG 创建图形则需要构建 XML 元素树。
这两种绘图手段同样强大,而且可以相互模拟。但从表面上来看,这两种手段迥然不同,又有各自的优缺点。
比如,修改 SVG 图形很简单,可能只需从描述中删除元素即可。
而要从同样的 <canvas> 图形中删除元素通常需要先擦掉图形再重新绘制。
画布绘图 API 是基于 JavaScipt, 而且相对比较简洁(不像 SVG 语法那么复杂)

画布中的 3D 图形:
在调用 getContext() 时传入 "webgl" 也可以获取一个 3D 图像上下文,并使用 WebGL API 来绘制 3D 图形。
WebGL API 是一套庞大、复杂、低级的 JavaScript API,开发者通过它可以访问 GPU、写自定义的着色器,以及执行其他非常强大的图形操作。

Canvas 与 SVG

HTML5 有两个主要的 2D 图形技术: Canvas 和 SVG。事实上,Canvas 和 SVG 是两门完全不同的技术。两者具有以下区别

(1) Canvas 是使用 JavaScript 动态生成的,SVG 是使用 XML 静态描述的

(2) Canvas 是基于 "位图" 的,适用于像素处理和动态渲染,图形放大回影响质量。SVG 是基于"矢量"的,不适用于像素处理和静态描述,图形放大不会影响质量。
也就是说,使用 Canvas 绘制出来的是一个 “位图”,而使用 SVG 绘制出来的是一个 “矢量图”

(3) 每次发生修改,Canvas 需要重绘,而 SVG 不需要重绘

(4) Canvas 与 SVG 的关系,简单来说,就像“美术与几何”的关系一样

此外,并非 Canvas 就比 SVG 更有前途,也并非 SVG 就比 Canvas 更有前途,因为这两个是用于不同场合的。在实际开发中,我们应该根据开发需求去选择。

当然,这里只是简单介绍了一下 Canvas 与 SVG 的区别,如果想真正了解,我们还需要深入学习这两门技术。
最后给大家一个小小的建议: 很多人接触新技术的时候,喜欢在第一遍学习中就把每一个细节都弄清楚,事实上这是效率最低的学习方法。
在第一遍学习中,如果有些东西实在没办法理解,那就直接跳过,等到学到后面或者看第二遍的时候,自然而然就懂了

Canvas 元素知识

HTML5 Canvas,简单来说,就是一门使用 JavaScript 来操作 Canvas 元素的技术。使用 Canvas 元素来绘制图形,需要以下三步。

(1) 获取 canvas 对象
(2) 获取上下文环境对象 context
(3) 开始绘制图形

大多数画布绘图 API 都没有定义在 <canvas> 元素上,而是定义在通过画布的 getContext() 方法获得的 “绘图上下文” 上。
调用 getContext() 时传入 "2d" 可以得到一个 Canvas RenderingContext2D 对象,使用它能够在画布上绘制二维图形

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <title>Page Title</title>
  <script type="text/javascript">
    window.onload = function() {
      let cnv = document.getElementById("canvas")
      let ctx = cnv.getContext("2d")
      ctx.moveTo(50, 100)
      ctx.lineTo(150, 50)
      ctx.stroke()
    }
  </script>
</head>
<body>
  <canvas
    id="canvas"
    width="200"
    height="150"
    style="border:1px dashed gray;"
  >
  </canvas>
</body>
</html>

Canvas 是一个行内块元素(即 inline-block), 我们一般需要指定其三个属性: id、width 和 height。
width 和 height 分别定义 Canvas 的宽度和高度。默认情况下,Canvas 的宽度为 300px,高度为 150px

作为 Canvas API 的一个简单示例,以下 HTML 文档使用了 <canvas> 元素和一些 JavaScript 展示了两个简单的形状

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <title>Page Title</title>
</head>
<body>
  <p>This is a red square: <canvas id="square" width=10 height=10></canvas></p>
  <p>This is a blue circle: <canvas id="circle" width=10 height=10></canvas></p>
  <script>
    let canvas = document.querySelector("#square") // 取得第一个画布元素   
    let context = canvas.getContext("2d")  // 取得 2D 回去上下文   
    context.fillStyle = "#f00";  // 设置填充色为红色   
    context.fillRect(0,0,10,10)   // 填充一个方块      

    canvas = document.querySelector("#circle") // 第二个画布元素   
    context = canvas.getContext("2d") // 取得其上下文   
    context.beginPath();  // 开始一个新的 “路径”   
    context.arc(5, 5, 5, 0, 2*Math.PI, true) // 为路径添加一个圆形     
    context.fillStyle = "#00f";  // 设置蓝色填充色
    context.fill()   // 填充路径    
  </script>
</body>
</html>

我们知道,SVG 将复杂图形描述为可以绘制和填充的直线“路径”或曲线。
而 canvas API 也使用了路径的概念,但它没有使用字母和数字的字符串来描述路径,而是通过一系列方法调用来定义路径。
比如前面的例子中的 beginPath() 和 arc() 调用。定义了路径之后,后面的方法调用(如 fill() ) 就会操作该路径。
上下文对象的各种属性(如 fillStyle)) 用于指定如何执行操作

1
2
beginPath()
closePath()   
1
2
3
4
5
context.arc(
    centerx, centery, radius,
    stratingAngle, endingAngle,
    anticlockwise=false
)

画布大小与坐标

在 HTML 中通过 <canvas> 的 width 和 height 属性,或者在 JavaScript 中通过画布对象的 weight 和 height 属性可以指定画布的大小。
画布坐标系的默认原点在画布左上角的 (0,0) 点。x 坐标向右增大,y 坐标向下增大。画布中的点可以使用浮点数来指定