illustratorとDrawSVGで作る、手書き風のテキストアニメーションの作り方 webデザイン
こんにちは、Webデザインしてます。イケダです。
上記のタイトルどおり、今日はSVGを使って手で文字を描くようなアニメーションについて綴りたいと思います。
当サイトのトップページでも使用しているのですが、SVGアニメーションを作ったのは2016年くらい。当時は、面白くて没頭していました。
コンテンツのアイキャッチくらいしか使い所がないのですが、個人的にこのSVGを使った手書き風の表現が好きなので。今回プログラミングの復習とともにブログで手法を綴りたいと思います。
はじめに、上記はgif画像ですが。コーディングしたデモページを作りました。完成すると下記のリンク先のようになります。
今回必要なソフトは、illustrator イラストレーターです。
あと、html / css / javascript / jQuery / SVGアニメーションプラグイン jQuery DrawSVG を利用します。
それでは。まず目次から。
目次
- illustratorで文字をつくる
- SVGデータを編集
- コーディング内容
- 最後にひとこと
順に、説明いたします。
1.illustratorで、文字をつくる。
まず、手書きしたい文字をつくります。好きなフォント、もしくはパスを引いても大丈夫です。描画したい色で作成し、アウトライン化をします。(ここ重要!)
今回の、デモは黒背景に白文字で描画します。なので、データの保存の際に塗りを白にしています。黒背景に黒文字だと、当たり前ですが描画が見れないのでご注意を。(イケダは、ここでハマった経験があります)
アウトラインができたら、svg形式で保存します。
次に出る、保存時の svgプロファイルはこんな感じ。
- SVGプロファイル – SVG 1.1
- フォント – 文字 SVG / サブセット なし
- オプション – 埋め込み
- CSSプロパティ – スタイル属性
- 小数点以下の桁数 – 3
- エンコーディング – UTF-8
- <tspan>エレメントの出力を制御 – チェック
…と、この設定でできたので、真似してもらえば大丈夫と思います。不要なものがありましたらすみません。
描画の線を、パスでなぞっていく。
次に、連続して文字を描画させるため、線で先ほどの文字をなぞっていきます。
文字を筆跡していく順に、パスは線でなぞっていきます。
見やすい色で、半透明をかけるとトレースしやすいです。アウトライン化した文字からはみ出すようにします。
最後まで、なぞれたらレイヤー順を確認します。画像のように、文字が描かれる最初のレイヤーが一番下。最後に描かれるレイヤーが一番上です。
線のパスだけを選択し、別のファイルをコピペ。先ほどと同じくsvg形式で保存します。
イラストレーターを使った、文字の作成はここまでです。
次は、保存したsvgデータを テキストエディタで編集します。
2.SVGデータを編集
線でなぞった方のsvgのファイルを、テキストエディタで開きます。僕の場合は、Bracketsを使っています。コーディングをしやすいものでOK。
開くと下記のようなコードです。
この中から、いらないものを削除し、コードを別ファイル保存します。
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" width="602.398px" height="133.001px" viewBox="0 0 602.398 133.001" style="enable-background:new 0 0 602.398 133.001;"
xml:space="preserve">
<path style="opacity:0.5;fill:none;stroke:#CC3333;stroke-width:20;stroke-miterlimit:10;enable-background:new ;" d="
M108.5,28.001c0,0-16.75-18.141-43.976-18c0,0-54.497,0.964-54.524,56.5c-0.004,9,4.25,50.5,55.5,53.5
c28.25,0,40.231-15.975,42.305-18.048"/>
<path style="opacity:0.5;fill:none;stroke:#CC3333;stroke-width:20;stroke-miterlimit:10;enable-background:new ;" d="
M187,78.001c0,0-37.096-0.635-43.423,1.933c-6.327,2.568-13.845,9.817-13.211,20.317c0.634,10.5,8.168,18.321,23.384,19.75
c21.292,2,33-11.5,38.75-22"/>
<!-- あとにつづく path 省略 -->
</svg>
必要なコードは、<path> です。それ以外と、<path>のstyle属性も削除します。下記のように整えたコードを別ファイルで一旦、保存します。
<path d="M108.5,28.001c0,0-16.75-18.141-43.976-18c0,0-54.497,0.964-54.524,56.5c-0.004,9,4.25,50.5,55.5,53.5
c28.25,0,40.231-15.975,42.305-18.048"/>
<path d="M187,78.001c0,0-37.096-0.635-43.423,1.933c-6.327,2.568-13.845,9.817-13.211,20.317c0.634,10.5,8.168,18.321,23.384,19.75
c21.292,2,33-11.5,38.75-22"/>
<path d="M125.982,51.251c11.267-6.75,23.323-11.5,36.795-11.5c13.472-0.25,23.722,5.75,28.972,15.5c4.5,9.25,3.5,63.5,3.5,73.5"/>
<!-- あとにつづく path 省略 -->
3.コーディングの内容。
htmlの内容
ようやくコーディングです。
先に今回のデモページのhtmlコード。完成すると下記になります。
<div id="top">
<!-- 描画ロゴの位置指定 -->
<div class="logo">
<!-- 1.svg読み込み -->
<svg class="draw" viewBox="0 0 600 125.139" width="260" height="58">
<defs>
<!-- 2-a.マスクの指定 -->
<mask id="mask--logo">
<!-- 3.描画パスの挿入 -->
<path class="stroke22" d="M108.952,26.836
c0,0-15.084-13.291-25.459-14.791s-50.45-10.719-68,27.576c-16.291,35.549,8.25,63.164,14.375,68.424
c6.966,5.981,29.846,15.292,52.5,9c21.977-6.104,27.25-19.125,27.25-19.125"/>
<path class="stroke22" d="M187,78.001c0,0-37.096-0.635-43.423,1.933c-6.327,2.568-13.845,9.817-13.211,20.317c0.634,10.5,8.168,18.321,23.384,19.75
c21.292,2,33-11.5,38.75-22"/>
<path class="stroke22" d="M125.982,51.251c11.267-6.75,23.323-11.5,36.795-11.5c13.472-0.25,23.722,5.75,28.972,15.5c4.5,9.25,3.5,63.5,3.5,73.5"/>
<path class="stroke22" d="M236.25,31.001l1,97.75c0,0-3-56.5,6.25-69.75s18.5-19.016,31.25-19.257c12.75-0.242,31.5,6.757,33,25.507s0.5,60.75,0,63.5"/>
<path class="stroke22" d="M333.5,28.001c0,0,37.631,95,42.064,95s41.436-92.25,41.936-95"/>
<path class="stroke22" d="M493,78.001c0,0-37.096-0.635-43.423,1.933c-6.327,2.568-13.845,9.817-13.211,20.317s8.168,18.321,23.384,19.75
c21.292,2,33-11.5,38.75-22"/>
<path class="stroke22" d="M431.982,51.251c11.267-6.75,23.323-11.5,36.795-11.5c13.472-0.25,23.722,5.75,28.972,15.5c4.5,9.25,3.5,63.5,3.5,73.5"/>
<path class="stroke22" d="M595.5,48.501c-10.75-5.5-20.5-10.765-37-8.757s-25.25,8.007-25.5,19.007s5.5,15.25,15.5,17.75s20.75,6.496,29.75,7.746
c10.5,1.254,17.5,11.004,12.5,23.254c-4.75,8.5-14.5,12.146-27.75,12.699c-13.25,0.552-37.8-9.449-40.274-12.449"/>
</mask>
</defs>
<!-- 2-b.マスクの指定 -->
<image xlink:href="https://canvas-i.com/wp/wp-content/themes/canvas_202105/img/d-logo-2.svg" width="100%" height="100%" mask="url(#mask--logo)"></image>
</svg>
<img class="logo-under" src="https://canvas-i.com/wp/wp-content/themes/canvas_201802/demo/draw-svg/img/logo-under.svg"></div>
</div>
<!-- 4.jQuery DrawSVGの読み込み -->
<script src="js/jquery.drawsvg.js">
<script src="js/draw.js">
自分がつまづいたところに、番号つきのコメントアウトをふりました。順番に解説します。
1. svg の読み込み
<!-- 1.svgの読み込み -->
<svg class="draw" viewBox="0 0 600 125.139" width="260" height="58">
<defs>
描画する<path>のsvgは、インラインで書き込みます。注意点は viewBox の値です。
最初にillustratorで作った、アウトライン化したsvgデータをエディタで開くと viewBox=” 数値 数値 数値 数値 “ という属性があります。その数値をコピーして、上記コードへ貼り付けます。
一致しないと、マスクと描画の位置がずれるので注意です。
width=”” height=”” は、CSS側で指定もするのですが。無いと昔のie とかで崩れてた気がする…(うろ覚え) もう省いてもいいのかな…
2. マスクの指定
<!-- 2-a.マスクの指定 -->
<mask id="mask--logo">="58">
...省略
<defs>
<!-- 2-b.マスクの指定 -->
<image xlink:href="https://canvas-i.com/wp/wp-content/themes/canvas_202105/img/d-logo-2.svg" width="100%" height="100%" mask="url(#mask--logo)"></image>
</svg>
2行目:2-a.マスクの指定で、描画する線のパスと、マスクをかける塗りの画像(最初にアウトラインをとったsvgデータ)をリンクさせる。
その為に、id=”…” をつける。
9行目:2-b <image xlink:href=”” で、塗りの画像を配置。
mask=”url(#…)”に、同じidをつける。描画のサイズとぴったり合わせるため widthとheightを100%に設定。
illustrator や photoshop で使う、クリッピングマスクをコードで指定しているようです。いろいろ調べたのですが、ここの理解が難しい…
すみませんが、詳しい解説は省きます。
3.描画パスの挿入
<mask id="mask--logo">
<!-- 3.描画パスの挿入 -->
<path class="stroke22" d="M108.952,26.836
c0,0-15.084-13.291-25.459-14.791s-50.45-10.719-68,27.576c-16.291,35.549,8.25,63.164,14.375,68.424
c6.966,5.981,29.846,15.292,52.5,9c21.977-6.104,27.25-19.125,27.25-19.125"/>
<path class="stroke22" d="M187,78.001c0,0-37.096-0.635-43.423,1.933c-6.327,2.568-13.845,9.817-13.211,20.317c0.634,10.5,8.168,18.321,23.384,19.75
c21.292,2,33-11.5,38.75-22"/>
<path class="stroke22" d="M125.982,51.251c11.267-6.75,23.323-11.5,36.795-11.5c13.472-0.25,23.722,5.75,28.972,15.5c4.5,9.25,3.5,63.5,3.5,73.5"/>
...省略
</mask>
4行目以降:3.描画パスの挿入
SVGデータ編集の際に、一旦保存しておいた<path> のコピーをここで使用します。<mask> 内に、ペーストします。この時に、描画線の太さをCSSで設定できるので、class=”…”を振って、stroke-width: ◯px;と設定しましょう。
4.jQuery DrawSVGの読み込み
37行目:本当は、自作javascriptでゴリゴリ動かしたかったのですが。自分には無理でした。おとなしくプラグインに頼ります。
こちらからダウンロードいただきまして、プラグインを読み込みます。
38行目は、jsの設定です。内容は、あとに記載しています。
これで、htmlの設定は終了です。
まだ続きます。
CSSの内容
#top {
height: 500px;
background-color: #000;
}
#top .logo { /* 描画位置の指定 */
width: 280px;
margin: auto;
position: absolute;
text-align: center;
top: 170px;
left: 0;
right: 0;
z-index: 100;
}
#top .logo .draw { /* 描画範囲の指定 */
width: 260px;
}
#top .logo .draw .stroke22 { /* 線の描画太さ*/
stroke-width: 22px;
}
#top .draw { /*drawアニメーションの設定*/
fill: none;
stroke: #fff; /*マスクは黒を透明 白を描画色で表示される。ストロークはを白、クリップするimgが描画色になる*/
visibility: hidden;
}
描画の位置とdrawアニメーションの設定。コメントアウトの内容で分かるかと思います。
drawアニメションの設定は、 fill: none; にしないと描画のパスが切れるとこがありました。少し謎ですが、こうすると綺麗に描画されました。
JSの内容
jQuery(function($){
//描画のフェードイン
jQuery('.draw').css({
'visibility': 'visible',
});
// Canvasのを描画走らせる
setTimeout(function () {
logo.drawsvg('animate');
}, 600);
// DrawSVGアニメーション設定
var canvas_draw = {
duration: 300, //ひとつのpathが描き終わる速度
stagger: 200, //次のpathを書き始めるまでの遅延時間。
easing: 'swing', //jqueryで使用できるイージングを実装。
reverse: false, //描く方向の指定。
callback: function () {
//処理を記述
}
},
logo = jQuery(".draw").drawsvg(canvas_draw);
});
最後の仕上げ。プラグイン [ jQuery DrawSVG ] を発火させます。
jsのコンフリクトで動かなかったので、。$(function(){ → jQuery(function($){ に変え記述しています。最近まで知らなかった。こんな方法あったすね…
と、いうわけで。
最後にひとこと。
「手書き風のテキストアニメーションの作り方について」でした。
ちなみに、このプログラムを理解して実装するのに、イケダは数ヶ月かかりました。過去で一番難しかった表現です。上記をさらっと分かって、再現できたらお見事!
おかしな説明なありましたら、ご教授いただけますと幸いですm(_ _)m
冒頭でも触れましたが、今回復習を兼ねてブログで綴りました。数年ぶりに自分の書いたコードみて、理解に苦しむところもたくさんありました。
新しい表現を覚えたら、すぐにブログがノートに取って整理する。これからは心がけたいと思います。
それでは、今回は長くなってしまいました。
最後までお読みいただきまして、ありがとうございました🙌