本文主要是講解關於 SVG 的一些高級動畫特效,好比 SVG 動畫標籤,圖形漸變,路徑動畫,線條動畫,SVG 裁剪等。html
例如:路徑動畫前端
圖形漸變:瀏覽器
線條動畫:svg
以及,相關的動畫的矩陣知識,這個也是如今 CSS 動畫裏面最重要,同時也是最爲欠缺的知識點:工具
文章會先從基本語法入手,而後,慢慢深刻。介紹一些動畫基本原理和對應的數學原理知識點。而且文章後面,還附有相關語法的介紹,當你在遇到不熟悉語法的時候能夠參考參考。字體
前面一篇文章,主要介紹了一些 SVG 的基本概念和基本圖形。接下來咱們須要瞭解一下,SVG 處理矢量這個特性以外,還有啥內容吸引咱們,能讓 SVG 如今普及度這麼高?動畫
原文參考:前端小吉米ui
在 SVG 中,若是咱們想實現一個動畫效果,可使用 CSS,JS,或者直接使用 SVG 中自帶的 animate
元素添加動畫。url
使用 CSS 的話,有兩種選擇一種是經過 style
直接內聯在裏面,另外是直接使用相關的動畫屬性-- transform
。spa
<use id="star" class="starStyle" xlink:href="#starDef" transform="translate(100, 100)" style="fill: #008000; stroke: #008000"/>
而使用 SVG 中自定的 animate
主要仍是 SVG 本身的東西,比較好用。若是想用 CSS 的動畫,這都無所謂。
先看一個 SVG animate DEMO:
<rect x="10" y="10" width="200" height="20" stroke="black" fill="none"> <animate attributeName="width" attributeType="XML" from="200" to="20" begin="0s" dur="5s" fill="freeze" /> </rect>
經過將 animate 標籤嵌套在指定的圖形裏面,便可實現變換的效果。另外,還有 animateTransform,它主要是用來作變形動畫的。
<rect x="-10" y="-10" width="20" height="20" style="fill: #ff9; stroke: black;"> <animateTransform attributeType="XML" attributeName="transform" type="scale" from="1" to="4 2" begin="0s" dur="4s" fill="freeze"/> </rect>
簡單來講:
animate: 至關於 CSS 中的 transition
animateTransform: 至關於 CSS 中的 transform
裏面一些技術細節咱們這裏就不過多講解了。這裏,主要想介紹一下 animate 中的 morph 的效果。
該效果主要作的就是圖形內部的漸變。如圖:
這種動畫是怎麼實現呢?
直接看代碼吧:
<path fill="#1EB287"> <animate attributeName="d" dur="1440ms" repeatCount="indefinite" keyTimes="0; .0625; .208333333; .3125; .395833333; .645833333; .833333333; 1" calcMode="spline" keySplines="0,0,1,1; .42,0,.58,1; .42,0,1,1; 0,0,.58,1; .42,0,.58,1; .42,0,.58,1; .42,0,.58,1" values="M 0,0 C 50,0 50,0 100,0 100,50 100,50 100,100 50,100 50,100 0,100 0,50 0,50 0,0 Z; M 0,0 C 50,0 50,0 100,0 100,50 100,50 100,100 50,100 50,100 0,100 0,50 0,50 0,0 Z; M 50,0 C 75,25 75,25 100,50 75,75 75,75 50,100 25,75 25,75 0,50 25,25 25,25 50,0 Z; M 25,50 C 37.5,25 37.5,25 50,0 75,50 75,50 100,100 50,100 50,100 0,100 12.5,75 12.5,75 25,50 Z; M 25,50 C 37.5,25 37.5,25 50,0 75,50 75,50 100,100 50,100 50,100 0,100 12.5,75 12.5,75 25,50 Z; M 50,0 C 77.6,0 100,22.4 100,50 100,77.6 77.6,100 50,100 22.4,100, 0,77.6, 0,50 0,22.4, 22.4,0, 50,0 Z; M 50,0 C 77.6,0 100,22.4 100,50 100,77.6 77.6,100 50,100 22.4,100, 0,77.6, 0,50 0,22.4, 22.4,0, 50,0 Z; M 100,0 C 100,50 100,50 100,100 50,100 50,100 0,100 0,50 0,50 0,0 50,0 50,0 100,0 Z;"/> </path>
這麼多,是否是感受有點懵逼。不過,咱們細分來看一下其實很簡單。裏面主要是利用 animate
中的 keyTimes
,calcMode
,keySplines
,以及 values
這幾個屬性。不急,咱們一個一個來解釋一下。
keyTimes: 這其實和 CSS 中定義的 @keyframes
同樣。經過 0-1 之間的值,定義每段動畫完成的時間。格式爲:value;value...
。例如 0;.0625;.208333333;.3125;.395833333;.645833333;.833333333;1
。從第一個動畫,到第二個動畫經歷的時間比例爲 6.25%。而且,keyTimes 須要和 values 裏面定義的幀數一致。
calcMode: 用來定義動畫具體的插值模型。取值有: discrete | linear[default] | paced | spline
。具體能夠參考 MDN。這裏咱們主要介紹一下 spline。該值表示每一個動畫間使用自定的貝塞爾變換曲線。若是沒有特殊要求,使用 linear 其實已經足夠了,這樣就不用麻煩去定義下面的 keySplines
屬性。
keySplines:該值用來具體定義動畫執行時的 貝塞爾曲線。使用格式是經過 ;
來分隔每個值。即,cubic-bezier(.31,.57,.93,.46)
爲一組。使用 keySplines 表達,則爲:keySplines = ".31,.57,.93,.46;"
。固然,裏面的貝塞爾曲線組數爲 整個動畫幀數 - 1
。
而 values 就很簡單了。它是直接結合 attributeName
屬性,來設置具體的值,每一個值之間使用 ;
進行分隔。
像上面那樣,能夠在指定元素裏面嵌套多個 animate,既實現了形狀的改變,又實現了顏色的改變。Morph 比較經常使用於數字的更迭,好比,倒數 10s 的相關動畫。到這裏,Morpah 相關的知識點就結束了。
接着,讓咱們來看一下 SVG 中,另一很是重要的標籤 -- animateMotion
。
該標籤可讓指定的元素,繞着指定的路徑進行運動。因此這對於複雜的路徑來講很是有用,由於咱們很難使用 transform 去模擬複雜的變換路徑。看一個 DEMO
animateMotion 大體的屬性和 animate
差很少,不過,它還擁有本身特有的屬性,好比 keyPoints
、rotate
、path
等。不過,calcMode 在 AM(animateMotion) 中的默認屬性由,linear
變爲 paced
。
這些屬性,咱們慢慢介紹,先從最簡單的開始吧。首先,咱們來看一個 DEMO:
<g> <rect x="0" y="0" width="30" height="30" style="fill: #ccc;"/> <circle cx="30" cy="30" r="15" style="fill: #cfc; stroke: green;"/> <animateMotion from="0,0" to="60,30" dur="4s" fill="freeze"/> </g>
from,to:指定兩點的位置,位置參數是以元素的座標爲原點的。
dur:執行渲染時間
fill:指定動畫結束後停留的裝填。有 freeze
和 remove
效果。remove 表示回到動畫開始的位置,freeze 表示停留在動畫結束的位置。
若是,你想要更復雜的路徑,能夠直接使用 path
屬性來指定路徑。用法和 path
標籤中 d
屬性是同樣的。
<rect x="0" y="0" width="30" height="30" style="fill: #ccc;"> <animateMotion path="M50,125 C 100,25 150,225, 200, 125" dur="6s" fill="freeze"/> </rect>
或者使用 mpath
標籤,引用外部的 path
。
<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" /> <!-- 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>
動畫效果爲:
因此,通常而言咱們在定義 AM 的路徑的時候,只用一種方式定義便可,不然會發生相應的覆蓋:mpath
>path
>values
>from/to
。
在 AM 運動中,還有一個很重要的概念就是旋轉角。默認狀況下,運動物體的角度是按照它和座標軸的初始角度肯定的。例如:
這樣看起來確實有些彆扭,那能不能讓物體垂直於路徑進行運動呢?
有的,根據 rotate
屬性值,一共有 3 個值可供選擇。
auto:讓物體垂直於路徑的切線方向運動。不過,若是你的路徑是閉合曲線的話,須要注意起始點的位置。
例如:
auto-reverse:讓物體垂直於路徑的切線方向並 + 180°。也就是和 auto 運動關於切線對稱。
Number:讓物體以固定的旋轉角度運動。這個就至關於使用 transform:rotate(deg) 進行控制。
在動畫設置標籤中,還有一個更簡單的--set
。
該標籤也是用來模擬 transition
效果的。它和 animate
的主要區別是,它僅僅須要 to
的指定屬性,而不須要其餘的參考屬性,好比 from
,by
等。那它有啥特別的存在乎義嗎?
有的,由於 set 針對於全部屬性,甚至包括 style 裏面的相關 CSS 屬性。因此,能夠靠它來很好描述一些非 number
的屬性值。
<text text-anchor="middle" x="60" y="60" style="visibility: hidden;"> <set attributeName="visibility" attributeType="CSS" to="visible" begin="4.5s" dur="1s" fill="freeze"/> All gone! </text>
上面差很少簡單闡述了關於 SVG 一些比較有特色的動畫。固然,還有比較重要的線條動畫,這個咱們放到後面進行講解。這裏先來看一下全部動畫中,很是重要的矩陣原理。線性代數應該是大學裏面來講,最容易學的一門科目,MD。。。還記得,大學線代期末考試的時候,100 分的同窗應該說是如韭菜地般,一抓一大片(對不起,我沒能和他們同流合污。)
那矩陣是如何在動畫中使用的呢?
簡單的說,矩陣中的每一個元素其實能夠等價代換爲每一個因式裏面的係數:
上面也叫做 三維矩陣。即,它涉及到 x,y,z 軸的計算。那對於咱們平面 2D 變換來講,那麼此時矩陣又是哪一種形式呢?
很簡單,只要將 z 軸永遠置爲一個常數就 OK。這裏,慣例上是直接取 0 0 1 來設置。
不信的話,你們只要代進去乘以乘,應該就能夠獲得結果了。因此,在二維中,具體變換方式爲:
後面,咱們也會依據這個公式進行相關的變形操做。那矩陣變換是怎麼運用到 CSS/SVG 當中呢?
在 CSS 中,是直接使用 transform
中的屬性:
transform: matrix(a,b,c,d,e,f);
固然,在 SVG 中也是同樣的:
<g transform="matrix(1,2,3,4,5,6)"> <line x1="10" y1="20" x2="30" y2="40" style="stroke-width: 10px; stroke: blue;"/> </g>
因此,咱們主要的重點就是講解一下 matrix
這個屬性。它的格式爲:
matrix(a,b,c,d,e,f);
對應於咱們上面的公式有:
在接觸 transform
的時候,你們應該瞭解到 transform
裏面有不少固定的動畫屬性:
translate()
rotate()
scale()
skew()
實際上,在底層仍是使用 matrix 實現的變換。就拿 translate 舉個例子吧。
translate 的格式爲:
translate(dx,dy)
至關於參考當前原點,在 x/y 軸上移動 dx/dy 的距離。那麼映射到矩陣,應該如何表示呢?
很簡單,它等同於:
matrix(1 0 0 1 dx dy);
使用代數證實一下:
假設有 matrix(1 0 0 1 20 30)
變爲矩陣爲:
根據,上面的表達式有:
X = x'*1 + y'*0 + 20 = x' + 20 Y = x'*0 + y'*0 + 30 = y' + 30
因此,就是 X 在原有 X 軸座標上向右移動 20 的距離,Y 相對於原有移動 30 的距離。
那麼其餘幾個屬性呢?也是怎麼變化的嗎?
恩,相似。只是裏面取值不同:
scale(x,y): 放大 X/Y 軸,矩陣的表達爲 matrix(x 0 0 y 0 0)。
rotate(θ): 座標旋轉,矩陣的表達爲 matrix(cosθ sinθ -sinθ cosθ 0 0)。
skew(θx,θy): X/Y 軸拉伸,矩陣的表達爲 matrix(1 tanθx tanθy 1 0 0)。
注意,上面三個都會改變原有物體的座標系!!! 這點很重要,換句話說,後面每次變換都是基於前面一個的變換結果的。
詳情看圖:
詳情能夠參考:MDN matrix
不過,這並非咱們使用 matrix 的重點,也不是它的優點。它的優點在於可計算,即,可以將複雜的動畫集合到一個表達式中,而且,後續的變換能夠直接基於當前的 matrix。
咱們先來了解一下,若是多個變換動畫一塊兒使用,matrix 應該如何表達呢?
只須要找到咱們變換動畫對應的矩陣,而後相乘便可。例如,先旋轉 45°,而後放大 1.5 倍,則有變換動畫爲:
transform: rotate(45deg) scale(1.5,1.5);
注意,雖然,你定義動畫是分開的,但此時的動畫是同時進行的。爲啥?由於,這兩個動畫實際上能夠整合成爲一個變換矩陣:
而且,位置是不能夠調換的。好比,transform: scale(2,2) translate(20px,30px)
。即,你先放大兩倍,而後移動 20,30 的距離。注意,這裏移動的 20,30 相對的是已經放大事後的座標,相對於原座標而言就是 40,60 了。 若是,你調換位置,即 transform: translate(20px,30px) scale(2,2)
。就變成如今原座標移動 20,30,而後再放大兩倍。
而上面強調的順序關係,實際上就能夠理解爲矩陣不知足交換律的原則。由於一旦交換,結果極可能不同。
上面的內容只是簡單的描述了關於矩陣的概念。在實際中,矩陣能夠說是真正利器。
假設如今有一個動畫,要求你將一個物體從一個點經過拋物線的方式移動到另一個點,那麼此時要求 JS/CSS 隨你挑。此時,你會不會感受,呼吸急促,頭腦發熱呢?
恩,matrix 能夠治,並且包治百病。不過,matrix 有一個限制點,它只能用於一次線性動畫表達式。即,針對於拋物線,橢圓曲線這類複雜曲線來講,不太合適。那麼有什麼辦法嗎?
有的,微分思想。每一段動畫其實均可以經過必定範圍內的直線拼接而成,那麼這樣,咱們就能夠將一段拋物線拆分爲由幾段線段構成的曲線。固然,若是你分的越細,擬合度就越高。這裏咱們不打算過分你和,咱們簡單的將一段拋物線分爲 5段。
如圖:
那麼接下來就是摳細節。這裏,依次取傾角爲 45°,30°,0°,-45°,-30° 這 5 段直線。每段分配的時間比例爲 20%、25%、10%、25%、20% 這主要是用於 keyframe 的設定。如今,用數學來分析一下,這個動畫到底該怎麼弄。
如今,已知兩點之間的距離爲 100px。那麼咱們一樣根據上述比例分,則有 20px, 25px, 10px, 25px, 20px。
這裏咱們以 45° 傾角爲參考點,則終點座標爲 (20,20); 。那麼,該段的矩陣爲:
// 注意 Y 軸須要取負值! 1 0 20 0 1 -20 0 0 1
CSS 中的變形動畫爲:
transform: matrix(1,0,0,1,20,-20);
而後,第二段就爲:
1 0 25 0 1 -14.4 0 0 1
使用矩陣的乘法法,則有:
1 0 45 0 1 -34.4 0 0 1
變形動畫爲:
transform: matrix(1,0,0,1,45,-34.4);
剩餘幾段也是這樣的作法。最終,整個 keyframe 就應該表示爲:
@keyframe Parabola{ 20%{ transform: matrix(1,0,0,1,20,-20); } 45%{ transform: matrix(1,0,0,1,45,-34.4); } ... }
整個動畫過程差很少都是這樣。固然,矩陣也不只僅侷限於這幾個動畫,憑藉着高度定製化和靈活性的特色,這它還經常用於進行回彈,彈跳等動畫中。若是你們有興趣,後期也能夠對這類動畫進行簡單的講解。
後面,咱們最後來了解一下 SVG 中很重要的線條動畫。
SVG 中的線條動畫經常用做過渡屏(splash screen)中。例如:
或者,一些比較炫酷的 LOGO 中,好比 AllowTeam 的:
看到這些炫酷的效果,你們有沒有動心想學一學,看看本身到底可否作的這麼好呢?
OK,咱們如今來正式介紹一下線條動畫。在 SVG 中,最長用到的線條標籤就是 Path
。這裏我前面一篇文章已經作了介紹,我這裏就不贅述了。
而在具體變化當中用到的是關於 stroke
的相關屬性:(下面的屬性均可以直接用在 CSS 當中!)
stroke*:定義筆觸的顏色。例如:stroke="green"
stroke-dasharray*:定義 dash 和 gap 的長度。它主要是經過使用 ,
來分隔 實線 和 間隔 的值。例如:stroke-dasharray="5, 5"
表示,按照 實線爲 5,間隔爲 5 的排布重複下去。以下圖:
放大看有:
另外,stroke-dasharray 並不侷限於只能設置兩個值,要知道,它自己的含義是設置最小重複單元,即,dash,gap,dash,gap...
。好比,我定義 stroke-dasharray="15, 10, 5"
則至關於,[15,10,5] 爲一段。則有:
放大看則有:
stroke-dashoffset*: 用來設置 dasharray 定義其實 dash 線條開始的位置。值能夠爲 number || percentage
。百分數是相對於 SVG 的 viewport。一般結合 dasharray 能夠實現線條的運動。
stroke-linecap: 線條的端點樣式。
stroke-linejoin: 線條鏈接的樣式
stroke-miterlimit: 一個比較複雜的概念,若是咱們只是畫一些通常的線段,使用上面 linejoin 便可。若是涉及對邊角要求比較高的,則可使用該屬性進行定義。它的值,其實就是角長度比上線寬:
而實際理解的話,就是假設當 width 爲 1。此時比例爲 2。那麼 miter = 2。那麼超過 2 的 miter 部分則會被 cut 掉。能夠參照:
他主要是配合 linejoin
一塊兒使用。由於 linejoin 默認取值就是 miter
。因此,默認狀況下就可使用該標籤屬性。它默認值爲 4。其他的你們下去實踐一下便可。詳細能夠參考: miter
stroke-opacity:線段的透明度
stroke-width:線的粗細。
OK,介紹完關於 path 的全部 stroke 屬性以後,咱們就要開始動手寫一下讓線條動起來的代碼。簡單來講,就是經過 stroke-dashoffset
和 stroke-dasharray
來作。整個動畫能夠分爲兩個過程:
經過 dasharray 將實線部分隱藏,空餘爲全線段長。而後,將實線部分增長至全長。好比:dasharray: 0,1000
變爲 dasharray: 1000,1000
。
同時,經過 dashoffset 來移動新增的實線部分,形成線段移動的效果。有: dashoffset:0
,變爲 dashoffset:1000
。
不過,這裏咱們不打算使用 Path 來作啥複雜的動畫,這主要考慮到手頭沒有一些 SVG 生成工具。因此,這裏咱們就以 Text 來作吧(由於作起來真的簡單)。
這裏,先以 IV-WEB 這段文字來作動畫。
先給你們看一下最終結果:
那麼這種動畫是怎麼作的呢?
這裏,我主要介紹一下關於 CSS 相關,SVG 就一個 Text 我直接貼代碼了:
<svg viewBox="0 0 1320 300"> <!-- Symbol --> <symbol id="s-text"> <text text-anchor="middle" x="50%" y="50%" dy=".35em"> IV-WEB </text> </symbol> <!-- Duplicate symbols --> <use xlink:href="#s-text" class="text" ></use> <use xlink:href="#s-text" class="text" ></use> <use xlink:href="#s-text" class="text" ></use> </svg>
上面是經過建立一個居中定位的字體,而後使用 3 個 text 重疊。具體 CSS 咱們下面來講一下。首先,咱們營造的效果是從無到有,就須要使用 dasharray
將 gap 設置的足夠大。這裏我取 300 便可。
stroke-dasharray: 0 300;
而後,經過 nth-child
選擇器,給每個文字使用不一樣的顏色值:
.text:nth-child(3n + 1) { stroke: #F60A0A; } .text:nth-child(3n + 2) { stroke: #F2FF14; } .text:nth-child(3n + 3) { stroke: #FB9505; }
下面纔是重點內容。此時,這 3 個 text 的起始點重合。我如今既要他們在運行時不徹底重合,又要他們的線條能進行滾動。不囉嗦了,直接看代碼吧:
@keyframes stroke { 100% { stroke-dashoffset: 1000; stroke-dasharray: 80 160; } } @keyframes stroke1 { 100% { stroke-dashoffset: 1080; stroke-dasharray: 80 160; } } @keyframes stroke2 { 100% { stroke-dashoffset: 1160; stroke-dasharray: 80 160; } }
這就是上面 3 個不一樣的 text 運用的動畫。dashoffet
由 0 到 1000。這完成了滾動的目的。同時,爲了讓字體不重合,我還須要在對應字體的 dashoffset
上,加上不一樣的間隔距離。好比,第一個字體 offset 爲 1000。那麼第二個字體,我須要加上前一個字體 dash 的長度,即,80。因此,第二個字體就變爲 1080
。那麼第三個就是加上前兩個的 dash 長度,即 1160
。
大體過程就是這樣,詳情能夠查看: IVWEB 線條動畫。
這裏再給你們佈置一個練習做業,如何實現無線連續的分段動畫呢?
具體效果如圖:
給點提示:
將多個文字重疊,取不一樣的 offset 和 array 便可。動畫的終止位置通常取一個 gap + dash 的週期長便可。
後面看看這篇文章反響如何,到時候再決定是否再寫一篇續集,介紹該做業的原理。
在 SVG 中定義文字直接使用 text
標籤便可。關於文字來講,通常而言須要注意的點就那麼便可,文字的排列,間距等等。這些均可以直接使用 CSS 進行控制。不過,有幾個屬性比較特殊,這裏須要額外提一下。
用來定義參考點和實際字符之間的定位關係。格式爲:
text-anchor: start | middle | end | inherit
直接看代碼解釋吧:
<!-- Anchors in action --> <text text-anchor="start" x="60" y="40">A</text> <text text-anchor="middle" x="60" y="75">A</text> <text text-anchor="end" x="60" y="110">A</text>
第一個 A,參考的是 (60,40) 的點,定義爲 start
,那麼參考點應該在字符的前面。
而剩下兩個也是一樣的道理:
如今,假如咱們想在 text 裏面添加一些特殊的字符效果,好比斜體,加粗等。因爲,text 標籤不能實現嵌套,因此,爲了解決這個痛點,提出了 tspan
的標籤。它其實就是一個能夠嵌套的 text 標籤。
<text x="10" y="30" style="font-size:12pt;"> Switch among <tspan style="font-style:italic">italic</tspan>, normal, and <tspan style="font-weight:bold">bold</tspan> text. </text>
tspan 裏面一樣能夠自定義相關的自身屬性。詳細的能夠參考 tspan 我這裏就不詳述了。
Text 通常能夠橫放,豎放。那有沒有啥辦法讓文字能夠按照必定的路徑任意排放呢?
有的,這裏可使用 textPath
標籤,來定義具體參考路徑。
<path id="sharp-corner" d="M 30 110 100 110 100 160" style="stroke: gray; fill: none;"/> <text> <textPath xlink:href="#sharp-corner"> Making a quick turn </textPath> </text>
如圖:
具體細節我這裏就很少說了。
在 DOM 中若是想展現一個圖片的部分,或者以某種形狀展現圖片的部分,通常是經過一個 cover div 來實現的。不過,若是涉及到不規則圖形的話,那麼 DOM 就有天生缺陷了(固然使用 CSS 裏的 clip-path
能夠完成,不過兼容性不太好)。而在 SVG 中,提供了 clipPath
標籤,可以讓咱們自定義裁剪圖片的範圍和形狀。
clipPath 裏面能夠接任何圖形,好比,path,rect 甚至是 text。使用的時候,直接在 style 中,指定 clip-path
便可,或者直接使用 clip-path
屬性指定。
<defs> <clipPath id="textClip"> <text id="text1" x="20" y="20" transform="rotate(60)" style="font-family: 'Liberation Sans'; font-size: 48pt; stroke: black; fill: none;"> CLIP </text> </clipPath> </defs> <use transform="translate(100, 0)" xlink:href="#shapes" style="clip-path: url(#textClip);"/> <use transform="translate(100, 0)" xlink:href="#shapes" clip-path="url(#textClip);"/>
或者說,若是咱們想畫一個圓的裁剪區域的話:
<defs> <clipPath id="circularPath" clipPathUnits="objectBoundingBox"> <circle cx="0.5" cy="0.5" r="0.5"/> </clipPath> </defs> <use xlink:href="#shapes" style="clip-path: url(#circularPath);" />
分組標籤應該毫無心外排第一,由於其實做爲繪製圖形中最常和最基本的標籤。前面一篇文章也主要介紹過了,這裏作點補充。
每個分組標籤都帶有 id
屬性,惟一標識該分組,爲何呢?
由於,後面咱們可使用該 id 標籤添加動畫,重用該分組等。
<g id="demo" stroke="green" fill="white" stroke-width="5"> <circle cx="25" cy="25" r="15"/> <circle cx="40" cy="25" r="15"/> <circle cx="55" cy="25" r="15"/> <circle cx="70" cy="25" r="15"/> </g>
每一個分組裏面能夠含有一些描述標籤,好比 desc
。 這些描述內容是不會被渲染的。
<g id="demo" stroke="green" fill="white" stroke-width="5"> <desc>Just Demo</desc> <circle cx="25" cy="25" r="15"/> </g>
該標籤就是結合 g
標籤一塊兒使用,做用是能夠複用 g 分組的樣式。
<g id="Port"> <circle style="fill: inherit;" r="10"/> </g> <use x="50" y="30" xlink:href="#Port" class="classA"/>
裏面使用 xlink:href
加上指定 group 的 id,而後經過 x
,y
屬性指定副本放置的位置。不過,有一個限制,use 標籤的 style 屬性,並不能覆蓋點原始的 group style 樣式。並且,有時候,咱們只是想使用一些模板,即,圖形並未被解析,只有代碼存在。這時候,就須要使用 defs
來包裹了。
用來保存一些代碼,使其不會被瀏覽器解析。而且裏面的分組能夠被 use 屬性的 style 樣式所覆蓋。
<defs> <g id="Port"> <circle style="fill: inherit;" r="10"/> </g> </defs> <use x="50" y="50" xlink:href="#Port" style="fill: blue;"/>
該標籤和 g
標籤相似,也是用來進行分組。不過,它有個特色,即,不會被瀏覽器所渲染。那它不和 defs
差很少嗎?
恩,確實。不過,defs 是官方推薦,用來包裹一些模板 svg 代碼而創造出來,用來增長可讀性的標籤。而 symbol 是存粹的做爲一個模板。它能夠獨立於 svg 的 viewbox 來自定義子 viewbox 和 preserveAspectRatio。
<symbol id="sym01" viewBox="0 0 150 110"> <circle cx="50" cy="50" r="40" stroke-width="8" stroke="red" fill="red"/> <circle cx="90" cy="60" r="40" stroke-width="8" stroke="green" fill="white"/> </symbol> <use href="#sym01" x="0" y="0" width="100" height="50"/>
一樣使用該模板,也是使用 use
標籤來完成。
既然 use
能夠重用 SVG 代碼,那麼 SVG 裏面能不能重用已經畫好的 png/jpg 的圖片呢?
這時候,就須要用到 image
標籤。其能夠用來加載外部的 PNG, JPEG 圖片,注意,官方規定是前兩種,其它圖片支持不支持官方沒作答覆。即,若是你使用 GIF 圖片,並不能保證全部的瀏覽器都能正常顯示。
<image xlink:href="kwanghwamun.jpg" x="72" y="92" width="160" height="120"/> </svg>
一樣,該 image
標籤也具備自定義 preserveAspectRatio 的效果。
x: 定義水平位置
y: 定義垂直位置
width: 圖片渲染的寬度,必須有。
height: 圖片渲染的高度,必須有。
preserveAspectRatio: 控制圖片的縮放
marker 通常是用來畫箭頭或者線段始末的標識圖形。
<defs> <marker id="Triangle" viewBox="0 0 10 10" refX="1" refY="5" markerWidth="6" markerHeight="6" orient="auto"> <path d="M 0 0 L 10 5 L 0 10 z" /> </marker> </defs> <polyline points="10,90 50,80 90,20" fill="none" stroke="black" stroke-width="2" marker-end="url(#Triangle)" />
如圖:
這裏咱們只須要裏瞭解便可,由於在實際畫的時候,直接使用相關工具生成更加方便。
這裏的 a 標籤和咱們直接在 HTML 使用的超連接 a 標籤相似。也是用來定義一個外鏈的。
<a xlink:href="https://developer.mozilla.org/en-US/docs/SVG" target="_blank"> <rect height="30" width="120" y="0" x="0" rx="15"/> <text fill="white" text-anchor="middle" y="21" x="60">SVG on MDN</text> </a>
更多內容,能夠關注個人公衆號:前端小吉米。
分享吉米的前端路,後面也會按期推出當前熱門的前端技術~ 好比,直播,VR