您的位置:首页 > 其它

svg和canvas的应用场景分析【转载】

2012-03-12 11:30 274 查看

原文地址:http://blogs.msdn.com/b/weizhong/archive/2011/07/16/canvas-svg.aspx

思考什么时候使用Canvas和SVG



wzhong
15Jul20119:07PM

0

HTML5Canvas和SVG是IE9中引入的两项令人激动的图形功能。上周在拉斯维加斯举办的MIX11大会对这两个功能进行了介绍(请参阅深入剖析HTML5<canvas>和现代化您的网站:SVG遇到HTML5)。

这些技术可用于解决现代网络上众多的图形场景。由于Canvas带来了众多激动人心的功能,人们往往会忽略SVG,而在许多情况下SVG可能是更好的选择。这里我提供一些关于在何时选择Canvas、SVG或二者的组合的想法。

Canvas和SVG总体概述

以下是对Canvas和SVG的一个总体概述,为关于何时使用一种特定的矢量图形技术的讨论提供了框架。

CanvasSVG的对比

Canvas

SVG

基于像素(Canvas在本质上是一个具有绘图API的图像元素)

基于对象模型(SVG元素与HTML元素类似)

单个HTML元素,在行为上类似于<img>

多个图形元素,是文档对象模型(DOM)的一部分

视觉呈现通过脚本以编程方式创建和修改

视觉呈现使用标记创建并通过CSS或通过脚本以编程方式修改

事件模型/用户交互是粗粒度的–仅在画布元素上,交互必须根据鼠标坐标手动编程

事件模型/用户交互基于对象,是在原语图形元素上的–线条、矩形、路径

API不支持可访问性,除了画布,还必须使用基于标记的技术

SVG标记和对象模型直接支持可访问性

SVG作为一种在内存模型中持久保存的保留模式图形模型而著称。类似于HTML,SVG构建一个包含元素、特性和样式的对象模型。当<svg>元素出现在HTML5文档中时,它的行为类似于一个内联块,是HTML文档树的一部分。

Canvas是一个位图,包含一个即时模式图形应用程序编程接口(API)来在它之上进行绘制。Canvas是一种“即发即弃”模型,直接向它的位图呈现它的图形,然后对所绘制的形状没有任何认知,只会得到最终的位图。

可以这么认为,Canvas类似于WindowsGDIAPI,其中您以编程方式向窗口绘制图形,而SVG类似于包含元素、样式、事件和基于DOM的可编程性的HTML标记。Canvas是过程性的,而SVG是声明性的。

场景

以下几节介绍两种技术的技术优势和不足,包括确定一种技术何时适用于给定任务的一种常用方法。从下图中可以看出,每个场景落在从Canvas到SVG之间的一个范围中,两种技术中间有一个明确的交叉点。




矢量图领域

高保真度复杂矢量文档
高保真度复杂矢量文档已是并将继续是SVG的最佳点。它非常详细,适用于查看和打印,可以是独立的,也可以嵌入到网页中。SVG的声明性特征提供了从数据库到形状的工具、客户端或服务器端生成。

InternetExplorerTestDrive上提供了一个真实图形演示:





第一幅图显示了图,而第二幅图显示了放大到1000%的图





当考虑到观察大型示意图的适用性,但需要下钻到详细信息或出于工程用途打印整个文档时,可缩放的矢量图形中的“可缩放”特征会变得非常清晰。出于这些原因,我们将高保真度复杂矢量文档放在范围的SVG端。

混合交叉

用于查看和打印的高保真度文档





SVG作为一种图像格式
SVG的另一个常见用途是用于网页内的静态图像。使用目前的高DPI显示器,开发人员必须考虑图形的质量。下面的图像表示通过CSS设置了样式的可能的<li>项目符号图像。下面的图像在外观和文件大小上几乎完全相同。




左侧是SVG图形,右侧是它的PNG呈现

如果开发人员希望大规模重用该图像,或者如果最终用户使用了高DPI屏幕,光栅图像将变得失真,或者需要更大的文件才能保持保真度。




左侧是放大的SVG图形,右侧是放大的4KPNG

因此,SVG是网页上最简单图像的一种好替换格式。Canvas没有适用的替换格式可用。

静态
图像

混合交叉

用于查看和打印的高保真度文档





在范围的另一端,Canvas具有很高的呈现速度,不需要保留所绘制的内容。当首次引入Canvas时,开发了许多有趣的实验。我将这些实验划分为3种不同的场景。

像素操作
因为Canvas专门用于绘制和操作基于像素的绘图面,所以一些Canvas实验和展示包括复杂的算法,以实现令人印象深刻的图形效果,比如光线跟踪或滤镜。

下面的示例由AdamBurmister编写。该实验通过跟踪光线在一个图像平面上创建了一幅图像,模拟它遇到虚拟物体的效果。





作者本身提供了以下警告:“这会消耗大量CPU资源。您的浏览器可能看起来会停止响应。”因此,尽管CanvasAPI能够生成这样的图片,但这可能并不是一个好想法。正如网站作者AdamBurmister所总结的,“光线跟踪[是]有史以来最糟糕的JavaScript应用。”

其他场景范围的像素操作也可以这么说。下面的函数将一个画布中的绿色像素替换为另一个具有相同大小的画布中的像素。这样的函数可用于创建视频的“绿屏”效果。

functionGreenScreenAtoB(a,b){

varaImageData=a.getImageData(0,0,a.canvas.width,a.canvas.height);

varbImageData=b.getImageData(0,0,b.canvas.width,b.canvas.height);

varaPixels=aImageData.data;

varbPixels=bImageData.data;


if(aPixels.length!=bPixels.length){

window.alert("Canvasesdonothavethesamenumberofpixels");

returnbImageData;

}


varpixelCount=bPixels.length;

for(varpixelIndex=0;pixelIndex<pixelcount;pixelIndex+=4){

//grabtheRGBAcomponentsofeachpixelinb

varr=bPixels[pixelIndex+0];

varg=bPixels[pixelIndex+1];

varb=bPixels[pixelIndex+2];

vara=bPixels[pixelIndex+3];


//ifthebpixelisgreen,replaceitwithapixelfroma

if(r==0&&g==255&&b==0&&a==255){

bPixels[pixelIndex+0]=aPixels[pixelIndex+0];

bPixels[pixelIndex+1]=aPixels[pixelIndex+1];

bPixels[pixelIndex+2]=aPixels[pixelIndex+2];

bPixels[pixelIndex+3]=aPixels[pixelIndex+3];

}

}


returnbImageData;

}

这是一个有趣的实验,但是与上面的光线跟踪示例一样,目前的机器性能会拖后腿。我列举这些示例有一个主要原因:这种像素操作使用SVG无法实现。它是两种技术之间的区别性因素。一种技术处理像素,而另一种处理模型。

无论是从简单的矢量图形创建真实的图像还是为视频创建绿屏效果,在大多数情况下,这些图形场景都不适合在如今的网络上进行快速部署。但是,某些场景具有足够的响应能力(比如应用滤镜来删除照片中的红眼)。这些像素操作场景在范围中与画布场景一样位于最左端。

混合交叉

用于查看和打印的高保真度文档

静态图像

高性能(滤镜、光线跟踪器)





HybridandCrossover
最有趣的用例不会指明明确获胜者。这些用例可分为两种主要场景:图表/图形/映射和二维游戏。

图表和图形需要矢量图,Canvas或SVG都可以使用。但是,由于SVG固有的功能,它常常是更好的选择。

SVG图表/图形/映射场景
网络上一个流行的图表和图形子集包括:

交互式组织图和流程图

交互式地图–路径查找

建筑楼层平面图

工程示意图

航线或活动场所座位布局

一般数据或财务图表(柱状图、条形图、折线图、散点图、环形图等)

对于所有这些,SVG是首选技术的原因在于:

它们可以通过将XML转换为SVG,从现有数据轻松生成

静态版本可从工具(包括Inkscape、AdobeIllustrator、MicrosoftVisio和各种CAD程序)导出

它们需要准确的用户交互

第三方内容提供商可使用CSS样式为Web作者进行自定义

它们需要可访问性

为了更准确地演示,我们看一下在美国地图上选择一个州的场景。



网页上此图显示不出来,请插入该图

上面显示的阿拉斯加州详细地图是公共领域,可在WikimediaCommons上看到。

在SVG中,阿拉斯加州使用一个<path>元素表示,该元素的“d”特性中包含大约162,500字符的地理数据。

<pathid="AK"fill="#cdc3cc"d="M777.5514,1536.1543C776.4904,1535.0933776.7795,1530.0041777.9416,1529.2859C781.3258,1527.1943787.2657,1532.4522784.8317,1535.3849…"/>

对于Canvas,此形状可使用一系列JavaScript调用创建:

functiondrawAlaska(){

varcanvas=document.getElementById("myCanvas");

varctx=canvas.getContext("2d");

ctx.beginPath();

ctx.moveTo(777.5514,1536.1543);

ctx.bezierCurveTo(776.4904,1535.0933,776.7795,1530.0041,777.9416,1529.2859);

ctx.bezierCurveTo(781.3258,1527.1943,787.2657,1532.4522,784.8317,1535.3849);

//

//2,875morepath-drawingdirectives

//

ctx.bezierCurveTo(1689.8261,12.13753,1689.1395,12.17333,1685.8848,10.52683);

ctx.closePath();

ctx.fillStyle="#cdc3cc";

ctx.fill();

}

实际上,它需要2,878条路径绘制指令(moveTo、lineTo和bezierCurveTo)来绘制复杂的阿拉斯加州地图。当然,可以实现此地图的低分辨率版本。怀俄明州和科罗拉多州所需的代码要少得多。:-)

SVG基于地图的应用程序通常包含一种涉及到悬停效果、选择、项目之间的缩进和缩放的交互式体验。在使用SVG时,比如用于处理鼠标事件,这些操作仅需要轻量型的HTML概念:

<pathid="AK"fill="#cdc3cc"onmousedown="window.alert('Alaska');"d="M777.5514,1536.1543…"/>

或者使用CSS创建一个悬停突出显示效果:

path#AK:hover{fill:yellow;}

此交互式地图类型的一个示例可以在TestDrive演示AtlaszurEuropawahl2004inDeutschland中看到,2004年德国的欧洲选举结果的可视化。

在Canvas中,创建这些效果需要使用事件对象的鼠标坐标对您自己的点击检测进行编码。可以使用任何形状。尽管有isPointOnPath()API,但它仅适用于创建的最后一条路径。

代码能够并确实以图形库的形式存在,以在图形上启用具体的点击检测,能够正常地使用像素数据来检测点击和悬停。它们也可供SVG使用,如果在设计中利用了SVG功能,将具有更高的性能。

混合交叉

用于查看和打印的高保真度文档

静态图像

交互式图表和图形

高性能(滤镜、光线跟踪器)





Canvas图表/图形场景
Canvas为图表和图形场景提供了自己的空间。要设置此场景的上下文,我们需要了解SVG和Canvas的性能特征。

有时,一些外部影响因素要求选择一种(几乎)与功能独立的技术。对于SVG和Canvas,有两个主要的区别。

开发人员知识、技能集和现有的资产将在技术选择中扮演着重要角色。如果在创建游戏期间,开发人员拥有深厚的低级图形API知识和有限的Web技术知识,那么可能的技术选择是Canvas(稍后将详细介绍)。对于游戏移植,一些工具支持从第三方实现迁移到Canvas。

如果性能至关重要,常常要求精确到毫秒级,那么有必要对比两种技术的性能特征。这并不意味着Canvas(通常被视为具有很高的性能)是显而易见的选择。但是,对于具有必须在像素级别绘制的大量数据的应用程序,Canvas显然是更好的选择。

下面的天气地图不需要较大的表面区域,屏幕上的对象数量非常多。使用Canvas,无需更新DOM即可快速绘制这些对象。





尽管上图完全可以在SVG中创建,使用圆圈或椭圆元素表示点,但将数千个元素加载到DOM中可能要花费很多时间。无论您是看到大量像素还是图像,这都是表明Canvas是要使用的技术的好线索——无论这是天文学、生物细胞运动还是音频调制显示。这里对数据可视化速度的限制是CPU速度、Canvas实现速度和JavaScript实现速度。

实时高容量数据表示

交互式图表和图形

用于查看和打印的高保真度文档

高性能(滤镜、光线跟踪器)

混合交叉

静态图像





二维游戏
休闲游戏是我们要探索的最复杂的场景。一些初始观察结果如下:

游戏库利用了较低级的图形API

开发人员的游戏行业技能集针对这些较低级的API进行了调优

许多游戏在很大程度上是基于图像或子画面的

Adobe等供应商正在开始支持导出Canvas

休闲游戏通常不需要复杂的点击测试

休闲游戏通常没有大量的“对象”

在游戏库中(例如,流行的力学引擎),图形模型是独立的,并且图形成为了一种实现细节。图形几何特征,比如边界、速度、大小和位置都提供给引擎,随后引擎使用速度、碰撞和位置进行响应。图形仅用于在屏幕上获取计算的场景。

图形与游戏逻辑独立的概念在两个游戏中得到了展示,这两个游戏由同一个人开发,旨在分别强调SVG和<canvas>:SVG-oids和canvas-pinball。

尽管游戏和演示逻辑是不同的,但二者都利用了相同的力学引擎,该引擎跟踪位置、碰撞、速度和游戏组件的其他力学方面。最后,一个人可以使用SVG绘制(或移动)游戏元素,其他人可以使用Canvas重新绘制它们。

如今为HTML5构建的大部分2D休闲游戏都使用了Canvas,所以我们将此场景放在交叉点上靠近Canvas的一端。

2D休闲游戏

交互式图表和图形

实时高容量数据表示

高性能(滤镜、光线跟踪器)

用于查看和打印的高保真度文档

混合交叉

静态图像





混合场景
休闲游戏属于混合场景,因为它能够利用两种技术的优势。对于轻松的点击检测和用户交互,SVG几何结构的一个最不透明的层可用于定位元素,而底层Canvas可非常快地定位相关图像并提供实时动画。

休闲游戏领域外部越来越多的人发现使用混合场景很有吸引力。当一个场景同时包含生动的动态图形和动画的需要(Canvas)以及丰富的用户交互的需要(SVG)时,这两种技术都应该使用。一个代表场景就是TheBeautyoftheWeb网站上展示的来自我们的一家合作伙伴的BrainPower网站。这个BrainPower网站(以及TheBeautyoftheWeb上的其他特色网站)已发现了此恰当的平衡。

对于BrainPower的用户交互和显示部分,该网站利用了更高级的SVG几何结构:

<polygonid="SensoryCortex"points="253,80,266,93,…"/>

对于实时动画和特殊效果,可以使用Canvas:

<canvasid="cnvDisplay"width="1920"height="1099"/>

结束语

对最新的现代浏览器中可用的现有矢量图技术的分析表明,可以通过一种交互式方式使用标准Web技术创建新的场景。

包含丰富图形的Web

实时高容量数据表示

交互式图表和图形

混合交叉

用于查看和打印的高保真度文档

静态图像

高性能(滤镜、光线跟踪器)

2D休闲游戏





Web的持续演化将不断继续,在其核心位置包含更加丰富的图形。我们提供了一种关于将这些技术应用到特定场景的观点。最后,Canvas和SVG都是包含丰富图形的HTML5Web的重要组件。

我们期待听到您如何将这些新HTML5技术应用到您的网站。包含URL并请通过包含HTML5doctype、<!DOCTYPEhtml>和使用功能检测(而不是浏览器检测)来了解支持SVG还是Canvas;确保您的页面适用于IE9。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: