SVG動畫


動畫原理

SVG動畫,就是元素的屬性值關於時間的變化。 如下圖來說,元素的某個屬性值的起始值(from)到結束值(to)在一個時間段(duration)根據時間函數(timing-function)計算出每一幀(frame)的插值(interpolation)作為變換的行為。

PS:SVG動畫是幀動畫,在SVG里也就是每秒設置多少個value值。

SVG動畫語法

SVG動畫是基於SMIL(Synchronized Multimedia Integration Language)語言的,全稱是同步多媒體集成語言。

SVG動畫使用

SVG元素使用動畫有兩種方式:

1. 被xlink:href引用

<animate  xlink:href="url(#rect1)"></animate> 

2. 包含在目標元素里

<rect  x="0"  ...>
     <animate></animate>
</rect>

<animate>標簽

該標簽用於基本動畫。

參數 描述
attributeName 要變化屬性名稱
1.可以是元素直接暴露的屬性
2.可以是CSS屬性
attributeType  用來表明attributeName屬性值的類型
支持三個固定參數,CSS/XML/auto,默認值auto。
例如:x、 y以及transform就屬於XML, opacity就屬於CSS。
from 起始值
起始值與元素的默認值是一樣的,該參數可省略。
to 結束值
by 相對from的變化值
PS:當有to值時,該值無效。
values 動畫的多個關鍵值,用分號分隔。
dur 持續時間
取值:常規時間值 | "indefinite"
repeatCount 動畫執行次數
取值:合法數值或者“indefinite”
fill 動畫間隙的填充方式
取值:freeze | remove(默認值)。
remove:表示動畫結束直接回到開始的地方。
freeze:表示動畫結束后保持了動畫結束之后的狀態。
calcMode 控制動畫的快慢
取值:discrete | linear(默認值) | paced | spline.
中文意思分別是:“離散”|“線性”|“踏步”|“樣條”。
另外,該參數要結合keyTimes、keySplines使用,數值的是對應values的,
所以如果沒有設置values和keyTime或keySplines,是沒有效果的。
begin 動畫開始的時機,取值:
time-value | offset-value | syncbase-value | event-value | repeat-value |
accessKey-value | media-marker-value | wallclock-sync-value | "indefinite"
1. time-value:動畫開始時間,可傳多個值,分號分隔。
2. syncbase-value:[元素的id].begin/end +/- 時間值(offset-value)
    某個動畫效果開始或結束觸發此動畫的,可加上偏移量。
3. event-value:事件觸發
4. repeat-value:指某animation重復多少次開始。
    語法為:[元素的id].repeat(整數) +/- 時間值
end end與begin除了名字和字面含義不一樣,其值的種類與表意都是一模一樣的。

PS:只列出常用參數,其他請查閱參考文獻。

例子:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
     <rect x="50" y ="50" width="100" height="50" fill="red">
          <animate attributeType="XML"
               attributeName="x"
               from="50"
               to="400"
               dur="5s"
               fill="freeze">
          </animate>
     </rect>
     <rect x="50" y ="150" width="100" height="50" fill="green">
          <animate attributeType="XML"
               attributeName="x"
               from="50"
               by="400"
               dur="5s"
               fill="freeze">
          </animate>
     </rect>
     <rect x="50" y ="250" width="100" height="50" fill="blue">
          <animate attributeType="XML"
               attributeName="x"
               values="50;450;50"
               dur="10s"
               >
          </animate>
     </rect>
     <rect x="50" y ="350" width="100" height="50" fill="orange">
          <animate attributeType="XML"
               attributeName="x"
               dur="10s"
               values="50;450;50"
               calcMode="spline"
               keySplines=".5 0 .5 1; 0 0 1 1"
               fill="freeze"
               >
          </animate>
     </rect>
     <rect x="50" y ="450" width="100" height="50" fill="black">
          <animate attributeType="XML"
               attributeName="x"
               from="50"
               by="400"
               dur="5s"
               calcMode="spline"
               keySplines=".5 0 .5 1; 0 0 1 1"
               fill="freeze"
               >
          </animate>
     </rect>
</svg>

效果:

begin例子:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
     <text x="50" y="30" id="t" stroke="red">click red go</text>
     <rect x="50" y ="50" width="100" height="50" fill="red">
          <animate attributeType="XML"
               attributeName="x"
               begin="t.click"
               from="50"
               to="400"
               dur="5s"
               fill="freeze">
          </animate>
     </rect>
     <rect x="50" y ="150" width="100" height="50" fill="green">
          <!--表示的是3s之后動畫開始,10s時候動畫再開始一次
               (如果之前動畫沒走完,會立即停止從頭開始)-->
          <animate attributeType="XML"
               attributeName="x"
               begin="3s;10s"
               from="50"
               to="400"
               dur="5s"
               fill="freeze">
          </animate>
     </rect>
     <rect x="50" y ="250" width="100" height="50" fill="blue">
          <animate id="goleft" attributeType="XML"
               attributeName="x"
               from="50"
               to="400"
               dur="5s"
               fill="freeze"
               >
          </animate>
          <!--注意begin的id是animate的id,不是元素的-->
          <animate attributeType="XML"
               attributeName="y"
               begin="goleft.end"
               to="350"
               dur="2s"
               fill="freeze"
               >
          </animate>
     </rect>
     <rect x="50" y ="350" width="100" height="50" fill="orange">
          <animate id="goleft" attributeType="XML"
               attributeName="x"
               from="50"
               to="400"
               dur="5s"
               fill="freeze"
               >
          </animate>
          <!--注意begin的id是animate的id,不是元素的-->
          <animate attributeType="XML"
               attributeName="y"
               to="400"
               dur="5s"
               fill="freeze"
               >
          </animate>
     </rect>
     <line stroke='black' x1="50" y1="350" x2="500" y2="350"/>
     <line stroke='black' x1="50" y1="400" x2="500" y2="400"//>
</svg>

效果:

注意:

1. 多個animate是可以疊加的。

<animateTransform>標簽

該標簽用於變換動畫,animateTransform也有animate的參數,額外的是type。

參數 描述
type 變換的類型,取值:translate、scale、rotate、skewX、skewY

例子:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="-200 -200 800 800">
     <rect x="50" y ="50" width="50" height="50" fill="red">
          <animateTransform attributeName="transform"
               attributeType="XML"
               type="rotate"
               from="0 75 75"
               to="360 75 75"
               dur="2"
               repeatCount="indefinite"/>
     </rect>
     <!--x、y都放大了-->
     <rect x="50" y ="150" width="50" height="50" fill="green">
          <animateTransform attributeName="transform"
               attributeType="XML"
               type="scale"
               from="1"
               to="2"
               dur="2"
               fill="freeze"/>
     </rect>     
     <rect x="50" y ="250" width="50" height="50" fill="blue">
          <animateTransform attributeName="transform"
               attributeType="XML"
               type="translate"
               to="250 0"
               dur="2"
               fill="freeze"/>
     </rect>
     <rect x="50" y ="150" width="50" height="50" fill="black">
          <animateTransform attributeName="transform"
               attributeType="XML"
               type="rotate"
               from="0 75 125"
               to="360 75 125"
               dur="2"
               repeatCount="indefinite" additive="sum"/>
          <animateTransform attributeName="transform"
               attributeType="XML"
               type="scale"
               from="1"
               to="2"
               dur="2"
               fill="freeze" additive="sum"/>
     </rect>
</svg>

效果:

注意:

1. animateTransform也是可以疊加的,不過要加上additive="sum",否則后面的無效了。

<animateMotion>標簽

這個標簽讓元素在路徑(Path)上滑動。

例子:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
     <path d="M100,400Q150,300 250,400 T400,400" stroke="red" fill="none"/>
     <rect width="20" height="20" fill="red">
          <animateMotion
               path="M100,400Q150,300 250,400 T400,400"
               rotate="auto"
               dur="3s"
               fill="freeze">
          </animateMotion>
     </rect>
</svg>

效果:

注意:

1. 設置rotate="auto",可以讓元素根據路徑的切線方向做旋轉。

腳本動畫

SVG的requestAnimationFrame函數可以讓我們用js來做動畫,瀏覽器對requestAnimationFrame調用的頻率是每秒60次逐幀動畫。

例子:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
     <rect id="rect" x="50" y="50" width="100" height="100" fill="green" />
</svg>
<script>
    var cur = 0;
    var rect=document.getElementById("rect");
    var frames = window.requestAnimationFrame(doAnim);
    function doAnim(){
        if(cur>=360){
            //取消幀動畫
            window.cancelAnimationFrame(frames);
            return;
        }
        cur++;
        rect.setAttribute("transform", "rotate(" + cur + ",100, 100)");
        frames = window.requestAnimationFrame(doAnim);
    }
</script>

PS:效果就是正方形旋轉360°后停止。

 

參考視頻

1. SVG課程(慕課網)

 

參考文獻

1. http://www.w3.org/TR/SVG/animate.html

2. http://www.zhangxinxu.com/wordpress/?p=4333

 

本文為原創文章,轉載請保留原出處,方便溯源,如有錯誤地方,謝謝指正。

本文地址 :http://www.cnblogs.com/lovesong/p/6011328.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM