SVG 与 Canvas:如何选择

文章来源:https://msdn.microsoft.com/zh-cn/library/gg193983

本主题一开始将对 SVG 与 Canvas 进行简要比较,接下来会讨论大量的比较代码示例,如光线跟踪和绿屏。

注意  为了查看本主题中包含的很多示例,你必须使用支持 SVG 和 Canvas 元素的浏览器(如 Windows Internet Explorer 9)。

 

简介

HTML 不断演变以提供更好、更丰富的标准图形来帮助改进客户体验。 为 Web 开发人员创造了使用基于标准的 Web 技术创建图形丰富的交互网站和应用程序的机会,而无需使用专用的技术或编写浏览器特定的代码。以下各节介绍了矢量图形的概念并执行相应操作:

  • 区分即时模式和保留模式之间的差异
  • 介绍用于即时模式图形的 HTML5 Canvas 元素并提供对 Canvas 的概述
  • 介绍可缩放矢量图形 (SVG)、一组用于保留模式图形的 HTML5 元素并提供对 SVG 的概述
  • 指导新开发人员和有经验的开发人员对矢量图形和 HTML5 使用其中一个矢量图形模型(或同时使用两者,具体取决于方案)

矢量图形

矢量图形不是新概念。它们是全部基于矢量来表示图像的几何基元(形状、点、线条和多边形)。在 1960 年代后期,向 Logo 编程语言添加了矢量图形语言(海龟绘图)来支持用于执行绘图功能的海龟机器人。虽然图形世界在复杂性方面已经发生了重大的演变,但是存在的基本概念是相同的。

矢量图形的复杂性范围从简单到适中再到相当复杂。下面是一些基本示例。

  • 简单 – 一个文档或插图中的标注。
  • 适中 – 图表、关系图和地图等插图。
  • 复杂 – 类似那些用于工程的文档。

尽管前面的示例在性质上是静态的,但是矢量图形也支持交互性,这是一项可显著扩展方案的关键功能。矢量图形为 Web、桌面和设备上的应用程序提供交互和静态的格式。

矢量图形方案的简要概述

在当今 Web 上

  • 网页中使用矢量图形作为背景图像以支持高 DPI 和“收缩”缩放功能。
  • 地图属性(如 Bing 地图)用来执行线路查找操作。
  • 显示实时的图表和图形的交互式股票网站。
  • 选择和其他地图
  • 航班或音乐厅的座位图。
  • 游戏。

在办公室中

  • Microsoft Office Word(用于剪贴画)、PowerPoint 和 Excel 以及 Visio 形状等高效工具。
  • 输出矢量图形格式的 CAD 工具。
  • 呈现交互图表和图形的 Oracle 和 Microsoft Dynamics 应用程序等企业工具。

在设备上

  • 使得图形用户界面更加丰富。
  • 用户交互小工具和图标。
  • 完整 PDA 用户体验。

专业设计器和使用工具

专业的 Web 设计人员在如下工具集中查看矢量图形:

  • 用于创建高质量静态图像(可以导出为 SVG)的 Adobe Illustrator
  • 可以导出为基于 XML 的矢量语言的 Adobe Flash Professional
  • 用于 Windows Presentation Foundation (WPF) 和 Silverlight 的 Microsoft Expression Blend

请务必注意,矢量图形已经在桌面、设备和 Web 上存在很长时间了。

HTML5 图形技术

借助 HTML5,开发人员或设计人员现在可以使用基于标准的技术来创建以前的体验。这样可消除对插件的安装(50% 的网站放弃访问均与插件的安装相关),从而可以极大地改善用户体验。目前,图形由浏览器原生提供,而对于 Internet Explorer 9,则利用 Microsoft Windows 和硬件加速图形的功能。

下一节概述了两种全新但不同的技术、这两种技术的使用方法以及各自的优势和限制。使用一个矢量图形方案谱表来讨论用于为每个方案选择最佳技术的方法。

下图显示了存在于矢量图形中的一个常规方案谱表。每一个方案都可能会更接近于 canvas 或 svg,这意味着一种技术相对于其他技术更适合该方案。如果方案位于谱表中间,那么选择任一技术都是可行的

矢量图形方案谱表几乎所有矢量图形都可以使用上述任一种技术来绘制,但有时根据任务的不同,会有非常多的工作要由开发人员或计算机完成。 当我们检查每种技术的用例,然后将其应用于常见方案时,我们会进一步了解此谱表。

技术简介

下一节介绍了用于在 HTML5 中创建矢量图形的技术,从而建立对早期存在的方案的讨论。

使用示例

若要使用以下示例,请将以下代码示例用作模板。可以使用此模板来开发 SVG 而非 HTML。此模板在本主题的每个示例中使用。由于格式原因,你可以使用脚本以及样式。此模板还包含一个 Meta 标记,这使得可以在本地文件共享上更轻松地进行 SVG 开发。这些示例使用下面的格式。首先提供有意义的代码,然后链接到完整代码。

<!DOCTYPE html >
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=9"/>
    <style type="text/css" media="screen">
    </style>
    <script type="text/javascript">
    </script>
  </head>
  <body>
  </body>
</html>

http://samples.msdn.microsoft.com/workshop/samples/graphicsInHTML5/template.htm (单击“查看源文件”即可查看此标记)。

SVG

SVG 用于描述可缩放矢量图形,这是一个保留在内存中模型中的保留模式图形模型,而内存中模型可通过重新呈现的代码结果进行操作。这不同于即时模式,该模式将稍后讨论。在 HTML5 中同时提供这两种模式。

SVG 是一个保留模式模型,作为对独立供应商(Microsoft 和 Adobe)所提出的两个建议的回应,在 1999 年引入。成立了 W3C SVG 工作组,并且在 2001 年 SVG 规范达到了“建议的状态”。目前,我们按照 SVG 1.1 第 2 版工作,该版本在编写本文时处于“最后征求意见”阶段。

尽管 SVG 可以作为独立文件进行提供,但是最初着重于将它与 HTML 自然集成。

类似于 HTML,SVG 也是使用元素、属性、和样式来构建文档。首次将 <svg> 元素引入到文档中时,该元素的行为非常类似于 <div> 且作为 HTMLDocument 的一部分,但它包含附加接口 SVGDocument(SVGDocument 提供与矢量图形的更深入、更丰富的交互)。

元素

尽管外部 <svg> 包装适合于 HTML 框模型,但是大多数情况下,内部模型都会从该包装中分离出来,因为矢量不局限于简单的框。这种分离要求扩展 SVG 中的属性才能提供丰富的图形。

例如:

<svg height="1000px" width="1000px">	
  <rect id="myRect" height="100px" width="100px" fill="blue"/>
</svg>

http://samples.msdn.microsoft.com/workshop/samples/graphicsInHTML5/bluerect.htm

注意  为了呈现此内容以及以下很多示例,你必须使用支持 SVG 和 Canvas 元素的浏览器(如 Internet Explorer 9)。

之前的 HTML 代码将创建一个正方形,长宽均为 100 像素,并使用蓝色背景进行填充。

SVG 蓝色正方形此 <rect> 元素保留在 HTML 文档的文档对象模型 (DOM) 中。就像其他 HTML 元素一样,可通过多种不同的方式设置 SVG 的样式。下面的示例是一个表。

样式设置

开发人员可能会注意到属性是类似的。SVG 同时具有属性和演示属性。此处看起来描述有点随意,但关键在于可以按照 CSS 样式规则设置演示属性的样式。

四个矩形使用几种不同的方法进行填充。

<!--No fill (defaults the color to #000000)-->
<rect id="myRect1" height="100%" width="100%" >

<!--using the-->
<rect id="myRect2" height="100%" width="100%" class="greenrect"/>

<!--using the style="fill:pink"-->	
<rect id="myRect3" height="100%" width="100%" style="fill:pink"/> 

<!--using the attribute fill="red"-->	
<rect id="myRect4" height="100%" width="100%" fill="red"/>

四个带颜色的 SVG 正方形第一个示例演示省去一个属性会在图形上产生可视效果。在此示例中,颜色默认为黑色。

第二个示例演示使用 class=”greenrect” 来填充矩形。包含的用于填充此矩形的 CSS 的形式为:

rect.greenrect {fill:green;}

第三个示例使用内联样式将填充设置为粉色。最后一个示例使用相应属性填充红色。此示例还演示了 CSS 选择器的用法。样式还包括:

rect:hover {fill:yellow;}

这针对所有矩形建立一个规则,即鼠标悬停在这些矩形之上时颜色更改为黄色。

这些对于有经验的 Web 开发人员来说应该都不是新内容了。此处提供这些示例是为了强调相似性(使用样式、样式表、类和选择器)以及差异(样式不适用于所有属性,仅适用于演示属性、新属性或不一致的属性)。

http://samples.msdn.microsoft.com/workshop/samples/graphicsInHTML5/svgstyling.htm

可编程性

属性 API 及其他 DOM 操作仍应用并遵循当前的属性规则。例外情况是,演示应用程序基于样式所取代的属性(如果适用)。

如果这些属性是通过核心属性或通过其各自的 DOM 方法进行设置的,则将影响这些属性的演示,并且基础 DOM 将相应地发生更改(注意使用 SVG DOM 设置高度的不同语法):

document.getElementById("myDiv").style.height = "200px";
// alternatively
//document.getElementById("myDiv").style="height;200px";

document.getElementById("myRect").height.baseVal.value = 200;
// alternatively
//document.getElementById("myRect").setAttribute("height","200px");

交互

SVG 的另一个关键区分因素是能够进行代码交互且不复杂。正如 SVG 具有一个类似 HTML 的可编程 DOM 一样,它还具有事件模型。检查下面比矩形或正方形更复杂的图形:路径。

使用路径可绘制任意形状,例如在该示例中为表示美国的阿拉斯加州和夏威夷州的两个形状。

阿拉斯加州和夏威夷州http://samples.msdn.microsoft.com/workshop/samples/graphicsInHTML5/svginteractivity.htm

触发创建之前指定的警报的事件。这些复杂形状(像更简单的矩形)也会响应 CSS 选择器。使用一行 CSS 即可实现简单的突出显示机制:

path:hover {fill:yellow;}

Canvas

另一种向用户提供更丰富的图形体验的方法,通过 <canvas> 标记提供,该标记由 Apple for Safari 在 HTML5 中或在其他图形小工具中引入。它在绘制即时模式图形(包括矩形、路径和图像)方面公开更具编程性的体验,与 SVG 类似。即时模式图形呈现是一个“触发即忘”模型,该模型将图形直接呈现到屏幕上,但随后对所完成的操作不保留任何上下文。与保留模式相反,不保存呈现的图形;要在每次需要新框架时描述整个场景,开发人员需要重新调用所有必需的绘图命令,而不考虑实际更改(SVG 已知拥有“场景图”)。

元素

为了使用画布 (Canvas) 功能,Web 开发人员直接引入了一个 Canvas 元素:

<canvas id="myCanvas" width="1200px" height="1200px"></canvas>

然后使用 <canvas> 传统的2D基础库 API 来绘制图像和矢量。

使用 JavaScript 代码执行对画布上图形的操作,通过添加对图形的支持可以获得 Web 开发人员熟悉使用的优势。

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");

如前面提到的,存在与 SVG 中相似的形状和对象,举例来说,开发人员可以使用下面的代码来绘制矩形:

ctx.fillStyle = "rgb(0,0,255)";
ctx.fillRect(10, 10, 100, 100);

稍后将讨论这些方法的优缺点以及适当的方案。

最终结果与在 SVG 中相同。http://samples.msdn.microsoft.com/workshop/samples/graphicsInHTML5/canvasintro.htm

Canvas 蓝色正方形但正如 SVG 一样,Canvas 具有更复杂的几何基元,区别在于这些基元采用函数形式。

事件的可编程性

为了能够绘制比矩形更复杂的图形(如前面显示的夏威夷地图),canvas API 提供了一个路径 API,该路径 API 支持与 SVG 中的 <path> 元素相似的命令,只是你要对每一行代码段调用相应的 API,而不是在单个属性中列出它们:

ctx.beginPath();
ctx.moveTo(233.08751,519.30948);
ctx.lineTo(235.02744,515.75293);
ctx.lineTo(237.29070000000002,515.42961);
ctx.lineTo(237.61402,516.23791);
ctx.lineTo(235.51242000000002,519.30948);
ctx.lineTo(233.08751,519.30948);
ctx.closePath();

有关夏威夷地图,请参阅 http://samples.msdn.microsoft.com/workshop/samples/graphicsInHTML5/canvasmap.htm

路径 API 并不局限于 moveTo 和 arc,它包含相同的 SVG 方向相位(包括二次曲线和贝塞尔曲线)。

通过有限的事件和功能可以捕获鼠标在图像上的位置。因为不存在图形保留知识,所以编程人员必须转换 mouseX 标记的单个元素上的 mouseY<canvas> 坐标,然后将该命令相应地传送到位于内存中结构中的形状。第三方库为支持更复杂的路径而存在,这包括内置isPointInPath API,但后者被限制为最后路径绘制。因而与 SVG 不同,既没有任何样式也不支持多个几何图上的命中检测。另外,因为 Canvas 不支持可伸缩性,所以缩放时夏威夷地图将很快失真:

夏威夷地图在缩放时显示失真Canvas 是一个功能强大的低级别 API,开发人员利用它可以提供新的图形体验。

Canvas 与 SVG 的简要摘要

下面是简要摘要,可帮助你确定何时使用 Canvas 而不使用 SVG 或者何时使用 SVG 而不使用 Canvas 来创建矢量图形。

Canvas SVG
基于像素(动态 .png) 基于形状
单个 HTML 元素 多个图形元素,这些元素成为 DOM 的一部分
仅通过脚本修改 通过脚本和 CSS 修改
事件模型/用户交互颗粒化 (x,y) 事件模型/用户交互抽象化 (rect, path)
图面较小时、对象数量较大 (>10k)(或同时满足这二者)时性能更佳 对象数量较小 (<10k)、图面更大(或同时满足这二者)时性能更佳

 

在上表中,考虑这二者在现有软件方面的意象模型。Canvas 类似于 MSPaint,在其中,你可以使用形状和其他工具来绘制和创建图像。SVG 类似于 Office PowerPoint 幻灯片,它具有可编程的支持并且能够添加主题。

何时使用 <canvas>、何时使用 SVG:方案

这一节介绍这两种技术的技术优势和限制,包括用于确定一种技术何时相对于另一种技术更适合的常用方法。应该注意的是,SVG 和 <canvas> 都能实现几乎相同的结果,功能也完全重复。介绍以下特定情况非常重要:<canvas> 明显好于 SVG,或相反,二者组合更加合适,或可以使用和考虑任一技术。

矢量图形方案谱表这些方案比较清晰地描述了更适合使用 SVG 的情况、更适合使用 Canvas 的情况,以及其他介于这之间的情况。它们描述了每种技术的优缺点,以便开发人员可以了解相应技术的行为并针对其应用程序做出好的选择。

从性能方面选择

有时存在一些外部影响,要求独立于(或几乎独立于)功能选择技术。有关使用 Canvas 或 SVG 的问题,存在两个主要区别。

有时开发人员的知识、技能组合和现有资产会对技术的选择起到重大作用。如果开发人员具备低级别图形 API 方面的深层知识,但在 Web 技术方面知识有限,则很可能会选择 Canvas 技术。

另外,性能对于高流量的网站来说是绝对关键的。可以对这两种技术的性能特征加以比较。这可能会要求开发 Canvas 没有附带的辅助功能、自定义样式以及更粒度化的用户交互功能。虽然 Canvas 通常被视为具有高性能,但是并不意味着它就是明显的选择。下图显示了 SVG 对象和 Canvas 对象之间在呈现时间上的差异。

Canvas 与 SVG 性能一般情况下,随着屏幕大小的增大,画布将开始降级,因为需要绘制更多的像素。随着屏幕上的对象数目增多,SVG 将开始降级,因为我们正不断将这些对象添加到 DOM 中。这些度量不一定准确,以下方面的不同一定会引起变化:实现和平台、是否使用完全硬件加速的图形,以及 JavaScript 引擎的速度。

高保真度的复杂矢量文档

高保真度的复杂矢量文档已经成为并将继续成为 SVG 的最有效点,原因主要有两个。存在足够多的极为详细的文档,包括由 CAD 程序生成的那些文档,针对这些文档,SVG 的 scalable 部分提供了独立文档形式或嵌入网页中的文档形式的详细视图。通过该技术还可以进行高保真打印。SVG 的声明性性质向工具、客户端或服务器端提供从数据库生成形状的能力。 最后,我们看到了政府机构的发展,因工程图(为了专利)或工业图(为了城市规划目的)缘故从建议支持转变为对 SVG 的必需支持。这种转变还将继续,因为对于公众使用的电子文档(如下),政府部门越来越不是只喜欢一家供应商:

  • 建筑图、工程图和楼层图
  • 电子图、航空图和示意图
  • 组织结构图
  • 地图
  • 生物图

以下各图显示了前一方案中可以保留的详细信息示例。第一个图像显示可以在测试驱动网站上找到的网页快照。它包含呼吸系统图和元素周期表。

http://ie.microsoft.com/testdrive/Graphics/RealWorldDataAndDiagrams/Default.xhtml

缩小的元素周期表第二个图像显示同一张图放大 1000% 后的效果

放大的元素周期表尽管考虑到观察大的示意图的有用性,但在需要细化到细节处时或者出于工程目的需要打印整个示意图时,具有可缩放性的 S 将变得足够清晰和有价值。出于这些原因,我们将高保真度的复杂矢量文档放在谱表的远端,接近 SVG,如下图中所示。

高保真的文档显示在接近 SVG 的谱表端这些文档也可以受益于交互性,这是 SVG 使这些方案最适合于保留图形模式的第二方面。

增强的 Web 图形

SVG 作为图像格式

SVG 另外还常用于简单图像,无论是应用程序还是网页中的图像,大图像还是小图像。由于 SVG 要加载到 DOM 中,或者创建图像前至少要进行解析,所以性能会稍微有所下降,但相比于呈现网页的成本(大约几毫秒),这种下降是极其微小。

在文件大小方面(为了评估网络流量的目的),下面演示的两个图像是一样的,只差了 1K(SVG 稍微大点,没有压缩)。

两个蓝色球体的图像与以前一样,因为 SVG 作为图像格式是可缩放的,所以如果开发人员想要以更大的比例使用该图像,或者用户使用高 DPI的屏幕,则可移植网络图形 (PNG) 要么会变得异常,要么需要更大形式的文件来实现保真。

两个蓝色球体的图像SVG 因此可以充当非常好的图像替换格式,甚至对网页上最简单的图像也是如此。静态 WebApp/网页图像因此落在谱表的 SVG 端。

静态图像显示在接近于 SVG 的谱表端

像素操作

在谱表的另一端,当使用 Canvas 时可以获得快速的绘图速度,且不需要保留相应信息。存在若干种最适合于 <canvas> 的实时数据方案。使用光线跟踪在像平面上通过像素跟踪光线路径并模拟其与虚拟对象相遇的效果,可以水化图像。 下图显示了这种模拟。

使用 Canvas 的光线跟踪示例

需要很多计算,因此速度依赖于浏览器中的 JavaScript 引擎速度。然而尽管大多数情况下本地代码无可置疑要更快一些,但是随着 JavaScript 引擎逐渐成熟,我们开始看到在像程序集和 C++ 这样的时期内这种差距在缩小。

光线跟踪(通常在 Web 上的背景中完成)获得的效果甚为广泛。范围从创建许多不同的视觉效果(包括根据其他简单矢量图形创建逼真的图像)到应用照片过滤器以去除红眼。

因为 Canvas API 允许开发人员读写像素,所以这里唯一的限制是速度和想象力。上一个示例由 Adam Burmister 提供并且位于 http://labs.flog.co.nz/raytracer/ 上。 在此示例中,可通过大量的库来实现创建最终图像所需的计算,但主结束函数是 fillRect

setPixel: function(x, y, color){
  var pxW, pxH;
  pxW = this.options.pixelWidth;
  pxH = this.options.pixelHeight;

  this.canvas.fillStyle = color.toString();
  this.canvas.fillRect (x * pxW, y * pxH, pxW, pxH);
},

出于此原因,高性能图形(如光线跟踪器)作为 Canvas 方案落在谱表的最左端,如下图所示。

高性能图形在谱表上靠近 Canvas注意生成上述光线跟踪器的作者 注意 因为该方案将产生静态图像,所以桌面软件经过了很好的调整以适合光线跟踪器所需的大量浮动操作。

下至金属像素操作的有趣实现是图像的过滤器应用。过滤器已存在于 Web 上,且需要显著的处理速度(受益于其对图形管道中更深层的硬件加速图形的应用),因此开发人员可以试用边缘检测或其他数学表达式等算法。

实时数据

对于更常见的方案,Canvas 非常适合输出实时数据。请注意如何简便地确定这些方案,因为已经表明使用 Canvas 难以进行用户交互。因此,下面将讨论非交互的实时数据可视化。

今天的天气数据可以通过特定间隔内服务器上生成的图像非常静态地呈现,也可以尽可能快地通过客户端第三方插件呈现。尽管 ECWMF 已经研究过使用 SVG 而不使用服务器生成的图像如何节省成本,但是 Canvas 在天气模式(以及其他快速的实时数据)的大多数图形表示形式方面,明显是赢家。下图显示以图形方式显示在地图上的天气模式。

显示在地图上的天气模式

如你可以从上图中看到的,没有必要存在大的绘图图面,而且屏幕上的对象数量是相当高的。通过使用 Canvas API,可以在不影响 DOM 的情况下快速绘制(和擦除)这些对象。尽管可以使用 SVG Ellipse 完成此操作,但是将它们加载到 DOM 中以及通过动画修改它们的成本是非常高的。事实上,无论你是在图像中还是在数据动画中看到大量的形状(尤其是不相似的形状)要进行分析,通常都会指出 Canvas 是要使用的技术。这里的实际限制是受 CPU 速度和 JavaScript 引擎速度的控制,能多快可视化显示数据。但除了占用 CPU 的光线跟踪方案之外,仍然可以实现合理的动画。Reasonable 描述客户端可以使用 JavaScript 执行的操作与服务器可以通过电线计算和封送的操作之间的相对动画。

此方案似乎是 <canvas> 的关键用例。

复杂场景和实时动画在谱表上偏向 Canvas

像素替换(绿屏)

另一个使用 Canvas 的可能情况是,在视频上进行颜色检测以便用其他场景或图像替换背景色。像光线跟踪器或过滤器一样,因 JavaScript 中当前性能速度限制的缘故,很可能会使用桌面软件预处理任何需要高的最终产品质量的现实方案。但是,由于 <canvas> 是为低级别像素读取和写入设计的,因此诸如 greenscreen 替换之类的方案甚至无法使用 SVG 完成。

从两个视频中读写像素到另一个视频中所需的代码要求使用两个视频、两个画布和一个最终画布。一次捕捉视频上的一帧,然后绘制到两个单独的画布上。这样允许读回数据。

ctxSource1.drawImage(video1, 0, 0, videoWidth, videoHeight);
ctxSource2.drawImage(video2, 0, 0, videoWidth, videoHeight);

因此,下一步是检索每个绘制图像的句柄,以便你可以检查每个单独的像素。

currentFrameSource1 = ctxSource1.getImageData(0, 0, videoWidth, videoHeight);
currentFrameSource2 = ctxSource2.getImageData(0, 0, videoWidth, videoHeight);

获取后,代码将浏览绿屏的像素数组,搜索绿色像素,如果找到,代码将用背景场景中的像素替换所有绿色像素。

for (var i = 0; i < n; i++) 
{
  // Grab the RBG for each pixel:
  r = currentFrameSource1.data[i * 4 + 0];
  g = currentFrameSource1.data[i * 4 + 1];
  b = currentFrameSource1.data[i * 4 + 2];

  // If this seems like a green pixel replace it:
  if ( (r >= 0 && r <= 59) && (g >= 74 && g <= 144) && (b >= 0 && b <= 56) ) // Target green is (24, 109, 21), so look around those values.
  {
    pixelIndex = i * 4;
    currentFrameSource1.data[pixelIndex] = currentFrameSource2.data[pixelIndex];
    currentFrameSource1.data[pixelIndex + 1] = currentFrameSource2.data[pixelIndex + 1];
    currentFrameSource1.data[pixelIndex + 2] = currentFrameSource2.data[pixelIndex + 2];
    currentFrameSource1.data[pixelIndex + 3] = currentFrameSource2.data[pixelIndex + 3];
  }
}

最后,像素数组将写入到目标画布中。

ctxDest.putImageData(currentFrameSource1, 0, 0);

http://samples.msdn.microsoft.com/workshop/samples/graphicsInHTML5/canvasgreenscreen.htm(若要完整地查看 greenscreen 代码,请查看该页的源代码。)

Canvas 与 SVG 谱表

组合/交叉方案

以下方案可以在 SVG 或 Canvas 中完成,都可以获得适当的结果,但你可能会更喜欢一项技术胜过另一项技术。

图表和图形

需要矢量图形的图表和图形的谱表很宽广。大部分这些图形最好使用 SVG 进行创建,因为它们具有下列三个特征之一:

  • 图形是从可以轻松转换为 XML (SVG) 的现有数据生成的
  • 它们需要用户交互
  • 优点是可在网页上设置样式

我们使用可显著增加方案范围的交互功能来扩展高保真文档方案。 其中包括:

  • 交互的组织结构图和流程图
  • 数据图(环形图、条形图、散点图)
  • 交互式地图 – 路径查找
  • 建筑图、工程图和楼层图
  • 航班或音乐厅的座位图

已经确定快速的实时数据处理已针对 Canvas 进行了更好地优化(主要取决于速度)。

二维游戏

制作休闲游戏(此处定义为 Web 上的简单二维游戏)时,开发人员需要在 canvas 和 svg 之间做出选择。因为历史上游戏库一直利用较低级别的图形 API,所以将倾向于选择 <canvas>

当库的其他组成部分(如受欢迎的物理引擎)比图形层要明显深时,图形将变成实现细节。边框、速度、大小和位置等图形几何将传递给引擎,而引擎随后将用速度、碰撞和位置进行响应。图形位于堆栈中的最高层。

通过由同一作者开发的两个游戏来演示独立于游戏逻辑的图形概念,旨在说明 <svg> 和 <canvas>SVG-oids 和 canvas-pinball。一个出色的、独立于游戏引擎的图形层示例是将 canvas-pinball 与 SVG-Dice 进行比较(当两者都使用相同的物理引擎时)。

尽管游戏和演示逻辑是不同的,但是这两个游戏的物理引擎都会跟踪位置、碰撞、速度以及游戏组成部分的其他物理方面。

对于 canvas-pinball,自定义的更高级别的动画管理器通过使用一系列 Canvas API 重新绘制场景。

if (animationsInProgress) {
  ctx.save();
  ctx.lineWidth = 2.0;
  ctx.beginPath();
  ctx.moveTo(89, 322);
  ctx.lineTo(101, 295);
    .
    .
    .
  ctx.stroke();
  ctx.restore();
  ctx.moveTo(tVp.x, tVp.y);
}

对于 SVG Dice,自定义的更高级别的动画管理器使用组转换通过 DOM 在屏幕上重新定位现有图形。

if (animationsInProgress) 
{
  this.rotation += (this.circleBody.m_linearVelocity.x/20);
  var transFormString = "translate(" +
    Math.round(this.circleBody.m_position.x) + "," +
    Math.round(this.circleBody.m_position.y) + ") scale (" +
    this.scale.toString() + ") rotate(" +
    Math.round(this.rotation).toString() + "," +
    Math.round(this.xTrans).toString() + "," +
    Math.round(this.yTrans).toString() + ")";
    this.die2.setAttribute("transform", transFormString);
}

一种技术要重新绘制和重新定位形状,而另一种技术只需重新定位,但需要在内存中维护形状,这会带来成本。此成本对于大多数休闲游戏来说都是相当低的,但预期是使用较低级别的 API 实现即时模式图形的游戏更加让人熟悉。

高级方案

可能大部分功能强大的方案都会涉及组合整个图形、样式和文档技术。

用户界面设计

几年前可能就在争论 SVG 是否是适合用于用户界面设计的技术。这些要求与 SVG 一致。事实上,Linux 操作系统的至少一个前端完全建立在 SVG 之上。滑块、复选框、圆形按钮等控件以及其他标准固有控件集中的非框控件都很适合在矢量图形中使用。但是,随着 CSS 的最近和未来开发(包括圆角、渐变、过滤器和打印机事件),可以通过标准的框模型 HTML 文档中心构造来开发大多数这些控件。其他控件(尤其是使用最新 CSS Grid 和 Flexbox 模型的控件)都更好地面向 HTML 元素,至少作为容器。

此处提供了一个丰富的数据驱动图表的示例。 尽管该示例的输出没有架构好,但显示的最终结果正确。 图形和图表控件是众所周知的难开发,但第三方以及 Microsoft 已经成功了。 通过在客户端或服务器端提供最新的数据绑定抽象,客户端的 Web 呈现主要保持静态或者需要插件,这样可减轻开发人员的负担。 下面我们利用了 SVG 的丰富性来提供增强的用户体验。 无论代码如何(将传递给客户端,又或许在将来更多的声明性交互中使用),图表都用两个关键组件来呈现。 工具和数据。图形工具或背景是基本的静态 SVG:

<rect id="tipsh" x="20" y="100" width="194" height="34" rx="5" ry="5" />
<rect id="tip" x="20" y="100" width="190" height="30" rx="5" ry="5" />
<text id="tiptxt" x="40" y="120" font-size="12" font-family="Arial" fill="#ffffff" visibility="hidden">milliseconds</text>
<polygon id="arrow" points="10,110 20,105 20,115" style="fill:#ffffff" />
<line x1="3" x2="460" y1="359" y2="359" style="stroke:#cccccc;stroke-width:1"/>

然后每个单独的数据点要么传递到客户端并进行操作,要么在服务器上生成:

<text x="10" y="348" font-size="12" font-family="Arial">{Page}.svg</text>
<rect x="115" y="350" width="86" height="8" style="fill:url(#inverseblue);filter:url(#Gaussian_Blur);" rx="12" ry="12"/>
<rect x="115" y="333" width="86" height="17" rx="12" ry="12" onmouseover="changeColor(evt)" onmousemove="changeText(evt,'2 milliseconds')" onmouseout="changeTextNotOver(evt)" />
<text x="171" y="345" font-size="11" font-family="Arial" fill="#ffffff">6.1%</text>

http://samples.msdn.microsoft.com/workshop/samples/graphicsInHTML5/svgchart.htm

结论

通过最新浏览器中提供的现有矢量图形技术的分析功能,可以交互方式使用标准 Web 技术来满足现有的和新的方案。 从今以后,我们将拥有巨大的机会可以让声明性动画支持广告版位。 通过使用方案驱动的功能开发,我们可以在竞争中处于领先地位,并在 Web 应用程序和网页中提供基于标准的图形丰富的体验。

发表评论