SVG學習筆錄(二)

1、svg動畫SMIL

      SVG採用的是使用文原本定義圖形,這種文檔結構很是適合於建立動畫。要改變圖形的位置、大小和顏色,只須要調整相應的屬性就能夠了。事實上,SVG有爲各類事件處理而專門設計的屬性,甚至不少仍是專門爲動畫量身定作的。在SVG中,實現動畫一般使用SVG SMIL animation。
      經過SMIL能夠實現的基本動畫:
      •動畫元素的數值屬性(X, Y, …)
      •動畫屬性變換(平移或旋轉)
      •動畫顏色屬性
      •沿着運動路徑運動(這一點很是有趣)css

  對svg動畫瀏覽器兼容狀況:html

  能夠看到ie都不支持svg動畫,移動端andriod4.1纔開始支持svg動畫。git

2、svg動畫元素

  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元素上的xy或者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表明動畫結束之後元素回到動畫前的狀態,這個是默認值。

3、svg動畫實例解析

  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 SMIL animation動畫詳解

  w3cplus大漠博客上的svg教程

  基本 SVG 動畫

  知乎上面對svg的一些討論(你們在使用時,有必要能夠看一下)

  svg動畫推薦

  svg案例

  SVG技術入門:如何畫出一條會動的線

推薦svg庫:

  Walkway

  chartist-js

  snapsvg.io

  progressbar.js

  raphaeljs

  bonsaijs

相關文章
相關標籤/搜索