# 什么是 Canvas

前一段学习了一个学知识的方法论,个人觉得很有用,推荐给大家,就是在学习一个概念的时候,先问一下这个知识的概念是什么,然后再看一下这个知识它被提出来的目的是什么,然后如果你能将其用一句话说清楚,那么你就理解了该知识点。

所以对于什么是 Canvas,我们也按照这个方法来分析。

学习概念步骤

# 什么是 Canvas

MDN 中是这样定义 <canvas> 的:

<canvas> 是 HTML5 新增的元素,可用于通过使用 JavaScript 中的脚本来绘制图形。例如,它可以用于绘制图形、制作照片、创建动画,甚至可以进行实时视频处理或渲染。

这里需要划重点的是,<canvas> 只是一个画布,本身并不具有绘图的能力,绘图必须使用 JavaScript 等脚本语言。

<canvas> 标签允许脚本语言动态渲染位图像。<canvas> 标签创建出了一个可绘制区域,JavaScript 代码可以通过一套完整的绘图功能类似于其他通用二维的 API 访问该区域,从而生成动态的图形。

我们可以认为 <canvas> 标签只是一个矩形的画布。JavaScript 就是画笔,负责在画布上画画。

例如,我的个人博客中的背景就是使用 Canvas 制作的。 http://cherryblog.site/

我们审查元素可以看到整个背景就是一个 Canvas 元素,宽度和高度都是 100%。 http://cherryblog.site/

# Canvas 解决了什么问题

我在 MSDN(《Microsoft Developer Network》是微软一个期刊产品,专门介绍各种编程技巧)上找到了 Canvas 出现的背景,来给大家简单介绍一下。

在互联网出现的早期,Web 只不过是静态文本和链接的集合。1993 年,有人提出了 img 标签,它可以用来嵌入图像。

由于互联网的发展越来越迅猛,Web 应用已经从 Web 文档发展到 Web 应用程序。但是图像一直是静态的,人们越来越希望在其网站和应用程序中使用动态媒体(如音频、视频和交互式动画等),于是 Flash 就出现了。

但是随着 Web 应用的发展,出现了 HTML5,在 HTML5 中,浏览器中的媒体元素大受青睐。包括出现新的 AudioVideo 标签,可以直接将音频和视频资源放在 Web 上,而不需要其他第三方。

其次就是为了解决只能在 Web 页面中显示静态图片的问题,出现了 Canvas 标签。它是一个绘图表面,包含一组丰富的 JavaScript API,这些 API 使你能够动态创建和操作图像及动画。img 对静态图形内容起到了哪些作用,Canvas 就可能对可编写脚本的动态内容起到哪些作用。

# 一句话总结 Canvas 是什么

什么是 Canvas?Canvas 是为了解决 Web 页面中只能显示静态图片这个问题而提出的,一个可以使用 JavaScript 等脚本语言向其中绘制图像的 HTML 标签。

# 浏览器支持情况

Canvas 已经受到了主流浏览器的支持,并且支持情况良好,具体支持情况如下:

元素 Chrome IE Firefox Safari Opera
Canvas 4.0+ 9.0+ 2.0+ 3.1+ 9.0+

# 怎么在网页上画一个圆

通过上述的介绍,大家应该大体上明白了 <canvas> 是可以在 Web 页面上绘制图形的 HTML 标签。那么为什么要使用这种技术而不是其他的呢?

这里我们就要分析一下 canvas 和其他技术的区别了。

怎么在网页上画一个圆?这是笔者之前在面试的时候遇到的一个问题 (ಥ_ಥ)

我想到的方法有以下几种,当然,如果你有更(qí)好(jì)方(yín)式(qiǎo)也可以留言。

  • 直接使用图片,如果需求只是显示一个圆形,那么可以直接使用图片。
  • 使用 div + CSS3 的 border + border-radius 模拟一个圆。
  • 使用 svg。可能对于很多前端来说,svg 和 png、jpg 等其他图片格式是一样的,但其实还是有一定的差别。下面我们会详细介绍 svg。
  • Canvas + JavaScript 动态画一个圆。

那么我们来分析一下以上几种方式的优劣性:

  • 使用图片可以说是以上几种方式中排名倒数第一的了,因为直接使用图片首先会增加一次请求(制作成精灵图另说),其次是不易更改,如果想换一种颜色就需要更换图片,代价太大。
  • 使用 div + CSS3 的方式适用于单个的圆,实现起来比较简单,代价也比较小,但增加了一个没有意义的 DOM 节点,不符合语义化编程规范。
  • 使用 svg 和 Canvas 都可以使用脚本语言来动态写入一个圆。

那么,使用 svg 和 Canvas 又有什么区别呢?

# svg 和 Canvas 的区别

# 什么是 svg

刚刚我们介绍了 Canvas,那么什么是 svg 呢?

svg(Scalable Vector Graphics,可缩放矢量图形)是基于 XML(可扩展标记语言,标准通用标记语言的子集),用于描述二维矢量图形的一种图形格式。它由 W3C(万维网联盟)制定,是一个开放标准。

简单的说就是,svg 可以用来定义 XML 格式的矢量图形

因为其本质是 XML 文件,所以 svg 是使用 XML 文档描述来绘图的。和 HTML 一样,如果我们需要修改 svg 文件,可以直接使用记事本打开修改。

# Canvas 和 svg 的区别

Canvas 和 svg都允许你在浏览器中创建图形,但是它们在根本上是不同的,那么 Canvas 和 svg 有什么根本区别呢?

就如刚刚介绍的那样,svg 本质上是一种使用 XML 描述 2D 图形的语言

svg 创建的每一个元素都是一个独立的 DOM 元素,既然是独立的 DOM 元素,那么我们就可以通过 css 和 JavaScript 来操控 dom。可以对每一个 DOM 元素进行监听。

并且因为每一个元素都是一个 DOM 元素,所以修改 svg 中的 DOM 元素,系统会自动进行 DOM 重绘。

Canvas 通过 JavaScript 来绘制 2D 图形,Canvas 只是一个 HTML 元素,其中的图形不会单独创建 DOM 元素。因此我们不能通过 JavaScript 操控 Canvas 内单独的图形,不能对其中的具体图形进行监控。

在 Canvas 中,一旦图形被绘制完成,它就不会继续得到浏览器的关注。如果其位置发生变化,那么整个场景也需要重新绘制,包括任何或许已被图形覆盖的对象。

实际上 Canvas 是基于像素的即时模式图形系统,绘制完对象后不保存对象到内存中,当再次需要这个对象时,需要重新绘制;svg 是基于形状的保留模式图形系统,绘制完对象后会将其保存在内存中,当需要修改这个对象信息时,直接修改就可以了。这种根本的区别导致了很多应用场景的不同。

Canvas svg
依赖分辨率(位图) 不依赖分辨率(矢量图)
单个 HTML 元素 每一个图形都是一个 DOM 元素
只能通过脚本语言绘制图形 可以通过 CSS 也可以通过脚本语言绘制
不支持事件处理程序 支持事件处理程序
弱的文本渲染能力 最适合带有大型渲染区域的应用程序(比如谷歌地图)
图面较小,对象数量较大(>10k)时性能最佳 对象数量较小 (<10k)、图面更大时性能更佳

所以是选择 Canvas 还是 svg 还是需要看自己的需求。

本小册主要介绍 Canvas 的相关内容,对 svg 不做过多的介绍~