SVGテキストが線で描画され塗りつぶされるアニメーション
テキストのアウトラインがまず線で描かれ、その後塗りつぶされていくアニメーションの実装方法について解説しています。
今回はGSAPのDrawSVGPluginを使用して実装してみました。SVGのpathをアニメーションさせる際にとても便利なプラグインで、2025年から無料で使用することができます。
実装例
早速ですが下記が実装例です。
ページ読み込み後にテキストが線で描かれ、その後文字の内側が塗りつぶされていきます。もう一度実行したい場合は、右下にある「Return」ボタンをクリックしてください。
線で描かれてから文字が現れる一連の流れがあり、伝えたいテキストへ自然と視線を集められます。そのためキャッチコピーやオープニングでの演出に向いているアニメーションだと感じます。
解説
HTML / CSS / JavaScriptの処理を順を追って解説していきます。
HTML(SVGの準備)
HTMLは次のとおりです。
<div class="catch-copy"> <svg class="catch-copy__canvas js-canvas" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 284.0 62.894" width="280" height="62.008"> <g> <title>想像を創造へ</title> </g> <g> <path transform="translate(6.799 47.746) scale(0.04289 -0.04289)" d="M273 203V52C273 -37 305 -63 426 -63..." /> <path transform="translate(54.282 47.746) scale(0.04289 -0.04289)" d="M481 711H658C643 687 626 664 609 645H427..." /> <!-- 各文字分のpathが続く --> </g> </svg></div>DrawSVGPluginは線に対して機能するため、<text>要素のSVGではなく、字形(グリフ)の輪郭データ(ベジェ曲線)を<path>化したSVGを用意する必要があります。
さらに1文字ずつ別々の<path>に分けておくと、後述のstaggerや特定文字の強調にも応用しやすくなります。各pathにはtransformで位置・サイズが個別に指定されています。
AIでSVGを生成する際のヒント
AIで生成依頼を出す際には、次のように伝えると字形の輪郭データをpath化したSVGが得られやすいです。
字形の輪郭データを1文字ずつpath要素にしたsvgを作成してフォントは作業環境にあるものが使用できます。今回のデモではNoto Sans JPを使用しています。
<title>要素でスクリーンリーダー向けにテキスト内容を提供しています。js-canvasクラスはJavaScriptからpath要素を取得するためのフックです。
CSSのポイント
CSSは次のとおりです。
.catch-copy { width: 50vw;}
.catch-copy__canvas { display: block; width: 100%; height: auto;}
.catch-copy__canvas path { stroke: currentColor; stroke-width: 12; fill: currentColor; fill-opacity: 0;}strokeとfillで線と塗りの色を指定しています。いずれもcurrentColorを指定しているため、親要素の文字色を継承します。stroke-widthで線の太さを調整できます。
fill-opacityの初期値を0に指定しているのは、アニメーション前に塗りが表示されてちらつくのを防ぐためです。JavaScriptでfillOpacityを1にアニメーションさせることで、線描画の後に塗りが表示されます。
fill-opacityとは?
fill-opacityは、SVG要素の塗り(fill)の不透明度を指定するプロパティです。0で完全に透明、1で完全不透明になります。fillで色を指定したうえで、塗りだけを透過させたいときに使います。
あまり聞きなれないプロパティですが、今回のように塗りをアニメーションさせる際に必要なプロパティです。
JavaScriptの処理
GSAP本体とDrawSVGPluginを読み込んだうえで、次のコードを実行します。
gsap.registerPlugin(DrawSVGPlugin);
const draw = () => { const paths = document.querySelectorAll(".js-canvas path"); const tl = gsap.timeline();
tl.from(paths, { drawSVG: 0, duration: 1.5, ease: "power1.in", }).to( paths, { fillOpacity: 1, duration: 1.2, ease: "power1.inOut", }, "+=0.5", );};
if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", draw);} else { draw();}querySelectorAllでSVG内のpath要素をすべて取得し、gsap.timeline()で2段階のアニメーションを連結しています。
タイムラインの内容を表にまとめると次のとおりです。
| アニメーション | 時間 | ease | 遅延 |
|---|---|---|---|
線描画(drawSVG: 0で線を0%から描画) | 1.5s | power1.in | なし |
塗り表示(fillOpacity: 1で塗りを表示) | 1.2s | power1.inOut | 前のアニメーション終了後 +0.5s |
第1段階ではdrawSVG: 0を指定し、線が0%の状態から描画されるアニメーションを行います。第2段階ではfillOpacity: 1を指定し、塗りが表示されるアニメーションを行います。"+=0.5"は、前のアニメーション終了から0.5秒後に次のアニメーションを開始するという意味です。
表現アレンジのアイデア
今回の構成はシンプルなため、いくつかの値や要素を変えるだけで表現の幅を広げられます。
- 文字ごとに遅延を設定する:
drawSVGのアニメーションにstaggerオプションを追加すると、文字が順番に描画される演出になります。一文字ずつ現れるリズムが生まれ、テキストが書き進むようなより自然な動きに見えます。
tl.from(paths, { drawSVG: 0, duration: 1.5, ease: "power1.in", stagger: 0.15,});- 強調したい文字のfillの色を変える:特定のpathにクラスを付与し、CSSで
fillを上書きします。強調したい語句を色で際立たせ、メッセージの伝わりやすさを高められます。
<svg class="catch-copy__canvas js-canvas" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 284.0 62.894" width="280" height="62.008"> <g> <path class="catch-copy__emphasis" transform="..." d="..."></path> <!-- 各文字分のpathが続く --> </g></svg>.catch-copy__emphasis { fill: #e63946;}まとめ
「字形をpath化したSVG」と「GSAPのDrawSVGPlugin」を組み合わせることで、テキストが線で描かれてから塗りつぶされるアニメーションを実装することができました。
タイムラインでdrawSVGによる線描画とfillOpacityによる塗り表示を連結するだけで、シンプルな構成で表現可能です。staggerやfillの色変更を加えれば、様々な演出にも応用できそうです。
あわせて読みたい
