javascript中的Canvas如何绘图_与SVG相比有何优劣

Canvas是位图渲染、画完即忘,SVG是矢量DOM、保留结构;Canvas适合高频动态场景,SVG适合交互与语义化需求。

Canvas 是通过 JavaScript 操作像素来绘图的位图渲染方式,SVG 则是基于 XML 的矢量图形描述语言。两者根本差异在于:Canvas 画完即忘,SVG 保留每个图形元素的结构和属性。

Canvas 绘图的核心逻辑

Canvas 需先获取 元素的上下文(通常是 2d),再调用绘图方法逐帧绘制:

  • beginPath() 开启路径,moveTo()lineTo()arc() 等定义形状
  • stroke() 描边或 fill() 填充,图形立刻被“烧录”进像素缓冲区
  • 没有内置事件绑定机制,点击某个圆形需手动计算坐标是否在圆内
  • 缩放时会模糊,因为本质是固定尺寸的位图(除非监听窗口变化并重绘)

SVG 绘图的核心逻辑

SVG 直接写标签或用 JS 动态创建元素,每个图形都是 DOM 节点:

  • 就是一个可选中、可监听 click、可 CSS 控制的完整对象
  • 天然支持缩放、旋转等变换,且不失真——因为浏览器实时重计算矢量路径
  • 可被搜索引擎读取,也方便无障碍访问(添加 titlearia-label 即可)
  • 大量图形时 DOM 节点增多,可能影响性能,尤其频繁增删节点的动画场景

性能与适用场景对比

Canvas 更适合高频率更新的画面,比如游戏、实时数据可视化(粒子系统、波形图)、图像处理;SVG 更适合图标、交互图表(如可点击的饼图切片)、需要打印或导出高清图的 UI 元素。

  • Canvas 内存占用低,单帧绘制快,但无法直接选中/修改已画内容,得靠代码维护状态
  • SVG 渲染开销随元素数量线性增长,但每个元素独立可控,调试直观(开发者工具里能看到所有
  • 混合使用常见:用 SVG 做静态图层(背景、文字),Canvas 叠加动态层(动画、手写笔迹)

可访问性与维护成本

SVG 天然支持语义化标注,Canvas 需额外用 aria-liverole="img" 和文本替代描述补足;Canvas 代码易变复杂(尤其涉及坐标换算、状态管理),SVG 结构清晰但嵌套深时 CSS 样式易冲突。

  • Canvas 导出图片简单:canvas.toDataURL() 一行搞定
  • SVG 导出需序列化整个 XML 字符串,或用 new XMLSerializer().serializeToString(svg)
  • 动画方面:Canvas 依赖 requestAnimationFrame 手动控制;SVG 可用 CSS 动画或 SMIL(虽部分浏览器已弃用),也可用 GSAP 等库驱动属性