SVG 与 HTML5 的 canvas 各有啥优点,哪个更有前途

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SVG 与 HTML5 的 canvas 各有啥优点,哪个更有前途相关的知识,希望对你有一定的参考价值。

对于开发人员而言,最直观的区别在于: 1.对于画在Canvas上的部件,你需要处理重绘。而SVG则不用,你修改svg dom则系统会自动帮你重绘 2.Hittest,即canvas不负责帮你侦测鼠标/触摸事件发生在哪一个图形元件上;而svg可以。 3.Canvas效率高得多 canvas的工作方式就像传统的2d图形引擎比如GDI;而SVG的工作方式更像WPF(XAML)、html/CSS这类由标记控制的绘图引擎 参考技术A Canvas 和SVG的比较
下表显示了canvas与SVG的主要不同点:

Canvas
依赖分辨率
不支持事件处理器
弱文本渲染能力
可以保存最终图片为PNG或者JPG
最适合许多 对象频繁重画的图形游戏

SVG
独立于分辨率
支持事件处理器
最适合具有大渲染面积的应用(谷歌地图)
复杂图像,重画变慢(任何使用DOM很多的情况都会变慢)
不适合游戏应用本回答被提问者和网友采纳

SVG 和 HTML5 Canvas 有啥区别?

【中文标题】SVG 和 HTML5 Canvas 有啥区别?【英文标题】:What is the difference between SVG and HTML5 Canvas?SVG 和 HTML5 Canvas 有什么区别? 【发布时间】:2011-06-27 03:38:35 【问题描述】:

SVG 和 HTML5 Canvas 有什么区别?他们似乎都对我做同样的事情。基本上,它们都使用坐标点绘制矢量图。

我错过了什么? SVG 和 HTML5 Canvas 之间的主要区别是什么?为什么我应该选择一个而不是另一个?

【问题讨论】:

***有一篇有用的文章:Canvas versus Scalable Vector Graphics (SVG) 据我所知,Canvas 不提供矢量图形。都是关于位图的。 HTML5 Canvas vs SVG/VML?的可能重复 Canvas 是光栅图形,svgs 是可缩放的矢量图形。 sitePoint 链接的最佳解释:sitepoint.com/canvas-vs-svg-choosing-the-right-tool-for-the-job 【参考方案1】:

参见***:http://en.wikipedia.org/wiki/Canvas_element

SVG 是早期的绘图标准 浏览器中的形状。然而,SVG 在 从根本上更高的水平,因为 每个绘制的形状都被记住为 场景图或 DOM 中的对象,其中 随后被渲染为位图。 这意味着如果一个属性 SVG 对象被改变,浏览器 可以自动重新渲染场景。

在上面的例子中,一旦 矩形被绘制,事实上它 被系统遗忘了。 如果要改变它的位置, 整个场景都需要 重绘,包括任何对象 可能已经被 长方形。但在等效的 SVG 情况下,一个人可以简单地改变 矩形的位置属性 并且浏览器将确定如何 重绘它。也可以 分层绘制画布,然后 重新创建特定图层。

SVG 图像以 XML 表示,并且 可以创建复杂的场景并 使用 XML 编辑工具维护。

SVG 场景图启用事件 要关联的处理程序 对象,因此矩形可能会响应 一个 onClick 事件。得到同样的 画布的功能,必须 手动匹配坐标 鼠标点击坐标 绘制的矩形来确定 是否被点击。

从概念上讲,画布是一个较低的层次 SVG 可能基于的协议 建。[需要引用] 然而,这 不是(通常)情况——它们是 独立的标准。情况 因为有场景所以复杂 Canvas 和 SVG 的图形库 有一些位图操作 功能。

更新: 我使用 SVG 是因为它的标记语言能力——它可以由 XSLT 处理,并且可以在其节点中保存其他标记。同样,我可以在我的标记(化学)中保存 SVG。这允许我通过标记组合来操作 SVG 属性(例如渲染)。这在 Canvas 中可能是可能的,但我怀疑这要困难得多。

【讨论】:

最后一段中的最后一句也需要引用一两次。 SVG 没有“位图操作功能”,除非作者试图歪曲 svg 滤镜效果,但它的含义远不清楚。 @Erik 我同意你的看法。看起来这个 WP 条目需要编辑 听起来对于大多数应用程序来说,SVG 优于 Canvas。真的吗? Canvas 有什么 SVG 做不到的吗? 我知道是几年后的事了,但今天有很多画布库,比如 paper.js 和 fabric.js svg 不利于性能,因为它使用真实 dom 来不断更新导致回流的对象【参考方案2】:

它们是什么以及它们为你做什么是不同的。

SVG 是一种可缩放矢量图形的文档格式。 Canvas 是一个 javascript API,用于将矢量图形绘制为特定大小的位图。

详细说明一下,格式与 API:

使用 svg,您可以在许多不同的工具中查看、保存和编辑文件。使用画布,您只需绘制,除了屏幕上的结果图像之外,您刚刚所做的一切都不会保留。您可以为两者设置动画,SVG 只需查看指定的元素和属性即可为您处理重绘,而对于画布,您必须使用 API 自己重绘每一帧。两者都可以缩放,但 SVG 会自动缩放,而再次使用画布时,您必须重新发出给定尺寸的绘图命令。

【讨论】:

也许是所有答案中最公平和技术上最准确的。 SVG 是文档格式,在服务器(主要是静态)或客户端 itlsef 上创建。画布框架只不过是图片。所以很自然地它需要你重绘有它的 API。【参考方案3】:

SVG 就像一个“绘图”程序。绘图被指定为每个形状的绘图指令,任何形状的任何部分都可以更改。绘图是面向形状的。

Canvas 就像一个“绘画”程序。一旦像素出现在屏幕上,这就是您的绘图。您不能更改形状,除非用其他像素覆盖它们。绘画是面向像素的。

能够更改图纸对于某些程序来说非常重要;例如绘图应用程序、图表工具等。因此 SVG 在这里具有优势。

能够控制单个像素对于某些艺术程序很重要。

使用 Canvas 比 SVG 更容易通过鼠标拖动为用户操作获得出色的动画性能。

计算机屏幕上的单个像素通常会消耗 4 个字节的信息,而如今的计算机屏幕需要数兆字节。因此,如果您想让用户编辑图像然后再次上传,Canvas 可能会很不方便。

相比之下,使用 SVG 绘制几个覆盖整个屏幕的形状只需要几个字节,下载速度很快,并且可以轻松地再次上传,在这个方向上的优势与在另一个方向上的优势相同。所以 SVG 可以比 Canvas 更快。

Google 使用 SVG 实现了 Google 地图。这为网络应用程序提供了快速的性能和流畅的滚动。

【讨论】:

不会投票给你 - 新版本的谷歌地图现在实际上使用画布,而不是 svg。 svg 版本现已弃用。【参考方案4】:

对于 SVG 和 Canvas,我印象最深的两件事是,

能够在没有 DOM 的情况下使用 Canvas,因为 SVG 严重依赖 DOM,并且随着复杂性的增加,性能会降低。就像在游戏设计中一样。

使用 SVG 的优势在于跨平台的分辨率保持不变,这在 Canvas 中缺乏。

本网站提供了更多详细信息。 http://dev.opera.com/articles/view/svg-or-canvas-choosing-between-the-two/

【讨论】:

【参考方案5】:

这完全取决于您的需要/要求。

如果您只想在屏幕上显示图像/图表,那么推荐 方法是画布。 (例如 PNG、GIF、BMP 等)

如果您想扩展图形的功能,例如,如果您 鼠标悬停在图表上想要放大某个区域而不破坏 显示质量,然后选择 SVG。 (很好的例子是 AutoCAD、Visio、 GIS 文件)。

如果您想使用形状连接器构建动态流程图创建工具,最好选择 SVG 而不是 CANVAS。

当屏幕尺寸增加时,画布开始退化为 需要绘制更多像素。

当屏幕上的对象数量增加时,SVG 开始 随着我们不断将它们添加到 DOM 中而降级。

另请参考:http://msdn.microsoft.com/en-us/library/gg193983(v=vs.85).aspx

【讨论】:

【参考方案6】:

Canvas 与 SVG 的高级总结

画布

    基于像素(动态 .png) 单个 HTML 元素。(在开发者工具中检查元素。您只能看到画布标签) 仅通过脚本修改 事件模型/用户交互是精细的 (x,y) 较小的表面、较大数量的对象 (>10k) 或两者兼有时性能更好

SVG

    基于形状 多个图形元素,成为 DOM 的一部分 通过脚本和 CSS 修改 事件模型/用户交互被抽象化(矩形、路径) 对象数量较少 (

详细区别请阅读http://msdn.microsoft.com/en-us/library/ie/gg193983(v=vs.85).aspx

【讨论】:

【参考方案7】:

补充以上几点:

与 JPEG、GIF 等相比,SVG 在网络传输方面是轻量级的,并且在调整大小时它可以极大地缩放而不会失去质量。

【讨论】:

【参考方案8】:

SVG

基于用例 SVG 用于徽标、图表,因为它的矢量图形您绘制并忘记了它。当视口发生改变(如重新调整大小(或缩放))时,它会自行调整,无需重绘。

画布

Canvas 是位图(或光栅),它通过在屏幕上绘制像素来完成。它用于在给定区域中开发游戏或图形体验 (https://www.chromeexperiments.com/webgl),它绘制像素并通过重绘另一个区域来改变它。由于它是一种栅格类型,我们需要随着视口的变化而完全重绘。

参考

http://www.sitepoint.com/7-reasons-to-consider-svgs-instead-of-canvas

http://en.wikipedia.org/wiki/WebGL

http://vector-conversions.com/vectorizing/raster_vs_vector.html

【讨论】:

【参考方案9】:

SVG 是图形的规范,类似于文件格式。 SVG 是一个文档。您可以像 HTML 文件一样交换 SVG 文件。此外,由于 SVG 元素和 HTML 元素共享相同的 DOM API,因此可以使用 JavaScript 生成 SVG DOM,就像创建 HTML DOM 一样。但是您不需要 JavaScript 来生成 SVG 文件。一个简单的文本编辑器就足以编写一个 SVG。但是你至少需要一个计算器来计算图形中形状的坐标。

CANVAS 只是一个绘图区。有必要使用 JavaScript 来生成画布的内容。您不能交换画布。它不是文件。而且画布的元素不是 DOM 树的一部分。您不能使用 DOM API 来操作画布的内容。相反,您必须使用专用的画布 API 将形状绘制到画布中。

SVG 的优势在于,您可以将绘图作为文档进行交换。 CANVAS 的优点是生成内容的 JavaScript API 不那么冗长。

这是一个例子,它表明你可以达到类似的结果,但是在 JavaScript 中的实现方式却大不相同。

// Italic S in SVG

(function () 

  const ns='http://www.w3.org/2000/svg';
  let s = document.querySelector('svg');
  let p = document.createElementNS (ns, 'path');
  p.setAttribute ('id', 'arc');
  p.setAttribute ('d', 'M 0.9 -0.9 a 0.8,0.4 -10 0,0 -0.9,0.9');
  s.appendChild (p);
  let u = document.createElementNS (ns, 'use');
  u.setAttribute ('href', '#arc');
  u.setAttribute ('transform', 'rotate(180)');
  s.appendChild (u);

)();

// Italic S in CANVAS

(function () 

  let c = document.querySelector('canvas');
  let w = c.width = c.clientWidth;
  let h = c.height = c.clientHeight;
  let x = c.getContext('2d');
  x.lineWidth = 0.05 * w;
  x.moveTo (w/2, h/2);
  x.bezierCurveTo (w*0.02, h*0.4,
                   w*0.4, -h*0.02,
                   w*0.95, h*0.05);
  x.moveTo (w/2, h/2);
  x.bezierCurveTo (w*(1-0.02), h*(1-0.4),
                   w*(1-0.4), h*(1+0.02),
                   w*(1-0.95), h*(1-0.05));
  x.stroke();

)();
svg, canvas 
  width: 3em;
  height: 3em;


svg 
  vertical-align: text-top;
  stroke: black;
  stroke-width: 0.1;
  fill: none;


canvas 
  vertical-align: text-bottom;


div 
  float: left;
<div><svg viewBox="-1 -1 2 2"></svg>VG</div>
<div>CANVA<canvas></canvas></div>

如您所见,结果几乎相同,但 JavaScript 代码完全不同。

SVG 是通过 DOM API 使用 createElementsetAttributeappendChild 创建的。所有图形都在属性字符串中。 SVG 有更强大的原语。例如,CANVAS 没有与 SVG 弧形路径等效的东西。 CANVAS 示例尝试使用贝塞尔曲线模拟 SVG 弧。在 SVG 中,您可以重用元素来转换它们。在 CANVAS 中你不能重用元素。相反,您必须编写一个 JavaScript 函数才能调用它两次。 SVG 有一个viewBox,它允许使用归一化坐标,从而简化了旋转。在画布中,您必须根据clientWidthclientHeight 自己计算坐标。您可以使用 CSS 设置所有 SVG 元素的样式。在 CANVAS 中,您不能使用 CSS 设置任何样式。因为 SVG 是一个 DOM,所以您可以将事件处理程序分配给所有 SVG 元素。 CANVAS 中的元素没有 DOM,也没有 DOM 事件处理程序。

但另一方面,CANVAS 代码更易于阅读。您不需要关心 XML 名称空间。并且您可以直接调用图形函数,因为您不需要构建 DOM。

教训很清楚:如果您想快速绘制一些图形,请使用 CANVAS。如果您需要共享图形,例如使用 CSS 设置样式或想在图形中使用 DOM 事件处理程序,请构建 SVG。

【讨论】:

【参考方案10】:

SVG 它是基于对象模型的。 适合使用大的渲染区域。 SVG 为事件处理程序提供任何支持。 允许通过脚本和 CSS 进行修改。 SVG 具有更好的可扩展性 SVG 是基于矢量的(由形状组成)。 SVG 不适用于游戏图形。 SVG 不依赖于分辨率。 SVG 能够用于 API 动画。 SVG 适用于高质量和任何分辨率的打印。

画布元素

它是基于像素的。

适合使用小渲染

Canvas 不为事件处理程序提供任何资源。

只允许通过脚本进行修改。

Canvas 的可扩展性很差。

画布基于光栅(由一个像素组成)。

Canvas 适用于游戏图形。

画布完全取决于分辨率。

Canvas 没有任何动画 API。

画布不适合打印高质量和高分辨率。

【讨论】:

以上是关于SVG 与 HTML5 的 canvas 各有啥优点,哪个更有前途的主要内容,如果未能解决你的问题,请参考以下文章

SVG 与 HTML5 的 canvas 各有啥优点,哪个更有前途

SVG 与 HTML5 的 canvas 各有啥优点,哪个更有前途

SVG 和 HTML5 Canvas 有啥区别?

HTML中SVG和CANVAS的区别

HTML5——Canvas 与 SVG 区别

CANVAS画布与SVG的区别