”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 帆布与SVG:选择合适的工具

帆布与SVG:选择合适的工具

发布于2025-02-21
浏览:837

HTML5 Canvas与SVG:选择哪一个?

Canvas vs SVG: Choosing the Right Tool for the Job

HTML5 Canvas和SVG都是基于标准的HTML5技术,可用于创建令人惊艳的图形和视觉效果。本文探讨一个关键问题:在项目中选择哪一个技术更合适?换句话说,在哪些情况下更倾向于使用HTML5 Canvas而不是SVG?

首先,让我们简要介绍HTML5 Canvas和SVG。

关键要点

  • HTML5 Canvas和SVG都是用于创建图形和视觉体验的HTML5技术。Canvas依赖于分辨率,用于动态渲染图表、游戏图形、艺术作品或其他视觉图像。SVG(可缩放矢量图形)是一种XML文件格式,在缩放时可保持其质量。
  • HTML5 Canvas和SVG的工作方式根本不同。Canvas是一种即时图形系统,一旦像素绘制完成,就会被丢弃。SVG采用保留模式,绘制的每个对象都会添加到浏览器的内部模型中,这对于开发人员来说更容易,但可能会影响性能。
  • HTML5 Canvas非常适合图形密集型、高度交互式游戏、生成式艺术以及需要在小表面上绘制大量对象的场景。但是,放大或在Retina显示屏上显示时,其质量可能会下降。
  • 对于需要可缩放性的场景(例如高保真、复杂的图形,如建筑和工程图、生物图和组织结构图),SVG更可取。SVG在可访问性方面也更好,因为它可以被人类和机器读取。
  • 可以将HTML5 Canvas和SVG结合起来用于高级场景。例如,基于Canvas的游戏可以使用SVG图像作为精灵,或者绘图程序可以使用SVG设计其用户界面,并嵌入Canvas元素进行绘图。

什么是HTML5 Canvas?

WHATWG规范对canvas元素的介绍如下:

canvas元素为脚本提供了一个依赖于分辨率的位图画布,可用于动态渲染图表、游戏图形、艺术作品或其他视觉图像。

换句话说,标签提供了一个表面,您可以使用JavaScript可编程接口逐像素创建和操作光栅图像。

这是一个基本的代码示例:

(此处应嵌入CodePen示例,展示基本的Canvas形状)

Canvas vs SVG: Choosing the Right Tool for the Job

由于依赖于分辨率,在上创建的图像在放大或在Retina显示屏上显示时,质量可能会下降。

绘制简单的形状只是冰山一角。HTML5 Canvas API允许您绘制弧线、路径、文本、渐变等。您还可以逐像素操作图像。这意味着您可以替换图形某些区域中的颜色,可以动画化您的绘图,甚至可以将视频绘制到画布上并更改其外观。

什么是SVG?

SVG代表可缩放矢量图形。根据规范:

SVG是一种用于描述二维图形的语言。作为独立格式或与其他XML混合使用时,它使用XML语法。与HTML5混合使用时,它使用HTML5语法……

SVG绘图可以是交互式和动态的。动画可以通过声明方式(即通过在SVG内容中嵌入SVG动画元素)或通过脚本定义和触发。

SVG是一种XML文件格式,用于创建矢量图形。可缩放的特性使其能够在保持清晰度和高质量的同时增加或减少矢量图像。(HTML5 Canvas生成的图像无法做到这一点)。

以下是使用SVG绘制的相同红色正方形(之前使用HTML5 Canvas创建):

(此处应嵌入CodePen示例,展示基本的SVG形状)

您可以使用SVG执行大部分可以使用Canvas执行的操作,例如绘制形状和路径、渐变、图案、动画等等。但是,这两种技术的工作方式根本不同。与基于Canvas的图形不同,SVG具有DOM,因此CSS和JavaScript都可以访问它。例如,您可以使用CSS更改SVG图形的外观,使用CSS或JavaScript为其节点设置动画,使任何部分像

一样响应鼠标或键盘事件。正如在以下部分中将更清楚地看到的那样,当您需要在下一个项目中在Canvas和SVG之间进行选择时,这种差异起着重要的作用。

即时模式和保留模式

区分即时模式和保留模式至关重要。HTML5 Canvas是前者的示例,SVG是后者的示例。

即时模式意味着,一旦您的绘图在画布上,画布就会停止跟踪它。换句话说,作为开发人员,您需要制定绘制对象的命令,创建和维护最终输出应是什么样子的模型或场景,并指定需要更新的内容。浏览器的图形API只是将您的绘图命令传达给浏览器,然后浏览器执行这些命令。

SVG使用保留模式,您只需发出要在屏幕上显示的内容的绘图指令,浏览器的图形API就会创建最终输出的内存中模型或场景,并将其转换为浏览器的绘图命令。

作为即时图形系统,Canvas没有DOM或文档对象模型。使用Canvas,您绘制像素,系统会忘记所有这些像素,从而减少了维护绘图内部模型所需的额外内存。使用SVG,您绘制的每个对象都会添加到浏览器的内部模型中,这使得您作为开发人员的生活更容易一些,但在性能方面会付出一些代价。

基于即时模式和保留模式之间的区别,以及Canvas和SVG各自的其他特定特性,可以概述一些使用一种技术而不是另一种技术可能更好地服务于项目目标的情况。

HTML5 Canvas:优点和缺点

HTML5 Canvas规范明确建议作者不应在有其他更合适的方法可用时使用元素。

例如,对于图形丰富的元素,最好的工具是HTML和CSS,而不是(顺便说一句,SVG也不是)。Zim JS画布框架的创建者和创始人Dr Abstract证实了这种观点,他写道:

DOM和DOM框架擅长显示信息,特别是文本信息。相比之下,画布是一张图片。文本可以添加到画布中,并且可以使其具有响应性,但文本不能像在DOM上那样轻松地被选择或搜索。长滚动文本页面或文本和图像页面是DOM的绝佳用途。DOM非常适合社交媒体网站、论坛、购物以及我们习惯使用的所有信息应用程序。——“何时使用JavaScript画布库或框架”

因此,这是一个关于何时不使用的明确示例。但是,何时是一个不错的选择呢?

(此处应嵌入Sarah Drasner的推文截图)

HTML5 Canvas擅长什么?

Alvin Wan根据绘制的对象数量和对象或画布本身的大小,对Canvas和SVG的性能进行了基准测试。他将结果总结如下:

总之,当处理数百甚至数千个对象时,DOM渲染的开销更为明显;在这种情况下,Canvas是明显的赢家。但是,画布和SVG都不受对象大小的影响。鉴于最终统计数据,画布在性能方面提供了明显的优势。

根据我们对Canvas的了解,特别是它在绘制大量对象方面的出色性能,以下是一些可能适合甚至优于SVG的场景。

游戏和生成式艺术

对于图形密集型高度交互式游戏,以及生成式艺术,Canvas通常是最佳选择。

光线追踪

光线追踪是一种创建3D图形的技术。

光线追踪可用于通过追踪图像平面中像素的光线路径并模拟其与虚拟对象的相遇效果来填充图像……光线追踪实现的效果……范围从……从简单的矢量图形创建逼真的图像到应用类似照片的滤镜以去除红眼。——SVG与Canvas:如何选择,Microsoft Docs。

如果您好奇,这是Mark Webster正在运行的光线追踪应用程序。

Canvas vs SVG: Choosing the Right Tool for the Job

但是,尽管HTML5 Canvas肯定比SVG更适合这项任务,但这并不一定意味着光线追踪最好在元素上执行。事实上,对CPU的压力可能相当大,以至于浏览器可能会停止响应。

在小表面上绘制大量对象

另一个示例是应用程序需要在相对较小的表面上绘制大量对象的场景——例如非交互式实时数据可视化,例如天气模式的图形表示。

Canvas vs SVG: Choosing the Right Tool for the Job

视频中的像素替换

如这篇HTML5 Doctor文章所示,另一个适合使用Canvas的示例是将视频背景颜色替换为不同的颜色、另一个场景或图像。

Canvas vs SVG: Choosing the Right Tool for the Job

HTML5 Canvas不擅长什么?

另一方面,在许多情况下,与SVG相比,Canvas可能不是最佳选择。

可缩放性

大多数可缩放性是优势的场景都将更好地使用SVG而不是Canvas。高保真、复杂的图形,如建筑和工程图、组织结构图、生物图等,就是这种情况的例子。

使用SVG绘制时,放大图像或打印图像会保留所有细节,达到很高的质量水平。您还可以从数据库生成这些文档,这使得SVG的XML格式非常适合这项任务。

此外,这些图形通常是交互式的。例如,当您在线预订机票时,请考虑座位图,这使其成为SVG等保留图形系统的绝佳用例。

也就是说,借助CreateJS和Zim(扩展CreateJS)等一些优秀的库,开发人员可以相对快速地将其鼠标事件、命中测试、多点触控手势、拖放功能、控件等等集成到基于Canvas的创作中。

可访问性

尽管您可以采取一些步骤来提高Canvas图形的可访问性——一个好的Canvas库(如Zim)可以帮助您加快此过程——但在可访问性方面,Canvas并不出色。您在画布表面上绘制的内容只是一堆像素,辅助技术或搜索引擎机器人无法读取或解释这些像素。这是SVG更可取的另一个领域:SVG只是XML,这使得人和机器都可以读取它。

不依赖于JavaScript

如果您不想在应用程序中使用JavaScript,那么Canvas就不是您的最佳选择。事实上,您使用元素的唯一方法是使用JavaScript。相反,您可以使用Adobe Illustrator或Inkscape等标准矢量编辑程序绘制SVG图形,并且可以使用纯CSS来控制其外观并执行引人注目的、细微的动画和微交互。

将HTML5 Canvas和SVG结合用于高级场景

在某些情况下,您的应用程序可以通过结合HTML5 Canvas和SVG来获得两全其美。例如,基于Canvas的游戏可以使用矢量编辑程序生成的SVG图像作为精灵,以利用其可缩放性和与PNG图像相比更小的下载大小。或者,绘图程序可以使用SVG设计其用户界面,并嵌入元素用于绘图。

最后,像Paper.js这样功能强大的库可以使您能够在HTML5 Canvas之上编写矢量图形脚本,从而为开发人员提供了一种方便的方式来同时使用这两种技术。

结论

在本文中,我探讨了HTML5 Canvas和SVG的一些关键特性,以帮助您确定哪种技术最适合特定任务。

答案是什么?

Chris Coyier同意Benjamin De Cock的观点,后者在推特上写道:

回答这个问题的一种极其基本的方法是“当您无法使用svg时使用canvas”(其中“无法”可能意味着动画化数千个对象、单独操作每个像素等)。换句话说,SVG应该是您的默认选择,canvas是您的备用方案。

— Benjamin De Cock (@bdc) 2019年10月2日

Dr Abstract提供了许多最适合使用Canvas构建的事物清单,包括交互式徽标和广告、交互式信息图表、电子学习应用程序等等。

在我看来,对于何时最好使用Canvas而不是SVG,并没有什么硬性规定。即时模式和保留模式之间的区别表明,在构建图形密集型游戏等方面,HTML5 Canvas是无可争议的赢家,而对于平面图像、图标和UI元素等,SVG则更可取。但是,在这两者之间,HTML5 Canvas还有扩展其应用范围的空间,特别是考虑到各种强大的Canvas库可以提供什么。它们不仅使在同一图形工作中更容易同时使用这两种技术,而且还使Canvas原生项目中一些难以实现的功能(如交互式控件和事件、响应能力、可访问性功能等等)现在可以为大多数开发人员所用,这为HTML5 Canvas更有趣的用途打开了大门。

Canvas与SVG的常见问题解答 (FAQs)

(此处应包含FAQ部分,根据原文内容进行改写,保持简洁明了,并使用更自然的语言表达。)

最新教程 更多>
  • 如何解决由于Android的内容安全策略而拒绝加载脚本... \”错误?
    如何解决由于Android的内容安全策略而拒绝加载脚本... \”错误?
    Unveiling the Mystery: Content Security Policy Directive ErrorsEncountering the enigmatic error "Refused to load the script..." when deployi...
    编程 发布于2025-04-08
  • 为什么不使用CSS`content'属性显示图像?
    为什么不使用CSS`content'属性显示图像?
    在Firefox extemers属性为某些图像很大,&& && && &&华倍华倍[华氏华倍华氏度]很少见,却是某些浏览属性很少,尤其是特定于Firefox的某些浏览器未能在使用内容属性引用时未能显示图像的情况。这可以在提供的CSS类中看到:。googlepic { 内容:url(&#...
    编程 发布于2025-04-08
  • 在细胞编辑后,如何维护自定义的JTable细胞渲染?
    在细胞编辑后,如何维护自定义的JTable细胞渲染?
    在JTable中维护jtable单元格渲染后,在JTable中,在JTable中实现自定义单元格渲染和编辑功能可以增强用户体验。但是,至关重要的是要确保即使在编辑操作后也保留所需的格式。在设置用于格式化“价格”列的“价格”列,用户遇到的数字格式丢失的“价格”列的“价格”之后,问题在设置自定义单元格...
    编程 发布于2025-04-08
  • 为什么Microsoft Visual C ++无法正确实现两台模板的实例?
    为什么Microsoft Visual C ++无法正确实现两台模板的实例?
    The Mystery of "Broken" Two-Phase Template Instantiation in Microsoft Visual C Problem Statement:Users commonly express concerns that Micro...
    编程 发布于2025-04-08
  • 如何有效地选择熊猫数据框中的列?
    如何有效地选择熊猫数据框中的列?
    在处理数据操作任务时,在Pandas DataFrames 中选择列时,选择特定列的必要条件是必要的。在Pandas中,选择列的各种选项。选项1:使用列名 如果已知列索引,请使用ILOC函数选择它们。请注意,python索引基于零。 df1 = df.iloc [:,0:2]#使用索引0和1 的 ...
    编程 发布于2025-04-08
  • 如何限制动态大小的父元素中元素的滚动范围?
    如何限制动态大小的父元素中元素的滚动范围?
    在交互式接口中实现垂直滚动元素的CSS高度限制问题:考虑一个布局,其中我们具有与用户垂直滚动一起移动的可滚动地图div,同时与固定的固定sidebar保持一致。但是,地图的滚动无限期扩展,超过了视口的高度,阻止用户访问页面页脚。$("#map").css({ marginT...
    编程 发布于2025-04-08
  • 为什么不````''{margin:0; }`始终删除CSS中的最高边距?
    为什么不````''{margin:0; }`始终删除CSS中的最高边距?
    在CSS 问题:不正确的代码: 全球范围将所有余量重置为零,如提供的代码所建议的,可能会导致意外的副作用。解决特定的保证金问题是更建议的。 例如,在提供的示例中,将以下代码添加到CSS中,将解决余量问题: body H1 { 保证金顶:-40px; } 此方法更精确,避免了由全局保证金重置引...
    编程 发布于2025-04-08
  • 如何有效地转换PHP中的时区?
    如何有效地转换PHP中的时区?
    在PHP 利用dateTime对象和functions DateTime对象及其相应的功能别名为时区转换提供方便的方法。例如: //定义用户的时区 date_default_timezone_set('欧洲/伦敦'); //创建DateTime对象 $ dateTime = ne...
    编程 发布于2025-04-08
  • 为什么使用Firefox后退按钮时JavaScript执行停止?
    为什么使用Firefox后退按钮时JavaScript执行停止?
    导航历史记录问题:JavaScript使用Firefox Back Back 此行为是由浏览器缓存JavaScript资源引起的。要解决此问题并确保在后续页面访问中执行脚本,Firefox用户应设置一个空功能。 警报'); }; alert('inline Alert')...
    编程 发布于2025-04-08
  • 哪种在JavaScript中声明多个变量的方法更可维护?
    哪种在JavaScript中声明多个变量的方法更可维护?
    在JavaScript中声明多个变量:探索两个方法在JavaScript中,开发人员经常遇到需要声明多个变量的需要。对此的两种常见方法是:在单独的行上声明每个变量: 当涉及性能时,这两种方法本质上都是等效的。但是,可维护性可能会有所不同。 第一个方法被认为更易于维护。每个声明都是其自己的语句,使其...
    编程 发布于2025-04-08
  • 如何克服PHP的功能重新定义限制?
    如何克服PHP的功能重新定义限制?
    克服PHP的函数重新定义限制在PHP中,多次定义一个相同名称的函数是一个no-no。尝试这样做,如提供的代码段所示,将导致可怕的“不能重新列出”错误。 但是,PHP工具腰带中有一个隐藏的宝石:runkit扩展。它使您能够灵活地重新定义函数。 runkit_function_renction_re...
    编程 发布于2025-04-08
  • 为什么PYTZ最初显示出意外的时区偏移?
    为什么PYTZ最初显示出意外的时区偏移?
    与pytz 最初从pytz获得特定的偏移。例如,亚洲/hong_kong最初显示一个七个小时37分钟的偏移: 差异源利用本地化将时区分配给日期,使用了适当的时区名称和偏移量。但是,直接使用DateTime构造器分配时区不允许进行正确的调整。 example pytz.timezone(...
    编程 发布于2025-04-08
  • 如何将多种用户类型(学生,老师和管理员)重定向到Firebase应用中的各自活动?
    如何将多种用户类型(学生,老师和管理员)重定向到Firebase应用中的各自活动?
    Red: How to Redirect Multiple User Types to Respective ActivitiesUnderstanding the ProblemIn a Firebase-based voting app with three distinct user type...
    编程 发布于2025-04-08
  • 如何将MySQL数据库添加到Visual Studio 2012中的数据源对话框中?
    如何将MySQL数据库添加到Visual Studio 2012中的数据源对话框中?
    在Visual Studio 2012 尽管已安装了MySQL Connector v.6.5.4,但无法将MySQL数据库添加到实体框架的“ DataSource对话框”中。为了解决这一问题,至关重要的是要了解MySQL连接器v.6.5.5及以后的6.6.x版本将提供MySQL的官方Visual...
    编程 发布于2025-04-08
  • 哪种方法更有效地用于点 - 填点检测:射线跟踪或matplotlib \的路径contains_points?
    哪种方法更有效地用于点 - 填点检测:射线跟踪或matplotlib \的路径contains_points?
    在Python Matplotlib's path.contains_points FunctionMatplotlib's path.contains_points function employs a path object to represent the polygon.它...
    编程 发布于2025-04-08

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3