SVG还是画布?



SVG和canvas是可用于在网页上绘制内容的技术。 因此,应该对它们进行比较并弄清楚何时使用SVG,何时使用画布。 即使对这些技术的本质有了非常肤浅的了解,您也可以做出明智的选择。 实际上,这是两种典型的情况,其中一种应首选SVG,而另一种是canvas:

  • 需要画一个小图标吗? 这当然是SVG的领域。
  • 需要创建一个交互式浏览器游戏吗? 在这里,当然,我们需要画布技术。

这篇文章的作者(我们今天将要翻译的译本)说,他知道他尚未透露这种选择的原因。 但是他希望这些原因在分享有关SVG和canvas的一些细节后,这些原因将变得显而易见。

SVG-声明式描述的矢量图形


如果您知道需要在网页上放置矢量图像,则意味着SVG非常适合您。 矢量图像通常看起来比存储在JPG文件中的类似光栅图像更好。 此外,矢量图像文件通常比栅格图像文件小。

结果是SVG通常用于绘制徽标 。 描述此类图像的代码可以直接嵌入HTML中。 它看起来像一组声明性指令:

<svg viewBox="0 0 100 100">   <circle cx="50" cy="50" r="50" /> </svg> 

如果您需要图像灵活且响应迅速,那么SVG是您的选择。

画布-用于绘制的JavaScript API


要在页面的HTML代码中创建画布图像,请放置<canvas> ,然后使用JavaScript在该元素上“绘制”。 换句话说,程序员向浏览器提供有关他需要如何绘画的指令(这种方法更接近命令式而不是声明式)。 看起来是这样的:

 <canvas id="myCanvas" width="578" height="200"></canvas> <script>  var canvas = document.getElementById('myCanvas');  var context = canvas.getContext('2d');  var centerX = canvas.width / 2;  var centerY = canvas.height / 2;  var radius = 70;  context.beginPath();  context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);  context.fillStyle = 'green';  context.fill(); </script> 

SVG图像存储在DOM中


如果您熟悉DOM事件,例如clickmouseDown ,那么请注意,在使用SVG时也可以使用这些事件。 在这方面,SVG <circle>元素与HTML <div>元素没有太大区别。

 <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> 

SVG更适合使页面内容可访问


可以为canvas元素分配其替代文本:

 <canvas aria-label="Hello ARIA World" role="img"></canvas> 

可以对SVG元素执行相同的操作。 但是,由于SVG图像及其内部机制直接存储在DOM中,因此SVG通常被视为在创建残疾人可以访问的项目时使用的技术。

换句话说,您可以创建一个SVG图像,其中的辅助技术可以帮助用户浏览网页。

当最好使用SVG时,也是图像一部分的文本数据也是如此。 SVG甚至有一个特殊元素- <text>辅助技术可以使您显示清晰的文字字符。 如果使用canvas元素可视化文本,则此类文本通常显示不佳且看起来模糊。

画布更适合处理单个像素图像


下面我们给出一些表格,这些表格是在比较各个专家的SVG和canvas的基础上编制的。 在莎拉·德拉斯纳(Sarah Drasner)进行的一次这样的比较中,据说使用画布可以使像素跳舞。 当然,这只是个玩笑,但实质上是这样。

Canvas非常适合创建包含许多复杂细节,渐变色过渡等的交互式图像。 因此,在开发比SVG大得多的浏览器游戏时会使用canvas。 当然,尽管总能找到与总体趋势的偏差。 例如,这里的游戏是使用SVG工具创建的图形。


SVG游戏

请注意,它的图形组件非常简单,看起来很“矢量”。

CSS图像可能会受到CSS的影响


我们已经说过SVG元素存储在DOM中,并且可以从JavaScript代码获得对这些元素的访问。 就CSS而言,这个故事重复了一下:

 <svg viewBox="0 0 100 100">   <circle cx="50" cy="50" r="50" />   <style>    circle { fill: blue; }  </style> </svg> 

请注意,在示例中, <script><style>块放置在<svg>块内。 这是完全正常的。 但是考虑到SVG元素是纯HTML代码的事实,事实证明,内部的<script><style>块可以从其中完全删除。 另外,如有必要,您可以使用外部样式和脚本来处理SVG元素。

这是有关SVG元素和CSS属性的许多材料。 这里最重要的是,使用CSS可以对页面元素进行的所有操作都适用于SVG。 例如,这使用了:hover:hover和动画元素。

这是一个用CSS为<circle>元素设置动画的示例。

 <svg viewBox="0 0 100 100">   <circle cx="50" cy="50" r="50" />   <style>    circle { fill: blue; animation: pulse 2s alternate infinite; }    @keyframes pulse {      100% {        r: 30;      }    }  </style>   <script>    document.querySelector('circle').addEventListener('click', e => {      e.target.style.fill = "red";    });  </script> </svg> 


使用CSS的CSS元素动画

SVG和画布的组合


从技术角度来看,canvas和SVG技术不能称为互斥。 例如,SVG图像可以显示在<canvas>元素中。 同时,如例所示, <canvas>元素中显示的SVG图像可以很好地保持非常清晰和高质量。


将SVG图像输出到<canvas>元素

现在,让我们看一些表格,这些表格总结了各个专家在SVG和画布之间进行的比较。

比较SVG和画布


▍露丝·约翰


是构建下表的基础上项目。
商机
SVG
帆布
矢量图形
+
--
栅格图形
--+
访问DOM
+
--
有空
+
±
文字输出
+
+
渐变和图案的结论
+
+
CSS动画支持
+
--
CSS过滤器支持
+
+
SVG过滤器支持
+
+
支持输出图像文件和视频文件
--+
导出项目内容
--+
单像素管理
--+
JavaScript访问
--+
动画表演
±
+
支持在主线程之外执行的计算
--+

▍莎拉·德拉斯纳(Sarah Drasner)


下表基于推文。
DOM /虚拟DOM
帆布
好处非常适合UI / UX动画。跳舞,像素!
非常适合输出与分辨率无关的SVG图像。非常适合3D图形输出和其他类似用例。
易于调试。方便地管理许多移动物体。
缺点图像是由许多单独的对象创建的。使内容更易于访问。
鉴于前面的减法,事实证明在对SVG图像进行动画处理时需要格外小心。在标准形式下,画布图像取决于分辨率。
难以组织用户与图像的各个元素的交互。

WuShirley Wu


下表基于推文。
SVG
帆布
好处
更容易学习。
很高的性能。
更容易组织对用户曝光的响应。
更容易更新。
更容易制作动画。
缺点
您可能需要使用复杂的DOM结构。
更难学。
处理大量元素时生产率低下。
应对用户曝光更加困难。
要设置对象动画,您需要编写自己的代码。

许多人认为画布更适合处理大量对象(根据Shirley的说明(数量超过1000个))。

SVG是标准选择。 画布是一种后备


这是我关于使用SVG和canvas选项的推文答案。 该答案的作者说,SVG和画布之间的选择应按以下方式进行:“在无法使用SVG时使用画布”。 在无法正常使用SVG的情况下,我们可以提到需要动画处理数千个对象,处理图像中每个特定像素的情况,等等。

总结


在本文的开头,我们介绍了SVG和canvas的两种典型用法。 我们将返回到它们并考虑我们刚刚学到的内容来扩展它们的描述。

  • 需要画一个小图标吗? 这当然是SVG的领域。 事实是,SVG图像的描述存储在DOM中,因为SVG非常适合在按钮上绘制图标之类的东西。 不用说,SVG图像会受到CSS的影响,并且使用JavaScript,您可以将事件处理程序连接到其元素。
  • 需要创建一个交互式浏览器游戏吗? 在这里,当然,我们需要画布技术。 当然,浏览器游戏将包含许多移动元素和复杂的动画。 游戏世界中的元素将彼此交互,这意味着某些性能要求。 画布非常适合解决此类问题。

应当指出,在这两个极端选择之间有一个很大的中间区域。 例如,作为一名Web开发人员和设计师,我认为从实际的角度来看SVG更方便。 我什至不知道我是否会使用画布进行一些实际的项目。 也许这部分是因为我对画布还不够熟悉。 而且我对SVG非常熟悉。 我研究了这项技术,并写了一本书 。 结果,我对SVG有了足够的了解,因此这项技术可以帮助我完成所需的工作。

亲爱的读者们! 在哪种情况下使用SVG,在哪种画布上使用?


Source: https://habr.com/ru/post/zh-CN476292/


All Articles