ワンランクアップ!手書き風の文字アニメーション

ワンランクアップ!手書き風の文字アニメーション

以前にも、SVGを使ったアニメーションを紹介しましたが、今回はまた違ったアニメーションをご紹介したいと思います。

前回は、文字の枠線をアニメーションで動かす → 最後にフェードインで塗りの入った文字が出てくるというアニメーションをご紹介しましたが、今回は、手で実際に文字を書いているかのような動きのアニメーションです。

こんな感じ

*参考: https://notes.sharesl.net/articles/134/

はじめに

準備するもの
・ベースのテキスト svgデータ(アウトライン化したもの) = ベース!
・アニメーション用に1文字ずつパスで書いたテキスト svgデータ = マスク!
・vivus.js

今回は、「SAMPLE」という文字をアニメーションさせたいと思います。

まず、今回2種類のSVGデータが必要というところで、???になってしまったのですが…
構造を理解すればなるほど!です。

一見、このアニメーションは、文字を手で書く書き順で動かしているように見えるのですが、
実際には、① “SAMPLE”とすでに書かれたSVGデータ(黒字)の上に、② “SAMPLE”という文字を手で書く書き順と同じようにパスでなぞったデータ(白地)がかぶせてあって、②のパスをアニメーションで動かすことで、下に敷いてある黒い文字が見えるようになり、文字を書いているように見えるという動きになっています。

 

ベース用のテキストを用意する = ベース!

まずは、先ほど説明した① “SAMPLE”とすでに書かれたSVGデータ(黒字)を用意します。
こちらは簡単で、Aiで動かしたいテキストを打ち込んで、アウトライン化し、その後複合パスを作成するだけです。作成後、このレイヤーに[base]という名前をつけます。

 

アニメーション用に1文字ずつパスで書いたテキストを用意する = マスク!

こちらが先ほど説明した②”SAMPLE”という文字を手で書く書き順と同じようにパスでなぞったデータ(白地) にあたります。Ai操作に慣れていない私には若干難しかったのですが、

手順2で作成したベーステキストレイヤーをロックして、その上に新しくレイヤーを追加し、そこにベースレイヤーを覆うようにペンツールでなぞります。

 

枠線を細くして、線の角を丸くして描くと、割と綺麗に仕上がると思います。

また、ペンで描くのと同じ書き順でなぞりましょう。

 

下記のですと、若干下のマスクレイヤーの黒文字が見えてしまっていますが、これを綺麗に覆うようにしてください!

こちらも完成したら、レイヤーに[mask]という名前をつけましょう。

 

SVGに書き出し

2つのレイヤーが準備できた状態で、SVG形式で書き出します。

書き出したSVGファイルをエディターで開くと、

長〜いコードが書かれていると思いますが、<g id=”base”> と <g id=”mask”>というくくりで記載されているので、
どこまでがベーステキストで、どこからがマスクテキストか一目瞭然です!

 

HTMLに必要な情報を入れていく

ここからは参考サイトにあったテンプレートが非常に役に立ちましたので、こちらを使用させていただきます。

SVGファイルの中身から、必要な情報を切り取って下記の該当箇所に入れていきます。

 

主な入力箇所:

  • <style> </style>の中に、CSSの記述部分を切り取って貼り付け
  • <SVG>の中のviewboxの数字をコピペ
  • <mask id=”clipMask”></mask>の中にSVGファイルの中のマスク用のパス部分を切り取ってはりつけ
  • <image xlink:href=”SVGファイルへのパス” ~> </image>にSVGファイルパスを入れる

・CSSの記述に、fillとstrokeの記述があるかと思います。こちらはfill:none;stroke: #fff;としておきます。

・<image xlink:href=””>を入力する時点では、ベース画像のパスのみが残っていて、元々あったCSSの記述やマスク用のパスはない状態になります。

 

jsの部分は、vivus.jsを使用していますが、cdnで読み込んでいるので、今回は特に別ファイルを準備する必要はありません。ここも今回はテンプレートのまま使用させていただきました。

<!DOCTYPE html>
<html lang="ja">
<head>
<title>CSSとSVGで手書き風のアニメーション</title>
<style>
.svgall {
	background-image: url(img/pic_2.jpg);
	width: 100%;
	height: 100vh;
	background-size: cover;
	background-repeat: no-repeat;
}	
	
.mask {
    width: 80%;
    position: relative;
    top: 30%;
    left: 10%;
}
	
.cls-1 {
	fill: none;
}
.cls-2 {
	fill: none;
	stroke: #fff;
	stroke-linecap: round;
	stroke-miterlimit: 10;
	stroke-width: 20px;
}
</style>
</head>
<body>
<div class="svgall">
  <svg class="mask" viewBox="0 0 345.63 101.88" id="move" > 
    <!-- アニメーション画像 -->
    <defs>
      <mask id="clipMask"> 
        <!--マスクのpath-->
        <path class="cls-2" d="M50,21.25S26.88,19.38,13.75,35.62s45,5.63,31.87,29.38S23.12,83.12,10,76.88"/>
        <path class="cls-2" d="M53.75,10s-7.5,17.5-6.25,25.62"/>
        <path class="cls-2" d="M57.5,82.5c1.25-3.12,21.25-65,29.38-68.75S105.62,74.38,105,88.12"/>
        <path class="cls-2" d="M63.75,55.17s18.75-6.88,33.13-7.5"/>
        <path class="cls-2" d="M121.08,81.25s2.5-56.25,9.38-61.87,6.25,49.37,13.75,43.74,13.75-45,21.87-45.62,0,68.12-1.87,74.38"/>
        <path class="cls-2" d="M180,88.75c-.22-4.88,6.31-47.91,7.85-56.19.45-2.45,2.15-11.31,2.15-11.31,30-1.25,45.62,15,1.88,35"/>
        <path class="cls-2" d="M236.71,14.21s-10.63,51.87-5.63,64.37,43.75-14.37,43.75-14.37"/>
        <path class="cls-2" d="M298.12,17.54s32.5-4.37,37.5-3.12"/>
        <path class="cls-2" d="M296.58,13.75s-23.75,65-11.25,68.75,31.88-3.75,37.5-8.12"/>
        <path class="cls-2" d="M286.13,50s18.75-3.12,30.62-2.5"/>
      </mask>
    </defs>
    <!-- ベース画像 -->
    <image xlink:href="img/aset.svg" width="100%" height="100%" mask="url(#clipMask)"> </image>
  </svg>
</div>
<script src="https://cdn.jsdelivr.net/npm/vivus@latest/dist/vivus.min.js"></script> 
<script>
    new Vivus('move', {
        type: 'oneByOne',duration: 200,forceRender: false, animTimingFunction:Vivus.EASE_OUT})</script>
</body>
</html>

サンプル

そして今回作ったサンプルがこちらです。

若干雑な感じはありますが、書き順通りにアニメーションされています!

 

参考

このタイプのアニメーションについては、いろんな参考サイトで紹介されていました。いくつか見たサイトではうまく動作せず、最終的に動画付きで解説されていた参考サイトのやりかたでうまくいきました。

[ビデオ解説付き]CSSとSVGで手書き風のアニメーションを作る方法

 

みなさんもぜひ試して見てください!