经常性的,我很喜欢观察一些精巧的动画,观察一些精美的图表。也知道很多效果是通过canvas实现的,也配合实现过一个小图表吗,而且一些数据可视化库如ECharts大部分都是通过canvas实现的。但一直以来并未完整的学习一下canvas,最近刚好需要研究一下数据可视化,决定对canvas进行系统的学习。
什么是 Canvas
在 MDN 中是这样定义<canvas>
的:
<canvas>
是 HTML5 新增的元素,可用于通过使用 JavaScript 中的脚本来绘制图形。例如,它可以用于绘制图形、制作照片、创建动画,甚至可以进行实时视频处理或渲染。
<canvas>
只是一个画布,本身并不具有绘图的能力,绘图必须使用 JavaScript 等脚本语言。
canvas标签允许脚本语言动态渲染位图像,使用该标签可以创建出一个可绘制的区域,js代码通过一套完整的绘图功能api,对该区域进行操作,从而生成动态的图形。换句话说,canvas是一块矩形画布,js是画笔,负责在画布上实现图形的绘制。
web应用的发展
在互联网出现的早期,Web 只不过是静态文本和链接的集合。1993 年,有人提出了 img 标签,它可以用来嵌入图像。
由于互联网的发展越来越迅猛,Web 应用已经从 Web 文档发展到 Web 应用程序。但是图像一直是静态的,人们越来越希望在其网站和应用程序中使用动态媒体(如音频、视频和交互式动画等),于是 Flash 就出现了。
但是随着 Web 应用的发展,出现了 HTML5,在 HTML5 中,浏览器中的媒体元素大受青睐。包括出现新的 Audio 和 Video 标签,可以直接将音频和视频资源放在 Web 上,而不需要其他第三方。其次就是为了解决只能在 Web 页面中显示静态图片的问题,出现了 Canvas 标签。它是一个绘图表面,包含一组丰富的 JavaScript API,这些 API 使你能够动态创建和操作图像及动画。img 对静态图形内容起到了哪些作用,Canvas 就可能对可编写脚本的动态内容起到哪些作用。
兼容性
Canvas 已经受到了主流浏览器的支持,并且支持情况良好,具体支持情况如下:
canvas和其他技术的区别
假如有个简单图形需要显示到界面上,我们可以通过很多种方式实现,比如:img标签直接使用图片,比如使用div+css,比如使用svg(和使用其他的图片格式在使用方式上基本没有区别),然后就是使用canvas。
- 使用图片的话是最不好的一个方式,首先会有增加一次网络请求,制作成为精灵图会好点;其次是不容易修改,需要换个颜色的话,代价太大。
- 使用div+css的方式适合单个的图形,实现起来也较为简单,代价也很小,但是增加了一个没有意义的dom节点,不符合语义化编程的规范。
- 使用svg和canvas都可以动态写入一个图形,两者的实现都不错,但是使用的场景有些区别。
svg 和 Canvas 的区别
那么什么是 svg 呢?
svg(Scalable Vector Graphics,可缩放矢量图形)是基于 XML(可扩展标记语言,标准通用标记语言的子集),用于描述二维矢量图形的一种图形格式。它由 W3C(万维网联盟)制定,是一个开放标准。
简单的说就是,svg 可以用来定义 XML 格式的矢量图形。
因为其本质是 XML 文件,所以 svg 是使用 XML 文档描述来绘图的。和 HTML 一样,如果我们需要修改 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的应用场景
绘制图标,web游戏开发,一些活动页面(如转盘抽奖,刮奖等),一些背景特效(如粒子特效,与鼠标的交互背景,web看板等)
好玩的栗子
14款震撼人心的HTML5文字特效
10大炫酷的HTML5文字动画特效欣赏
参考资料
HTML5 Canvas半知半解