SVG初體驗

引言

借鑑出處

此基礎教程主要來源於w3c school svg,慢慢地發現mdn svg是更好的進階資料,之後的主要研究圍繞它展開.由於忙於工做上的事情, 因此這篇文章前先後後花了很長時間, 一把鼻涕一把淚, 雖說不是很難.css

正文

SVG簡介

以前一直久聞SVG大名,但一直沒機會,這幾天趁有空的時候初體驗了幾把,嚐嚐鮮.Scalable Vector Graphics是一門基於XML用來描述二維矢量圖形的標記語言,感受SVG在國外用得較多,國內相對不受歡迎,我在公司用得較少,不過咱們老大爲了解決一個金字塔設計問題派上了用場,哦對了想起了還有一些以前用上的SVG icons---IcoMoon因此有點癢也想搞搞.
SVG對於Web圖像的重要性至關於HTML對於Web文本的重要性.它的主要競爭者是Adobe未開源的Flash技術,和Flash相比SVG採用XML文本格式來定義圖像,和CSS,DOM,XSL,SMIL同樣都是Web標準,共同協做.html

SVG圖像優點

  • 在放大或者改變尺寸的狀況下圖形質量不會損失.html5

  • 與JPEG,GIF圖像比起來,尺寸更小,可壓縮性更強.css3

  • 可伸縮canvas

  • 圖像中的文本可選瀏覽器

  • 全部瀏覽器均支持SVG文件框架

SVG使用

下面是SVG簡單示例:svg

<?xml version="1.0" standalone="no"?>

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1/EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>
</svg>

第一行是xml聲明,standalone屬性代表是否有對外部文件的引用,此svg文件是否"獨立".standalone="no"是說會引用一個dtd文件.
第二行和第三行引用了這個外部SVG DTD:"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd,該dtd位於w3c,含有全部容許的svg元素.
svg代碼從<svg>根元素開始,<circle>用來建立一個圓,cx,cy是圓心座標(默認(0,0)),r是半徑.stroke和sroke-width用來設置形狀輪廓,fill用來設置形狀內顏色.全部元素都有關閉標籤,包括</svg>,/>等等,用來關閉svg元素和文檔自己.
svg文件能夠經過如下三種不一樣方法嵌入到html文檔:<embed>, <object>, <iframe>標籤.函數

  • 全部主流瀏覽器都支持<embed>標籤,並容許使用腳本.當在html頁面中嵌入svg時使用<embed>標籤是adobe svg viewer推薦的方法,若是須要建立合法的xhtml,就不能使用<embed>.性能

<embed src="rect.svg" width="300" height="100" type="image/svg+xml" pluginspage="http://www.adobe.com/svg/viewer/install" />
//pluginspage指向下載插件的url.
  • <object>是html4中的標準標籤,較新瀏覽器支持地較好可是不容許使用腳本.最新adobe svg viewer安裝了的話<object>會失效.

<object data="rect.svg" width="300" height="100" type="image/svg+xml" codebase="http://www.adobe.com/svg/viewer/install" />
//codebase指向下載插件的url
  • <iframe>支持地很好

<iframe srv="rect.svg" width="300" heght="100"></iframe>

SVG組成

這裏是我寫的一個有較多類svg元素的demo,Command+S保存快捷鍵還有第一次保存以後每隔一分鐘自動保存仍是很方便的.提示一點,Condepen上面不須要聲明DOCTYPE,只須要往html代碼塊裏面寫上<body>裏的代碼,因此

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3c.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<?xml version="1.0" standalone="no"?>

這一部分能夠省去.

SVG形狀

svg有一些預約義的形狀提供使用:矩形<rect>,圓形<circle>,橢圓<ellipse>,線<line>,折線<polyline>,多邊形<polygon>,路徑<path>.下面逐個介紹:

  • <rect>用來建立矩形及其變形.rect.svg內容以下:

<?xml version"1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"
<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3c.org/2000/svg">
    <rect x="20" y="20" width="300" height="100" style="fill:pink;stroke-width:1;stroke:rgb(0, 0, 0);fill-opacity=0.9;stroke-opacity=0.1" />
</svg>
//stroke指矩形邊框顏色,fill指矩形中間填充顏色

style裏面還可使用opacity表示所屬svg元素的透明度,rx,ry表明橢圓角的a,b取值.

  • <circle>

<circle cx="200" cy="100" r="50" stroke="#123456" stroke-width="2" fill="#654321" opacity=".4" />

demo裏面<circle>元素和<rect>元素處於同一個<svg>根元素之下,注意兩個元素不要重疊,若是存在重疊將按照元素出現次序進行前後覆蓋(固然若是相鄰的兩個元素均設置了透明度則覆蓋仍是被覆蓋沒有意義,若是隻有一方設置了透明度那麼仍是存在覆蓋與被覆蓋的狀況).

  • <ellipse>

<ellipse cx="240" cy="100" rx="220" ry="30" style="fill:yellow"/>

<ellipse cx="220" cy="100" rx="190" ry="20" style="fill:white"/>
  • <line>

<line x1="50" y1="100" x2="750" y2="100" stroke-width="5"  stroke="#987654" />

注意線條<line>元素沒有fill屬性,設置了定值也毫無心義.

  • <polygon>用於建立很多於三條邊的元素--多邊形

<polygon points="800,20 890,20 935,100 890,180 800,180 755,100"  style="stroke:#123987;stroke-width:4;fill:#aef492"/>
  • <polyline>

<polyline points="50,300 50,325 75,325 75,400 150,400" style="fill:#afc196;stroke:red;stroke-width:8"/>

注意polyline元素能夠給fill屬性賦值,針對的是相鄰的點,邊之間圍成的區域.

  • <path>
    因爲該元素涉及較多的命令,要想熟練運用好這些命令並不容易,因此<path>是svg裏面最複雜的元素,可是複雜的東西每每能夠實現很棒的功能,<path>能夠繪製出帶有複雜路徑的圖形.

用於路徑的經常使用命令:`M=moveto, L=lineto,
H=horizontal lineto, V=vertical lineto, C=curveto, S=smooth curveto, Q=quadratic bezier curve, T=smooth quadratic bezier curve, A=elliptical Arc, Z=closepath實際上這些命令簡寫字母能夠大寫能夠小寫,大寫表示絕對定位,小寫表示相對定位.

SVG濾鏡

它用來向形狀和文字添加特殊的效果.濾鏡有:feBlend, feColorMatrix, feComponentTransfer, feComposite, feConvolveMatrix, feDiffuselighting, feDisplacementMap, feFlood, feGaussianBlur, feImage, feMerge, feMorphology, feOffset, feSpecularLighting, feTile, feTurbulence, feDistantLight, fePointLight, feSpotlight.能夠在svg元素上使用多個濾鏡.

高斯模糊

<defs>
  <filter id="Gaussian_Blur_1">
    <feGaussianBlur in="SourceGraphic" stdDeviation="2">
  </filter>
  <filter id="Gaussian_Blur_2">
    <feGaussianBlur in="SourceGraphic" stdDeviation="20">
  </filter> 
</defs>
<ellipse cx="300" cy="100" rx="100" ry="50" filter="url(#Gaussian_Blur_1)" />
<polygon points="800,20 890,20 935,100 890,180 800,180 755,100"  style="stroke:#123987;stroke-width:4;fill:#aef492; filter:url(#Gaussian_Blur_2)"/>

在<defs>標籤內部嵌套<filter>標籤,而後在<filter>當中定義濾鏡,<filter>的id屬性值惟一,和須要採用過濾效果的svg元素的filter屬性值相呼應.濾鏡效果由<feGaussianBlur>定義,stdDeviation是模糊程度,in="SourceGraphic"代表在整個圖像上面建立效果.

SVG漸變

能夠在一個元素上面應用多個顏色的過渡,相似於css3,svg漸變有線性漸變<linearGradient>和徑向漸變<radialGradient>.

<linearGradient>

和<filter>同樣,<linearGradient>嵌套在<defs>內部,definitions縮寫成defs,能夠嵌套<filter>, <linearGrandient>, <radialGradient>等特殊元素,進行定義.

<defs>
  <filter id="Gaussian_Blur_1">
    <feGaussianBlur in="SourceGraphic" stdDeviation="2">
  </filter>
  <filter id="Gaussian_Blur_2">
    <feGaussianBlur in="SourceGraphic" stdDeviation="20">
  </filter> 
</defs>
<ellipse cx="300" cy="100" rx="100" ry="50" filter="url(#Gaussian_Blur_1)" />
<polygon points="800,20 890,20 935,100 890,180 800,180 755,100"  style="stroke:#123987;stroke-width:4;fill:#aef492; filter:url(#Gaussian_Blur_2)" />

y1 = y2, x1 != x2, 那麼是水平漸變;
x1 = x2, y1 != y2, 那麼是垂直漸變;
x1 != x2, y1 != y2,那麼是角形漸變.

<radialGradient>

與<linearGradient>相似,不過<radialGradient>在參數上的區別是cx, cy, r定義外圈;fx, fy定義內圈.

SVG元素列表

<a>:超連接;<altGlyph>:容許對象性文字進行控制,來呈現特殊的字符數據,<altGlyphDef>定義一系列象性符號的替換,<altGlyphItem>定義一系列候選象形符號的替換;<animate>隨時間動態改變屬性,<animateColor>規定隨時間進行的顏色轉換,<animateMotion>使元素沿着動做路徑移動,<animateTransform>對元素進行動態地屬性轉換;<circle>定義圓;<color-profile>顏色配置描述, <cursor>定義獨立於平臺的光標, <definition-src>定義單獨的字體定義源, <defs>被引用元素的容器, <desc>對SVG元素的純文本描述-並不做爲圖形的一部分來顯示,做用相似於html中的title屬性, <ellipse>定義橢圓, <feBlend>, <feColorMatrix>等等...
以上是w3 school的svg elements列表,下面是mdn對svg元素進行的科學分類:

動畫類

<animate>, <animateColor>, <animateMotion>, <animateTransform>, <mpath>, <set>

基本形狀類

<circle>, <ellipse>, <line>, <polygon>, <polyline>, <rect>

容器類

<a>, <defs>, <glyph>, <g>, <marker>, <mask>, <missing-glyph>, <pattern>, <svg>, <swtich>, <symbol>

描述類

<desc>, <metadata>, <title>

過濾器相關類

<feBlend>, <feColorMatrix>, <feComponentTransfer>, <feComposite>, <feConvolveMatrix>, <feDiffuseLighting>, <feDisplacementMap>, <feFlood>, <feFuncA>, <feFuncB>, <feFuncG>, <feFuncR>, <feGussianBlur>, <feImage>, <feMerge>, <feMergeNode>, <feMorpholopy>, <feOffset>, <feSpecularLighting>, <feTile>, <feTurbulence>

字體類

<font>, <font-face>, <font-face-format>, <font-face-name>, <font-face-src>, <font-face-uri>, <hkern>, <vkern>

漸近類

<linearGradient>, <radialGradient>, <stop>

圖形類

它和基本形狀類有差異,字面含義上能夠看出.包含<circle>, <ellipse>, <image>, <line>, <path>, <polygon>, <polyline>, <rect>, <text>, <use>

光源類

<feDistanLight>, <fePointLight>, <feSpotLight>

形狀類

相比於基本形狀類,只多出了<path>元素

結構類

<defs>, <g>, <svg>, <symbol>, <use>

文本內容類

<altGlyph>, <altGlyphDef>, <altGlyphItem>, <glyph>, <glyphRef>, <textPath>, <text>, <tref>, <tspan>

文本內容後代類

<altGlyph>, <textPath>, <tref>, <tspan>

其餘未分類

<clip-path>, <color-profile>, <cursor>, <filter>, <foreignObject>, <script>, <style>, <view>
以<aniamteMotion>爲例,
這是mdn svg elements上面的一個例子:

<?xml version="1.0"?>
<svg width="120" height="120"  viewBox="0 0 120 120"
     xmlns="http://www.w3.org/2000/svg" version="1.1"
     xmlns:xlink="http://www.w3.org/1999/xlink" >
     
    <!-- Draw the outline of the motion path in grey, along
         with 2 small circles at key points -->
    <path d="M10,110 A120,120 -45 0,1 110 10 A120,120 -45 0,1 10,110"
          stroke="lightgrey" stroke-width="2" 
          fill="none" id="theMotionPath"/>
    <circle cx="10" cy="110" r="3" fill="lightgrey"  />
    <circle cx="110" cy="10" r="3" fill="lightgrey"  />

    <!-- Here is a red circle which will be moved along the motion path. -->
    <circle cx="" cy="" r="5" fill="red">

        <!-- Define the motion path animation -->
        <animateMotion dur="6s" repeatCount="indefinite">
           <mpath xlink:href="#theMotionPath"/>
        </animateMotion>
    </circle>
</svg>

最後,給你們推薦一個東西:IcoMoon,svg用於字體圖標,大小可伸縮,清晰度高.

Canvas簡介

canvas是html5中的一項新技術,它使用js在網頁中繪製圖像,畫布是一個矩形區域,經過canvas技術能夠控制其中的每個像素,有許多方法用來繪製路徑,矩形,圓形,字符還能夠添加圖像.使用步驟以下:

  • 向頁面中添加canvas元素,規定元素的id,寬度,高度:

<canvas id="my-canvas" width="200" height="100"></canvas>
  • 經過js來控制繪製流程,由於canvas元素自己沒有繪製能力.

<script>
    var c = document.getElementById("my-canvas");
    //js經過id來查找canvas元素
    var cxt = c.getContext("2d");
    //而後建立context對象,getContext("2d")對象是內建的html5對象,擁有多種繪製路徑,矩形,圓形,字符以及添加圖像的方法.
    cxt.fillStyle="#ff0000";
    cxt.fiiRect(0, 0, 150, 75);
    //fillStyle方法規定填充顏色,fillRect方法規定了形狀,位置,尺寸.
</script>

事實上,w3 school代表canvas還有許許多多方法,涉及顏色,演示,陰影;線條樣式;矩形,路徑,轉換,文本,圖像繪製,像素操做,合成,其餘等等.

SVG, Canvas之間的比較

原本還想和WebGL之間作比較,如今想一想WebGL和後二者徹底不同,這是wiki上面的WebGL,訪問不了的話可使用虫部落,SVG和Canvas主要是作2D圖形,而WebGL是用js來作3D應用,e.g.遊戲等等(threejs),徹底不同,因此做比較沒多大意義.

這裏我比較二者主要參考的資料來源於:msdn上面.aspx),w3 school html5 canvas vs svg,做出一些概括:
canvas和svg都是在瀏覽器當中建立圖形,可是本質上徹底不同.

SVG

  • 一種用XML描述2D圖形的語言

  • SVG基於XML,意味着SVG DOM中的每一個元素都是可用的,能夠爲每一個元素添加js事件處理器

  • 每一個被繪製的圖形都是對象,若是對象的屬性發生變化,那麼瀏覽器可以自動重現圖形.

  1. 不依賴分辨率

  2. 支持事件處理器

  3. 最適合帶有大型渲染區域的應用程序

  4. 複雜度高減慢渲染速度(過分使用DOM)

  5. 不適合遊戲應用

Canvas

  1. 依賴分辨率

  2. 不支持事件處理器

  3. 文本渲染差

  4. 可以右鍵以.jpg, .png保存結果圖像(SVG圖形右鍵保存是svg格式,強制另換格式保存改變不了圖形縮放性)

  5. 最適合圖像密集型的遊戲,其中許多對象會被重繪.

  6. 經過js來繪製2D圖形

  7. 逐個逐個像素進行渲染

SVG是保留模式,Canvas是即時模式.矢量圖形概念早已出現,複雜性範圍從一個文檔或插圖中的標註,到圖表,關係圖,地圖等插圖,再到工程文檔.這些場景都是靜態的可是矢量圖形也支持交互性,
SVG爲Web,桌面和設備上的應用程序提供交互和靜態格式.這裏的探究以Web爲主,e.g.在網頁中使用矢量圖形爲背景圖像以支持高DPI和縮放功能;做爲地圖屬性用來執行查找線路操做;顯示實時圖表圖形的交互式股票網站;航班,音樂廳,電影院座位圖;遊戲等等.
SVG是一個保留在內存模型中的保留模式圖形模型,而內存中模型可經過從新呈現的代碼結果進行操做.SVG能夠做爲獨立文件提供,也能夠與HTML集成.相似於HTML,SVG也使用元素,屬性,樣式來構建文檔,相似於<div>,SVG是HTMLDocument的一部分,同時SVGDocument爲<svg>元素提供與矢量圖形的深刻豐富交互的附加接口.<svg>元素適合於html框模型,可是由於豐富的矢量圖形不侷限於簡單的框,因此內部模型從框中分離出來的話要求屬性獲得擴展.以<rect>元素爲例,它保留在HTML文檔對象模型DOM當中,相似普通的HTML元素,能夠經過不一樣的方式設置樣式:

<!-- No fill(default color is #000) -->
<rect id="myRect0" width="100%" height="100%" />

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

<!-- using the style="fill:pink" 內聯樣式-->
<rect id="myRect0" width="100%" height="100%" style="fill:pink" />

<!-- using the attribute fill="red" 使用fill, fill-opacity等內置的有關svg的css屬性-->
<rect id="myRect0" width="100%" height="100%" fill="red" />

也能夠經過SVG DOM方法設置樣式:

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

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

Canvas是"觸發即忘"模型,將圖形直接呈如今屏幕上可是隨後對所完成的操做不保留任何上下文,與保留模式相反,不保存呈現的圖形;每次須要新框架時須要描述整個場景,開發人員須要從新調用全部的必須的繪圖命令,而不考慮實際更改(SVG擁有場景圖).這個新框架很差理解的話能夠藉助於SVG <path>元素d命令的"簡潔性"與Canvas ctx對象的beginPath(),lineTo(x1, y1) moveTo(x2, y2)...closePath()等命令"零碎性"之間的區別.和SVG同樣,Canvas也有很複雜的幾何基元,區別在於這些基元採用函數形式.Canvas的路徑API並不侷限於moveTo和arc,和SVG同樣都包含貝賽爾曲線.Canvas能夠捕獲鼠標在圖像上的位置,因爲是"即時模式",因此必須經過單個元素的mouseX,mouseY<canvas>座標來捕獲.Canvas沒有任何樣式,縮放的話也會致使失真.
下面總結一下,做出一些關鍵方面的比較

  • Canvas SVG

  • 基於像素,動態,.png 基於形狀

  • 單個HTML元素 多個圖形元素,這些元素成爲DOM的一部分

  • 經過js操做圖形 經過css,js

  • 事件模型/用戶交互顆粒化(x, y) 事件模型/用戶交互抽象化(rect, path)

  • 圖面較小,對象數量較多(>10k)性能更好 與前者相反

使用場景的比較

屏幕較大的話,Canvas性能欠佳,由於須要繪製更多的像素;對象數量較多的話,SVG性能欠佳,由於DOM加載較慢.另外還有js引擎速度,瀏覽器或者其餘環境是否徹底使用硬件加速等等也會左右着二者的選擇.在瀏覽器,能夠說Canvas這項H5新技術更容易爲廣大的Web開發人員所接受,很重要的一方面是由於它簡單且高效.可是除去瀏覽器,SVG等等可用於CAD建築,工程等要求高保真度的複雜矢量文檔方面,它佔有很明顯的優點.

實時數據傳輸

實時兩個字已經道出Canvas的優點意味.用戶交互是Canvas的短板,非交互的實時數據可視化倒是它的強項,由於屏幕上的對象數量至關高.
Canvas vs SVG0.png

劇終

相關文章
相關標籤/搜索