ChatGPT解决这个技术问题 Extra ChatGPT

SVG 和 HTML5 Canvas 有什么区别?

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

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

维基百科对此有一篇有用的文章:Canvas versus Scalable Vector Graphics (SVG)
据我了解,画布不提供矢量图形。这都是关于位图的。
HTML5 Canvas vs SVG/VML? 的可能重复项
画布是光栅图形,svg 是可缩放的矢量图形。 sitePoint 链接的最佳解释:sitepoint.com/canvas-vs-svg-choosing-the-right-tool-for-the-job

J
JohnnySoftware

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

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

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

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

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

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

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

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


不会投票给你 - 新版本的谷歌地图现在实际上使用画布,而不是 svg。 svg 版本现已弃用。
R
Rahul Sagore

参见维基百科: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 来不断更新导致回流的对象
F
Fizer Khan

Canvas 与 SVG 的高级总结

帆布

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

SVG

基于形状 多个图形元素,成为 DOM 的一部分 通过脚本和 CSS 修改 事件模型/用户交互被抽象(矩形、路径) 对象数量较少(<10k)、表面较大或两者兼有时性能更好

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


E
Erik Dahlström

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

SVG 是一种可缩放矢量图形的文档格式。

Canvas 是一个 javascript API,用于将矢量图形绘制为特定大小的位图。

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

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


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

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

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

使用 SVG 的优点是跨平台的分辨率保持不变,而 Canvas 则没有。

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


A
Aji

这绝对取决于您的需要/要求。

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

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

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

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

当屏幕上的对象数量增加时,SVG 开始退化,因为我们不断地将它们添加到 DOM。

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


P
Purushoth

SVG

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

帆布

画布是位图(或光栅),它通过将像素绘制到屏幕上来完成。它用于在给定区域中开发游戏或图形体验 (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


c
ceving

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 中做到这一点的方式却大不相同。

// SVG 中的斜体 S (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); })(); // CANVAS 中的斜体 S (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,画布{宽度:3em;高度:3em; } SVG { 垂直对齐:文本顶部;中风:黑色;笔画宽度:0.1;填写:无; } 画布 { 垂直对齐:文本底部; } div { 浮动:左; }

VG
CANVA

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

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

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

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


N
Narayana Swamy

补充以上几点:

与 JPEG、GIF 等相比,SVG 是轻量级的,用于在网络上传输,并且在调整大小时它的缩放比例非常高,而不会失去质量。


V
Vasundhara

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

画布元素

它是基于像素的。

适合使用小渲染

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

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

Canvas 的可扩展性很差。

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

画布适用于游戏图形。

画布完全取决于分辨率。

Canvas 没有任何动画 API。

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