HTML5 Canvas與SVG均為基於標準的HTML5技術,可用於創建令人驚嘆的圖形和視覺體驗。本文探討的問題是:在專案中應該使用哪一種?換言之,是否存在偏好HTML5 Canvas而非SVG的使用場景?
首先,讓我們簡要介紹HTML5 Canvas與SVG。
何謂HTML5 Canvas?
canvas
元素為腳本提供了一個依賴解析度的位圖畫布,可用於即時渲染圖表、遊戲圖形、藝術作品或其他視覺圖像。
換句話說,<canvas>
標籤展示了一個可以通過JavaScript編程接口逐像素創建和操作光柵化圖像的表面。
以下是一個基本代碼示例:
HTML部分:
<canvas id="myCanvas" width="800" height="800"></canvas>
JavaScript部分:
const canvas = document.getElementById('myCanvas');
const context = canvas.getContext('2d');
context.fillStyle = '#c00';
context.fillRect(10, 10, 100, 100);
通過獲取2D上下文對象的引用,您可以利用HTML5 Canvas API的方法和屬性。在上例中,我繪製了一個簡單的紅色方塊,尺寸為100 x 100像素,位於<canvas>
繪圖表面左側10px、上方10px處。
由於解析度依賴性,您在<canvas>
上創建的圖像在放大或顯示於Retina顯示器上時可能會失去品質。
繪製簡單形狀僅是冰山一角。HTML5 Canvas API允許您繪製弧線、路徑、文字、漸變等。您還可以逐像素地操縱您的圖像。這意味著您可以在圖形的某些區域中將一種顏色替換為另一種,可以對您的繪圖進行動畫化,甚至將視頻繪製到畫布上並改變其外觀。
什麼是SVG?
SVG代表可縮放向量圖形。根據規範:
SVG是一種用於描述二維圖形的語言。作為單獨格式或在與其他XML混合時,它使用XML語法。當與HTML5混合時,它使用HTML5語法。…
SVG圖形可以是交互式的和動態的。可以通過聲明性地(即,通過在SVG內容中嵌入SVG動畫元素)或通過腳本來定義和觸發動畫。
SVG是一種用於創建向量圖形的XML文件格式。由於其可縮放性,您可以在保持清晰度和高品質的同時放大或縮小向量圖像。(這對於HTML5 Canvas生成的圖像來說是不可能的。)
這裡是同一個紅色方塊(之前使用HTML5 Canvas創建),這次使用SVG繪製:
<svg xmlns="https://www.w3.org/2000/svg" viewbox="0 0 600 600">
<desc>Red rectangle shape</desc>
<rect x="10" y="10" width="100" height="100" fill="#c00" />
</svg>
使用SVG,您可以完成大部分Canvas能做的事情——例如繪製形狀和路徑、漸變、圖案、動畫等。然而,這兩種技術的工作原理本質上有所不同。與Canvas圖形不同,SVG擁有DOM,因此CSS和JavaScript都能訪問它。例如,您可以使用CSS改變SVG圖形的樣式,通過CSS或JavaScript對其節點進行動畫處理,使其部分像<div>
一樣響應鼠標或鍵盤事件。正如後續章節將更清晰地展示,這種差異在您需要為下一個項目選擇Canvas或SVG時起著重要作用。
立即模式與保留模式
區分立即模式和保留模式至關重要。HTML5 Canvas是前者的例子,而SVG則是後者。
立即模式意味著一旦您的繪圖出現在畫布上,畫布就不再跟蹤它。換句話說,作為開發者,您需要計算出繪製對象的命令,創建並維護最終輸出應該呈現的模型或場景,並指定需要更新什麼。瀏覽器的圖形API僅將您的繪圖命令傳達給瀏覽器,然後由瀏覽器執行這些命令。
SVG採用保留模式,您只需發出繪圖指令,描述您希望在螢幕上顯示的內容,瀏覽器的圖形API便會建立一個內存模型或場景,代表最終輸出,並將其轉換為瀏覽器的繪圖命令。
相對地,Canvas作為立即模式圖形系統,並不具備DOM(文件物件模型)。使用Canvas時,您繪製像素,系統隨後便會忘記這些像素,從而減少維護繪圖內部模型所需的額外記憶體。而在SVG中,您繪製的每個物件都會被添加到瀏覽器的內部模型中,這使得開發者的工作更為便捷,但代價是性能上的成本。
基於立即模式與保留模式的區別,以及其他Canvas和SVG各自的特定特性,可以概述在某些情況下,使用其中一種技術可能更符合您的項目目標。
HTML5 Canvas:優點與缺點
HTML5 Canvas規範明確建議,作者應不在有其他更合適手段的情況下使用<canvas>
元素。
例如,對於圖形豐富的<header>
元素,最佳工具是HTML和CSS,而非<canvas>
(同樣,SVG亦非首選)。Zim JS canvas框架的創建者及創始人Dr Abstract也確認了這一觀點,他寫道:
DOM 以及 DOM 框架擅長於展示資訊,尤其是文字資訊。相較之下,canvas 就像是一幅畫。雖然可以在 canvas 上加入文字並使其具有響應性,但這些文字無法像在 DOM 上那樣輕易地被選取或搜尋。長滾動頁面包含大量文字或文字與圖像的組合,是 DOM 的絕佳應用場景。DOM 非常適合社交媒體網站、論壇、購物以及我們習慣使用的所有資訊應用程式。— “何時使用 JavaScript Canvas 庫或框架”
因此,這是一個明確的例子,說明何時不應使用<canvas>
。但何時<canvas>
是一個好的選擇呢?
這則Sarah Drasner 的推文概述了 canvas 特性與能力的幾個主要優缺點,這有助於我們找出這項強大技術的一些應用案例:
I had this slide in a lot of talks and workshops over the years: pic.twitter.com/4K0C7mNzg2
— Sarah Drasner (@sarah_edo) October 2, 2019
您可以從這裡查看推文中的圖片。
HTML5 Canvas 的優秀應用場景
Alvin Wan已經對 Canvas 和 SVG 進行了性能基準測試,考慮到繪製的物件數量以及物件或 canvas 本身的尺寸大小。他總結的結果如下:
總結來說,當處理數百甚至數千個對象時,DOM渲染的開銷更為顯著;在此情況下,Canvas顯然是贏家。然而,無論是Canvas還是SVG,對於對象大小都是不變的。綜合考量,Canvas在性能上提供了明顯的優勢。
基於我們對Canvas的了解,尤其是其在繪製大量對象時的卓越性能,以下是一些可能適合使用Canvas,甚至優於SVG的場景。
遊戲與生成藝術
對於圖形密集型、高度互動的遊戲,以及生成藝術,Canvas通常是首選。
光線追蹤
光線追蹤是一種用於創建3D圖形的技術。
光線追蹤可以通過追蹤光線在圖像平面上通過像素的路徑並模擬其與虛擬對象相遇的效果來豐富圖像。…光線追蹤所達到的效果,…從…將原本簡單的矢量圖形創建成逼真的圖像,到應用類似照片的濾鏡以去除紅眼。—SVG vs Canvas: 如何選擇, 微軟文檔。
如果你感到好奇,這裡有一個由Mark Webster展示的射線追踪應用程序。
然而,儘管HTML5 Canvas無疑比SVG更適合此任務,但這並不意味著射線追踪在<canvas>
元素上執行最佳。事實上,CPU的壓力可能相當大,以至於你的瀏覽器可能停止響應。
在小表面上繪製大量物件
另一個例子是,當你的應用程序需要在相對較小的表面上繪製大量物件時,例如非交互式的實時數據可視化,如天氣模式的圖形表示。
上圖來自這篇MSDN文章,這是我為此作品進行研究的一部分。
視頻中的像素替換
如HTML5 Doctor文章所示,另一個適合使用Canvas的情況是替換視頻背景顏色,使用不同的顏色、另一個場景或圖像。
HTML5 Canvas不太適合的情況
另一方面,也有許多情況下,Canvas可能不如SVG適合。
可擴展性
在大多數需要可擴展性的場景中,使用SVG而非Canvas會更為合適。例如建築與工程圖、組織結構圖、生物學圖表等高保真度、複雜圖形,均屬此類。
當使用SVG繪製時,無論放大圖像或打印,所有細節均能保持高品質。此外,這些文件可從數據庫生成,使得SVG的XML格式極適合此類任務。
同時,這些圖形常具互動性。以網上訂票時的座位圖為例,這使得SVG這樣的保留模式圖形系統成為理想選擇。
當然,借助如CreateJS及擴展CreateJS的Zim等優秀庫,開發者能相對迅速地將鼠標事件、命中測試、多點觸控手勢、拖放功能、控制元件等整合至Canvas作品中。
可訪問性
雖然可以採取措施使Canvas圖形更易於訪問,且如Zim這樣的優秀Canvas庫能加速此過程,但Canvas在可訪問性方面並不突出。Canvas上的繪製僅為像素集合,無法被輔助技術或搜索引擎機器人讀取或解釋。這正是SVG更受青睞的另一領域:SVG即XML,對人與機器皆可讀。
不依賴JavaScript
如果你不想在你的應用程式中使用JavaScript,那麼Canvas可能不是你的最佳選擇。事實上,你唯一能與<canvas>
元素互動的方式就是透過JavaScript。相反地,你可以使用標準的向量編輯程式如Adobe Illustrator或Inkscape來繪製SVG圖形,並且可以使用純CSS來控制它們的外觀以及進行引人注目、微妙的動畫和微互動。
結合HTML5 Canvas與SVG應對高級場景
有些情況下,你的應用程式可以通過結合HTML5 Canvas和SVG來獲得兩者的最佳效果。例如,一個基於Canvas的遊戲可以從向量編輯程式生成的SVG圖像中實現精靈,以利用其可擴展性和與PNG圖像相比的較小下載大小。或者,一個繪圖程式可以將其用戶界面設計為SVG,並嵌入一個<canvas>
元素,用於繪圖。
最後,一個強大的庫如Paper.js使得在HTML5 Canvas之上編寫向量圖形成為可能,從而為開發者提供了一種方便的方式來同時使用這兩種技術。
結論
在本文中,我探討了HTML5 Canvas和SVG的一些關鍵特性,以幫助你決定哪種技術可能最適合特定的任務。
答案是什麼?
Chris Coyier同意Benjamin De Cock的觀點,正如後者所發推文所示:
一個極其基本的回答是「當你無法使用SVG時,就使用Canvas」(此處的「無法」可能意味著需要動畫成千上萬的物件,或是需要對每個像素進行個別操作等)。換句話說,SVG應該是你的首選,而Canvas則是備用方案。
— Benjamin De Cock (@bdc) October 2, 2019
Dr Abstract提供了一份適合使用Canvas建構的長清單,包括互動式標誌和廣告、互動式資訊圖表、電子學習應用程式等等。
依我之見,並沒有嚴格的規則來界定何時使用Canvas優於SVG。即時模式與保留模式的區別指出,在建立如圖形密集型遊戲等項目時,HTML5 Canvas是無可爭議的贏家;而對於平面圖像、圖標和UI元素等,SVG則更為適合。然而,在兩者之間,HTML5 Canvas仍有擴展其應用範疇的空間,尤其是考慮到各種強大的Canvas函式庫所能帶來的便利。這些函式庫不僅使得在同一圖形作品中同時運用這兩種技術變得更加容易,而且還讓一些在原生Canvas專案中難以實現的功能——如互動控制和事件、響應性、可訪問性特性等——現在對大多數開發者來說觸手可及,這為HTML5 Canvas帶來了更多有趣的應用可能性。
關於Canvas與SVG的常見問題(FAQs)
Canvas和SVG之間的主要區別是什麼?
Canvas 與 SVG 均為用於創建圖形的網頁技術,但它們存在一些關鍵差異。Canvas 採用基於位圖的方法,即與像素打交道。它非常適合製作複雜、互動式的圖形,如遊戲或其他需要動態視覺效果的應用。然而,一旦繪製了形狀,除了重新繪製外,無法更改。相對地,SVG 是一種基於向量的方法。它處理形狀和路徑,且每個對象在繪製後仍可操作。這使得 SVG 非常適合創建靜態圖形、標誌和需要無損縮放的圖標。
何時應選擇 Canvas 而非 SVG?
當你需要創建複雜、互動式且高性能的圖形時,Canvas 是最佳選擇。這是因為 Canvas 操作像素,允許直接操控個別像素,非常適合實時視頻處理或渲染大數據集。但值得注意的是,Canvas 不支持事件處理器,因此若需要互動性,你必須自行實現。
何時 SVG 比 Canvas 更為合適?
當你需要創建無損縮放的圖形,如標誌或圖標時,SVG 是更好的選擇。SVG 也支持事件處理器,使得創建互動式圖形更為簡單。此外,SVG 元素是 DOM 的一部分,意味著它們可以像任何其他 HTML 元素一樣,用 CSS 進行樣式設計,並用 JavaScript 進行操作。
我可以在同一個項目中同時使用 Canvas 和 SVG 嗎?
是的,您可以在同一项目中同时使用 Canvas 和 SVG。事实上,结合使用两者有时会带来好处,因为它们各自有其优势和局限。例如,您可能会在项目中需要复杂、交互式图形的部分使用 Canvas,而在需要可缩放、静态图形的部分使用 SVG。
Canvas 和 SVG 的浏览器支持情况如何比较?
Canvas 和 SVG 都拥有出色的浏览器支持。它们被所有现代浏览器所支持,包括 Chrome、Firefox、Safari 和 Edge。然而,如果您需要支持旧版浏览器,值得注意的是 SVG 存在时间更长,因此对于旧版浏览器的支持稍好一些。
Canvas 和 SVG 如何处理动画?
Canvas 和 SVG 都可以用来创建动画,但它们处理动画的方式不同。使用 Canvas 时,您需要手动清除并重绘每一帧的画布。而使用 SVG 时,您可以通过 CSS 或 JavaScript 来动画 SVG 元素,这通常更简单且更高效。
Canvas 和 SVG 对页面加载时间有何影响?
页面加载时间的影响取决于您创建的图形的复杂度和大小。Canvas 对于复杂的交互式图形可能更快,因为它不需要为每个对象维护 DOM。然而,SVG 对于简单的静态图形可能更快,因为它不需要每次更改时都重绘整个图形。
我可以在 Canvas 和 SVG 中使用 CSS 吗?
SVG元素屬於DOM的一部分,因此您可以像對待任何其他HTML元素一樣,使用CSS對其進行樣式設計。相對地,Canvas是一種位圖,不支持CSS樣式。不過,您可以使用CSS來樣式化canvas元素本身,例如設置其背景色或邊框。
Canvas和SVG如何處理響應性?
SVG本質上是響應式的,因為它是一種基於向量的格式,因此可以無損地良好縮放。相反,Canvas不是本質上響應式的,因為它是一種基於位圖的格式。然而,您可以使用JavaScript根據視口大小調整其大小,從而使Canvas具有響應性。
我應該如何在我的項目中選擇Canvas或SVG?
Canvas與SVG之間的選擇取決於您項目的具體需求。考慮因素包括您需要創建的圖形的複雜性和互動性、對可擴展性和響應性的需求、瀏覽器支持以及您對這些技術的熟悉程度。在某些情況下,在同一項目中同時使用Canvas和SVG可能會更有益。