SVG採用的是使用文原本定義圖形,這種文檔結構很是適合於建立動畫。要改變圖形的位置、大小和顏色,只須要調整相應的屬性就能夠了。事實上,SVG有爲各類事件處理而專門設計的屬性,甚至不少仍是專門爲動畫量身定作的。在SVG中,實現動畫一般使用SVG SMIL animation。
經過SMIL能夠實現的基本動畫:
•動畫元素的數值屬性(X, Y, …)
•動畫屬性變換(平移或旋轉)
•動畫顏色屬性
•沿着運動路徑運動(這一點很是有趣)css
對svg動畫瀏覽器兼容狀況:html
能夠看到ie都不支持svg動畫,移動端andriod4.1纔開始支持svg動畫。git
1. animate元素
這個是最基本的動畫元素,能夠直接爲相關屬性提供不一樣時間點的值。
2. set元素
這個是animate元素的簡寫形式,支持全部的屬性類型,尤爲是當對非數字型的屬性(例如visibility)進行動畫時很方便。set元素是非增量的,相關的屬性對之無效。 to指定的動畫結束值類型必定要符合屬性的取值類型。
3. animateMotion元素
路勁動畫元素。github
4. animateColor元素
顏色動畫元素。這是一個過期的元素,基本上全部功能均可以用animate代替,因此仍是不要用了。web
5. animateTransform元素
canvas
變換動畫元素。看看特殊的一些屬性:
type = "translate | scale | rotate | skewX | skewY"
這個屬性指定了變換的類型,translate是默認值,這裏的rotate是以svg容器的端點爲圓心旋轉。
from,by和to的值相應的都是對應變換的參數,這個仍是與前面講的變換是一致的。values則是一組分號隔開的這樣的值系列。瀏覽器
支持動畫效果的元素和屬性
基本上全部圖形元素(path,rect,ellipse,text,image...),容器元素(svg, g, defs, use, switch, clipPath, mask...)都支持動畫。基本上大多數的屬性都支持動畫效果。app
animate元素--基本元素動畫svg
<svg width="200" height="200" > <rect x="0" y="40" width="200" height="200" fill="rgba(0,0,0,.4)" /> <text font-family="microsoft yahei" font-size="40" y="80" x="0" fill="red" stroke="green" stroke-width="1"> hello <animate attributeName="x" attributeType="XML" from="0" to="100" begin="0s" dur="2s" repeatCount="indefinite"/> </text> </svg>
set動畫,能夠方便設置延遲wordpress
<!-- set 能夠實現基本的延遲功能 --> <svg width="200" height="200" > <rect x="0" y="40" width="200" height="200" fill="rgba(0,0,0,.4)" /> <text font-family="microsoft yahei" font-size="40" y="80" x="0" fill="red" stroke="green" stroke-width="1"> hello <set attributeName="x" attributeType="XML" to="80" begin="3s" /> </text> </svg>
animateMotion動畫
<svg width="360" height="200" xmlns="http://www.w3.org/2000/svg"> <text font-family="microsoft yahei" font-size="40" x="0" y="0" fill="#cd0000">hello <animateMotion path="M10,80 q100,120 120,20 q140,-50 160,0" begin="0s" dur="3s" rotate="40" repeatCount="indefinite"/> </text> <path d="M10,80 q100,120 120,20 q140,-50 160,0" stroke="#cd0000" stroke-width="2" fill="none" /> </svg>
animateTransform動畫
<svg width="200" height="200" > <rect x="0" y="40" width="200" height="200" fill="rgba(0,0,0,.4)" /> <text font-family="microsoft yahei" font-size="40" y="80" x="0" fill="red" stroke="green" stroke-width="1"> hello <animate attributeName="x" attributeType="XML" from="0" to="100" begin="0s" dur="2s" repeatCount="indefinite"/> <animateTransform attributeName="transform" type="scale" from="1" to="1.2" begin="0s" dur="2s" repeatCount="indefinite"/> </text> </svg>
相關屬性解釋:
attributeName = <attributeName>
要變化的元素屬性名稱,① 能夠是元素直接暴露的屬性,例如,對於本文反覆出現的「馬」對應的text
元素上的x
, y
或者font-size
; ② 能夠是CSS屬性。例如,透明度opacity
.
attributeType = 「CSS | XML | auto」
這個屬性指定了屬性取值的命名空間,這幾個值的含義以下:
CSS:表明attributeName指定的屬性是CSS屬性。
XML:表明attributeName指定的屬性是XML默認命名空間下的屬性(注意svg文檔本質上是xml文檔)。
auto:表明先在CSS屬性中查找attributeName指定的屬性,若是沒找到,則在默認的XML命名空間下尋找該屬性。
注意:若是你不確信某屬性是XML類別仍是CSS類別的時候,個人建議是不設置attributeType
值,直接讓瀏覽器本身去判斷
begin = "begin-value-list"
該屬性定義了動畫的開始時間。能夠是分號分開的一系列時間值。也能夠是一些其餘觸發動畫開始的值。好比事件,快捷鍵等。
dur = Clock-value | "media" | "indefinite"
定義了動畫的持續時間。能夠設置爲以時鐘格式顯示的值。也能夠設置爲下列兩個值:
media:指定動畫的時間爲內部多媒體元素的持續時間。
indefinite:指定動畫時間爲無限。
repeatCount = numeric value | "indefinite"
設置了動畫重複的次數。 indefinite表明無限重複。
repeatDur = Clock-value | "indefinite"
設置重複的總的動畫時間。indefinite表明無限重複。
fill = "freeze" | "remove(默認值)"
設置了動畫結束後元素的狀態。freeze表示動畫結束後元素停留在動畫的最後狀態。remove表明動畫結束之後元素回到動畫前的狀態,這個是默認值。
1.利用stroke屬性實現線框效果
在作這個動畫以前,咱們先講一下,作這個動畫的stroke相關屬性:
1. 若是不提供stroke屬性,則默認不繪製圖形邊框。
2. 能夠設置邊的透明度,就是stroke-opacity,值的範圍是0到1
3. 線的端點 - stroke-linecap屬性,這個屬性定義了線段端點的風格,這個屬性可使用butt,square(方形),round(圓形)三個值
4.線的鏈接 - stroke-linejoin屬性,定義了線段鏈接處的風格,這個屬性可使用miter,round,bevel三個值
5. 線的虛實 - stroke-dasharray屬性
這個屬性是設置一些列數字,不過這些數字必須是逗號隔開的。屬性中固然能夠包含空格,可是空格不做爲分隔符。每一個數字定義了實線段的長度,分別是按照繪製、不繪製這個順序循環下去。
6.stroke-miterlimit:這個和canvas中的同樣,它處理何時畫和不畫線鏈接處的miter效果。
7.stroke-dashoffset:這個屬性設置開始畫線的位置。
下面看看咱們如何實現效果:
html, body { background: #333; height: 100%; overflow: hidden; text-align: center; } .svg-wrapper { height: 60px; margin: 0 auto; position: relative; top: 50%; transform: translateY(-50%); width: 320px; } //初始咱們經過stroke-dasharray:140 540 即實線140 虛線540 可是總長度320*2+60*2=760 則說明最終能看到的實線爲140
//而後經過stroke-dashoffset設置畫線的位置 .shape { fill: transparent; stroke-dasharray: 140 540; stroke-dashoffset: -474; stroke-width: 8px; stroke: #19f6e8; } .text { color: #fff; font-family: 'Roboto Condensed'; font-size: 22px; letter-spacing: 8px; line-height: 32px; position: relative; top: -48px; } //經過animation切換便可 @keyframes draw { 0% { stroke-dasharray: 140 540; stroke-dashoffset: -474; stroke-width: 8px; } 100% { stroke-dasharray: 760; stroke-dashoffset: 0; stroke-width: 2px; } } .svg-wrapper:hover .shape { -webkit-animation: 0.5s draw linear forwards; animation: 0.5s draw linear forwards; } </style> <!-- SVG stroke-dasharray 屬性 --> <div class="svg-wrapper"> <svg height="60" width="320" xmlns="http://www.w3.org/2000/svg"> <rect class="shape" height="60" width="320" /> </svg> <div class="text">HOVER</div> </div>
二.線條中心到兩邊擴張效果
兩種方案:
第一種: css+svg實現
.path{ stroke-dasharray:0,200; stroke-dashoffset:-100; -webkit-animation: move 1s linear 0.5s forwards; animation: move 1s linear 0.5s forwards; } @-webkit-keyframes move{ 0%{ stroke-dasharray:0,200; stroke-dashoffset:-100; } 100%{ stroke-dasharray:200,0; stroke-dashoffset:0; } } <path class="path" d="M 10 75 L 200 75" stroke="red" stroke-linecap="round" stroke-width="1" fill="none"> </path>
第二種: svg實現
<svg width="200" height="200"> <path d="M 10 100 L 200 100" stroke="orange" stroke-linecap="round" stroke-width="1" stroke-dasharray="0,200" stroke-dashoffset="-100" fill="none"> <animate attributeName="stroke-dashoffset" attributeType="XML" from="-100" to="0" begin="0s" dur="1s" /> <!-- fill = "freeze" | "remove(默認值)" freeze表示動畫結束後元素停留在動畫的最後狀態 remove表明動畫結束之後元素回到動畫前的狀態,這個是默認值--> <animate attributeName="stroke-dasharray" attributeType="XML" from="0,200" to="200,0" begin="0s" dur="1s" fill="freeze"/> </path> </svg>
這裏注意兩個知識點:
fill = "freeze" | "remove(默認值)" freeze表示動畫結束後元素停留在動畫的最後狀態 remove表明動畫結束之後元素回到動畫前的狀態,這個是默認值
在直線上面stroke-dashoffset="100"和stroke-dashoffset="-100"在同一個位置,只是最終畫的位置由stroke-dasharray="20 0"和stroke-dashoffset一塊兒肯定,例前面兩個值起始點120(100+20) 和80(|-100+20|)
三.填坑animateTransform中rotate針對的svg左上角那個點移動到元素中心點
實例代碼:
<svg width="400" height="400"> <rect x="0" y="0" fill="green" rx="4" width="200" height="200"> <animateTransform attributeName="transform" type="rotate" form="0" to="360" begin="0" dur="5s" repeatCount="indefinite" /></rect> </svg>
例上面的代碼咱們讓200x200的方形元素,作旋轉運動,可是在svg裏面rotate旋轉針對的點是svg的左上角。咱們想在針對元素中心點運動怎麼辦。
一般的解決方案:
<svg width="400" height="400"> <g transform="translate(200,200)"> <rect x="-100" y="-100" fill="green" rx="4" width="200" height="200"> <animateTransform attributeName="transform" type="rotate" form="0" to="360" begin="0" dur="5s" repeatCount="indefinite" /> <g> </svg>
咱們加了一個組合標籤<g transform="translate(200,200)"></g>將svg的座標起始點移動到容器的中心點(svg的佔位位置仍是沒有變化),而後元素再根據這個新的起始點畫出來,進行旋轉就能夠了。
四.簡單的用js操做動畫的案例
<svg width="400" height="400"> <g transform="translate(200,200)"> <rect id="rect" x="-100" y="-100" fill="green" rx="4" width="200" height="200"> <!-- <animateTransform attributeName="transform" type="rotate" form="0" to="360" begin="0" dur="5s" repeatCount="indefinite" /> --> <g> </svg> <script> var cur = 0; var rect=document.getElementById("rect"); //requestAnimationFrame調用的頻率是每秒60次逐幀動畫 var frames = window.requestAnimationFrame(doAnim); function doAnim(){ if(cur>=360){ //取消幀動畫 window.cancelAnimationFrame(frames); return; } cur++; console.log(cur); rect.setAttribute("transform", "rotate(" + cur + ")"); frames = window.requestAnimationFrame(doAnim); } </script>
參考資料:
突襲HTML5之SVG 2D入門(svg教程寫的很全,推薦指數5星)
SVG 教程(w3school的svg教程,也不錯)
mozilla svg教程(推薦給喜歡看英文教程的朋友)
知乎上面對svg的一些討論(你們在使用時,有必要能夠看一下)
推薦svg庫: