SVGアニメーション(SMIL)の備忘録

SVGをアニメーションする方法

  • CSSのアニメーションやトランジションをつかう(SVG要素にidやclassをつけます)
  • JavaScriptをつかって制御する
  • SMILをつかうアニメーション(アニメーションさせるSVG要素に直接書きます)
    *SMILは、ブラウザー上で「テキスト・画像・動画など」の「時間や位置」を指定して表示できる「XMLベースのマークアップ言語」です
    *IEは非対応

SMILをつかうSVGアニメーションのまとめです
HTMLだけでアニメーションができ、お手軽でコンパクトです^^

目次
  1. アニメーションの要素
    1. animate
    2. animateTransform
    3. animateMotion
    4. set
  2. キーフレームのアニメーション
  3. 線のアニメーション
  4. その他

アニメーションの要素

アニメーション要素

  • animate
  • animateTransform
  • animateMotion
  • set

「アニメーションする要素」と「アニメーション要素」を関連づけする方法は「2通り」あります

  • 「アニメーションする要素」に「id 属性」を指定し「アニメーション要素のxlink:href属性」で「id名を参照する」
  • 「アニメーション要素」を「アニメーションをさせたい要素の子要素にする」
 <!--id名を参照する -->
<circle id="id名" cx="0" cy="50" r="15" fill="blue"/>
<animate xlink:href="id名" 省略 />

 <!--子要素にする -->
<circle id="id名" cx="0" cy="50" r="15" fill="blue">
  <animate 省略/>
</circle>

タイミングの属性

dur
アニメーションの時間
初期値は不定の時間です
1秒は”1s”
repeatCount
アニメーションを繰り返しの回数(数値)
*初期値なし
indefinite:無限に繰り返す
repeatDur
アニメーションを繰り返すための合計時間(数値s)
*初期値なし
indefinite:無限に繰り返す
begin
アニメーション開始のタイミング
初期値は「0」
秒数を指定しますが、clickなどのイベントも指定できます
fill
アニメーションの最終の状態を指定します
初期値は「remove」
freeze : 最後のアニメーションの状態
remove : 最初のアニメーションの状態
end
アニメーション終了のタイミング
初期値なし
秒数を指定しますが、clickなどのイベントも指定できます
min
アニメーション時間の最小値
初期値は「0」
max
アニメーション時間の最大値
初期値なし
restart
アニメーションを再開できるかどうかを指定します
初期値はalwaysです
always : いつも再開できる
whenNotActive : アニメーションがアクティブでない場合のみ再開できる
never : 再開できない

JavaScriptを使わなくてもクリックなどのイベントで動くアニメーションができます
begin="click"を要素の属性につけるだけです

また「beginとend属性」は、他のアニメーションの状態をトリガーにすることができます

その他おもなイベント

イベント発生する状況
click
mousedown
mouseup
マウスボタンがクリックされ離れたとき
マウスボタンがクリックされたとき
マウスボタンが離されたとき
mouseover
mouseenter
マウスポイントが要素にのる
(バブリングしない)
mouseout
mouseleave
マウスポイントが要素から離れる
(バブリングしない)
mousemove要素内のすべてのマウス移動で発生

「beginとend属性」の値について

  • 他の要素のイベントをトリガーにする:他の要素のid.イベント名
  • 他の要素の開始をトリガーにする:他の要素のid.begin
  • 他の要素の終了をトリガーにする:他の要素のid.end
  • begin="click + 3s"でクリックして3秒後
    begin="他の要素のid.begin + 3s"で他の要素の開始から3秒後
  • 「;」で区切ると「または」になます
    例えばbegin="click;3s"はクリックされるか3秒後

などの設定ができます

animate

<animate>要素は、時間の経過に応じて要素の属性を変化させます

<animate>要素は、「アニメーションの対象となる属性」ごとに必要です

animateの重要な属性

attributeName
「アニメーションの対象となる属性」
from
「アニメーションの対象となる属性」の最初の値
to
「アニメーションの対象となる属性」の最後の値
<circle cx="0" cy="50" r="15" fill="blue">
 <animate attributeName="cx" from="0" to="100" dur="5s" repeatCount="indefinite" />
 <animate attributeName="r" from="0" to="50" dur="5s" repeatCount="indefinite" />
</circle>

animateTransform

<animateTransform>要素は、トランスフォームのアニメーションをするときにつかいます
*「移動(translate)・拡大・縮小(scale )・回転(rotate)・ 傾斜(skewX skewY)」

SVGは3Dに対応していないので、Z軸を使うときは、CSSをつかいます

<animateTransform>要素に「attributeName=”transform”」と「type属性にトランジションのタイプ」を指定します

<animatetransform attributeName="transform" type="トランジションのタイプ" 省略/>

トランジションのタイプ

translate(x [,y])
X軸(Y軸)に指定した距離を移動します
yを省略したときはY軸は0です
scale(x [,y])
比率で拡大・縮小します
yを省略したときはxと同じ値です(同じ比率)
「1」が等倍です
rotate(角度 [,x, y])
指定された角度を時計まわりに回転します
[,x, y]は、回転の中心になる座標です
[,x, y]を省略したときは要素の左上「0 0」が中心になります
skewX(角度)
X軸に対する傾斜角度
skewY(角度)
Y軸に対する傾斜角度
<rect x="100" y="100" width="100" height="100">
     <animateTransform
       attributeName="transform"
       type="rotate"
       dur="5s"
       from="0 150 150"
       to="360 150 150"
       repeatCount="indefinite"
      />
</rect>

animateMotion

<animateMotion>要素は、モーションパスに沿って移動するアニメーションを指定します

モーションパスに沿って移動する動作は、CSSアニメーションではできません

path属性
モーションパスを指定します
「path属性の値」は、「path要素のd属性の値」と同じです
「アニメーションする要素の座標」は、pathの始点からの相対的な位置になります
(アニメーションする要素の座標が(0 0)のときにpath上を移動します)
rotate属性
要素に適用される回転を指定します
デフォルト値は0で、元の方向を保ちます
auto : 要素は自動で回転して右側を現在の移動方向に揃えます
auto-reverse : 要素は自動で回転して左側を現在の移動方向に揃えます
<circle cx="0" cy="0" r="10">
  <animateMotion
   path="M10,110 A120,120 -45 0,1 110 10 A120,120 -45 0,1 10,110"
   dur="10s" repeatCount="indefinite"
  />
</circle>

ドローソフトでモーションパスを描くときに注意すること
アニメーションする要素の中心は、アートボードの左上(0 0)に配置して、エクスポートします

rotate属性のイメージ

auto

auto-reverse

デフォルト

「path要素」でモーションパスも表示するとき
mpath要素()を使うと「path要素」を参照できるので便利です

<path id="mpath" d="M10,110 A120,120 -45 0,1 110 10 A120,120 -45 0,1 10,110" stroke="#999" stroke-width="1" fill="transparent" />
    
<circle cx="0" cy="0" r="10">
  <animateMotion dur="10s" repeatCount="indefinite"/>
     <mpath xlink:href="#mpath" />
  </animateMotion>
</circle>

set

<set>要素は、アニメーションする要素に「特定の時間だけ」「特定の属性値」」を設定します
*非加算的要素です 

時間の経過(始まりや終わり)の概念はなくて「特定の時間の状態」を表します
そのため「from属性」「by属性」「additive属性」「 accumulate属性」は使えません

「to属性」と「アニメーションタイミング属性」を指定します
*赤丸をクリックすると緑に、緑になって3秒後に黄色

<circle cx="100" cy="100" r="20" fill="red">
    <set
     id="animation"
     />
    <set
     id="animation2"
     attributeName="fill"
     begin="click"
     to="green"
     dur="3s"/>
    <set
     id="animation3"
     attributeName="fill"
     begin="animation2.end"
     to="yellow"
     dur="2s"/>
</circle>

キーフレームのアニメーション

「fromとto」
属性の値を「fromの値」から「toの値」に変更します
「fromとby」
属性の値を「fromの値」から「byの値」だけ相対的に変更します
values属性
経過点が複数のときは「values 属性」で指定します
「keyTimes属性」がないときは、時間の配分は均等です
「;」区切りで値を指定します
keyTimes属性
経過時間と値(values属性の値)を紐付けて指定します
「0から1」の数字を「;」区切りで値を指定します
calcMode属性
アニメーションの進め方を指定します
初期値はlinear
linear:均等
discrete:次の値にジャンプする
paced:全体で均等、keyTimesまたはkeySplinesは無視されます
spline : 各間隔のコントロールポイントは「keySplines属性」で定義します
keySplines属性
3次ベジェ関数を定義します
calcMode=”spline”の設定が必須です
accumulate属性
アニメーションを累積するかどうか(初期値はnone)
1回目のアニメーションの終了値から2回目を始めたいときにaccumulate="sum"を指定します
additive属性
属性の値に対するオフセットをどうするか指定(初期値はreplaceで上書き)
同じ属性に複数のアニメーションを指定したいときにadditive="sum"を指定します

path要素のなめらかなアニメーション(モーフィング)はattributeName="d"で、「d」を動かします
パスは、同じ順番で記述されたアンカーポイントを目指して動きます

不器用でアンカーポイントの編集が全くできなくて、収縮させただけ 😂  

<path id="dog" d="M170 ・・省略 Z" fill="#F3AD55">
  <animate repeatCount="indefinite"
    dur="8s"
    attributeName="d"
    values="M75 ・・省略 Z;
         M57 ・・省略 Z;
         M170・・省略 Z;
         M75 ・・省略 Z
    " />
</path>

線のアニメーション

「stroke-dasharray」と「stroke-dashoffset」をつかうと、いろいろなパターンで線をアニメーションできます

「stroke-dasharray」は、間隔のある線のパターン指定します
「stroke-dashoffset」は、間隔の始まりの位置(オフセット)を指定します
どちらも「line rect circleなどの図形」「text」 「path」でつかえます
CSSのプロパティとしても使えます

アニメーションで「stroke-dashoffset」を「0」に変化させます
基本的には「stroke-dasharray」の値と同じ「stroke-dashoffset」を指定すれば、線のアニメーションができます(ややこしいのでそう考えています💦)

「stroke-dasharray値のちがい」で見え方がかわります

「stroke-dasharray」の値が小さいとスピードが遅くなるので、そのときは「stroke-dashoffset」の値を大きくして調整します

「四角形の1辺の長さのstroke-dasharray」
「線全体の長さと同じstroke-dasharray」
「小さい値のstroke-dasharray」

 <!--四角形の1辺の長さのstroke-dasharray -->
<rect x="100" y="100" width="100" height="100" 
fill="none" stroke="blue" stroke-width="5"
stroke-linecap="square"
stroke-dasharray="100" 
>
<animate 
repeatCount="indefinite"
dur="5s"
attributeName="stroke-dashoffset" 
from="100" to="0" />
</rect>

 <!--線全体の長さと同じstroke-dasharray -->
<rect x="100" y="10" width="100" height="100"
fill="none" stroke="blue" stroke-width="5"
stroke-linecap="square"
stroke-dasharray="400"
>
<animate 
repeatCount="indefinite"
dur="5s" 
attributeName="stroke-dashoffset" 
from="400" to="0" />
</rect>

 <!--小さい値のstroke-dasharray -->
<rect x="80" y="80" width="100" height="100" 
fill="none" stroke="blue" stroke-width="2"
stroke-dasharray="10" >
<animate 
repeatCount="indefinite" 
dur="10s" 
attributeName="stroke-dashoffset" 
from="200" to="0" />
</rect>

*「stroke-linecap=”square”(線の端の形状をパスよりも少しだけ長めに設定)」で角を調整しています

pathなど複雑な破線全体の長さは、JavaScriptで確認できます

const len = document.querySelector("path").getTotalLength();
console.log(len)
<path stroke-dasharray="891" stroke="green" fill="none" stroke-width="2.0" d="m119.557045 66.420784c-15.075859 6.0363007 -25.191399 28.082275 -21.254593 43.837273c3.3707657 13.489723 31.349144 16.474998 41.1811 6.6430435c8.81691 -8.816917 3.4947815 -27.217247 -3.984253 -37.19423c-9.397736 -12.536499 -30.739815 -16.681404 -34.538055 -31.881886c-2.6315918 -10.531555 -2.041809 -25.365929 6.640419 -31.881891c8.145752 -6.1133366 23.354576 -7.203972 30.55381 0c12.38205 12.390213 -2.221344 38.095634 -14.611557 50.47769c-17.017677 17.006477 -77.56729 15.372551 -71.73491 -7.968502c8.315525 -33.278538 67.679474 11.608356 100.95801 19.923885c17.613388 4.401169 45.020554 4.2844925 53.13649 -11.955383c3.983551 -7.971039 -3.3101807 -21.750526 -11.955383 -23.910763c-17.29628 -4.32193 -35.860916 5.3136597 -51.808395 13.283466c-27.763245 13.8747635 -58.044968 38.353325 -62.433075 69.07874c-2.850998 19.962608 -6.834587 47.67652 9.296585 59.776894c13.225647 9.920868 33.11283 10.652908 49.152237 6.643051c8.1506195 -2.0376587 20.156464 -0.45513916 23.910751 -7.9711304" fill-rule="evenodd">
 <animate 
  repeatCount="indefinite" 
  dur="5s" 
  attributeName="stroke-dashoffset" 
  values="891;0;0" 
  keyTimes="0;0.8;1" />
</path>

その他

CSSのプロパティとして使えるSVGの属性

プレゼンテーション属性
すべての SVG プレゼンテーション属性が CSS プロパティとして使用できます。
alignment-baseline, baseline-shift (en-US), clip (en-US), clip-path (en-US), clip-rule (en-US), color, color-interpolation (en-US), color-interpolation-filters (en-US), color-profile (en-US), color-rendering (en-US), cursor (en-US), direction (en-US), display (en-US), dominant-baseline (en-US), enable-background (en-US), fill, fill-opacity, fill-rule (en-US), filter (en-US), flood-color (en-US), flood-opacity (en-US), font-family (en-US), font-size (en-US), font-size-adjust (en-US), font-stretch (en-US), font-style (en-US), font-variant (en-US), font-weight (en-US), glyph-orientation-horizontal (en-US), glyph-orientation-vertical (en-US), image-rendering (en-US), kerning (en-US), letter-spacing (en-US), lighting-color (en-US), marker-end (en-US), marker-mid, marker-start (en-US), mask (en-US), opacity (en-US), overflow (en-US), pointer-events (en-US), shape-rendering (en-US), stop-color, stop-opacity (en-US), stroke, stroke-dasharray, stroke-dashoffset, stroke-linecap, stroke-linejoin, stroke-miterlimit (en-US), stroke-opacity (en-US), stroke-width (en-US), text-anchor (en-US), text-decoration (en-US), text-rendering (en-US), transform, transform-origin (en-US), unicode-bidi (en-US), vector-effect (en-US), visibility (en-US), word-spacing (en-US), writing-mode

https://developer.mozilla.org/ja/docs/Web/SVG/Attribute

JavaScriptで制御するとき

SVGファイルから不要なものを自動で取り除きます