从SVG到Canvas:选择最适合你的Web图形技术

SVG 和 Canvas 都是可以在 Web 浏览器中绘制图形的技术。

众所周知, icon 通常使用 svg(如 iconfont),而交互式游戏采用 Canvas。二者具体的区别是什么?该如何选择?

  • 声明式还是命令式?
  • 绘制的图形不同:Svg 绘制矢量图(不依赖分辨率),Canvas 绘制位图(依赖分辨率);
  • 事件处理不同:Svg 基于 XML,对 DOM、事件友好,Canvas 通过 javascript 绘制,内部元素添加事件比较复杂;
  • Svg 对于 css 更加友好

声明式 pk 命令式

Svg 是矢量【声明式】

可缩放矢量图形 (Scalable Vector Graphics,SVG )基于 XML 标记语言,用于描述二维的矢量图形。

作为一个基于文本的开放网络标准,SVG 能够优雅而简洁地渲染不同大小的图形,并和CSS、DOM、JavaScript 和 SMIL 等其他网络标准无缝衔接。本质上,SVG 相对于图像,就好比 HTML 相对于文本。

SVG 图像及其相关行为被定义于 XML 文本文件之中,这意味着可以对它们进行搜索、索引、编写脚本以及压缩。此外,这也意味着可以使用任何文本编辑器和绘图软件来创建和编辑它们。

SVG 代码可以直接在 HTML 中运行,就像声明性绘图指令:

html 复制代码
<svg viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="50" />
</svg>

和传统的点阵图像模式(JPEG、PNG)不同的是,SVG 格式提供的是**矢量图,这意味着它的图像能够被无限放大而不失真或降低质量,并且可以方便地修改内容,无需图形编辑器。**通过使用合适的库进行配合,SVG 文件甚至可以随时进行本地化。

如果关心图形的灵活性和响应(不失真)能力,SVG 就是最佳选择。

Canvas 是一个 JavaScript 绘图 API【命令式】

Canvas 提供了一个通过 JavaScript 和 HTML 的元素来绘制图形的方式。

将一个<canvas>元素放入 HTML 中,然后使用 JavaScript 进行绘图。换句话说,可以发出命令告诉它如何绘制,典型的命令式!

html 复制代码
<canvas id="myCanvas" width="100" height="100"></canvas>
<script>
  var canvas = document.getElementById('myCanvas');
  var context = canvas.getContext('2d');
  var centerX = canvas.width / 2;
  var centerY = canvas.height / 2;
  var radius = 50;

  context.beginPath();
  context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
  context.fillStyle = 'green';
  context.fill();
</script>

DOM pk 画布

SVG 在 DOM 中

如果熟悉 DOM 事件(例如click和mouseDown等),那么 SVG 中也可以使用这些事件。

html 复制代码
<svg viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="50" />
  <script>
    document.querySelector('circle').addEventListener('click', e => {
      e.target.style.fill = "red";
    });
  </script>
</svg>

canvas 像画布

具有大量复杂细节和渐变的高度交互性工作是 Canvas 的领域。DOM 管理元素越多,速度就越慢,移动的元素越多,速度就越慢。且 Canvas 有不错的性能保障。由于这个原因,使用 Canvas 构建的游戏比使用 Svg 构建的游戏多得多。

与 CSS 的友好性

svg 可以很好的结合 css

与上述事件方式类似,可以通过css进行样式处理

html 复制代码
<svg viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="50" />
  <style>
    circle { fill: blue; }
  </style>
</svg>
相关推荐
周永恒3 小时前
汉字字形 SVG 库整理
svg·许可·汉字·字形
行者全栈架构师3 天前
我让 AI 独立开发了一款游戏:零依赖、188 个测试全绿、工期压到四分之一
typescript·canvas·vibecoding
一只游鱼6 天前
我用原生 JS 做了一个「会呼吸」的博客:Canvas 水境 + 合成音效 + 会破裂的留言气泡(vibe coding)
javascript·agent·canvas·github pages
code_long7 天前
.net core 连接打印机 使用zpl指令打印机,并且位图本地渲染zpl指令
c#·.netcore·位图·打印机·模板编辑·模板预览
长路 ㅤ   7 天前
从中国城市散点到 3D 全球访客地球:BlogLoom 访客地图的设计与实现
开源项目·数据可视化·canvas·blogloom·访客地图
贾伟康8 天前
【化学实验室|04】HarmonyOS ArkTS 场景选择器实战:让 13 个离线实验的入口、筛选和返回路径保持一致
harmonyos·arkts·canvas·arkui·化学实验
MicrosoftReactor8 天前
技术速递|当聊天框不再是合适的交互界面
ui·ai·copilot·canvas
贾伟康11 天前
【化学实验室|02】HarmonyOS ArkTS 实验结果载荷实战:用强类型模型隔离页面参数与结果展示
harmonyos·arkts·canvas·arkui·化学实验
行者-全栈开发13 天前
华为云码道 CodeArts 实测:让 AI 用纯 TypeScript 写一个确定性回放的塔防小游戏「熵减特勤局」
typescript·小游戏·canvas·ecs·ai 编程·华为云码道·codearts 代码智能体
ji_shuke16 天前
使用 Canvas 和 mix-blend-mode 实现跟随鼠标的反色圆圈
microsoft·计算机外设·canvas