<animate>元素用於實現動畫效果(動畫截圖比較麻煩,本文中的例子最好直接寫demo看效果)css
將<animate>元素嵌入到元素內,來實現該元素的動畫效果。svg
<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>
以上代碼會一個200*20的長方形,在5秒內漸變成一個20*20的正方形,而且在動畫結束時停留在正方形的狀態。動畫
<animate>元素的基本屬性:spa
定義發生變化的元素屬性名code
當attributeType="XML"時,attributeName被認爲是XML的屬性;當attributeType="CSS"時,attributeName被認爲是css的屬性;不指定attributeType時,默認爲"auto",會先將attributeName做爲css的屬性,若是無效,再將attributeName做爲XML的屬性。orm
from和to分別定義發生變化的屬性的初始值和終止值。from可缺省,表示初始值即爲<animate>父元素相應的屬性值。可用by替換to,表示變化偏移量。能夠理解爲to = from + by。對象
begin定義動畫開始時間;dur定義動畫所需時間;end定義動畫終止時間。時間單位h:小時;min:分鐘;s:秒;ms:毫秒。默認時間單位爲sblog
當fill="freeze"時,動畫終止時,發生變化的元素屬性值停留在動畫終止時的狀態;當fill="remove"時,動畫終止時,發生變化的元素屬性值回覆到動畫起始時的狀態。fill屬性默認值爲remove。
容許在同一個元素內嵌入多個<animate>事件
<rect x="10" y="10" width="20" height="20" style="stroke: black; fill: #cfc;"> <animate attributeName="width" attributeType="XML" begin="0s" dur="2s" from="20" to="120" fill="freeze"/> <animate attributeName="height" attributeType="XML" begin="0s" dur="2s" from="20" by="100" fill="freeze"/> </rect>
當begin設置爲一個具體時間,好比2s,svg會在元素加載完畢後,過2秒開始執行動畫。
begin還能夠指定一個其餘<animate>的begin或者end,好比:ip
<circle cx="60" cy="60" r="30" style="fill: #f9f; stroke: gray;"> <animate id="c1" attributeName="r" attributeType="XML" begin="0s" dur="4s" from="30" to="10" fill="freeze"/> </circle> <circle cx="120" cy="60" r="10" style="fill: #9f9; stroke: gray;"> <animate attributeName="r" attributeType="XML" begin="c1.end" dur="4s" from="10" to="30" fill="freeze"/> </circle>
第二個圓的動畫執行起始時間爲第一個圓動畫執行完畢時間。
begin屬性還能夠進行簡單計算:
begin="c1.end+1.5s":表示動畫執行起始時間爲第一個圓執行完畢後的1.5秒。
當end設置爲一個具體時間,好比2s,svg會在元素加載完畢後,過2秒即中止執行動畫,無論這個元素的動畫是否執行完畢。若是end設置的比begin小,則動畫根本不會執行。
end一樣能夠指定一個其餘<animate>的begin或者end,一樣支持計算。
經過設置repeatDur或者repeatCount屬性,讓動畫重複執行。
設置動畫執行的總時長。在repeatDur設置的時間內,動畫一直會重複執行。若是repeatDur小於dur,repeatDur的做用與end同樣。
設置動畫重複執行的次數。
repeatDur和repeatCount均可以經過設置爲indefinit實現無限循環動畫。
當repeatDur和repeatCount同時做用於同一個<animate>時,動畫終止時間取二者中較小值。
repeat可做爲begin和end中的參數使用:
<circle cx="60" cy="60" r="15" style="fill: none; stroke: red;"> <animate id="circleAnim" attributeName="cx" attributeType="XML" begin="0s" dur="5s" repeatCount="3" from="60" to="260" fill="freeze"/> </circle> <rect x="230" y="80" width="30" height="30" style="fill: #ccf; stroke: black;"> <animate attributeName="x" attributeType="XML" begin="circleAnim.repeat(1)+2.5s" dur="5s" from="230" to="30" fill="freeze"/> </rect>
長方形的動畫會在圓形動畫執行過一遍後延遲2.5秒後開始執行。
repeat(n)中的n需大於0。
動畫還可做用於顏色、paths、d等非純數字屬性。
顏色的動畫過程能夠分解成r,g,b,a四個數字的漸變。好比從#f00變化到#0f0,紅色部分從1漸變到0,綠色部分同時從0漸變到1。
paths和d要實現動畫有一個前提,其參數個數不能變。變化先後參數一一對應,全部參數同時漸變。
<polygon points="30 30 70 30 90 70 10 70" style="fill:#fcc; stroke:black"> <animate id="animation" attributeName="points" attributeType="XML" to="50 30 70 50 50 90 30 50" begin="0s" dur="5s" fill="freeze"/> </polygon> <path d="M15 50 Q 40 15, 50 50, 65 32, 100 40" style="fill:none; stroke: black" transform="translate(0,50)"> <animate attributeName="d" attributeType="XML" to="M50 15 Q 15 40, 50 50, 32 65, 40 100" begin="0s" dur="5s" fill="freeze"/> </path>
實現一個屬性的連續變化有兩種方式:
基礎動畫中提到過多<animate>組合方式;這裏說下values + keyTimes + calcMode。
values屬性值表示一個動畫通過的節點數值,數值間以分號分割。
<circle cx="175" cy="75" r="20" fill="red"> <animate attributeName="r" attributeType="XML" values="20;50;20" begin="0" dur="1" repeatCount="indefinite" fill="freeze"></animate> </circle>
上例中1秒內,圓的半徑由20變爲50,再由50變爲20。
keyTimes屬性值與values屬性值一一對應,第一個數值永遠是0(表示起始時間點),最後一個數值永遠是1(表示終止時間點),中間的數值表示變化到對應values屬性值時所處時間點百分比(0~1之間)。
<circle cx="175" cy="75" r="20" fill="red"> <animate attributeName="r" attributeType="XML" values="20;50;20" keyTimes="0;0.2;1" begin="0" dur="1" repeatCount="indefinite" fill="freeze"></animate> </circle>
上例中0.2秒時圓的半徑由20變爲50,在以後的0.8秒又從50變爲20。
calcMode能夠影響動畫各階段的表現。calcMode有四種屬性值:paced, linear, discrete, spline
calcMode="paced"時,動畫會忽略keyTimes屬性,根據values數值以勻速變化。
calcMode="linear"時,動畫根據values和keyTimes屬性,在每一個時間段內勻速變化。linear爲calcMode的默認屬性值。
calcMode="discrete"時,動畫根據values和keyTimes屬性,去掉過分動畫,到了keyTimes的某個節點,屬性值直接變爲values對應數值。
calcMode="spline"時,須要配合keySplines屬性,設置每一個時間段內的三次貝塞爾變化曲線。
<circle cx="175" cy="75" r="20" fill="red"> <animate attributeName="r" attributeType="XML" values="20;50;20" keyTimes="0;.15;1" calcMode="spline" keySplines=".5 0 .5 1;.5 0 .5 1" begin="0" dur="1" repeatCount="indefinite" fill="freeze"></animate> </circle>
上例中加上貝塞爾曲線後圓形的變化有點相似心跳的節奏。
<set>元素也可設置屬性變化的動畫,但與<animate>有明顯區別:
<text text-anchor="middle" x="60" y="60" style="visibility: hidden;"> <set attributeName="visibility" attributeType="CSS" to="visible" begin="1s" dur="10s" fill="freeze"></set> <set attributeName="x" attributeType="XML" to="120" begin="2s" dur="10s" fill="freeze"></set> All gone! </text>
上例中1秒後顯示All gone!,再過1秒後文字移動至(120,60)。
要實現transform屬性改變的動畫,須要使用<animateTransform>來替代<animate>。
<rect x="-10" y="-10" width="20" height="20" style="fill: #ff9; stroke: black;"> <animateTransform id="a1" attributeName="transform" attributeType="XML" type="scale" from="1" to="4 2" additive="sum" begin="0s" dur="4s" fill="freeze"></animateTransform> <animateTransform attributeName="transform" attributeType="XML" type="rotate" from="0" to="45" additive="sum" begin="a1.end" dur="4s" fill="freeze"></animateTransform> </rect>
<animateTransform>的attributeName指定爲transform(我的感受有點多餘,animateTransform自己就是應用於改變transform屬性值的)。用type屬性指定transform須要改變的屬性(translate, scale, rotate, skewX, skewY)。
<animateTransform>還有個additive屬性。上例中兩個<animateTransform>同時做用於一個<rect>元素,默認狀況下additive屬性值爲replace,表示當前<animateTransform>的初始狀態與以前的<animateTransform>變化結果無關。若是additive="sum",表示當前<animateTransform>的變化基於以前的<animateTransform>變化之上。
上例結果:
(剛看到一個長方形使用rotate會變成一個菱形感受哪裏不對,再回想了一下translate的本質和形變的次序,就明瞭了)
<animateMotion>是個很強大的元素,以前全部動畫功能在css裏均可以用animation實現,但<animateMotion>能實現的功能是單憑css沒法實現的。
<animateMotion>可讓父元素沿着指定的路徑運動!
直線路徑能夠簡單使用from + to屬性來指定起點和終點:
<g> <rect x="0" y="0" width="50" height="30" style="fill: #ccc;"/> <circle cx="40" cy="30" r="10" style="fill: #cfc; stroke: green;"/> <circle cx="10" cy="30" r="10" style="fill: #cfc; stroke: green;"/> <animateMotion from="0,0" to="60,30" dur="4s" fill="freeze"/> </g>
也能夠實用path指定複雜的路徑
<g> <rect x="0" y="0" width="50" height="30" style="fill: #ccc;"/> <circle cx="40" cy="30" r="10" style="fill: #cfc; stroke: green;"/> <circle cx="10" cy="30" r="10" style="fill: #cfc; stroke: green;"/> <animateMotion path="M50,125 C 100,25 150,225, 200, 125" dur="4s" fill="freeze"/> </g>
也能夠指定<path>元素做爲本身的路徑
<path id="cubicCurve" d="M50,125 C 100,25 150,225, 200, 125"/> <g> <rect x="0" y="0" width="50" height="30" style="fill: #ccc;"/> <circle cx="40" cy="30" r="10" style="fill: #cfc; stroke: green;"/> <circle cx="10" cy="30" r="10" style="fill: #cfc; stroke: green;"/> <animateMotion dur="6s" fill="freeze"> <mpath xlink:href="#cubicCurve"/> </animateMotion> </g>
<animateMotion>有個rotate屬性,默認爲0,元素在運動時不會旋轉。當設置爲auto時,元素對應的水平軸會始終與path路徑保持水平,上圖中加上rotate="auto"後的效果就像是車子開過山坡。
與多節點動畫相似,<animateMotion>也有三個屬性用於控制動畫的節點。
第一個屬性值爲0(表示path路徑的起始位置),最後一個屬性值爲1(表示path路徑的終點位置),各屬性值用分號分割,每一個屬性值與keyTimes的屬性值一一對應,表示到某個時點運動到相對於路徑的哪一個位置。
第一個屬性值爲0(表示動畫起始時間),最後一個屬性值爲1(表示動畫終止時間),各屬性值用分號分割,每一個屬性值與keyPoints的屬性值一一對應,表示運動到某個位置須要的總動畫時常佔比。
與多節點動畫中的calcMode屬性值及做用徹底一致。
<path d="M-10,-3 L10,-3 L0,-25z" style="fill: yellow; stroke: red;" > <animateMotion path="M50,125 C 100,25 150,225, 200, 125" rotate="auto" keyPoints="0;0.2;0.8;1" keyTimes="0;0.33;0.66;1" calcMode="linear" dur="6s" fill="freeze"/> </path>
css中有兩種實現動畫的方式:transition和animation。
transition用於實現較簡單的兩點動畫,即根據屬性的起始狀態和終止狀態,完整中間過渡動畫。
transition動畫相關的css屬性以下
定義動畫屬性,可定義多個屬性,逗號分隔
定義動畫執行時間,單位(s,ms),可定義多個屬性,與transition-property一一對應,逗號分隔
與calcMode相似,影響動畫的表現。默認值爲ease。可選項有:ease | linear | ease-in | ease-out | ease-in-out | step-start | step-end | steps(<integer>[, [ start | end ] ]?) | cubic-bezier(<number>, <number>, <number>, <number>)
定義動畫延遲多少時間後開始執行
其中transition-timing-function中的step-start、step-end和steps有點相似calcMode中的discrete模式,狀態之間切換沒有中間過渡。具體來講stepts(<integer>[, [start | end]])的第一個參數必須爲正整數,表示分幾步變化,第二個參數設置爲start時,表示在動畫開始執行時就進行變化,設置爲end表示在動畫通過transition-duration設置的時間纔開始變化,第二個參數容許省略,缺省值爲end。step-start至關於steps(1, start)即屬性一開始就變爲最終狀態;step-end至關於steps(1,end)即屬性通過transition-duration設置的時間後馬上變爲終止狀態。
#car{ transition-property:width, height; transition-duration:1s, 3s; transition-timing-function: ease-in, cubic-bezier(1,0,0,1); transition-delay:2s, 0.5s; }
可以使用transition縮寫簡化上例中的css,直接從W3C規範裏抄了下縮寫組成部分。
transition:<single-transition> [ ‘,’ <single-transition> ]* <single-transition> = [ none | <single-transition-property> ] || <time> || <single-transition-timing-function> || <time>
第一個<time>對應transition-duration,第二個<time>對應transition-delay。
若是有一個<single-transition>裏的第一個參數設置爲none,則整個transition無效。也就是說none只能這麼用:transition:none
#car{ transition:width 1s ease-in 2s, height 3s cubic-bezier(1,0,0,1) .5s; }
animation能夠說是transition的高級版,配合@keyframes能夠實現對動畫過程的多點控制。除了svg中延指定path路徑運動的動畫實現不了,其餘均可以用animation來實現。其不少屬性與svg的<animate>元素屬性做用也能一一對應。
先看下animation的屬性
對應<animate>的attributeName屬性,屬性值爲@keyframes名對應,後面再說@keyframes
對應<animate>的dur屬性
對應<animate>的calcMode屬性,可用三次貝塞爾曲線來設置動畫運行的效果
對應<animate>的repeatCount屬性。默認爲1。infinite表示無限重複(不一樣於repeatCount的indefinte)
動畫延遲執行時間。有點相似<animate>的start屬性的做用,用start加上一些事件和時間的計算,也能夠實現延遲執行動畫的效果
相似<animate>的fill屬性,但有區別。animation-fill-mode有四個屬性值可選:none | forwards | backwards | both。
- **forwards** 相似fill的freeze,動畫結束後保持最後一幀時的狀態。 - **backwards** 這個功能svg裏好像沒有。backwards是配合animation-delay一塊兒使用的,若是動畫延遲執行,那麼在開始執行以前處於延遲的這段時間內,動畫對象元素的默認狀態是其原始狀態,而非@keyframes的起始狀態。當animation-fill-mode設置成backwards時,動畫對象元素在延遲的這段時間內,將處於@keyframes設置的起始狀態。 - **both** 至關於同時設置了forwards和backwards兩個屬性值。 - **none** none是animation-fill-mode的默認屬性值,即動畫開始前和動畫結束後,對象元素均處於其原始狀態。
animation-play-state顧名思義控制動畫狀態的,兩個屬性值也好理解。
- **running** 表示讓動畫執行 - **paused** 表示暫停動畫 能夠經過改變這個屬性來控制動畫的播放和暫停,pause改成running後不會讓元素重頭再執行一遍動畫,而是接着暫停時的狀態繼續變化。
這個屬性用於控制動畫是正向執行,或者反向執行,若是設置了animation-iteration-count重複執行次數,還能控制一次動畫執行完畢後,以何種方式執行接下去的一次動畫。有四個屬性值normal | reverse | alternate | alternate-reverse
- **normal** 默認屬性值,動畫正向執行,重複執行動畫時,每次都從起始狀態開始變化。 - **reverse** 動畫反向執行,即從指定的終止狀態變化到起始狀態,重複執行動畫時,每次都從終止狀態開始變化。其中animation-timing-function設置的運動曲線也會被顛倒,原來的ease-in會變成ease-out的效果。 - **alternate** 第一次執行動畫時,從起始狀態開始變化。重複執行動畫時,單次動畫結束後,下一次動畫以當前狀態做爲起始狀態開始變化,以上一次動畫的起始狀態做爲該次動畫的終止狀態,至關於執行一次reverse的動畫效果。 - **alternate-reverse** 和alternate相似,可是第一次執行動畫時,從指定的結束狀態開始向起始狀態變化。
能夠用animation來縮寫以上全部屬性:
animation:<single-animation> [ ‘,’ <single-animation> ]* <single-animation> = <single-animation-name> || <time> || <single-animation-timing-function> || <time> || <single-animation-iteration-count> || <single-animation-direction> || <single-animation-fill-mode> || <single-animation-play-state>
其中第一個<time>爲animation-duration,第二個<time>爲animation-delay。
再來看與animation緊密相關的@keyframes
@keyframes的做用相似values + keyTimes,可精細設置動畫過程當中每一個變化節點。
@keyframes必須包含一個動畫起始狀態信息,和一個動畫終止狀態信息。能夠用from + to,也能夠用0% + 100%:
@keyframes rotate1{ from { left: 0; top: 0; } to { left: 100px; top: 100px; } } @keyframes rotate2{ 0% { left: 0; top: 0; } 100%{ left: 100px; top: 100px; } }
以上兩段代碼等價,都表示起始狀態的left和top屬性爲0,終止狀態的left和top屬性爲100px。
對於中間動畫節點,好比在動畫進行到四分之一時,但願left爲50px:
@keyframes rotate2{ 0% { left: 0; top: 0; } 50%{ left: 50px; } 100%{ left: 100px; top: 100px; } }
另外,還能夠對每段動畫的變化曲線作單獨設置animation-timing-function屬性,屬性須要設置在起始狀態信息中:
@keyframes rotate2{ 0% { left: 0; top: 0; animation-timing-function: ease-out; } 50%{ left: 50px; animation-timing-function: ease-in; } 100%{ left: 100px; top: 100px; } }