****
**教程細節**
·??????**語言**: JavaScript,HTML, SVG
·??????**難度:**?中等
·??????**預計閱讀時間:**?30 分鐘
? ? ? SVG-*可縮放矢量圖形*?,是一個XML風格標記驅動的矢量圖形的瀏覽器渲染引擎。除了IE 9.0和Android V3之前版本外的所有瀏覽器都支持SVG。Canvas也有同樣的支持情況,所以問題往往表現為:我們應該使用哪種方案?
? ? ??今天,我們將全面介紹SVG,并且解釋為什么“我應該使用哪一個”這個問題通常的答案是 “我要用它們來做什么”。要得到SVG的完整信息,請查看[Mozilla關于此主題的文檔](https://developer.mozilla.org/en/SVG/Element)。你還可以看看[SVG DOM API](https://developer.mozilla.org/en/Gecko_DOM_Reference#SVG_interfaces)。
### 概述
? ? ??我們將首先概述SVG的一些獨特的優勢。?然后,用不著通讀SVG所有長達80頁的節點類型,我們將說明如何通過Illustrator快速的把SVG文檔加入到網頁中。我們還會講講D3.js,一個強大的、SVG控制的JavaScript庫。
*“SVG并不只用于像素處理。”*
### SVG的主要優點
? ? ??除了用于某些應用上跨圖像或者基于Canvas的渲染之外,SVG還有相當多的優點。?SVG并不只用于進行像素處理,但是它能夠很好地處理矢量圖形和可編程性的矢量。
### 分辨率無關
? ? ??你可能不知道,分辨率無關和瀏覽器不可知論是近來前端開發中熱議的話題(想想“響應式設計”)。大多數用來解決分辨率問題(例如視網膜屏幕上)的方案既導致了大量不必要的數據下載(高清圖像替換)又為一個或者其他瀏覽器進行了妥協。這使得無線網絡中更高分辨率圖像的傳輸往往受限于數據下載速度的瓶頸。這并不理想。
? ? ??SVG提供了一種方法來提供全分辨率的圖形元素:不管什么大小的屏幕,縮放比例或著分辨率。?直到SVG出現之前,我們只能通過CSS和文本渲染看到清晰的元素樣式。在SVG里不需要使用div和:after元素來創建簡單的形狀和其他效果。相反你可以創建各種矢量形狀。
*“SVG提供了一種方法來提供全分辨率的圖形元素:不管什么大小的屏幕,縮放比例或著分辨率”*
### 基于DOM節點的API
? ? ??你寫HTML嗎??JavaScript和CSS呢??是的。?現在你已經知道了很多關于編寫SVG的信息。?SVG實際上使用和XML兼容的格式來定義其呈現的形狀。除此之外,你可以用CSS為形狀添加樣式,使它們與JavaScript進行交互。有多個像D3.js和Raphael的JS庫可以協助你。下面是一組SVG元素的例子(Envato葉子)。你也可以在JSFiddle上看到[這個示例](http://jsfiddle.net/jcutrell/eg6MZ/)?。
~~~
<svg>
<g>
<g>
<path fill="#8BAC54" d="M28.028,104.509c-35.271,44.527-36.619,105.084-7.616,150.407
c26.073-66.957,58.919-142.287,99.378-209.543C81.802,61.428,46.351,81.377,28.028,104.509z M278.797,11.28
c-0.408-3.492-2.227-6.447-4.845-8.41c-2.5-2.097-5.802-3.197-9.304-2.784c0,0-10.403,2.227-26.959,6.483
C158.62,82.498,93.735,184.229,43.453,281.932c1.875,1.628,3.778,3.255,5.749,4.794c56.202,44.471,137.782,34.972,182.238-21.163
C282.657,200.806,278.797,11.28,278.797,11.28z"/>
</g>
<g>
<path fill="#B1C982" d="M58.392,293.368c59.428-95.491,133.438-188.549,220.117-247.851c0.558-20.869,0.289-34.238,0.289-34.238
c-0.408-3.492-2.227-6.447-4.845-8.41c-2.5-2.097-5.802-3.197-9.304-2.784c0,0-10.403,2.227-26.959,6.483
C158.62,82.498,93.735,184.229,43.453,281.932c1.875,1.628,3.778,3.255,5.749,4.794C52.185,289.102,55.271,291.308,58.392,293.368
z"/>
</g>
</g>
</svg>
~~~
? ? ??SVG基于DOM節點的API比起客戶端側的CanvasAPI來說,無疑具有更高的可訪問性。你可以由此做到:
- 在服務器端創建基于SVG文檔的圖像
- 像其他HTML元素一樣檢查SVG元素
- 通過你熟悉的技術(JS和CSS)編程來處理形狀、樣式和位置
- 為SVG節點綁定事件函數
? ? ??DOM API為使用SVG提供了更多一系列明顯的優勢。
#### 無須不必要的HTTP請求
? ? ??當你在HTML中使用<img>標簽來引入圖像時,就是定義了一個用戶瀏覽器需要請求的文件。這個請求會占用帶寬,需要更多寶貴的時間來下載。如果你的圖像用一組DOM節點來代替,可以減少額外的HTTP請求,使你的網站速度更快,對用戶更加友好。
#### 簡單交互腳本
? ? ??盡管現在瀏覽器大戰,跨瀏覽器的DOMAPI在腳本的交互性方面提供了廣泛的靈活性,可以延伸到SVG元素上。可以通過CSS為SVG添加樣式;SVG元素支持瀏覽器事件API使得的通過腳本進行交互不在話下;還可以輕松的將一個事件函數綁定到SVG元素的節點上。
? ? ??這不是真正在畫布上繪制的元素。由于畫布是一個簡單的像素渲染引擎,繪制的元素不能在內存中保存為對象。腳本將保持這些元素的收集工作,并監管所有相關的位置和大小信息來在事件循環中尋找和觸發事件。除此之外,Z-index也由腳本處理。
? ? ??讓我們來看看一個例子。請注意:為了保持簡潔,我們將使用jQuery。
~~~
var circleCenter = [200, 300], radius = 50;
$(window).on("mousemove", function(e){
var mx = e.pageX, my = e.pageY;
if (mx > circleCenter[0] - radius && mx < circleCenter[0] + radius && my > circleCenter[1] - radius && my < circleCenter[1] + radius){
// now we are hovering
}
});
~~~
? ? ??相比之下,我們可以看到使用SVG可以更簡單的完成相同任務。
~~~
$("svg path#circle").on("hover", function(event){
// That's all.
});
~~~
? ? ??顯然開發者編寫簡單交互的腳本來說效率更高。
### 實際應用
? ? ??有大量的Canvas相關的JS庫(例如[KineticJS](http://www.kineticjs.com/),可以讓你實現一些酷炫的功能)。但如果你像我一樣,就不會在你的Web應用里使用完全的物理引擎。作為替代,我最經常需要可擴展的圖標、交互圖以及詳細的、美觀的方式來把信息呈現給用戶。大多數我需要的圖形就是簡單易用的公式。這些圖形元素很容易的使用SVG來創建,許多簡單的物理方程可以處理你的這些需求。所以讓我們來看看SVG的一些實際應用。
**圖形**
? ? ??因為SVG最大的優勢是基本的矢量形狀,自然非常適用于圖形和信息圖表。它不僅非常適合用來從給定的數值創建靜態的圖表,還適用于“實時的”圖形:通過AJAX請求、用戶輸入或者隨機生成的數據生成。
**路線圖**
? ? ??路線圖由堅硬的線條和精確的形狀組成。這些形狀可以用向量圖形很好的展示。
**復雜的UI元素**
? ? ??例如現在你需要一個UI元素,看上去像圓圈金字塔。你如何用HTML和CSS來實現?好吧,你要先為每一個洞創建一堆的div,為它們每個賦予確定的圓角邊框和邊框樣式。然后你要使用一個div容器來定位它們。現在你如果想要一個整體的漸變該如何實現?你可能必須要使用Mask,或者一些其他技術。我們寧可不使用圖像,因為它們不可擴展,而且不能用可編程的方式來重新渲染或者改變。相反,為什么不在Illustrator中繪制元素,并且將它保存為一個SVG文件?這將會讓你有一個單獨的、可擴展的元素,并且不用擔心多個div的管理。
**Logos**
? ? ??多數標志都是基于矢量的。你可以為你的Logo定義一個SVG文檔,并且把它放到任何地方,隨時縮放為任何尺寸,而完全不需要犧牲質量或者占用過多的帶寬。
**簡單游戲**
? ? ??Canvas適合游戲渲染,這并不是秘密。另外的原因是游戲往往不依賴于矢量圖形,相反它們使用基于像素的藝術字和動畫。然而,SVG對于需要更少字符動畫和更多信息展示的游戲來說是一個很棒的選擇(例如數獨游戲)。
### 為什么你可能不使用SVG
? ? ??現在我們已經看過了許多SVG的優點,讓我們來看看許多開發者為什么仍然選擇不使用SVG。最主要有兩個原因:
? ? ??1、他們從來沒有聽說過SVG或者從沒想過需要它,所以都忽略了(這不再是借口!)
? ? ? 2、?SVG XML文檔看起來相對古老和復雜,好像使用圖像更加簡單。
? ? ??當然沒有任何人想手動編輯SVG XML里的一個個點。幸運的是,沒有人需要這么做。這是人們常常沒有意識到的部分,這里有許多工具來編輯SVG,所以你永遠不需要手動來做這件事。
### SVG工具
### Illustrator,Inkscape
? ? ??這個矢量編輯器最有可能把你的文件保存為SVG。立即來試試吧!打開Illustrator,畫一兩個圓,并且把文件保存為SVG。然后在Sublime或者其他文本編輯器中打開,你能夠立即看到,除了一些額外的元數據,SVGXML可以馬上應用到HTML中。你最有可能看到<g>標簽(group),<path>標簽(path)以及<svg>元素。
### D3.js
? ? ??雖然你完全可以把SVG XML直接拖放到一個HTML文件中,但是當你想要動態創建SVG時怎么辦?D3.js是一個基于數據操作文檔的JS庫。換句話說,它的偉大之處在于可以基于一系列的數據生成例如條形圖和線狀圖的SVG元素。我們選擇展示D3是因為它符合瀏覽器里SVG實際實現的詞匯,請注意另外還有一些很棒的非標準SVG庫(值得注意的是Raphael.js)。
? ? ??D3.js除SVG處理外還提供其他更多功能。(請確保你查看了[D3.js官網上的示例](http://d3js.org/)和這個[討論](http://bost.ocks.org/mike/d3/workshop/))
#### 示例一:脈沖圈
? ? ??在第一個例子里,我們使用Math.sin和setInterval構造的迭代器簡單的創建一個脈沖圈。
[脈沖圈](http://jsfiddle.net/jcutrell/unFyq/1/)
#### 示例二:更新線狀圖
? ? ??在這個例子里,我們將用一些隨機值更新繪制的線狀圖。
[線狀圖](http://jsfiddle.net/jcutrell/3C9JW/5/)
**什么時候不用SVG?**
? ? ??SVG可以處理很多瀏覽器里的圖像渲染需求。雖然我們有很多使用SVG的理由,但是就像任何偉大的事物一樣,也有一些地方它表現不是很好。
- 如果你需要渲染上千個節點,更高性能的辦法是在Canvas上進行。
- 如果你的應用需要IE8的支持,記得你需要提供另外一個備用的向量(例如更復雜的?[VML](http://www.w3.org/TR/NOTE-VML)),或者依靠響應式的圖像來完全替代向量。
### 有用鏈接
? ? ??這里有一些有用的連接,可以幫助你更好的了解SVG。
- [Raphael.js](http://raphaeljs.com/)
- [Processing.js](http://processingjs.org/), 基于強大的Processing –一個Java圖像工具
- [jQuerySVG](http://keith-wood.name/svgRef.html)
- [Sitepoint article: 如何選擇Canvas和SVG](http://www.sitepoint.com/how-to-choose-between-canvas-and-svg/)
- [Canvasand SVG的性能](http://smus.com/canvas-vs-svg-performance/)
- [Nettuts+ article about Raphael](http://net.tutsplus.com/tutorials/javascript-ajax/an-introduction-to-the-raphael-js-library/)
? ? ??你還發現了SVG的其他用途嗎?請在評論中告訴我們,還要感謝你的閱讀。
? ? ? 譯自:[http://net.tutsplus.com/tutorials/why-arent-you-using-svg/](http://net.tutsplus.com/tutorials/why-arent-you-using-svg/)
? ? ? 轉載請注明:來自[蔣宇捷的博客](http://blog.csdn.net/hfahe)
- 前言
- AutoPager的簡單實現
- 利用CSS3特性巧妙實現漂亮的DIV箭頭
- IE9在Win7下任務欄新特性簡介
- 瀏覽器九宮格的簡單實現
- Raphael js庫簡介
- 使用CSS3構建Ajax加載動畫
- 用CSS3創建動畫價格表
- 用CSS3實現瀏覽器的縮放功能
- 用純CSS3實現QQ LOGO
- 用CSS3創建旋轉載入器
- 使用Javascript開發移動應用程序
- 用HTML5創建超酷圖像灰度漸變效果
- 使用CSS3創建文字顏色漸變(CSS3 Text Gradient)
- 僅用CSS創建立體旋轉幻燈片
- 如何創建跨瀏覽器的HTML5表單
- 用CSS3實現動畫進度條
- HTML5 Guitar Tab Player
- 奇妙的HTML5 Canvas動畫實例
- 談HTML5和CSS3的國際化支持
- 實現跨瀏覽器的HTML5占位符
- 前端開發必備工具:WhatFont Bookmarklet-方便的查詢網頁上的字體
- 使用HTML5和CSS3來創建幻燈片
- HTML5之美
- 如何使用HTML5創建在線精美簡歷
- 以小見大、由淺入深-談如何面試Javascript工程師
- 快速入門:HTML5強大的Details元素
- 用CSS3實現圖像風格
- HTML5視頻字幕與WebVTT
- 用純CSS3實現Path華麗動畫
- 用3個步驟實現響應式網頁設計
- 遇見CSS3濾鏡
- 關于CSS3濾鏡的碎念
- 用純CSS3繪制萌系漫畫人物動態頭像
- CSS3新的鼠標樣式介紹
- 用HTML5獻上愛的3D玫瑰
- 對HTML5 Device API相關規范的解惑
- 如何使用HTML5實現拍照上傳應用
- 2012第一季度國外HTML5移動開發趨勢
- HTML5新特性:范圍樣式
- 百度開發者大會-《用HTML5新特性開發移動App》PPT分享
- Chrome 19對于HTML5最新支持的動態:電池狀態API,全屏API,震動API,語音API
- 遇見Javascript類型數組(Typed Array)
- 用HTML5 Audio API開發游戲音樂
- 用HTML5實現人臉識別
- 用Javascript實現人臉美容
- Chrome 20對于HTML5最新支持的動態:顏色輸入,網絡信息API,CSS著色器
- 用HTML5實現手機搖一搖的功能
- 用HTML5實現iPad應用無限平滑滾動
- 用非響應式設計構建跨端Web App
- 了解SVG
- HTML5圖像適配介紹
- HTML5安全:內容安全策略(CSP)簡介
- HTML5安全:CORS(跨域資源共享)簡介
- 用CSS3 Region和3D變換實現書籍翻頁效果
- 談談移動App的思維誤區
- Chrome新特性:文件夾拖拽支持
- 《關注HTML5安全》
- HTML5安全風險詳析之一:CORS攻擊
- HTML5安全風險詳析之二:Web Storage攻擊
- HTML5圖像適配最新進展:響應式圖片規范草案
- HTML5移動Web App相關標準狀態及路線圖
- HTML5安全風險詳析之三:WebSQL攻擊
- Chrome引入WebRTC支持視頻聊天App
- HTML5安全風險詳析之四:Web Worker攻擊
- HTML5安全風險詳析之五:劫持攻擊
- HTML5安全風險詳析之六:API攻擊
- HTML5安全攻防詳析之七:新標簽攻擊
- 在iOS Safari中播放離線音頻
- 使用WebRTC實現遠程屏幕共享
- Firefox、Android、iOS遇見WebRTC
- HTML5光線傳感器簡介
- HTML5安全攻防詳析之八:Web Socket攻擊
- HTML5安全攻防詳析之完結篇:HTML5對安全的改進
- 激動人心!在網頁上通過語音輸入文字 - HTML5 Web Speech API介紹
- Web滾動性能優化實戰
- 用CSS3設計響應式導航菜單
- 用HTML5構建高性能視差網站
- 漫談@supports與CSS3條件規則
- HTML5下載屬性簡介
- 如何開發優秀的HTML5游戲?-迪斯尼《尋找奧茲之路》游戲技術詳解(一)
- 如何開發優秀的HTML5游戲?-迪斯尼《尋找奧茲之路》游戲技術詳解(二)
- 趨勢:Chrome為打包應用提供強大新特性
- 從HTML5移動應用現狀談發展趨勢
- 基于HTML5的Web跨設備超聲波通信方案