面试题:Canvas 和 SVG 有什么区别?

<canvas><svg> 都是 HTML5 中用于在网页上绘制图形、创建动态视觉效果的技术,但它们在底层原理、使用方式、性能特点和适用场景上有着根本性的区别。

以下是 Canvas 和 SVG 的主要区别:

特性Canvas (画布)SVG (可缩放矢量图形)
类型基于像素的位图 (Raster Graphics)基于矢量的图形 (Vector Graphics)
原理通过 JavaScript 脚本在画布上逐个像素地绘制图形。一旦绘制完成,浏览器就不再“记住”这些图形对象。使用 XML 描述图形。每个图形元素(如 <circle>, <rect>)都是 DOM 树中的一个独立节点,浏览器知道每个对象的存在。
可缩放性。放大时会出现像素化、模糊。因为它是固定分辨率的位图。极佳。可以无限放大而不会失真或模糊。因为它是基于数学公式描述的矢量图形。
DOM 操作不支持。画布上的图形不是独立的 DOM 元素。无法直接通过 CSS 或 JavaScript 选择器操作单个已绘制的图形。要修改,必须清除画布并重新绘制。支持。每个图形元素都是独立的 DOM 节点。可以使用 CSS 样式化,也可以用 JavaScript 轻松地添加、删除、修改单个元素及其属性(如颜色、位置、大小)。
事件处理复杂。无法直接为画布上的某个图形绑定事件(如点击)。需要通过计算鼠标坐标是否在图形区域内来手动实现(“命中检测”),逻辑复杂。简单。每个 SVG 元素都可以像普通 HTML 元素一样直接绑定事件监听器(如 onclick, onmouseover)。
文件大小对于复杂、密集的图像(如照片、大型游戏),文件体积通常更小。对于简单、线条构成的图形(如图标、图表),文件体积较小。图形越复杂,文件越大。
性能重绘性能好,适合高频率、大量的绘制操作(如游戏、实时数据可视化、视频处理)。但整个画布重绘成本高。单个元素操作性能好,适合少量、静态或需要频繁交互的图形。当图形元素非常多时,DOM 操作可能成为性能瓶颈。
文本渲染文本被视为像素图像的一部分,一旦绘制完成就无法像文本一样被选择或搜索。文本是真正的文本对象,可以被用户选择、复制,对搜索引擎友好,可访问性好。
学习曲线需要理解绘图 API 和坐标系统,编程方式更底层。语法是 XML/HTML,更接近声明式,对前端开发者更友好。
主要用途游戏、实时渲染、数据可视化(动态图表)、图像编辑、视频处理、需要高性能绘制的场景。图标、Logo、图表(静态或交互少)、地图、需要高可缩放性和可访问性的图形、印刷质量的图形。

核心区别总结

  1. 位图 vs 矢量
    • Canvas 是“画布”,你告诉它“在这里画一个红点,然后在那里画一条线”,它就把这些指令转换成像素画出来,完成后就忘了过程。
    • SVG 是“图纸”,你描述“这里有一个红色的圆,那里有一个蓝色的矩形”,它会记住这些对象,并能随时修改它们。
  2. 程序性 vs 声明性
    • Canvas程序性的:通过 JavaScript 代码一步步“命令”浏览器绘制。
    • SVG声明性的:用 XML/HTML 标签“声明”要什么图形。
  3. 修改方式
    • 修改 Canvas 上的图形,通常需要 clearRect() 清除画布,然后重新执行所有绘制命令。
    • 修改 SVG 中的图形,可以直接用 element.setAttribute('fill', 'blue') 改变某个 <circle> 的颜色,无需重绘整个画面。

如何选择?

  • 选择 Canvas 当
    • 需要高性能、高帧率的渲染(如 2D/3D 游戏)。
    • 需要处理像素级操作(如图像滤镜、视频帧处理)。
    • 图形非常复杂且动态变化频繁,但不需要单个元素交互。
    • 对文件大小有严格要求(针对复杂图像)。
  • 选择 SVG 当
    • 需要图形在任何尺寸下都清晰(如响应式设计、高分辨率屏幕)。
    • 图形相对简单,且需要与用户进行交互(如点击、悬停图表)。
    • 需要良好的可访问性(如屏幕阅读器能读取文本)。
    • 图形是静态或变化较少的(如图标、Logo、信息图表)。
    • 希望用 CSS 轻松地样式化图形。

简单记忆:Canvas 像 Photoshop(处理像素),SVG 像 Illustrator(处理矢量路径)。

THE END
喜欢就支持一下吧
点赞14 分享