vivus.jsで簡単手書きアニメーション

アニメーション
なる
なる

学習期間5ヶ月、独立後半年で月収50万を突破した「なる(@naru000006)」です。

この記事では、vivus.jsを使って手書きアニメーションを実装する方法を紹介しています。

この記事ではサービスのリンク先にプロモーションを含みます。ご了承ください。

実装すること

今回紹介するのは、vivus.jsを使った手書きアニメーションの実装方法です。

See the Pen 【vivus.js】手書きアニメーション by narukichi06 (@narukichi06) on CodePen.

解説

  1. 「vivus.js」とは
  2. 実装手順

vivus.jsとは

vivsu.jsとは…

今回はCDNで読み込みます。

</body>の直前にCDNと今回作成するJSファイルを読み込みましょう。

<script src="//cdn.jsdelivr.net/npm/vivus@latest/dist/vivus.min.js"></script>
<script src="js/main.js"></script>

実装手順

  1. イラレでテキストを用意する
  2. HTMLにコードをうつす
  3. CSSで整える
  4. JS

イラレでテキストを用意する

手順1-1:イラレでテキストを用意する

まずは、イラレで手書きアニメーションを実装したい文字を入力します。

手順1-2:用意したテキストをアウトライン化する

テキストを選択した状態で画面上部の「書式」→「アウトラインを作成」をクリックします。

文字の周りが縁どられたら成功です。

このときにレイヤー名を「base」にしておきます。(レイヤー名は識別できればなんでも可)

手順1-3:新規レイヤーを作成

次に新規レイヤーを作成します。

画面右下の+アイコンをクリックして新規レイヤーを作成します。

レイヤー名は「mask」にします。(レイヤー名は識別できればなんでも可)

このとき、「base」レイヤーにはロックをかけて編集できないようにしておくと次の手順がスムーズに進みます。

手順1-4:テキストをなぞる

ここからは「mask」レイヤー上で「base」レイヤーのテキストをなぞっていきます。

①「mask」レイヤーを選択

必ず「mask」レイヤーが選択されているかを確認してください。

②ペンツールででテキストをなぞる

まず、ペンツールを選択します。

コーダーにとってはあまり馴染みのないペンツールですが、大丈夫です。マウスとキーボードで完結します。

ペンツールを選択したら、テキストを文字を一筆ずつなぞります。

マウスをクリックして、テキストを覆うようにアンカーポイントを置いていきます。

このとき、線がテキストを覆うようにパスの太さを調整します。

手順1-5:SVGで書き出す

先ほどの「base」レイヤーと「mask」レイヤーをSVGで書き出します。

maskレイヤーを書き出すときはレイヤーの右端をクリックしてパスを全選択します。


今回は、それぞれbase.svgとmask.svgで書き出すこととします。

HTML

手順2-1:書き出したSVGをVSCodeで開く

書き出した2つのSVGファイルをHTMLファイルと同じ階層の「image」フォルダに入れておきます。

次にbase.svgとmask.svgをVSCodeで開きます。

手順2-2:SVGの中身をHTMLにうつす

①mask.svgの上から2行目のsvgタグ内をHTMLコードに移し、</svg>で閉じます。
<svg id="mask" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 346.47 70.11">
</svg>

このとき、SVGタグにid名「mask」をつけておくとスタイルを充てるときに指定しやすくなります。

③mask.svgをHTMLへコピペ

先ほどのsvgタグ内に<mask id=”clipmask”> … </mask>で枠を作り、中にmask.svgのpolyline、path、lineタグをうつします。

<svg id="mask" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 346.47 70.11">
 <mask id="clipmask">
<!-- この中にコピペ -->
 </mask>
</svg>
②base.svgをHTML内へコピペ

次に、base.svgのpathを先ほどのSVGタグ内に移動します。

このとき、pathを<g id=”base” mask=”url(#clipMask)”>…</g>で囲います。

<svg id="mask" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 349.83 81.11">
    <mask id="clipMask">
       <!-- 先ほどコピペしたmask.svg -->
    </mask>
    <g id="base" mask="url(#clipMask)">
       <!-- この中にコピペ -->
    </g>
</svg>

全体のコードはこのようになります。

<svg id="mask" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 349.83 81.11">
    <mask id="clipMask">
        <polyline class="cls-1" points=".47 27.32 63.62 21.3 35.38 36.01 31.64 56.12 54.15 72.04"/>
        <polyline class="cls-1" points="67.67 36.01 110.82 33.21 102.62 66.3 98.66 73.41 86.6 63.39"/>
        <line class="cls-1" x1="99.97" y1="11.33" x2="74.37" y2="66.7"/>
        <line class="cls-1" x1="112.62" y1="21.3" x2="137.06" y2="56.12"/>
        <line class="cls-1" x1="121.62" y1="13.93" x2="134.84" y2="33.21"/>
        <line class="cls-1" x1="125.26" y1="8.23" x2="143.6" y2="27.32"/>
        <line class="cls-1" x1="149.71" y1="27.32" x2="197.66" y2="17.97"/>
        <line class="cls-1" x1="154.17" y1="42.99" x2="204.26" y2="33.21"/>
        <polyline class="cls-1" points="162.62 5.3 197.66 56.12 173.42 53.31"/>
        <polyline class="cls-1" points="154.17 53.12 169.78 68.48 197.66 69.04"/>
        <line class="cls-1" x1="219.97" y1="27.32" x2="260.11" y2="27.32"/>
        <line class="cls-1" x1="219.97" y1="46.67" x2="260.11" y2="46.67"/>
        <polyline class="cls-1" points="248.43 .81 238.62 60.3 251.59 72.99 269.9 64.77 266.66 38.1"/>
        <polyline class="cls-1" points="306.8 11.33 310.62 62.3 325.63 70.71 344.83 46.67"/>
        <line class="cls-1" x1="324.24" y1="21.3" x2="338.16" y2="36.01"/>
        <path class="cls-1" d="M332.24,11.93s12.59,13.13,12.59,18.79"/>
    </mask>
    <g id="base" mask="url(#clipMask)">
        <path class="cls-1" d="M38.99,24.34c-7.2,1.48-15.46,2.82-24.79,4.04-3.56.47-5.67.7-6.33.7-2.93,0-4.39-1.56-4.39-4.68,0-1.97.89-3.25,2.67-3.83.52-.16,1.86-.34,4.04-.53,5.7-.49,13.35-1.43,22.96-2.81,6.8-1.01,12.33-1.95,16.59-2.81,1.15-.23,2.03-.35,2.64-.35,1.8,0,3.12.69,3.94,2.07.52.89.77,1.83.77,2.81,0,1.9-1.21,3.29-3.62,4.18-4.17,1.52-7.84,3.68-11,6.47-5.46,4.78-8.19,10.14-8.19,16.07,0,6.35,3.74,10.7,11.21,13.04,2.18.7,3.27,2.11,3.27,4.22,0,1.08-.34,2.06-1.02,2.95-.75,1.01-1.86,1.51-3.34,1.51-2.93,0-6.29-1.44-10.09-4.32-5.65-4.29-8.47-9.96-8.47-17.02,0-5.86,2.2-11.26,6.61-16.21,1.71-1.92,3.63-3.6,5.77-5.03.19-.12.44-.28.77-.49Z"/>
        <path class="cls-2" d="M96.01,26.13h1.44c8.02,0,12.02,3.52,12.02,10.55,0,4.73-.94,10.31-2.81,16.73-1.64,5.53-3.45,9.54-5.41,12.02-1.76,2.2-3.8,3.3-6.12,3.3-2.51,0-5.19-1.71-8.05-5.13-1.22-1.45-1.83-2.62-1.83-3.52,0-.59.21-1.12.63-1.62.49-.59,1.12-.88,1.9-.88.68,0,1.43.32,2.25.95,1.5,1.15,2.55,1.72,3.16,1.72.89,0,1.91-1.2,3.06-3.59,1.31-2.74,2.44-6.22,3.38-10.44.75-3.38,1.12-6.22,1.12-8.54,0-2.48-1.31-3.73-3.94-3.73-.63,0-1.31.02-2.04.07-.73.05-1.3.07-1.72.07-3.21,8.41-6.64,15.95-10.3,22.61-.82,1.45-1.34,2.34-1.55,2.67-.96,1.41-2.2,2.11-3.73,2.11-.87,0-1.65-.27-2.36-.81-1.24-.96-1.86-2.13-1.86-3.52,0-.75.47-1.95,1.41-3.59,3.4-5.86,6.43-12.06,9.11-18.6-3,.38-5.1.66-6.29.84-.49.09-.88.14-1.16.14-.96,0-1.75-.35-2.36-1.05-.63-.77-.95-1.77-.95-2.99,0-2.39,1.38-3.75,4.15-4.08,3.61-.42,6.87-.79,9.77-1.09,1.73-4.92,3.12-9.2,4.15-12.83.61-2.2,1.96-3.3,4.04-3.3.98,0,1.9.23,2.74.7,1.24.7,1.86,1.7,1.86,2.99,0,1.15-1.24,5.09-3.73,11.81ZM117.74,24.02c1.73,0,4.38,2,7.95,6.01,5.2,5.81,7.8,10.07,7.8,12.76,0,1.62-.76,2.88-2.29,3.8-.82.49-1.69.74-2.6.74-1.48,0-2.66-.57-3.55-1.72-.21-.28-.55-.93-1.02-1.93-1.99-4.17-4.92-8.79-8.79-13.85-.61-.8-.91-1.63-.91-2.5,0-1.01.35-1.82,1.05-2.43.68-.59,1.46-.88,2.36-.88ZM122.31,14.32c1.34,0,3.45,1.31,6.33,3.94,2.46,2.23,3.69,3.98,3.69,5.27,0,.91-.4,1.7-1.2,2.36-.63.52-1.35.77-2.14.77-1.08,0-1.99-.61-2.74-1.83-1.36-2.23-3.02-4.36-4.99-6.4-.66-.68-.98-1.38-.98-2.11,0-1.34.68-2,2.04-2ZM128.57,8.62c1.41,0,3.42,1.11,6.05,3.34,2.46,2.06,3.69,3.82,3.69,5.27,0,1.01-.39,1.81-1.16,2.39-.56.42-1.2.63-1.9.63-.98,0-1.86-.59-2.64-1.76-1.31-1.95-2.99-3.9-5.03-5.87-.75-.73-1.12-1.43-1.12-2.11,0-.47.19-.9.56-1.3.37-.4.89-.6,1.55-.6Z"/>
        <path class="cls-3" d="M168.15,18.85l-1.27-2.95c-.42-1.01-.73-1.72-.91-2.14-.38-.84-.56-1.55-.56-2.11,0-1.27.68-2.25,2.04-2.95.89-.44,1.79-.67,2.71-.67,1.92,0,3.27,1.03,4.04,3.09.47,1.24,1.34,3.27,2.6,6.08,3.77-.77,6.74-1.46,8.89-2.07.82-.23,1.52-.35,2.11-.35,1.55,0,2.64.76,3.27,2.29.28.68.42,1.32.42,1.93,0,1.81-.98,2.99-2.95,3.55-1.48.42-4.31,1.04-8.51,1.86,1.05,2.25,2.06,4.27,3.02,6.05,3.35-.8,6-1.49,7.95-2.07.68-.21,1.23-.32,1.65-.32,1.38,0,2.41.73,3.09,2.18.37.75.56,1.52.56,2.32,0,1.66-.91,2.78-2.74,3.34-1.81.56-3.96,1.12-6.47,1.69,1.57,2.51,2.84,4.3,3.8,5.38,1.31,1.48,1.97,2.97,1.97,4.46,0,.82-.18,1.56-.53,2.21-.75,1.43-2.12,2.14-4.11,2.14-.56,0-1.34-.11-2.32-.32-2.37-.54-5.02-.97-7.95-1.3-2.02-.23-3.02-1.12-3.02-2.67s1.04-2.39,3.13-2.39c1.08,0,2.58.08,4.5.25-1.31-1.95-2.6-3.96-3.87-6.05-9.42,1.76-15.04,2.64-16.84,2.64-1.71,0-2.88-.77-3.52-2.32-.26-.59-.39-1.2-.39-1.83,0-1.71.81-2.84,2.43-3.38.3-.09.88-.19,1.72-.28,3.07-.37,7.28-1.03,12.62-1.97-1.08-1.95-2.13-4.01-3.16-6.19-7.66,1.43-12.61,2.14-14.84,2.14-2.6,0-3.9-1.42-3.9-4.25,0-2.11,1.3-3.28,3.9-3.52,3.82-.35,7.63-.86,11.43-1.51ZM160.81,52.81c1.43,0,2.57.77,3.41,2.32,1.36,2.53,3.78,4.27,7.28,5.2,2.65.7,6.13,1.05,10.44,1.05,3.49,0,5.24,1.49,5.24,4.46s-1.83,4.25-5.48,4.25c-6.8,0-12.36-1.14-16.7-3.41-3.21-1.66-5.52-3.89-6.93-6.68-.73-1.41-1.09-2.62-1.09-3.66,0-1.22.47-2.16,1.41-2.81.73-.49,1.53-.74,2.43-.74Z"/>
        <path class="cls-4" d="M246.24,20.93h5.66c2.76,0,4.15,1.38,4.15,4.15s-1.41,4.15-4.22,4.15c-.21,0-.54-.01-.98-.04-1.22-.07-2.8-.12-4.75-.14-.56,0-1.05-.01-1.48-.04l-.21,1.16-.49,2.92-.49,2.71-.42,2.32-.11.6c1.43-.05,4.01-.2,7.73-.46.4-.02.71-.04.95-.04,1.15,0,2.1.34,2.85,1.02.77.73,1.16,1.72,1.16,2.99,0,2.32-1.22,3.69-3.66,4.11-1.59.28-4.93.48-10.02.6-.3,2.37-.46,4.18-.46,5.45,0,6.16,2.98,9.25,8.93,9.25,8.37,0,12.55-4.11,12.55-12.34,0-1.97-.25-4.24-.74-6.82-.14-.73-.21-1.31-.21-1.76,0-1.27.49-2.18,1.48-2.74.61-.35,1.24-.53,1.9-.53,1.5,0,2.71.97,3.62,2.92,1.52,3.19,2.29,6.7,2.29,10.55,0,6.98-2.51,12.11-7.52,15.36-3.49,2.27-7.99,3.41-13.5,3.41-4.92,0-8.91-1.25-11.95-3.76-3.66-3-5.48-7.36-5.48-13.08,0-1.34.15-3.26.46-5.77-3.42,0-5.61-.06-6.57-.18-2.53-.33-3.8-1.68-3.8-4.04,0-1.22.35-2.18,1.05-2.88s1.62-1.05,2.74-1.05c.21,0,.54.01.98.04,1.29.09,3.47.14,6.54.14.42-2.81,1-6.13,1.72-9.95h-.63c-3.92.12-6.26.2-7.03.25-.33.02-.56.04-.7.04-1.08,0-2.04-.28-2.88-.84-1.05-.73-1.58-1.76-1.58-3.09,0-1.5.6-2.64,1.79-3.41.63-.42,1.44-.67,2.43-.74,1.52-.09,3.98-.2,7.38-.32.91-.02,1.83-.06,2.74-.11.4-2.11,1.02-5.06,1.86-8.86.56-2.48,1.98-3.73,4.25-3.73.58,0,1.1.06,1.55.18,1.92.52,2.88,1.77,2.88,3.76,0,.47-.09,1.1-.28,1.9-.87,3.89-1.36,6.14-1.48,6.75Z"/>
        <path class="cls-5" d="M308.08,11.08c3.07,0,4.61,1.58,4.61,4.75,0,.87-.18,4.35-.53,10.44l-.35,5.7c-.42,7.45-.63,13.03-.63,16.73,0,7.12,2.92,10.69,8.75,10.69,3.82,0,7.1-1.05,9.84-3.16,2.95-2.25,5.25-5.06,6.89-8.44.7-1.43,1.82-2.14,3.34-2.14.98,0,1.83.35,2.53,1.05.63.61.95,1.41.95,2.39,0,1.38-.79,3.42-2.36,6.12-5.04,8.65-12.19,12.97-21.45,12.97-6.82,0-11.71-2.5-14.66-7.49-1.81-3.05-2.71-6.94-2.71-11.67,0-3.75.27-10.1.81-19.05.3-5.48.46-8.92.46-10.3l-.04-3.9c0-3.12,1.51-4.68,4.54-4.68ZM326.32,20.36c1.31,0,3.41,1.31,6.29,3.94,2.46,2.23,3.69,3.98,3.69,5.27,0,.91-.4,1.7-1.2,2.36-.63.52-1.34.77-2.11.77-1.1,0-2.02-.61-2.74-1.83-1.27-2.11-2.93-4.24-4.99-6.4-.66-.7-.98-1.41-.98-2.11,0-1.34.68-2,2.04-2ZM333,14.67c1.38,0,3.4,1.11,6.05,3.34,2.46,2.06,3.69,3.82,3.69,5.27,0,1.01-.39,1.81-1.16,2.39-.56.42-1.2.63-1.9.63-1.01,0-1.89-.59-2.64-1.76-1.24-1.9-2.92-3.85-5.03-5.87-.75-.73-1.12-1.43-1.12-2.11,0-.49.19-.93.56-1.3.37-.4.89-.6,1.55-.6Z"/>
    </g>
</svg>

CSS

CSSは以下の通りです。

このとき「visibility: hidden;」を設定することで、アニメーションが始まる前にテキストの全体が一瞬表示されてしまう現象を防ぐことができます。

アニメーションが動くけれど、きれいな手書きにならない場合は「stroke-width」の値を調整してみてください。

#mask {
    visibility: hidden;
}

#base path {
    fill:#000; /* 塗りの色 */
}
#clipMask path,
#clipMask polyline,
#clipMask line {
    fill:none; /* 塗りの色 */
    stroke:#ffffff; /* 線の色 */
    stroke-width:50px; /* 線幅 */
    stroke-linecap:round; /* 線端の形状 */
    stroke-linejoin:round; /* 角の形状 */
}

JavaScript

JSコードは以下の通りです。

//SVGアニメーションの描画
var stroke;
stroke = new Vivus('mask', {//アニメーションをするIDの指定
    start:'manual',
    type: 'oneByOne',
    duration: 250,//アニメーションの間隔
    forceRender: false,//パスの再レンダリング防止
    animTimingFunction:Vivus.EASE_OUT,//アニメーションの種類
}
);

window.addEventListener('load', function() {
    document.getElementById('mask').style.visibility = 'visible'; // SVGを表示
    stroke.play(); 
});

ほかにもたくさんのオプションがありますので、気になる方はvivus.jsの公式ページをご覧ください。

単価を上げたい・ライバルと差別化したいコーダー必見!

さいごに…

そんな私を変えてくれたのは「アニメーション」でした。

「どうやって単価をあげたらいいんだろう…」
「デザイナーと違ってコーダーってどうやって差別化すればいいのかわからない…」

https://brmk.io/odFe

アニメーションができるようになると、制作会社様から「こんなアニメーションをつけたいんですけど…」という相談に自信をもって「できます!」と即答できます。

そうすると、不思議とアニメーションの案件以外もお仕事が回ってくるようになりますし、単価が高くたって値切られることなくすんなり見積もりが通ります。

だって、アニメーションできる人がまだまだ少ないから。

私が面談したどの制作会社様も「コーダーはたくさんいるけど、アニメーションができるコーダーがいない」と嘆いています。

WEB制作の人口はこんなにも多いのに、アニメーションのスキルがある人が少ない理由…

それは「体系的な学習手段が少ないこと」が原因です。

アニメーションでおなじみGSAPはもはや下記のBrainしか学習方法がないといっても過言ではないです。裏を返せば、このBrainでGSAPを勉強すれば速攻で差別化コーダーになれます。

ぶっちゃけ、このBrainの価格はアニメーション案件を1つ受ければ速攻でペイできるので、もはや学ばない手はありません。

学習中の人も、これから営業する人も、単価をあげたい人も、すべての人におすすめのアニメーション教材です!

https://brmk.io/odFe

まとめ

vivus.jsを使えば難しいコードを書かくことなく簡単に手書きアニメーションを実装することができます。

手書きアニメーションは今回使ったvivus.jsではなくGSAPを使って実装することもできます。
GSAPを使った手書きアニメーションの実装方法はこちらの記事をご覧ください。

コメント

タイトルとURLをコピーしました