如何在 SVG 和 Canvas 之间进行选择
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
本主題一開始將對(duì) SVG 與 Canvas 進(jìn)行簡(jiǎn)要比較,接下來(lái)會(huì)討論大量的比較代碼示例,如光線跟蹤和綠屏。
注意??為了查看本主題中包含的很多示例,你必須使用支持?SVG?和?Canvas?元素的瀏覽器(如 Windows Internet Explorer?9)。
- 簡(jiǎn)介
- 向量圖形
- 向量圖形方案的簡(jiǎn)要概述
- 專業(yè)設(shè)計(jì)器和使用工具
- HTML5 圖形技術(shù)
- 技術(shù)簡(jiǎn)介
- 何時(shí)使用 <canvas>、何時(shí)使用 SVG:方案
- 從性能方面選擇
- 高保真度的復(fù)雜向量文檔
- 增強(qiáng)的 Web 圖形
- 像素操作
- 實(shí)時(shí)數(shù)據(jù)
- 像素替換(綠屏)
- 組合/交叉方案
- 高級(jí)方案
- 用戶界面設(shè)計(jì)
- 結(jié)論
- 相關(guān)主題
簡(jiǎn)介
HTML 不斷演變以提供更好、更豐富的標(biāo)準(zhǔn)圖形來(lái)幫助改進(jìn)客戶體驗(yàn)。 為 Web 開發(fā)人員創(chuàng)造了使用基于標(biāo)準(zhǔn)的 Web 技術(shù)創(chuàng)建圖形豐富的交互網(wǎng)站和應(yīng)用程序的機(jī)會(huì),而無(wú)需使用專用的技術(shù)或編寫瀏覽器特定的代碼。以下各節(jié)介紹了向量圖形的概念并執(zhí)行相應(yīng)操作:
- 區(qū)分即時(shí)模式和保留模式之間的差異
- 介紹用于即時(shí)模式圖形的 HTML5 Canvas 元素并提供對(duì) Canvas 的概述
- 介紹可縮放向量圖形 (SVG)、一組用于保留模式圖形的 HTML5 元素并提供對(duì) SVG 的概述
- 指導(dǎo)新開發(fā)人員和有經(jīng)驗(yàn)的開發(fā)人員對(duì)向量圖形和 HTML5 使用其中一個(gè)向量圖形模型(或同時(shí)使用兩者,具體取決于方案)
向量圖形
向量圖形不是新概念。它們是全部基于向量來(lái)表示圖像的幾何基元(形狀、點(diǎn)、線條和多邊形)。在 1960 年代后期,向 Logo 編程語(yǔ)言添加了向量圖形語(yǔ)言(海龜繪圖)來(lái)支持用于執(zhí)行繪圖功能的海龜機(jī)器人。雖然圖形世界在復(fù)雜性方面已經(jīng)發(fā)生了重大的演變,但是存在的基本概念是相同的。
向量圖形的復(fù)雜性范圍從簡(jiǎn)單到適中再到相當(dāng)復(fù)雜。下面是一些基本示例。
- 簡(jiǎn)單 - 一個(gè)文檔或插圖中的標(biāo)注。
- 適中 - 圖表、關(guān)系圖和地圖等插圖。
- 復(fù)雜 - 類似那些用于工程的文檔。
盡管前面的示例在性質(zhì)上是靜態(tài)的,但是向量圖形也支持交互性,這是一項(xiàng)可顯著擴(kuò)展方案的關(guān)鍵功能。向量圖形為 Web、桌面和設(shè)備上的應(yīng)用程序提供交互和靜態(tài)的格式。
向量圖形方案的簡(jiǎn)要概述
在當(dāng)今 Web 上
- 在網(wǎng)頁(yè)中使用向量圖形作為背景圖像以支持高 DPI 和“收縮”縮放功能。
- 地圖屬性(如?Bing 地圖)用來(lái)執(zhí)行線路查找操作。
- 顯示實(shí)時(shí)的圖表和圖形的交互式股票網(wǎng)站。
- 選擇和其他地圖。
- 航班或音樂(lè)廳的座位圖。
- 游戲。
在辦公室中
- Microsoft Office Word(用于剪貼畫)、PowerPoint 和 Excel 以及 Visio 形狀等高效工具。
- 輸出向量圖形格式的 CAD 工具。
- 呈現(xiàn)交互圖表和圖形的 Oracle 和 Microsoft Dynamics 應(yīng)用程序等企業(yè)工具。
在設(shè)備上
- 使得圖形用戶界面更加豐富。
- 用戶交互小工具和圖標(biāo)。
- 完整 PDA 用戶體驗(yàn)。
專業(yè)設(shè)計(jì)器和使用工具
專業(yè)的 Web 設(shè)計(jì)人員在如下工具集中查看向量圖形:
- 用于創(chuàng)建高質(zhì)量靜態(tài)圖像(可以導(dǎo)出為 SVG)的 Adobe Illustrator
- 可以導(dǎo)出為基于 XML 的向量語(yǔ)言的 Adobe?Flash Professional
- 用于 Windows Presentation Foundation (WPF) 和 Silverlight 的 Microsoft Expression?Blend
請(qǐng)務(wù)必注意,向量圖形已經(jīng)在桌面、設(shè)備和 Web 上存在很長(zhǎng)時(shí)間了。
HTML5 圖形技術(shù)
借助 HTML5,開發(fā)人員或設(shè)計(jì)人員現(xiàn)在可以使用基于標(biāo)準(zhǔn)的技術(shù)來(lái)創(chuàng)建以前的體驗(yàn)。這樣可消除對(duì)插件的安裝(50% 的網(wǎng)站放棄訪問(wèn)均與插件的安裝相關(guān)),從而可以極大地改善用戶體驗(yàn)。目前,圖形由瀏覽器原生提供,而對(duì)于 Internet Explorer?9,則利用 Microsoft Windows 和硬件加速圖形的功能。
下一節(jié)概述了兩種全新但不同的技術(shù)、這兩種技術(shù)的使用方法以及各自的優(yōu)勢(shì)和限制。使用一個(gè)向量圖形方案譜表來(lái)討論用于為每個(gè)方案選擇最佳技術(shù)的方法。
下圖顯示了存在于向量圖形中的一個(gè)常規(guī)方案譜表。每一個(gè)方案都可能會(huì)更接近于 canvas 或 svg,這意味著一種技術(shù)相對(duì)于其他技術(shù)更適合該方案。如果方案位于譜表中間,那么選擇任一技術(shù)都是可行的
幾乎所有向量圖形都可以使用上述任一種技術(shù)來(lái)繪制,但有時(shí)根據(jù)任務(wù)的不同,會(huì)有非常多的工作要由開發(fā)人員或計(jì)算機(jī)完成。 當(dāng)我們檢查每種技術(shù)的用例,然后將其應(yīng)用于常見方案時(shí),我們會(huì)進(jìn)一步了解此譜表。
技術(shù)簡(jiǎn)介
下一節(jié)介紹了用于在 HTML5 中創(chuàng)建向量圖形的技術(shù),從而建立對(duì)早期存在的方案的討論。
使用示例
若要使用以下示例,請(qǐng)將以下代碼示例用作模板。可以使用此模板來(lái)開發(fā) SVG 而非 HTML。此模板在本主題的每個(gè)示例中使用。由于格式原因,你可以使用腳本以及樣式。此模板還包含一個(gè) Meta 標(biāo)記,這使得可以在本地文件共享上更輕松地進(jìn)行 SVG 開發(fā)。這些示例使用下面的格式。首先提供有意義的代碼,然后鏈接到完整代碼。
HTML <!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?(單擊“查看源文件”即可查看此標(biāo)記)。
SVG
SVG 用于描述可縮放向量圖形,這是一個(gè)保留在內(nèi)存中模型中的保留模式圖形模型,而內(nèi)存中模型可通過(guò)重新呈現(xiàn)的代碼結(jié)果進(jìn)行操作。這不同于即時(shí)模式,該模式將稍后討論。在 HTML5 中同時(shí)提供這兩種模式。
SVG 是一個(gè)保留模式模型,作為對(duì)獨(dú)立供應(yīng)商(Microsoft 和 Adobe)所提出的兩個(gè)建議的回應(yīng),在 1999 年引入。成立了 W3C SVG 工作組,并且在 2001 年 SVG 規(guī)范達(dá)到了“建議的狀態(tài)”。目前,我們按照?SVG 1.1 第 2 版工作,該版本在編寫本文時(shí)處于“最后征求意見”階段。
盡管 SVG 可以作為獨(dú)立文件進(jìn)行提供,但是最初著重于將它與 HTML 自然集成。
類似于 HTML,SVG 也是使用元素、屬性、和樣式來(lái)構(gòu)建文檔。首次將 <svg> 元素引入到文檔中時(shí),該元素的行為非常類似于 <div> 且作為 HTMLDocument 的一部分,但它包含附加接口 SVGDocument(SVGDocument 提供與向量圖形的更深入、更豐富的交互)。
元素
盡管外部?<svg>?包裝適合于 HTML 框模型,但是大多數(shù)情況下,內(nèi)部模型都會(huì)從該包裝中分離出來(lái),因?yàn)橄蛄坎痪窒抻诤?jiǎn)單的框。這種分離要求擴(kuò)展 SVG 中的屬性才能提供豐富的圖形。
例如:
HTML <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
注意??為了呈現(xiàn)此內(nèi)容以及以下很多示例,你必須使用支持?SVG?和?Canvas?元素的瀏覽器(如 Internet Explorer?9)。
之前的 HTML 代碼將創(chuàng)建一個(gè)正方形,長(zhǎng)寬均為 100 像素,并使用藍(lán)色背景進(jìn)行填充。
此?<rect>?元素保留在 HTML 文檔的文檔對(duì)象模型 (DOM) 中。就像其他 HTML 元素一樣,可通過(guò)多種不同的方式設(shè)置 SVG 的樣式。下面的示例是一個(gè)表。
樣式設(shè)置
開發(fā)人員可能會(huì)注意到屬性是類似的。SVG 同時(shí)具有屬性和演示屬性。此處看起來(lái)描述有點(diǎn)隨意,但關(guān)鍵在于可以按照 CSS 樣式規(guī)則設(shè)置演示屬性的樣式。
四個(gè)矩形使用幾種不同的方法進(jìn)行填充。
HTML <!--No fill (defaults the color to #000000)--> <rect id="myRect1" height="100%" width="100%" > <!--using the class="greenrect"--> <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"/>第一個(gè)示例演示省去一個(gè)屬性會(huì)在圖形上產(chǎn)生可視效果。在此示例中,顏色默認(rèn)為黑色。
第二個(gè)示例演示使用?class="greenrect"?來(lái)填充矩形。包含的用于填充此矩形的 CSS 的形式為:
CSS rect.greenrect {fill:green;}第三個(gè)示例使用內(nèi)聯(lián)樣式將填充設(shè)置為粉色。最后一個(gè)示例使用相應(yīng)屬性填充紅色。此示例還演示了 CSS 選擇器的用法。樣式還包括:
CSS rect:hover {fill:yellow;}這針對(duì)所有矩形建立一個(gè)規(guī)則,即鼠標(biāo)懸停在這些矩形之上時(shí)顏色更改為黃色。
這些對(duì)于有經(jīng)驗(yàn)的 Web 開發(fā)人員來(lái)說(shuō)應(yīng)該都不是新內(nèi)容了。此處提供這些示例是為了強(qiáng)調(diào)相似性(使用樣式、樣式表、類和選擇器)以及差異(樣式不適用于所有屬性,僅適用于演示屬性、新屬性或不一致的屬性)。
http://samples.msdn.microsoft.com/workshop/samples/graphicsInHTML5/svgstyling.htm
可編程性
屬性 API 及其他 DOM 操作仍應(yīng)用并遵循當(dāng)前的屬性規(guī)則。例外情況是,演示應(yīng)用程序基于樣式所取代的屬性(如果適用)。
如果這些屬性是通過(guò)核心屬性或通過(guò)其各自的 DOM 方法進(jìn)行設(shè)置的,則將影響這些屬性的演示,并且基礎(chǔ) DOM 將相應(yīng)地發(fā)生更改(注意使用 SVG DOM 設(shè)置高度的不同語(yǔ)法):
HTML 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 的另一個(gè)關(guān)鍵區(qū)分因素是能夠進(jìn)行代碼交互且不復(fù)雜。正如 SVG 具有一個(gè)類似 HTML 的可編程 DOM 一樣,它還具有事件模型。檢查下面比矩形或正方形更復(fù)雜的圖形:路徑。
使用路徑可繪制任意形狀,例如在該示例中為表示美國(guó)的阿拉斯加州和夏威夷州的兩個(gè)形狀。
http://samples.msdn.microsoft.com/workshop/samples/graphicsInHTML5/svginteractivity.htm
觸發(fā)創(chuàng)建之前指定的警報(bào)的事件。這些復(fù)雜形狀(像更簡(jiǎn)單的矩形)也會(huì)響應(yīng) CSS 選擇器。使用一行 CSS 即可實(shí)現(xiàn)簡(jiǎn)單的突出顯示機(jī)制:
CSS path:hover {fill:yellow;}Canvas
另一種向用戶提供更豐富的圖形體驗(yàn)的方法,通過(guò) <canvas> 標(biāo)記提供,該標(biāo)記由 Apple for Safari 在 HTML5 中或在其他圖形小工具中引入。它在繪制即時(shí)模式圖形(包括矩形、路徑和圖像)方面公開更具編程性的體驗(yàn),與 SVG 類似。即時(shí)模式圖形呈現(xiàn)是一個(gè)“觸發(fā)即忘”模型,該模型將圖形直接呈現(xiàn)到屏幕上,但隨后對(duì)所完成的操作不保留任何上下文。與保留模式相反,不保存呈現(xiàn)的圖形;要在每次需要新框架時(shí)描述整個(gè)場(chǎng)景,開發(fā)人員需要重新調(diào)用所有必需的繪圖命令,而不考慮實(shí)際更改(SVG 已知擁有“場(chǎng)景圖”)。
元素
為了使用畫布 (Canvas) 功能,Web 開發(fā)人員直接引入了一個(gè) Canvas 元素:
HTML <canvas id="myCanvas" width="1200px" height="1200px"></canvas>然后使用 <canvas> 傳統(tǒng)的2D基礎(chǔ)庫(kù) API 來(lái)繪制圖像和向量。
使用 JavaScript 代碼執(zhí)行對(duì)畫布上圖形的操作,通過(guò)添加對(duì)圖形的支持可以獲得 Web 開發(fā)人員熟悉使用的優(yōu)勢(shì)。
JavaScript var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d");如前面提到的,存在與 SVG 中相似的形狀和對(duì)象,舉例來(lái)說(shuō),開發(fā)人員可以使用下面的代碼來(lái)繪制矩形:
JavaScript ctx.fillStyle = "rgb(0,0,255)"; ctx.fillRect(10, 10, 100, 100);稍后將討論這些方法的優(yōu)缺點(diǎn)以及適當(dāng)?shù)姆桨浮?
最終結(jié)果與在 SVG 中相同。http://samples.msdn.microsoft.com/workshop/samples/graphicsInHTML5/canvasintro.htm
但正如 SVG 一樣,Canvas 具有更復(fù)雜的幾何基元,區(qū)別在于這些基元采用函數(shù)形式。
事件的可編程性
為了能夠繪制比矩形更復(fù)雜的圖形(如前面顯示的夏威夷地圖),canvas?API 提供了一個(gè)路徑 API,該路徑 API 支持與 SVG 中的?<path>?元素相似的命令,只是你要對(duì)每一行代碼段調(diào)用相應(yīng)的 API,而不是在單個(gè)屬性中列出它們:
JavaScript 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();有關(guān)夏威夷地圖,請(qǐng)參閱?http://samples.msdn.microsoft.com/workshop/samples/graphicsInHTML5/canvasmap.htm。
路徑 API 并不局限于?moveTo?和?arc,它包含相同的 SVG 方向相位(包括二次曲線和貝塞爾曲線)。
通過(guò)有限的事件和功能可以捕獲鼠標(biāo)在圖像上的位置。因?yàn)椴淮嬖趫D形保留知識(shí),所以編程人員必須轉(zhuǎn)換?mouseX?標(biāo)記的單個(gè)元素上的?mouseY、<canvas>?坐標(biāo),然后將該命令相應(yīng)地傳送到位于內(nèi)存中結(jié)構(gòu)中的形狀。第三方庫(kù)為支持更復(fù)雜的路徑而存在,這包括內(nèi)置?isPointInPath?API,但后者被限制為最后路徑繪制。因而與 SVG 不同,既沒(méi)有任何樣式也不支持多個(gè)幾何圖上的命中檢測(cè)。另外,因?yàn)?Canvas 不支持可伸縮性,所以縮放時(shí)夏威夷地圖將很快失真:
Canvas 是一個(gè)功能強(qiáng)大的低級(jí)別 API,開發(fā)人員利用它可以提供新的圖形體驗(yàn)。
Canvas 與 SVG 的簡(jiǎn)要摘要
下面是簡(jiǎn)要摘要,可幫助你確定何時(shí)使用 Canvas 而不使用 SVG 或者何時(shí)使用 SVG 而不使用 Canvas 來(lái)創(chuàng)建向量圖形。
| 基于像素(動(dòng)態(tài) .png) | 基于形狀 |
| 單個(gè) HTML 元素 | 多個(gè)圖形元素,這些元素成為 DOM 的一部分 |
| 僅通過(guò)腳本修改 | 通過(guò)腳本和 CSS 修改 |
| 事件模型/用戶交互顆粒化 (x,y) | 事件模型/用戶交互抽象化 (rect, path) |
| 圖面較小時(shí)、對(duì)象數(shù)量較大 (>10k)(或同時(shí)滿足這二者)時(shí)性能更佳 | 對(duì)象數(shù)量較小 (<10k)、圖面更大(或同時(shí)滿足這二者)時(shí)性能更佳 |
?
在上表中,考慮這二者在現(xiàn)有軟件方面的意象模型。Canvas 類似于 MSPaint,在其中,你可以使用形狀和其他工具來(lái)繪制和創(chuàng)建圖像。SVG 類似于 Office PowerPoint 幻燈片,它具有可編程的支持并且能夠添加主題。
何時(shí)使用?<canvas>、何時(shí)使用 SVG:方案
這一節(jié)介紹這兩種技術(shù)的技術(shù)優(yōu)勢(shì)和限制,包括用于確定一種技術(shù)何時(shí)相對(duì)于另一種技術(shù)更適合的常用方法。應(yīng)該注意的是,SVG 和?<canvas>?都能實(shí)現(xiàn)幾乎相同的結(jié)果,功能也完全重復(fù)。介紹以下特定情況非常重要:<canvas>?明顯好于 SVG,或相反,二者組合更加合適,或可以使用和考慮任一技術(shù)。
這些方案比較清晰地描述了更適合使用 SVG 的情況、更適合使用 Canvas 的情況,以及其他介于這之間的情況。它們描述了每種技術(shù)的優(yōu)缺點(diǎn),以便開發(fā)人員可以了解相應(yīng)技術(shù)的行為并針對(duì)其應(yīng)用程序做出好的選擇。
從性能方面選擇
有時(shí)存在一些外部影響,要求獨(dú)立于(或幾乎獨(dú)立于)功能選擇技術(shù)。有關(guān)使用 Canvas 或 SVG 的問(wèn)題,存在兩個(gè)主要區(qū)別。
有時(shí)開發(fā)人員的知識(shí)、技能組合和現(xiàn)有資產(chǎn)會(huì)對(duì)技術(shù)的選擇起到重大作用。如果開發(fā)人員具備低級(jí)別圖形 API 方面的深層知識(shí),但在 Web 技術(shù)方面知識(shí)有限,則很可能會(huì)選擇 Canvas 技術(shù)。
另外,性能對(duì)于高流量的網(wǎng)站來(lái)說(shuō)是絕對(duì)關(guān)鍵的。可以對(duì)這兩種技術(shù)的性能特征加以比較。這可能會(huì)要求開發(fā) Canvas 沒(méi)有附帶的輔助功能、自定義樣式以及更粒度化的用戶交互功能。雖然 Canvas 通常被視為具有高性能,但是并不意味著它就是明顯的選擇。下圖顯示了 SVG 對(duì)象和 Canvas 對(duì)象之間在呈現(xiàn)時(shí)間上的差異。
一般情況下,隨著屏幕大小的增大,畫布將開始降級(jí),因?yàn)樾枰L制更多的像素。隨著屏幕上的對(duì)象數(shù)目增多,SVG 將開始降級(jí),因?yàn)槲覀冋粩鄬⑦@些對(duì)象添加到 DOM 中。這些度量不一定準(zhǔn)確,以下方面的不同一定會(huì)引起變化:實(shí)現(xiàn)和平臺(tái)、是否使用完全硬件加速的圖形,以及 JavaScript 引擎的速度。
高保真度的復(fù)雜向量文檔
高保真度的復(fù)雜向量文檔已經(jīng)成為并將繼續(xù)成為 SVG 的最有效點(diǎn),原因主要有兩個(gè)。存在足夠多的極為詳細(xì)的文檔,包括由 CAD 程序生成的那些文檔,針對(duì)這些文檔,SVG 的?scalable?部分提供了獨(dú)立文檔形式或嵌入網(wǎng)頁(yè)中的文檔形式的詳細(xì)視圖。通過(guò)該技術(shù)還可以進(jìn)行高保真打印。SVG 的聲明性性質(zhì)向工具、客戶端或服務(wù)器端提供從數(shù)據(jù)庫(kù)生成形狀的能力。 最后,我們看到了政府機(jī)構(gòu)的發(fā)展,因工程圖(為了專利)或工業(yè)圖(為了城市規(guī)劃目的)緣故從建議支持轉(zhuǎn)變?yōu)閷?duì) SVG 的必需支持。這種轉(zhuǎn)變還將繼續(xù),因?yàn)閷?duì)于公眾使用的電子文檔(如下),政府部門越來(lái)越不是只喜歡一家供應(yīng)商:
- 建筑圖、工程圖和樓層圖
- 電子圖、航空?qǐng)D和示意圖
- 組織結(jié)構(gòu)圖
- 地圖
- 生物圖
以下各圖顯示了前一方案中可以保留的詳細(xì)信息示例。第一個(gè)圖像顯示可以在測(cè)試驅(qū)動(dòng)網(wǎng)站上找到的網(wǎng)頁(yè)快照。它包含呼吸系統(tǒng)圖和元素周期表。
http://ie.microsoft.com/testdrive/Graphics/RealWorldDataAndDiagrams/Default.xhtml
第二個(gè)圖像顯示同一張圖放大 1000% 后的效果
盡管考慮到觀察大的示意圖的有用性,但在需要細(xì)化到細(xì)節(jié)處時(shí)或者出于工程目的需要打印整個(gè)示意圖時(shí),具有可縮放性的?S?將變得足夠清晰和有價(jià)值。出于這些原因,我們將高保真度的復(fù)雜向量文檔放在譜表的遠(yuǎn)端,接近 SVG,如下圖中所示。
這些文檔也可以受益于交互性,這是 SVG 使這些方案最適合于保留圖形模式的第二方面。
增強(qiáng)的 Web 圖形
SVG 作為圖像格式
SVG 另外還常用于簡(jiǎn)單圖像,無(wú)論是應(yīng)用程序還是網(wǎng)頁(yè)中的圖像,大圖像還是小圖像。由于 SVG 要加載到 DOM 中,或者創(chuàng)建圖像前至少要進(jìn)行解析,所以性能會(huì)稍微有所下降,但相比于呈現(xiàn)網(wǎng)頁(yè)的成本(大約幾毫秒),這種下降是極其微小。
在文件大小方面(為了評(píng)估網(wǎng)絡(luò)流量的目的),下面演示的兩個(gè)圖像是一樣的,只差了 1K(SVG 稍微大點(diǎn),沒(méi)有壓縮)。
與以前一樣,因?yàn)?SVG 作為圖像格式是可縮放的,所以如果開發(fā)人員想要以更大的比例使用該圖像,或者用戶使用高 DPI的屏幕,則可移植網(wǎng)絡(luò)圖形 (PNG) 要么會(huì)變得異常,要么需要更大形式的文件來(lái)實(shí)現(xiàn)保真。
SVG 因此可以充當(dāng)非常好的圖像替換格式,甚至對(duì)網(wǎng)頁(yè)上最簡(jiǎn)單的圖像也是如此。靜態(tài) WebApp/網(wǎng)頁(yè)圖像因此落在譜表的 SVG 端。
像素操作
在譜表的另一端,當(dāng)使用 Canvas 時(shí)可以獲得快速的繪圖速度,且不需要保留相應(yīng)信息。存在若干種最適合于 <canvas> 的實(shí)時(shí)數(shù)據(jù)方案。使用光線跟蹤在像平面上通過(guò)像素跟蹤光線路徑并模擬其與虛擬對(duì)象相遇的效果,可以水化圖像。 下圖顯示了這種模擬。
需要很多計(jì)算,因此速度依賴于瀏覽器中的 JavaScript 引擎速度。然而盡管大多數(shù)情況下本地代碼無(wú)可置疑要更快一些,但是隨著 JavaScript 引擎逐漸成熟,我們開始看到在像程序集和 C++ 這樣的時(shí)期內(nèi)這種差距在縮小。
光線跟蹤(通常在 Web 上的背景中完成)獲得的效果甚為廣泛。范圍從創(chuàng)建許多不同的視覺(jué)效果(包括根據(jù)其他簡(jiǎn)單向量圖形創(chuàng)建逼真的圖像)到應(yīng)用照片過(guò)濾器以去除紅眼。
因?yàn)?Canvas API 允許開發(fā)人員讀寫像素,所以這里唯一的限制是速度和想象力。上一個(gè)示例由 Adam Burmister 提供并且位于?http://labs.flog.co.nz/raytracer/上。 在此示例中,可通過(guò)大量的庫(kù)來(lái)實(shí)現(xiàn)創(chuàng)建最終圖像所需的計(jì)算,但主結(jié)束函數(shù)是?fillRect。
JavaScript 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 方案落在譜表的最左端,如下圖所示。
注意生成上述光線跟蹤器的作者 注意 因?yàn)樵摲桨笇a(chǎn)生靜態(tài)圖像,所以桌面軟件經(jīng)過(guò)了很好的調(diào)整以適合光線跟蹤器所需的大量浮動(dòng)操作。
下至金屬像素操作的有趣實(shí)現(xiàn)是圖像的過(guò)濾器應(yīng)用。過(guò)濾器已存在于 Web 上,且需要顯著的處理速度(受益于其對(duì)圖形管道中更深層的硬件加速圖形的應(yīng)用),因此開發(fā)人員可以試用邊緣檢測(cè)或其他數(shù)學(xué)表達(dá)式等算法。
實(shí)時(shí)數(shù)據(jù)
對(duì)于更常見的方案,Canvas 非常適合輸出實(shí)時(shí)數(shù)據(jù)。請(qǐng)注意如何簡(jiǎn)便地確定這些方案,因?yàn)橐呀?jīng)表明使用 Canvas 難以進(jìn)行用戶交互。因此,下面將討論非交互的實(shí)時(shí)數(shù)據(jù)可視化。
今天的天氣數(shù)據(jù)可以通過(guò)特定間隔內(nèi)服務(wù)器上生成的圖像非常靜態(tài)地呈現(xiàn),也可以盡可能快地通過(guò)客戶端第三方插件呈現(xiàn)。盡管 ECWMF 已經(jīng)研究過(guò)使用 SVG 而不使用服務(wù)器生成的圖像如何節(jié)省成本,但是 Canvas 在天氣模式(以及其他快速的實(shí)時(shí)數(shù)據(jù))的大多數(shù)圖形表示形式方面,明顯是贏家。下圖顯示以圖形方式顯示在地圖上的天氣模式。
如你可以從上圖中看到的,沒(méi)有必要存在大的繪圖圖面,而且屏幕上的對(duì)象數(shù)量是相當(dāng)高的。通過(guò)使用 Canvas API,可以在不影響 DOM 的情況下快速繪制(和擦除)這些對(duì)象。盡管可以使用 SVG Ellipse 完成此操作,但是將它們加載到 DOM 中以及通過(guò)動(dòng)畫修改它們的成本是非常高的。事實(shí)上,無(wú)論你是在圖像中還是在數(shù)據(jù)動(dòng)畫中看到大量的形狀(尤其是不相似的形狀)要進(jìn)行分析,通常都會(huì)指出 Canvas 是要使用的技術(shù)。這里的實(shí)際限制是受 CPU 速度和 JavaScript 引擎速度的控制,能多快可視化顯示數(shù)據(jù)。但除了占用 CPU 的光線跟蹤方案之外,仍然可以實(shí)現(xiàn)合理的動(dòng)畫。Reasonable?描述客戶端可以使用 JavaScript 執(zhí)行的操作與服務(wù)器可以通過(guò)電線計(jì)算和封送的操作之間的相對(duì)動(dòng)畫。
此方案似乎是?<canvas>?的關(guān)鍵用例。
像素替換(綠屏)
另一個(gè)使用 Canvas 的可能情況是,在視頻上進(jìn)行顏色檢測(cè)以便用其他場(chǎng)景或圖像替換背景色。像光線跟蹤器或過(guò)濾器一樣,因 JavaScript 中當(dāng)前性能速度限制的緣故,很可能會(huì)使用桌面軟件預(yù)處理任何需要高的最終產(chǎn)品質(zhì)量的現(xiàn)實(shí)方案。但是,由于 <canvas> 是為低級(jí)別像素讀取和寫入設(shè)計(jì)的,因此諸如?greenscreen?替換之類的方案甚至無(wú)法使用 SVG 完成。
從兩個(gè)視頻中讀寫像素到另一個(gè)視頻中所需的代碼要求使用兩個(gè)視頻、兩個(gè)畫布和一個(gè)最終畫布。一次捕捉視頻上的一幀,然后繪制到兩個(gè)單獨(dú)的畫布上。這樣允許讀回?cái)?shù)據(jù)。
JavaScript ctxSource1.drawImage(video1, 0, 0, videoWidth, videoHeight); ctxSource2.drawImage(video2, 0, 0, videoWidth, videoHeight);因此,下一步是檢索每個(gè)繪制圖像的句柄,以便你可以檢查每個(gè)單獨(dú)的像素。
JavaScript currentFrameSource1 = ctxSource1.getImageData(0, 0, videoWidth, videoHeight); currentFrameSource2 = ctxSource2.getImageData(0, 0, videoWidth, videoHeight);獲取后,代碼將瀏覽綠屏的像素?cái)?shù)組,搜索綠色像素,如果找到,代碼將用背景場(chǎng)景中的像素替換所有綠色像素。
JavaScript 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];} }最后,像素?cái)?shù)組將寫入到目標(biāo)畫布中。
JavaScript ctxDest.putImageData(currentFrameSource1, 0, 0);http://samples.msdn.microsoft.com/workshop/samples/graphicsInHTML5/canvasgreenscreen.htm(若要完整地查看 greenscreen 代碼,請(qǐng)查看該頁(yè)的源代碼。)
組合/交叉方案
以下方案可以在 SVG 或 Canvas 中完成,都可以獲得適當(dāng)?shù)慕Y(jié)果,但你可能會(huì)更喜歡一項(xiàng)技術(shù)勝過(guò)另一項(xiàng)技術(shù)。
圖表和圖形
需要向量圖形的圖表和圖形的譜表很寬廣。大部分這些圖形最好使用 SVG 進(jìn)行創(chuàng)建,因?yàn)樗鼈兙哂邢铝腥齻€(gè)特征之一:
- 圖形是從可以輕松轉(zhuǎn)換為 XML (SVG) 的現(xiàn)有數(shù)據(jù)生成的
- 它們需要用戶交互
- 優(yōu)點(diǎn)是可在網(wǎng)頁(yè)上設(shè)置樣式
我們使用可顯著增加方案范圍的交互功能來(lái)擴(kuò)展高保真文檔方案。 其中包括:
- 交互的組織結(jié)構(gòu)圖和流程圖
- 數(shù)據(jù)圖(環(huán)形圖、條形圖、散點(diǎn)圖)
- 交互式地圖 - 路徑查找
- 建筑圖、工程圖和樓層圖
- 航班或音樂(lè)廳的座位圖
已經(jīng)確定快速的實(shí)時(shí)數(shù)據(jù)處理已針對(duì) Canvas 進(jìn)行了更好地優(yōu)化(主要取決于速度)。
二維游戲
制作休閑游戲(此處定義為 Web 上的簡(jiǎn)單二維游戲)時(shí),開發(fā)人員需要在 canvas 和 svg 之間做出選擇。因?yàn)闅v史上游戲庫(kù)一直利用較低級(jí)別的圖形 API,所以將傾向于選擇?<canvas>。
當(dāng)庫(kù)的其他組成部分(如受歡迎的物理引擎)比圖形層要明顯深時(shí),圖形將變成實(shí)現(xiàn)細(xì)節(jié)。邊框、速度、大小和位置等圖形幾何將傳遞給引擎,而引擎隨后將用速度、碰撞和位置進(jìn)行響應(yīng)。圖形位于堆棧中的最高層。
通過(guò)由同一作者開發(fā)的兩個(gè)游戲來(lái)演示獨(dú)立于游戲邏輯的圖形概念,旨在說(shuō)明?<svg>?和?<canvas>:SVG-oids?和?canvas-pinball。一個(gè)出色的、獨(dú)立于游戲引擎的圖形層示例是將?canvas-pinball?與?SVG-Dice?進(jìn)行比較(當(dāng)兩者都使用相同的物理引擎時(shí))。
盡管游戲和演示邏輯是不同的,但是這兩個(gè)游戲的物理引擎都會(huì)跟蹤位置、碰撞、速度以及游戲組成部分的其他物理方面。
對(duì)于 canvas-pinball,自定義的更高級(jí)別的動(dòng)畫管理器通過(guò)使用一系列 Canvas API 重新繪制場(chǎng)景。
JavaScript 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); }對(duì)于 SVG Dice,自定義的更高級(jí)別的動(dòng)畫管理器使用組轉(zhuǎn)換通過(guò) DOM 在屏幕上重新定位現(xiàn)有圖形。
JavaScript 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); }一種技術(shù)要重新繪制和重新定位形狀,而另一種技術(shù)只需重新定位,但需要在內(nèi)存中維護(hù)形狀,這會(huì)帶來(lái)成本。此成本對(duì)于大多數(shù)休閑游戲來(lái)說(shuō)都是相當(dāng)?shù)偷?#xff0c;但預(yù)期是使用較低級(jí)別的 API 實(shí)現(xiàn)即時(shí)模式圖形的游戲更加讓人熟悉。
高級(jí)方案
可能大部分功能強(qiáng)大的方案都會(huì)涉及組合整個(gè)圖形、樣式和文檔技術(shù)。
用戶界面設(shè)計(jì)
幾年前可能就在爭(zhēng)論 SVG 是否是適合用于用戶界面設(shè)計(jì)的技術(shù)。這些要求與 SVG 一致。事實(shí)上,Linux 操作系統(tǒng)的至少一個(gè)前端完全建立在 SVG 之上。滑塊、復(fù)選框、圓形按鈕等控件以及其他標(biāo)準(zhǔn)固有控件集中的非框控件都很適合在向量圖形中使用。但是,隨著 CSS 的最近和未來(lái)開發(fā)(包括圓角、漸變、過(guò)濾器和打印機(jī)事件),可以通過(guò)標(biāo)準(zhǔn)的框模型 HTML 文檔中心構(gòu)造來(lái)開發(fā)大多數(shù)這些控件。其他控件(尤其是使用最新 CSS Grid 和 Flexbox 模型的控件)都更好地面向 HTML 元素,至少作為容器。
此處提供了一個(gè)豐富的數(shù)據(jù)驅(qū)動(dòng)圖表的示例。 盡管該示例的輸出沒(méi)有架構(gòu)好,但顯示的最終結(jié)果正確。 圖形和圖表控件是眾所周知的難開發(fā),但第三方以及 Microsoft 已經(jīng)成功了。 通過(guò)在客戶端或服務(wù)器端提供最新的數(shù)據(jù)綁定抽象,客戶端的 Web 呈現(xiàn)主要保持靜態(tài)或者需要插件,這樣可減輕開發(fā)人員的負(fù)擔(dān)。 下面我們利用了 SVG 的豐富性來(lái)提供增強(qiáng)的用戶體驗(yàn)。 無(wú)論代碼如何(將傳遞給客戶端,又或許在將來(lái)更多的聲明性交互中使用),圖表都用兩個(gè)關(guān)鍵組件來(lái)呈現(xiàn)。 工具和數(shù)據(jù)。圖形工具或背景是基本的靜態(tài) SVG:
HTML <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"/>然后每個(gè)單獨(dú)的數(shù)據(jù)點(diǎn)要么傳遞到客戶端并進(jìn)行操作,要么在服務(wù)器上生成:
HTML <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
結(jié)論
通過(guò)最新瀏覽器中提供的現(xiàn)有向量圖形技術(shù)的分析功能,可以交互方式使用標(biāo)準(zhǔn) Web 技術(shù)來(lái)滿足現(xiàn)有的和新的方案。 從今以后,我們將擁有巨大的機(jī)會(huì)可以讓聲明性動(dòng)畫支持廣告版位。 通過(guò)使用方案驅(qū)動(dòng)的功能開發(fā),我們可以在競(jìng)爭(zhēng)中處于領(lǐng)先地位,并在 Web 應(yīng)用程序和網(wǎng)頁(yè)中提供基于標(biāo)準(zhǔn)的圖形豐富的體驗(yàn)。
相關(guān)主題
HTML5 圖形 Scalable Vector Graphics (SVG) CANVAS Element | canvas Object轉(zhuǎn)載于:https://my.oschina.net/lujian863/blog/189803
總結(jié)
以上是生活随笔為你收集整理的如何在 SVG 和 Canvas 之间进行选择的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 自定义填充图案插件 cad_20个超实用
- 下一篇: POI 实现Word替换书签