SMILによるSVGアニメーション

SMILはSynchronized Multimedia Integration Languageの略で、SVGのアニメーション機能です。
※IEはSMILをサポートしていません。

SMIL以外の方法でのSVGアニメーションはこちらをご参照ください。
[SVGのアニメーション方法の比較](https://qiita.com/takeshisakuma/items/270bc3b7ace61f50ce48)

## 主なタグ(3種類)
- animate
- animateTransform
- animateMotion


## animate
### 単純なアニメーション
キーフレームが始点と終点のみのアニメーションに使います。

```:svg
<svg width="600" height="600" viewBox="0, 0, 600, 600" xmlns="http://www.w3.org/2000/svg">
  
  <circle cx="10" cy="10" r="10" fill="#3498db">
    <animate attributeType="XML" attributeName="cx" dur="5s" from="0" to="600" repeatCount="indefinite" />
  </circle>
  
</svg>
```

|animateタグの属性|内容|
|---|---|
|attributeType|attributeNameの対象の種類の指定(XML/CSS)|
|attributeName|アニメーションの対象となる属性|
|dur|アニメーションの1回のループにかける時間|
|repeatCount|リピート回数の指定(0以上の数/indefinite)|
|from|初期値(省略時はアニメーション適用前の値)|
|to|目標値|
|by|目標値(初期値から相対で指定)|

### キーフレームアニメーション
キーフレームが3点以上のアニメーションにも対応可能です。
from/to/byの代わりにvaluesで各時点での値をコロン区切りで指定します。

### プロパティのアニメーション

```:svg
<svg width="600" height="600" viewBox="0, 0, 600, 600" xmlns="http://www.w3.org/2000/svg">
 
  <circle cx="0" cy="10" r="10" fill="#27ae60" >
  　 <animate attributeType="XML" attributeName="cx" dur="5s" values="0;10;20;30;600" repeatCount="indefinite" />
  </circle>
   
</svg>
```

### モーフィング

「d=”~”」の箇所を「value=”~”」に入れます。
pathの区切りは「;」です。
アニメーション開始時と終了時のpath要素(d属性の内容)の形式(コマンドの種類や数)が一致していなければいけないので、path要素に変更する必要があります。
コマンドの種類や数が一致していない場合、滑らかな動きにはなりません。


```:svg
<svg width="600" height="600" viewBox="0, 0, 600, 600" xmlns="http://www.w3.org/2000/svg">
  
  <path fill="#27ae60" d="M 0,0 L 100,0 600,600 0,100">
    <animate attributeType="XML" attributeName="d" dur="6s" repeatCount="indefinite" 
      values="
        M 0,0 L 100,0 600,600 0,100;
        M 0,0 L 600,100 100,100 100,600;
        M 0,0 L 100,0 600,600 0,100"/>
  </path>
  
</svg>
```

## animateTransform
transform属性はanimateタグが使えないので、代わりにanimateTransformタグを使います。

|タグ|type属性|
|---|---|
|animate|type属性不要|
|animateTransform|type属性必要|


#### type="translate"
平行移動のアニメーションです。
値の形式：X、Y座標を空白・コンマ区切りで並べます。

```:svg
<svg width="600" height="600" viewBox="0, 0, 600, 600" xmlns="http://www.w3.org/2000/svg">
  
  <circle cx="10" cy="10" r="10" fill="#27ae60">
    <animateTransform attributeName="transform" attributeType="XML" type="translate" dur="6s" repeatCount="indefinite" values="10,10; 20,10; 600,10" />                            
  </circle>
  
</svg>    
```


#### type="scale"
拡大・縮小のアニメーションです。
値の形式：X方向、Y方向の倍率を空白・コンマ区切りで並べます。
拡大・縮小の中心は原点です。

```:svg
<svg width="600" height="600" viewBox="0, 0, 600, 600" xmlns="http://www.w3.org/2000/svg">
      
  <circle cx="100" cy="100" r="50" fill="#27ae60">
    <animateTransform attributeName="transform" attributeType="XML" type="scale" values="1 1; 2 1;1 1;" dur="6s" repeatCount="indefinite" />
  </circle>
  
</svg>
```

#### type="rotate"
回転のアニメーションです。
値の形式：回転角、回転中心のX、Y座標を空白・コンマ区切りで並べます。
回転の中心が指定できます。

```:svg
<svg width="600" height="600" viewBox="0, 0, 600, 600" xmlns="http://www.w3.org/2000/svg">
      
  <rect x="100" y="100" width="50" height="50" fill="#27ae60">
    <animateTransform attributeName="transform" attributeType="XML" type="rotate" values="0 100,100;360 100,100" dur="6s" repeatCount="indefinite" />
  </rect>
  
</svg>    
```

#### type="skewX"、type="skewY"
せん断変形のアニメーションです。
値は軸の回転角です。
変換の中心は原点です。

```:svg
<svg width="600" height="600" viewBox="0, 0, 600, 600" xmlns="http://www.w3.org/2000/svg">
  
  <circle cx="200" cy="100" r="50" fill="#27ae60">
    <animateTransform attributeName="transform" attributeType="XML" type="skewX"  values="30; -30; 30" dur="6s" repeatCount="indefinite" />
  </circle>
   
</svg>
```




## animateMotion
パスで定義した軌跡をなぞって移動するアニメーションです。
animateタグとの違い　from/to/byやvalues属性は指定できません。

### rotate属性
回転処理の指定を行います。

|値|内容|
|---|---|
|数値を指定|対象の図形を回転される角度を指定|
|auto|X軸が移動方向を向くように自動的に回転|
|auto-reverse|反対を向くように自動的に回転|

```:svg
<svg width="600" height="600" viewBox="0, 0, 600, 600" xmlns="http://www.w3.org/2000/svg">
      
  <rect x="0" y="0" width="10" height="5" fill="#27ae60">
    <animateMotion dur="6s" repeatCount="indefinite" path="M 10,40 c 0,-80 580,80 580,0 s -580,80 -580,0" rotate="auto-reverse"/>
  </rect>
   
</svg>
```

### キーフレームの制御
values属性によるアニメーションです。

#### calcMode属性
##### linear(デフォルト)
各キーフレーム間を一定の変化量で補完します。

```:svg
<svg width="600" height="600" viewBox="0, 0, 600, 600" xmlns="http://www.w3.org/2000/svg">
  
  <circle cx="0" cy="10" r="10" fill="#27ae60" >
    <animate attributeType="XML" attributeName="cx" dur="5s" values="0;100;200;400;500;550;600" repeatCount="indefinite" calcMode="linear"/>
  </circle>
  
</svg>
```

##### discrete
補完処理を行いません。

```:svg
<svg width="600" height="600" viewBox="0, 0, 600, 600" xmlns="http://www.w3.org/2000/svg">
  
  <circle cx="0" cy="10" r="10" fill="#27ae60">
    <animate attributeType="XML" attributeName="cx" dur="5s" values="0;100;200;400;500;550;600" repeatCount="indefinite" calcMode="discrete"/>
  </circle>
  
</svg>
```

##### spline
三次ベジェ曲線による補完
keySplines属性でベジェ曲線の制御点の指定が必要
値：空白・コンマ区切りの数値4つ「x1,y1 x2,y2」(コロン区切り)
数：キーフレームの数-1

```:svg   
<svg width="600" height="600" viewBox="0, 0, 600, 600" xmlns="http://www.w3.org/2000/svg">
 
  <circle cx="0" cy="10" r="10" fill="#27ae60">
    <animate attributeType="XML" attributeName="cx" dur="5s" values="0;100;200;400;500;550;600" repeatCount="indefinite" calcMode="spline" keySplines="01,01 0.1,0.1;0.2,0.2 0.2,0.2;0.3,0.3 0.3,0.3;0.4,0.4 0.4,0.4;0.5,0 0.5,0.5;0.6,0.6 0.6,0.6"/>    
  </circle>
  
</svg>
```

##### paced
区間の距離と関係なくアニメーション全体にわたって一定の速度で移動

```:svg
<svg width="600" height="600" viewBox="0, 0, 600, 600" xmlns="http://www.w3.org/2000/svg">
 
  <circle cx="0" cy="10" r="10" fill="#27ae60">
    <animate attributeType="XML" attributeName="cx" dur="5s" values="0;100;200;400;500;550;600" repeatCount="indefinite" calcMode="paced"/>
  </circle>
  
</svg>
```

#### keyTimes属性
区間ごとの時間の調整を明示的に行う
値：開始時点を0.0、終了時点を1.0とした小数(セミコロン区切り)
数：keyTimes属性に指定する値の数はvaluesと同じ

```:svg
<svg width="600" height="600" viewBox="0, 0, 600, 600" xmlns="http://www.w3.org/2000/svg">
 
  <circle cx="0" cy="10" r="10" fill="#27ae60">
    <animate attributeType="XML" attributeName="cx" dur="5s" values="0;100;200;400;500;550;600" repeatCount="indefinite" keyTimes="0;0.1;0.2;0.3;0.4;0.5;1"/>
  </circle>
  
</svg>
```

#### keyPoints属性
calcMode属性とkeyTimes属性をanimateTransformとanimateMotionに使う場合、モーションパス上にキーフレームが存在しないので、キーフレームを設定するために指定します。
値：モーションパス全体の長さを1.0として指定(セミコロン区切り)
数：keyTimes属性に指定する値の数はkeyPointsと同じ

```:svg
<svg width="600" height="600" viewBox="0, 0, 600, 600" xmlns="http://www.w3.org/2000/svg">
 
  <circle cx="0" cy="10" r="10" fill="#27ae60">
    <animateMotion attributeType="XML" dur="6s" repeatCount="indefinite" path="M 10,10 l 550,10 10,550 Z" calcMode="linear" keyPoints="0; 0.5; 1" keyTimes="0; 0.2; 1" />
  </circle> 
   
</svg>
```



### 開始トリガー
|開始/終了トリガー|内容|
|---|---|
|begin属性|開始トリガーのカスタマイズ　|
|end属性|終了トリガーのカスタマイズ|
※begin属性とend属性の指定方法は同じです。

#### begin属性/end属性
begin/endタグにはセミコロン区切りで複数のトリガーを併記できます。

|begin属性、end属性の値|内容|
|---|---|
|indefinite|デフォルト動作をしない|
|アニメーションのID.イベント名(±時間)|指定したタグで指定したイベントが発生した際にアニメーションを開始|
|アニメーションタグのID.repeat(n)(±時間)|特定のリピートの開始をトリガーにする|


#### fill属性
アニメーション終了後の状態を選択します。

|fill属性の値|内容|
|---|---|
|remove(デフォルト)|元の値を復帰する|
|freeze|アニメーション終了時の値を維持する|

### 時間経過をトリガーにする
begin属性に時間指定を記述します。(マイナスも指定可)

```:svg
<svg width="600" height="600" viewBox="0, 0, 600, 600" xmlns="http://www.w3.org/2000/svg">
   
  <rect x="10" y="10" width="100" height="100" fill="#27ae60">
    <animate attributeType="XML" attributeName="x" dur="10s" values="10; 290; 10" repeatCount="indefinite" /> 
  </rect>
 
  <rect x="10" y="210" width="100" height="100"  fill="#f39c12">
    <animate attributeType="XML" attributeName="x" dur="10s" values="10; 290; 10" begin="1s" repeatCount="indefinite" />
  </rect>
      
</svg>
```     

#### 他のアニメーションの開始、終了をトリガーにする
begin属性に「アニメーションのID.begin||end (± 時間)」を指定します。

```:svg
<svg width="600" height="200" viewBox="0, 0, 600, 200" xmlns="http://www.w3.org/2000/svg">
  
  <circle cx="10" cy="10" r="10" fill="#e74c3c">
    <animate attributeType="XML" attributeName="cx" dur="2s" from="10" to="590" id="anime1" begin="0s; anime4.end+1s" fill="freeze" />
    <animate attributeType="XML" attributeName="cx" dur="2s" from="590" to="10" id="anime3" begin="anime2.end+1s" fill="freeze" />
  </circle> 
      
  <circle cx="10" cy="50" r="10" fill="#2980b9">
    <animate attributeType="XML" attributeName="cx" dur="1s" from="10" to="590" id="anime2" begin="anime1.end+1s" fill="freeze" />
    <animate attributeType="XML" attributeName="cx" dur="1s" from="590" to="10" id="anime4" begin="anime3.end+1s"  fill="freeze"/>
  </circle>
          
</svg>
```


#### リピート回数をトリガーにして値を変更

##### setタグ
トリガーを受けて、一度だけto属性の値を対象の属性に設定します。

```:svg
<svg width="600" height="200" viewBox="0, 0, 600, 200" xmlns="http://www.w3.org/2000/svg">
  
  <circle cx="40" cy="40" r="10" fill="#27ae60">
    <animate repeatCount="3" attributeType="XML" attributeName="cx" dur="3s" values="40; 560;" id="move" begin="0s;move.end"/>   
      <set attributeType="XML" attributeName="r" begin="move.repeat(1)" to="20" />
      <set attributeType="XML" attributeName="fill" begin="move.repeat(1)" to="#3498db" />
      <set attributeType="XML" attributeName="r" begin="move.repeat(2)" to="40" />
      <set attributeType="XML" attributeName="fill" begin="move.repeat(2)" to="#34495e" />
  </circle>
     
</svg>
```




#### ユーザーの操作をトリガーにする

##### restart属性
2回目以降の開始トリガーの処理を指定します。

|restartの値|内容|
|---|---|
|always(デフォルト|常に開始する|
|whenNotActive|アニメーション中でなければ開始する|
|never|2回目以降は開始しない|

```:svg
<svg width="600" height="200" viewBox="0, 0, 600, 200" xmlns="http://www.w3.org/2000/svg">
  
  <circle cx="20" cy="20" r="20" fill="#27ae60">
    <animate attributeType="XML" attributeName="cx" dur="1s" values="20; 580" begin="move.click"/>
  </circle>
 
  <circle cx="318" cy="100" r="30" id="move" fill="#f1c40f" />
  <text x="300" y="105" pointer-events="none" fill="#fff">
    push
  </text>
     
</svg>
```


## 複数プロパティのアニメーション

```:svg
 <svg width="600" height="200" viewBox="0, 0, 600, 200" xmlns="http://www.w3.org/2000/svg">
   <circle cx="40" cy="40" r="20" fill="#3498db">
   <animate attributeType="XML" attributeName="cx" dur="3s" values="40;560;" repeatCount="indefinite" />
    <animate attributeType="XML" attributeName="r" dur="3s" values="20;40;" repeatCount="indefinite" />
    <animate attributeType="XML" attributeName="fill" dur="3s" values="#2ecc71;#8e44ad;" repeatCount="indefinite" />
  </circle>
</svg>
```

### additive属性
アニメーションで計算された値を属性値に反映させる処理を指定します。
animateTransformタグの変形アニメーションは移動・回転・スケーリング・せん断が全部transform属性なので「additive="sum"」の指定が必要です。

|additiveの値|内容|
|---|---|
|replace(デフォルト)|上書き|
|sum|元の値に加算|

```:svg
<svg width="600" height="200" viewBox="0, 0, 600, 200" xmlns="http://www.w3.org/2000/svg">
  
  <rect x="20" y="20" width="40" height="40" fill="#3498db">
    <animateTransform attributeName="transform" attributeType="XML" type="translate" values="40,60; 520,60;" dur="3s" repeatCount="indefinite" additive="sum"/>
    <animateTransform attributeName="transform" attributeType="XML" type="rotate" from="0 15,15" to="360 15,15" dur="3s" repeatCount="indefinite" additive="sum" />
  </rect>
         
</svg>
```

### accumulate属性
アニメーションのリピート時の動作を指定します。

|accumulateの値|内容|
|---|---|
|replace(デフォルト)|上書き|
|sum|前回のアニメーション終了位置から続ける|

```:svg
<svg width="600" height="200" viewBox="0, 0, 600, 200" xmlns="http://www.w3.org/2000/svg">
  
  <rect x="20" y="20"  width="40" height="40" fill="#3498db">
    <animate attributeType="XML" attributeName="x" dur="1s" values="0; 100" id="move" begin="0s; move.end" repeatCount="4" accumulate="replace" />
  </rect>

  <rect x="20" y="80"  width="40" height="40" fill="#e74c3c">
    <animate attributeType="XML" attributeName="x" dur="1s" values="0; 100" id="move" begin="0s; move.end" repeatCount="4" accumulate="sum" />
  </rect>
     
</svg>
```