今回は、 SVG と CSS でアニメーションを作る方法をご紹介します。
Step1. 破線を作る
まず簡単に、直線をアニメーションさせるところから始めましょう。SVG で線を引くには <line>
要素を使います。
<!DOCTYPE html>
<html lang="ja">
<head>
<style>
.my-line {
stroke: #000;
stroke-width: 3;
stroke-linecap: round;
}
</style>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 30">
<line class="my-line" x1="10" y1="18" x2="300" y2="18" />
</svg>
</body>
</html>
上記のコードをブラウザで実行すると、以下の直線が表示されます。
この直線に stroke-dasharray
を指定すると、破線になります。
stroke-dasharray: 10;
を指定すると、破線の実線部分(黒い部分)、ギャップの部分(白い部分)の長さがそれぞれ 10
になります。
ここから stroke-dasharray
の値を大きくしていくと、破線の実線 / ギャップの長さも大きくなります。
すると、 stroke-dasharray: 300;
の時点で元の直線と同じ状態になりました。破線の実線部分の長さが、元の線の長さと一致してしまったのです。
Step 2. 破線のオフセットを変える
次に、 stroke-dashoffset
を指定していきます。これは破線の開始位置(オフセット)を変化させるものです。
stroke-dashoffset: 0;
では元の直線がそのまま表示され、stroke-dashoffset: 300;
では直線が消えたのが分かります。
直線の開始位置と破線のギャップの開始位置が一致したので、長さ300のギャップが描画されました。見た目上は直線が消えてしまうのです。
Step 3. オフセットを変えてアニメーションさせる
先ほどの画像をよく見てください。すでにアニメーションの片鱗が見えているのがわかりますか? stroke-dashoffset: 300;
で線が消え、そこから数字を減らしていくと、線がだんだんと描画されています。
では、 CSS アニメーションで stroke-dashoffset
の値を変えていきましょう。
.animated-line {
stroke-dasharray: 300;
stroke-dashoffset: 300;
animation: line-animation 5s linear infinite;
}
@keyframes line-animation {
0% {
stroke-dashoffset: 300;
}
25% {
stroke-dashoffset: 300;
}
50% {
stroke-dashoffset: 0;
}
75% {
stroke-dashoffset: 0;
}
100% {
stroke-dashoffset: 300;
}
}
おめでとうございます、これで SVG アニメーションが完成しました!
「動いたといっても、ただの直線でしょう?」とお考えの方もいるかも知れませんが、心配無用です。この原理で複雑な線も動かすことができるのです。
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 100">
<path id="my-path"
class="my-line" fill="transparent"
d="M10 10 c 10 30, 10 10, 30 10 c 80 -5, 10 50, 90 15 c 120 10, 100 -10, 70 -15 c 150 -10, 50 30, 90 -10"
/>
<use href="#my-path" class="animated-path" y="50" />
</svg>
ただの落書きのような線だけではなく、冒頭でご紹介したような会社ロゴも動かすことが可能です。
<!DOCTYPE html>
<html lang="ja">
<head>
<style>
#logo {
fill: #fff;
stroke: #000;
stroke-width: 1;
stroke-linecap: round;
}
.logo-animated {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: line-animation 5s linear infinite;
}
@keyframes line-animation {
0% { stroke-dashoffset: 1000; }
25% { stroke-dashoffset: 1000; }
50% { stroke-dashoffset: 0; }
75% { stroke-dashoffset: 0; }
100% { stroke-dashoffset: 1000; }
}
</style>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 327.12 87.02">
<g id="logo" class="logo-animated">
<path d="M65.2 48.19c-1.57 0-2.83 1.27-2.83 2.83 0 6.25-5.09 11.34-11.34 11.34s-11.34-5.09-11.34-11.34c0-1.57-1.27-2.83-2.83-2.83s-2.83 1.27-2.83 2.83c0 9.38 7.63 17.01 17.01 17.01 9.38 0 17.01-7.63 17.01-17.01-.02-1.56-1.29-2.83-2.85-2.83zm243.78 19.56H80.64c2.8-4.94 4.4-10.64 4.4-16.72 0-18.79-15.23-34.02-34.02-34.02S17.01 32.24 17.01 51.02c0 6.25 1.69 12.1 4.63 17.13.75 1.04 1.68 1.86 3.32 1.86h7.47c.78 0 1.42-.63 1.42-1.42v-.1c-.02-.18-.13-.64-.77-1.39-.01-.01-.01-.02-.02-.03a24.015 24.015 0 01-6.13-16.06c0-13.31 10.79-24.09 24.09-24.09 13.31 0 24.09 10.79 24.09 24.09 0 6.17-2.32 11.79-6.13 16.06-.01.01-.01.02-.02.03-.64.75-.75 1.21-.77 1.39v.1c0 .78.63 1.42 1.42 1.42h239.37a1.129 1.129 0 100-2.26z"/><path d="M171.25 36.58c-.23-.58-.02-.88.21-1.38l8.05-15.2c.19-.3 0-.61-.31-.61h-7.23c-.38 0-.63.12-.81.48l-7.17 14.8a.32.32 0 01-.28.16c-.12 0-.22-.07-.28-.16V20c0-.36-.25-.61-.62-.61h-6.92c-.38 0-.62.24-.62.61v40.06c0 .36.25.61.62.61h6.92c.38 0 .62-.24.62-.61v-10.3c0-.59.08-1.03.26-1.4l1.92-3.92c.06-.09.16-.16.28-.16.12 0 .22.07.28.16l5.99 15.81c.06.3.25.42.63.42h7.42c.31 0 .5-.3.38-.61l-9.34-23.48zm-57.16-.43l-2.65-.98c-3.43-1.29-4.14-2.28-4.14-5.42 0-2.83 1.1-4.18 3.36-4.18 2.33 0 3.41 1.53 3.49 4.49.01.37.37.57.71.57h6.6c.17 0 .32-.08.42-.21.11-.12.16-.27.16-.47.11-6.26-2.8-11.39-11.65-11.39-7.83 0-11.65 4.06-11.65 11.63 0 6.71 2.14 9.85 8.35 12.13l2.65.98c3.3 1.23 4.08 2.52 4.08 6.22 0 3.82-1.1 4.99-3.5 4.99-2.52 0-3.7-1.61-3.82-5.31 0-.37-.25-.61-.71-.61h-6.92c-.27.01-.54.29-.52.68 0 7.3 2.73 12.26 11.91 12.26 8.74 0 12.17-4.43 12.17-12.99.01-7.1-2.32-10.18-8.34-12.39zm33.45-16.76h-18.52c-.38 0-.62.25-.62.62v40.03c0 .38.25.62.62.62h18.52c.38 0 .62-.25.62-.62v-6.11c0-.37-.25-.62-.62-.62h-10.41a.56.56 0 01-.56-.56v-8.43c0-.31.25-.56.57-.56h8.98c.37 0 .62-.25.62-.62v-6.11c0-.37-.25-.62-.62-.62h-8.98a.56.56 0 01-.56-.56v-8.51c0-.31.25-.56.57-.56h10.41c.38 0 .62-.25.62-.62v-6.11c-.02-.41-.27-.66-.64-.66zm77.97 0h-9.98c-.37 0-.62.25-.62.62v40.03c0 .38.25.62.62.62h6.92c.37 0 .62-.25.62-.62V46.65c0-.31.25-.57.57-.57h1.86c7.55 0 12.47-3.74 12.47-13.34.01-9.67-4.73-13.35-12.46-13.35zm-.25 19.52h-1.61a.57.57 0 01-.57-.57V27.13c0-.31.25-.57.57-.57h1.61c3.18 0 4.55 1.37 4.55 6.17 0 4.81-1.37 6.18-4.55 6.18zm66.68-19.52h-6.77c-.44 0-.65.08-.81.62l-4.37 14.29c-.08.12-.2.2-.35.2s-.27-.08-.35-.2l-4.37-14.29c-.17-.55-.38-.62-.81-.62h-6.77c-.5 0-.71.25-.59.62l8.55 24.25c.1.33.24.88.24 1.48v14.29c0 .38.25.62.63.62h6.93c.38 0 .63-.25.63-.62V45.75c.01-.6.15-1.16.25-1.48l8.55-24.25c.13-.38-.09-.63-.59-.63zm-91.66.61c-.13-.36-.31-.61-.69-.61h-7.36c-.38 0-.56.24-.69.61l-9.23 40.06c-.06.36.13.61.5.61h6.92c.44 0 .62-.24.69-.61l1.35-6.99c.06-.32.35-.48.66-.48h6.96c.31 0 .6.16.66.48l1.35 6.99c.06.36.25.61.69.61h6.92c.38 0 .56-.24.5-.61L200.28 20zm-2.1 26.28h-4.52c-.31 0-.47-.16-.47-.48l2.38-12.35c.08-.12.2-.2.35-.2s.28.08.35.2l2.38 12.35c0 .31-.16.48-.47.48zm54.66-26.89h-9.98c-.37 0-.62.25-.62.62v40.03c0 .38.25.62.62.62h6.92c.37 0 .62-.25.62-.62V46.65c0-.31.25-.57.57-.57h1.86c7.55 0 12.47-3.74 12.47-13.34.01-9.67-4.73-13.35-12.46-13.35zm-.25 19.52h-1.61a.57.57 0 01-.57-.57V27.13c0-.31.25-.57.57-.57h1.61c3.18 0 4.55 1.37 4.55 6.17 0 4.81-1.37 6.18-4.55 6.18z"/>
</g>
</svg>
</body>
</html>
アニメーションさせる画像を変更する場合は stroke-dasharray
や stroke-dashoffset
の値を調整する必要があります。線が長くなった分だけ、それらの値を大きくしましょう。
まとめ
SVG は CSS を使って装飾することが可能です。stroke-dasharray
や stroke-dashoffset
を上手く使うと、 CSS だけで面白いアニメーションをすることができます。