SVGのanimateTransform要素は、その親要素をアニメーションさせながら変形したり動かしたりするためのもの。fromとto要素だけでもちょっとしたことならできるけど、複雑なことをやるにはvaluesとkeyTimes属性とを組み合わせるようだ。
均等にシーンを割り当てる場合はvalues属性を書くだけで良い。
<animateTransform
attributeName="transform"
attributeType="XML"
begin="0s"
dur="8s"
repeatCount="indefinite"
values="0; 300; 300; 0; 0"
type="translate"/>
values属性に指定した値の個数から1を引いた数でdur属性の値が均等に割られ、割り当てられる。
シーンへの割り当てが偏る場合はvalues属性にkeyPoints属性でタイミングを割り当てる。
<animateTransform
attributeName="transform"
attributeType="XML"
begin="0s"
dur="8s"
repeatCount="indefinite"
values="0; 300; 300; 0; 0"
keyTimes="0; 0.375; 0.5; 0.875; 1"
type="translate"/>
keyTimes属性ではdur属性の値を1とした相対的な数値でvalues属性と同じ数だけ刻む。
calcMode="discrete"にするとアニメーション過程が省略される。
<animateTransform
attributeName="transform"
attributeType="XML"
begin="0s"
dur="8s"
repeatCount="indefinite"
calcMode="discrete"
values="0; 75; 150; 225; 300; 225; 150; 75; 0"
type="translate"/>
ここではtranslateに対してdiscreteなのでジャンプしているように見える。
アニメーションとジャンプを混ぜる場合はkeyTimes属性を同じタイミングで刻むだけで良い。ジャンプのみの場合もkeyTimes属性を使う方がdiscreteを使うより簡単かもしれない。
<animateTransform
attributeName="transform"
attributeType="XML"
begin="0s"
dur="8s"
repeatCount="indefinite"
values="0; 150; 300; 300; 150; 0; 0"
keyTimes="0; 0.375; 0.375; 0.5; 0.875; 0.875; 1"
type="translate"/>
移動するアニメーションとジャンプするアニメーションを別々に作り、endイベントを使ってチェーンさせるという手もあるけど、同じtranslateのアニメーションならまとめた方が書きやすい。
これにアニメーション自体のタイミングが加わることになるので、手で書くのはこれくらいが限界な気がする。そこへ行くとCSS TransitionsやCSS Animationsは書きやすい実装なんだな、と思った。