はじめに
普段何気なくSVGファイルを使用していますが、だいたいはimgタグや疑似要素に入れたりなんかして...
そういえばsvgタグってどんなことができるのか把握できていなかったと思い調べると思ったよりできることがありました。その中でも本記事では、<svg>
と<path>
とCSSでできるアニメーションをいくつかご紹介します。
SVGをアニメーションさせる事例
よくあるのはこういった線をなぞって塗りつぶすもの
See the Pen sample by shoco_cor (@shoko232) on CodePen.
animation
と@keyframes
で持続時間と速度を設定する
animation
まず使用するプロパティはanimation
です。
animation
は一括指定プロパティなので以下の構成要素を持っています。
// アニメーションの開始時間
animation-delay: 1s;
// アニメーションの再生方向
animation-direction: alternate;
// アニメーションの所要時間
animation-duration: 3s;
// アニメーション実行前後の状態
animation-fill-mode: forwards;
// アニメーションを何セット繰り返すか
animation-iteration-count: 1;
// 使用するキーフレームの名称
animation-name: test;
// アニメーションの実行状況
animation-play-state: running;
// アニメーション実行中の速度
animation-timing-function: ease;
この中から必要なものを記述していきます。今回はname
、duration
、timing-function
を主に使っていきます。
-
name
に@keyframes
に記述した名称を記載し(詳細は後述します) -
duration
でひとつのアニメーションが完了するまでの時間を設定 -
timing-function
でduration
の時間中の再生速度を設定
これらを書くことでアニメーションの大枠が作ることができます。
ではもっと詳細な中身を書いていきましょう。
といっても見本に出したSVGの図形に対して線を走らせて、内部を塗りつぶすアニメーションであればかなりシンプルです。
@keyframes
ここで@keyframes
について見ていきましょう。
from
-to
で始まりと終わりを設定する、もしくは0%~100%のなかで作動するタイミングを細かく指定することができます。
// 最初と最後の状態を設定する
@keyframes test1 {
from {
fill: transparent;
}
to {
fill: yellow;
}
}
// もしくは%で間を細かく設定することもできる
@keyframes test2 {
0% {
fill: transparent;
}
50% {
fill: lightyellow;
}
100% {
fill: yellow;
}
}
SVGで使えるfill
とstroke
fill
とstroke
はSVGで描画に使われる<rect>
や<circle>
、<path>
などのタグにインラインCSSで記述する属性ですが、今回はCSSにプロパティを記述してアニメーションさせる場合に焦点を当てています。
fill
fill
はオブジェクトの内部の色を設定します。
fill-opacity
で透過の設定ができます。
See the Pen fill by shoco_cor (@shoko232) on CodePen.
stroke
stroke
はオブジェクトを囲む線の色を設定します。
See the Pen stroke by shoco_cor (@shoko232) on CodePen.
このふたつを組み合わせることで星をなぞってから塗りつぶすアニメーションが完成します。
See the Pen sample by shoco_cor (@shoko232) on CodePen.
stroke
はオブジェクトの外側に線が付くのでSVGのデータの状態によっては描画範囲からはみ出してしまい見切れてしまいます。
See the Pen stroke-over by shoco_cor (@shoko232) on CodePen.
また、stroke
には他にもプロパティがあります。
// 線を破線にする
stroke-dasharray: 2 1;
// 線の描画開始位置
stroke-dashoffset: 50;
// 線の透過
stroke-opacity: 1;
// 線の幅
stroke-width: 2px;
// 以下はパスや基本的な図形に使える
// 線の端の形状
stroke-linecap: round;
// 線の連結部の形状
stroke-linejoin: miter;
// 線の連結部の尖り具合
stroke-miterlimit: 1;
見本にも使用しているstroke-dasharry
は破線の間隔を設定できるのですが、今回はパスの全長を設定しています。そしてstroke-dashoffset
で描画の開始位置を設定できるので、アニメーションで初期位置と終了位置をそれぞれ開始と終了に記載することで線を描画するアニメーションを作ることができます。
また、今回の星型はFigmaで図形を書いてSVGで取得し、getTotalLength()
を使用してパスの全長を計算した値を使用しています。
fill
とstroke
の注意点
見本では塗りつぶした星を使用していますが、線画の星の場合はfill
とstroke
の挙動が変わります。
See the Pen fillとstroke by shoco_cor (@shoko232) on CodePen.
SVGで使えるtransform
transform
は一般的なWeb制作でも使用する場面は多いと思いますので、transform
の詳細は割愛しますが、これもSVGのアニメーションで使うことができます。
translate
で位置を変更し、scale
でサイズを変え、rotate
で角度を変更すればかなりの動きは再現することができます。
See the Pen transform by shoco_cor (@shoko232) on CodePen.
rotate
で回転させる場合は、transform-origin
で回転の中心点を調整しないと初期値が左上になっています。
まとめ
様々なプロパティを見てきましたが、これまでのプロパティでかなりの動きは実装できそうですよね!
わたしはクリックしたときに動くようにしたかったので実装してみました。
星の線上でクリックしてみてください!
(クリックの判定がシビアですみません><)
See the Pen Untitled by shoco_cor (@shoko232) on CodePen.
あとがき
実は最近身近で既存のSVGファイルのアイコンに後からアニメーションを追加してほしいという依頼があったので、チームで試行錯誤する機会がありました。
みんなでいろいろと調べていく内にこれって実は可能性無限大では…??と思ったのが本記事を書くきっかけでした。SVGアニメーションを作るジェネレーターもありますが、どこまでなら人力で再現できるのか試したくなりました。想像以上にできる幅が広かったので、かなりターゲットを絞り込んで記事にしてしまいました。しかし、実際に自分でどこまで記事にするか試行錯誤する時間はとても楽しかったので、自分の好奇心をうまくアウトプットに繋げることができてよかったです。