SVGとCSSで作る手書き風テキストアニメーション【コピペOK完全コード付き】

手書き風テキストアニメーションとは、文字が筆で書かれていくように表示される演出のことで、JavaScript不要・SVGとCSSだけで実装できます。仕組みは、SVGのstroke-dasharrayで線を全長ぶん隠し、stroke-dashoffsetを@keyframesで0に戻すだけ。CSSは10行前後で完成します。本記事では、コピペで動く完全コード・実装3ステップ・つまずきポイントの解決策までを1記事で解説します。

手書き風テキストアニメーションの仕組み

fountain pen on black lined paper
Photo by Aaron Burden on Unsplash

手書き風アニメーションの正体は、「線を端から少しずつ表示する」CSSテクニックです。使うプロパティは実質3つだけです。

  • stroke-dasharray:線を破線にするプロパティ。パスの全長以上の値を指定すると「1本の長い破線」になり、線全体を隠せます。
  • stroke-dashoffset:破線の開始位置をずらすプロパティ。全長から0へ変化させると、線が端からスルスルと現れます。
  • mask:白い部分だけを表示するSVGのマスク機能。書き順どおりに引いたパスで文字本体をマスクすると、本物の書き順で文字が現れます。

構造は「表示する文字(アウトライン化したパス)」と「書き順どおりの一筆書きパス(マスク)」の2層です。マスク側の線をアニメーションさせることで、文字が手で書かれているように見えます。

コピペで動く最小コード

まずは動く最小サンプルです。以下のHTMLとCSSをそのまま貼り付けると、「hi」の2文字が書き順どおりに描かれます。ライブラリは一切不要です。

<svg viewBox="0 0 160 120" width="240" role="img" aria-label="hi">  <g fill="none" stroke="#2b2b2b" stroke-width="7"  stroke-linecap="round" stroke-linejoin="round"> <!-- hの縦画 → hの山 → iの縦画 → iの点(書き順どおり4本) --> <path class="stroke s1" d="M38 18 C35 45 33 70 33 96"/> <path class="stroke s2" d="M33 72 C38 55 62 48 63 64 C64 74 64 86 64 96"/> <path class="stroke s3" d="M92 60 C93 72 94 84 95 96"/> <path class="stroke s4" d="M90 40 L90.5 40.5"/>  </g></svg>
.stroke {  stroke-dasharray: 120;  stroke-dashoffset: 120;    animation: handwriting 0.6s ease-out forwards;}.s2 { animation-delay: 0.55s; }.s3 { animation-delay: 1.15s; }.s4 { animation-delay: 1.5s; animation-duration: 0.15s; }@keyframes handwriting {  to { stroke-dashoffset: 0; }}@media (prefers-reduced-motion: reduce) {  .stroke { animation: none; stroke-dashoffset: 0; }}

ポイントは2つです。stroke-dasharrayとstroke-dashoffsetに「パスの全長以上の値」を入れること、そして複数のパスにanimation-delayで時間差をつけて書き順を再現することです。

実案件向けの実装手順3ステップ

ロゴやキャッチコピーなど実案件で使う場合は、「アウトライン化した文字+マスク」方式が定番です。手順は次の3ステップで、慣れれば30分ほどで実装できます。

①テキストをアウトライン化し、書き順どおりのパスを引く

IllustratorやFigmaで筆記体などのテキストをアウトライン化します。その上に別レイヤーを作り、文字の中心をなぞるように書き順どおりの一筆書きパスを引きます。パスの線幅(stroke-width)は、下の文字が完全に隠れる太さに設定するのがコツです。

②mask要素で文字をパスでマスクする

SVGに書き出したら、mask要素の中に書き順パスを入れ、文字本体にmask属性で適用します。マスクは「白い部分だけ表示・黒い部分は非表示」というルールなので、パスのstrokeは必ず白(#fff)にします。

<svg class="handwriting" viewBox="0 0 649 118">  <!-- 表示する文字(アウトライン化したパス) -->  <g class="handwriting_text" mask="url(#mask)"> <path d="(文字のアウトラインパス)"/>  </g>  <!-- 書き順どおりに引いた一筆書きパスでマスク -->  <mask id="mask"> <path class="handwriting_mask_line"d="(書き順パス)"fill="none" stroke="#fff" stroke-width="7"stroke-linecap="round" stroke-linejoin="round"/>  </mask></svg>

③stroke-dashoffsetを@keyframesで動かす

最後にCSSでマスク側のパスをアニメーションさせます。dasharrayとdashoffsetにパス全長以上の値(例:4000)を入れ、offsetを0に戻すだけです。

.handwriting_text { fill: #404040; }.handwriting_mask_line {  stroke-dasharray: 4000;  stroke-dashoffset: 4000;  animation: handwriting 4s linear forwards;}@keyframes handwriting {  to { stroke-dashoffset: 0; }}

つまずきポイントと解決策

monitor showing Java programming
Photo by Ilya Pavlov on Unsplash

実装でつまずきやすいのは「パスの長さ」と「動きの調整」です。よくある4つのケースと解決策をまとめます。

パスの正確な長さがわからない:ブラウザのコンソールで次の1行を実行すると全長を取得できます。取得した値をdasharrayとdashoffsetに設定すれば、描画速度が安定します。

document.querySelector('.handwriting_mask_line').getTotalLength();

文字ごとに順番に書きたい:パスを文字単位で分割し、animation-delayで0.5秒ずつずらすと自然な書き順になります。線が途中で欠ける:マスク用パスのstroke-widthが細く、文字の端が隠れきれていないのが原因です。太くして解決します。描き出しの動きが不自然:一定速度で書きたい場合はlinear、筆の勢いを出したい場合はease-in-outを使い分けます。あわせてprefers-reduced-motion対応を入れておくと、アクセシビリティ面でも安心です。

よくある質問(FAQ)

JavaScriptなし・CSSだけで作れますか?

作れます。本記事の方法はSVGとCSSのみで動作します。vivus.jsなどのライブラリが必要になるのは、描画をスクロール連動させるなど動的に制御したい場合だけです。

日本語(漢字・ひらがな)でもできますか?

可能です。仕組みは同じですが、画数が多いぶん書き順パスの作成工数が増えます。ロゴや短いキャッチコピーなど、文字数の少ない箇所への使用がおすすめです。

アウトライン化せずWebフォントのままできますか?

SVGのtext要素にstrokeを適用すれば「輪郭をなぞる風」の表現は可能です。ただし本物の書き順を再現するには、アウトライン化+マスク方式が必須です。

どのブラウザで動きますか?

Chrome・Safari・Edge・Firefoxなどモダンブラウザ全てで動作します。CSS側でmaskを使う場合は、-webkit-maskのベンダープレフィックスも併記しておくとより安全です。

まとめ

手書き風テキストアニメーションは、stroke-dasharray・stroke-dashoffset・maskの3つを押さえれば、SVGとCSSだけで実装できます。まずは本記事の最小コードをコピペで動かし、実案件ではアウトライン化+マスク方式に発展させてみてください。サイトのファーストビューやロゴ演出に取り入れると、手仕事の温かみをぐっと演出できます。THREE D PLUSでは、こうした動きのあるWebサイト制作も承っています。お気軽にご相談ください。

最新情報をチェックしよう!