翻譯 | 編寫SVG的口袋指南(上)

作者:DDU(滬江前端開發工程師)

本文是原文翻譯,轉載請註明作者及出處。

簡介

Scalable Vector Graphics (SVG)是在XML中描述二維圖形的語言。這些圖形由路徑,圖片和(或)文本組成,並能夠在不失真的情況下任意變換尺寸。

本書主要介紹了內聯SVG,它是指在HTML中編寫的嵌入式代碼,以便在瀏覽器中生成這些圖形。

以這種方式使用SVG有許多優點,包括為了交互目的訪問所有圖形的各個部分,支持訪問 SVG 文檔構成的 DOM 節點樹,查詢、修改 DOM 節點的屬性,提升用戶可訪問性。

先介紹基本組織和簡單形狀,再繼續描述SVG坐標系或「Canvas」,然後用它繪製圖形的內部和/或邊框,變換,以及使用和操作圖形文本。通過漸變和模式等更高級的功能來總結。

這個指南快速且詳細的介紹內聯式SVG以及所有涵蓋的可使用的功能,有助於你學習SVG。 它面向設計師和開發人員,希望以最可行的方式將SVG添加到他們的工作流程中。

從小筆畫細節到開始使用手工製作的模式,本指南旨在成為一個圍繞「go-to」編寫SVG的參考。

前言

本「口袋指南」只針對已經有一些HTML和CSS基礎的人,在你喜愛的瀏覽器中繪製SVG之前最好知道一些額外的知識, 例如:在SVG中正確渲染的信息,如何讓你的圖形更容易訪問,以及何時何處使用矢量圖形軟體。

如何使用SVG

有許多方法可以把SVG插入到你的項目:內聯、img標籤、背景圖、<object>或者作為Data URI』s。我們主要介紹內聯SVG的使用方法,包括如何在結構清晰的HTML文檔中編寫SVG代碼。

儘管我們只是介紹了內聯SVG的使用方法,但在某些特定情況下,其他方法也許會更好。例如,如果你不需要圖形本身的編輯功能或訪問其各個部分,則用<img>標籤可能更適合。

矢量圖形軟體

當你想要創建幾乎不可能手寫的更複雜的圖形時,矢量圖形軟體更實用。你可以將Adobe Illustrator, Inkscape, Sketch, iDraw,和 WebCode這些工具放到你的SVG技能包中。

可以用這些工具直接導出SVG代碼並嵌入你的HTML。我們過一會再討論這個。

頁面上的SVG

為了簡潔起見,SVG DOCTYPE,版本號,xmlns和xml:space在這本書中不會被提到。

這些屬性專註於SVG的版本和文檔的命名空間。只要記住這一點,你不需要這些屬性就能成功地在瀏覽器中呈現圖形。 如下面這個例子,在Illustrator生成的SVG代碼時不要吃驚:

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">n<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"></svg>n

在大多數情況下,<svg>元素中的DOCTYPE和屬性不是必需的,可以刪除,以縮減你的代碼。

SVG用戶輔助功能

使用SVG輔助功能是一個好習慣,但是為了簡潔,描述和標題不會包含在整本書的代碼中。

一旦你更熟練的繪製SVG,這些元素將使你的圖形更能被用戶接受。例如,<desc>元素中的內容允許你向屏幕閱讀器的用戶提供圖形的詳細描述。

由於SVG文本可以被檢測和讀取,並且可以容易地調整大小以適應特定的閱讀偏好,提供了在可訪問性方面優於傳統的基於光柵的圖像的巨大優勢。

注意事項

使用之前一些更通用的注釋:整本書的演示字體都可通過Google Fonts獲得。雖然你可以通過font-family看到這些字體顯示出來,但你不會看到獲取谷歌字體時使用的相關link或@import。

示例始終使用像素和百分比作為單位標識符。 SVG支持的長度單位為:em,ex,px,pt,pc,cm,mm,in和百分比。

本書中的SVG代碼可以添加到任何文本編輯器,並且在任何支持內聯SVG的瀏覽器中查看。通常情況下瀏覽器支持對於SVG非常強大,但是有更多高級的特性(例如漸變)時這種支持會變得弱一些。Can I Use是一個檢查功能支持的實用網站,但實踐才是檢驗真理的唯一方法。

你也可以複製代碼,通過CodePen把它放在一個HTML部分,就能立即在屏幕上看到你的圖形。我說的可能不夠好,但它是我對SVG感興趣的第一因素。練習,修改甚至失敗是我最喜歡的學習方式。

最終,由於篇幅限制,一部分例子會有圖形代碼注釋,其他不想關的將被省略。

<svg>n <!--<path d=<this path is commented out> />-->n</svg>n

第一節:篇章組織

SVG詳細信息位於<svg>元素中。此元素中有幾個屬性,可以自定義你的圖形「canvas」。雖然這些屬性對於呈現圖像不是完全必要的,但是在跨瀏覽器執行時忽略它們可能使更複雜的圖形易受攻擊,並且使得它們容易不按預期進行呈現。

如上所述,內聯圖形可以「手動」編寫,或者通過訪問由矢量圖形軟體生成的XML代碼來嵌入。因為這些圖形元素的順序決定了它們的堆疊順序,所以無論哪種方式,正確的組織和結構對於編寫高效的SVG代碼至關重要的。

組織和語義

SVG文檔片段由<svg>元素中包含的任意數量的SVG元素組成。本文檔中的組織是至關重要的。文檔中的內容可以快速擴展,正確的組織提高了可訪問性和效率,使作者和用戶都受益。

本節將介紹編寫SVG的關鍵 - <svg>元素 - 並查看幫助初始文檔設置的一些常見屬性。

svg 元素

<svg>元素歸屬於容器和結構元素,在文檔內允許嵌套使用獨立的SVG片段。每個獨立的片段都有自己的坐標系。

此元素中使用的屬性(如width,height,preserveAspectRatio和viewBox)定義正在寫入圖形的畫布。

當從某些矢量軟體獲得SVG代碼時,在<svg>元素中有很多附加信息,例如SVG版本號(指示正在使用的SVG語言版本)和DOCTYPE。正如我已經提到的,這些信息不會包括在本指南的示例中,缺少它們不會阻止你的圖形在屏幕上呈現。

g 元素

g元素是組合相關圖形的容器元素。將此元素與描述和標題元素結合使用提供圖形的相關信息,並將相關圖形組件分在同一組在一起提高訪問性。 此外,通過相關元素分在同一組,可以將它們看作一個整體與各個獨立的部分。移動這些元素尤其方便,例如,可以移動整個組。 不包含在g中的任何元素則認為有它們自己的組。

use 元素

<use>元素允許您在整個文檔中重複使用元素。此元素中可以包含其他屬性,例如x,y,width和height,這些屬性定義圖形在坐標系中的詳細映射位置。 在這裡使用xlink:href屬性可以調用要重用的元素。例如,如果存在需要重新使用的蘋果的圖像的「apple」的id的<g>,則該圖像可以由<use>:<use x =「50」y =「50」 xlink:href =「#apple」/>。 這個元素作為一個重要的時間保護程序幫助壓縮代碼。

defs 元素

雖然<use>允許重用已經渲染的圖形,但<defs>元素中的圖形不會渲染到畫布上,而是能夠被引用,然後通過使用xlink:href來渲染。 圖形在<defs>中定義,然後可以通過引用該圖形的id在整個文檔中使用。 例如,下面的代碼繪製一個非常簡單的矩形漸變:

<svg>n <defs>n <linearGradient id="Gradient-1">n <stop offset="0%" stop-color="#bbc42a" />n <stop offset="100%" stop-color="#765373" />n </linearGradient>n </defs>n <rect x="10" y="10" width_="200" height="100" fill= "url(#Gradient-1)" stroke="#333333" stroke-width_="3px" />n</svg>n

<defs>除非引用其唯一的id來調用,不然內容沒有直觀的輸出,在這個實例中通過矩形的fill屬性完成內容渲染。

symbol 元素

<symbol>元素類似於<g>,因為它提供了一種組元素的方法,但是,如果沒有使用<use>元素,<symbol>中的元素沒有可視化輸出(如<defs>)。 它也不同於<g>元素,<symbol>建立自己的坐標系,與渲染的視口分開。 SVG視口和viewBox共同建立被映射的圖形的坐標系統,將進一步介紹不同的部分。

堆疊順序

HTML中的其他元素的堆疊順序可以CSS中的z-index操縱,但SVG不能。 SVG元素的堆疊順序完全取決於它們在文檔片段中的位置。 下面的葡萄和西瓜在同一個<svg>元素中。西瓜出現在葡萄前面,因為文檔中包含組成西瓜的路徑的組被列在葡萄之後。

<svg>n <g class="grapes">n <!--<path <stem path> />-->n <!--<path <grapes path> />-->n <!--<path <leaf path> />-->n </g>n <g class="watermelon">n <!--<path <outside path> />-->n <!--<path <inside path> />-->n <!--<path <seeds path> />-->n </g>n</svg>n

如果包含葡萄的組被移動到文檔的末尾,它將出現在西瓜的前面。

<svg>n <g class="grapes">n <!--<path <stem path> />-->n <!--<path <grapes path> />-->n <!--<path <leaf path> />-->n </g>n <g class="watermelon">n <!--<path <outside path> />-->n <!--<path <inside path> />-->n <!--<path <seeds path> />-->n </g>n</svg>n

這種定型的堆疊順序的方法也適用於組內的每一個元素。例如,將葡萄的莖的路徑移動到組的末尾將導致莖在頂部。

第二節:基本形狀和路徑

當你需要在HTML中使用更複雜的內聯SVG圖形時就沒有辦法再手工編寫了。那些更複雜的圖形可以使用矢量軟體創建,但現在我們來學習下手動編碼的基礎。

基本形狀

SVG包含以下基本形狀元素集:矩形,圓形,橢圓形,直線,折線和多邊形。每個元素在渲染之前需要一些屬性,如坐標和大小等詳細信息。

矩形

<rect>元素定義一個矩形。

<svg>n <rect width_="200" height="100" fill="#BBC42A" />n</svg>n

width和height屬性確定矩形的大小,而fill則設置形狀的內部顏色。數值默認為pixels,當未指定時,fill將默認為黑色。 其他屬性還有x和y坐標。這些值將圖形沿<svg>元素對應的軸移動相應的距離。

也可以通過指定rx和ry屬性中的值來創建圓角。例如,rx =「5」ry =「10」將產生具有5px半徑的角的水平邊,以及具有10px半徑的角的垂直邊。

圓形

基於中心點和外半徑設置<circle>元素。

<svg>n <circle cx="75" cy="75" r="75" fill="#ED6E46" />n</svg>n

cx和cy坐標建立圓的中心相對於由<svg>設置的工作空間尺寸的位置。

r屬性設置外半徑的大小。

橢圓

<ellipse>元素基於中心點和兩個半徑定義橢圓。

<svg>n <ellipse cx="100" cy="100" rx="100" ry="50" fill="#7AA20D" />n</svg>n

當cx和cy值基於到SVG坐標空間中的像素距離建立中心點時,rx和ry值定義形狀的邊的半徑。

直線

line元素定義具有開始點和結束點的直線。

x1和y1值確定線的開始坐標,而x2和y2值確定線的結束坐標。

折線

<polyline>元素定義了一組相連的直線段,通常構成開放形狀(不連接的開始點和結束點)。

<svg>n <polyline points="0,40 40,40 40,80 80,80 80,120 120,120 120,160" fill="white" stroke="#BBC42A" stroke-width_="6" />n</svg>n

在整個形狀中points的值在x和y軸上建立形狀的位置,並且在整個值列表中被分組為x,y。不能使用奇數點。

多邊形

<polygon>元素定義由連接的線組成的閉合形狀。

<svg>n <polygon points="50,5 100,5 125,30 125,80 100,105 50,105 25,80 25,30" fill="#ED6E46" />n</svg>n

多邊形形狀的點通過八組的x,y值來定義。

該元素還可以根據點的數量產生其他閉合形狀。

路徑元素

SVG路徑表示形狀的輪廓。此形狀可以填充,描邊,並用於導航文本和/或用作剪切路徑。 當涉及許多曲線時,這個路徑會變得非常複雜。然而,理解工作原理和涉及的語法將有助於管理這些特定路徑。

path data

路徑數據包含在<path>元素內的d屬性中,定義了形狀的輪廓:<path d =「<path data specifics>」/>。 d屬性中的這些數據說明了路徑的moveto,line,curve,arc和closepath指令。

下面的<path>詳細信息定義了青檸圖形的路徑細節:

<svg width_="258px" height="184px">n <path fill="#7AA20D" stroke="#7AA20D" stroke-width_="9" stroke-linejoin="round" d="M248.761,92c0,9.801-7.93,17.731-17.71,17.731c-0.319,0-0.617,0-0.935-0.021c-10.035,37.291-51.174,65.206-100.414,65.206 c-49.261,0-90.443-27.979-100.435-65.334c-0.765,0.106-1.531,0.149-2.317,0.149c-9.78,0-17.71-7.93-17.71-17.731 c0-9.78,7.93-17.71,17.71-17.71c0.787,0,1.552,0.042,2.317,0.149C39.238,37.084,80.419,9.083,129.702,9.083 c49.24,0,90.379,27.937,100.414,65.228h0.021c0.298-0.021,0.617-0.021,0.914-0.021C240.831,74.29,248.761,82.22,248.761,92z" />n</svg>n

moveto

moveto命令(M或m)建立一個新的點,就像提起一支鋼筆,並在紙上一個新位置繪製。包括路徑數據的代碼行必須以moveto命令開始,如上面的例子所示。 moveto命令跟在初始化路徑之後,代表新子路徑的開始和複合路徑的創建。這裡的大寫字母M表示絕對坐標,小寫字母m表示相對坐標。

closepath

closepath(Z或z)表示當前子路徑的結束,並從該點到路徑的初始點繪製直線。 如果closepath之後緊跟著一個moveto,這些moveto坐標表示下一個子路徑的開始。如果這個相同的closepath之後是moveto之外的任何東西,則下一個子路徑從當前子路徑的點開始。 這裡大寫或小寫z沒有區別。

lineto

lineto命令從當前點到新點繪製直線。

L, l

L和l命令從當前點繪製一條線到下一個提供的點坐標。這個新點然後變成當前點,以此類推。 大寫L表示絕對定位,而小寫l是相對定位。

H, h

H和h命令從當前點繪製水平線。

大寫H表示絕對定位,而小寫h是相對定位。

V, v

V和v命令從當前點繪製垂直線。

大寫V表示絕對定位,而小寫v是相對定位。

曲線命令

有三組命令繪製曲線路徑:CubicBézier(C,c,S,s),二次貝塞爾(Q,q,T,t)和橢圓弧(A,a)。 以下曲線部分將介紹每條曲線命令的基本概念,和映射的詳細信息,然後提供一個圖表供進一步了解。

Cubic Bézier

C和c CubicBézier命令從當前點繪製曲線,使用(x1,y1)參數作為曲線開始處的控制點,(x2,y2)作為結束處的控制點,定義形狀細節曲線。

S和s命令還繪製立方貝塞爾曲線,但在這種情況下,存在第一控制點是第二控制點的反射的假設。 下面的代碼繪製了一個基本的CubicBézier曲線:

<svg>n <path fill="none" stroke="#333333" stroke-width_="3" d="M10,55 C15,5 100,5 100,55" />n</svg>n

該曲線的第一和最後一組值將影響其開始和結束位置,兩個中心值將影響曲線本身在開始和結束時的形狀和定位。 S和s命令也繪製立方貝塞爾曲線,但在這種情況下,假設第一個控制點是前一個C命令的最後一個控制點的反映。則會作為相對於S命令的開始點。

大寫字母C表示絕對定位,而小寫字母c是相對定位。S和s也是一樣。

Quadratic Bézier

二次貝塞爾曲線(Q,q,T,t)類似於立方貝塞爾曲線,除了它只有一個控制點。

以下代碼繪製了一個基本的二次貝塞爾曲線:

<svg>n <path fill="none" stroke="#333333" stroke-width_="3" d="M20,50 Q40,5 100,50" />n</svg>n

操作第一個和最後一組值M20,50和100,50會影響曲線起點和終點的位置。中心值集Q40,5定義曲線的控制點,確定其形狀。

Q和q使用(x1,y1)作為控制項從初始點到終點繪製曲線。 T和t通過假設控制點是相對於新的T或t命令的開始點的先前列出的命令的控制的反映,從初始點到終點繪製曲線。

大寫的Q信號表示絕對定位,而小寫的q是相對定位。T和t也是一樣。

Elliptical Arc

橢圓弧(A,a)定義橢圓的線段。這些段通過A或命令創建,通過指定起點,終點,x和y半徑,旋轉和方向創建弧。

下面是一個基本橢圓弧的代碼:

<svg>n <path fill="none" stroke="#333333" stroke-width_="3" d="M65,10 a50,25 0 1,0 50,25" />n</svg>n

該路徑中的第一和最後一組值,M65,10和50,25表示初始和最終坐標,而第二組值定義兩個半徑。 1,0(大弧標誌和順時針標誌)的值確定如何繪製圓弧,因為這裡有四個不同的選項。 下圖顯示了四個弧選項以及大弧標誌值和順時針標誌值對弧段的最終渲染的影響。

矢量軟體嵌入

矢量圖形軟體可以製作更複雜的形狀和路徑,同時可以導出SVG代碼在其他地方使用和操作。

一旦圖形完成,生成的XML代碼可以被複制並嵌入到HTML中,圖形越複雜代碼越長。分解SVG的每個部分並且運用適當的組織元素可以極大地幫助引導和理解這些複雜和冗長的代碼。

這裡是一些櫻桃的SVG代碼圖像,添加了引導類:

<svg width_="215px" height="274px" viewBox="0 0 215 274">n <g>n <path class="stems" fill="none" stroke="#7AA20D" stroke-width_="8" stroke-linecap="round" stroke-linejoin="round" d="M54.817,169.848c0,0,77.943-73.477,82.528-104.043c4.585-30.566,46.364,91.186,27.512,121.498" />n <path class="leaf" fill="#7AA20D" stroke="#7AA20D" stroke-width_="4" stroke-linecap="round" stroke-linejoin="round" d="M134.747,62.926c-1.342-6.078,0.404-12.924,5.762-19.681c11.179-14.098,23.582-17.539,40.795-17.846 c0.007,0,22.115-0.396,26.714-20.031c-2.859,12.205-5.58,24.168-9.774,36.045c-6.817,19.301-22.399,48.527-47.631,38.028 C141.823,75.784,136.277,69.855,134.747,62.926z" />n </g>n <g>n <path class="r-cherry" fill="#ED6E46" stroke="#ED6E46" stroke-width_="12" d="M164.836,193.136 c1.754-0.12,3.609-0.485,5.649-1.148c8.512-2.768,21.185-6.985,28.181,3.152c15.076,21.845,5.764,55.876-18.387,66.523 c-27.61,12.172-58.962-16.947-56.383-45.005c1.266-13.779,8.163-35.95,26.136-27.478 C155.46,191.738,159.715,193.485,164.836,193.136z" />n <path class="l-cherry" fill="#ED6E46" stroke="#ED6E46" stroke-width_="12" d="M55.99,176.859 c1.736,0.273,3.626,0.328,5.763,0.135c8.914-0.809,22.207-2.108,26.778,9.329c9.851,24.647-6.784,55.761-32.696,60.78 c-29.623,5.739-53.728-29.614-44.985-56.399c4.294-13.154,15.94-33.241,31.584-20.99C47.158,173.415,50.919,176.062,55.99,176.859z" />n </g>n</svg>n

svg元素中的屬性定義工作區,或圖形的「畫布」。葉和莖在一個g(組)內,而櫻桃在另一個。數字字元串定義圖形將採用的路徑,fill和stroke屬性設置背景和邊框的顏色。

將這個代碼複製下來,它會通過一個SVG優化器在被放置在HTML之前,以助於消除不必要的代碼和間距,進而大大縮小文件。 關於這個方面Peter Collingridge的SVG Optimiser和SVGO也是非常有用的工具。

致謝

我用這一整節的內容來表達對你們特別的感謝:

CSS-Tricks(css-tricks.com/)

Lincoln Loop(lincolnloop.com/)

Designmodo(designmodo.com/)

Tahoe Partners(tahoepartners.com/)

Una Kravets(twitter.com/Una)

原文地址:svgpocketguide.com/book

剩餘部分將在編寫SVG的口袋指南(下)中展示,敬請期待。

iKcamp原創新書《移動Web前端高效開發實戰》已在亞馬遜、京東、噹噹開售。

滬江Web前端上海團隊招聘【Web前端架構師】,有意者簡歷至:zhouyao@hujiang.com

推薦閱讀:

SVG 圖標製作指南
數據可視化第一步,SVG【小概念】
外刊君談中國第三屆CSS大會

TAG:前端开发 | CSS | SVG |