Blog

ブログ

SVGのマスクとアニメーションで遊んでみる【vivus.js】

最終更新日:|公開日:

SVGのマスクとアニメーションで遊んでみる【vivus.js】

こんにちは、WEBデザイナーの板垣です。

最近、WEBサイトで動画やアニメーションを目にする機会が大変増えてきており、また、制作のご要望でも複雑なアニメーションが増えてきているように感じます。

以前もHTML5 Canvasを使用したアニメーションの記事をいくつか書かせていただきました。

ただ今回はCanvasではなく、『SVG』でいろいろ変わったアニメーションを作成しようと思います。

SVGについて

SVG(Scalable Vector Graphics)とは、よく使われる写真などの「ラスタ形式」の画像とは違い、パス・テキスト・シェイプなどの集合を画像として扱う「ベクトル形式」の画像フォーマットの事です。

私自身は、よく、Adobe Illustratorでパスを使ったイラストを制作し、それをSVG形式で保存してWEBサイトにて表示したりします。

写真のような画像を作成することはできませんが、ベクトルで表現できるものであれば、拡大しても画像がボケたりせず、ファイルサイズが軽量という利点があります。

また、CSSやJavaScriptなどと組み合わせることにより、拡大してもボケないアニメーションが作成できます。

Canvasと比べて

Canvasで何かアニメーションを作ろうとするよりも、比較的JSの知識がなくても良いです。
使いやすいプラグインも多数出ており、それらを使用すればほぼ、JSの知識がなくても可能です。

今回はそういったSVGアニメーションのプラグインの中でも、パスのストローク(線を引くこと)を簡単に行える『vivus.js』を用いて、いくつかアニメーションを作っていこうと思います。

vivus.jsを使ってみる

https://maxwellito.github.io/vivus/

Illustratorでパスを作成

このようにIllustratorでパスを作成し、SVG形式で保存します。
できたSVGファイルを、「テキストエディタ」で開いてください。

SVGのファイルの中身

これがSVGのファイルの中身です。
この中で1、2行目は必要ありません。
svgタグ、styleタグ、pathタグが必要ですので、それらをHTMLファイル内に直に書きこんでください。

↓コードはこちら

<style type="text/css">
  .st0 {
    fill: none;
    stroke: #222222;
    stroke-width: 2;
  }
</style>

<svg id="wreath" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1280 640" style="enable-background:new 0 0 1280 640;" xml:space="preserve">
  <path class="st0" d="M141.9,362.6h-23l-11.6-50.9h-0.6l-11.4,50.9H71.6l-16.8-71.8l-6-0.8v-12.5h35.3v12.3l-3.8,0.4
  c-2.2,0.3-3.3,1.5-2.9,4.2l8.1,40.3h0.3l11.1-50.8h21.2l11,49.2h0.5l8.4-42.5l-6.9-0.6v-12.4h33.3v12.2l-2.8,0.3
  c-2.3,0.1-3.5,1.2-4.2,4.1L141.9,362.6z"/>
  <path class="st0" d="M199.6,322v28l11.1,0.6v11.9h-39.6V351l4.2-0.4c2.6-0.1,3.1-1.2,3.1-4.2v-33.2c0-2.6-0.8-3.5-2.9-3.7l-4.5-0.4
  v-12h26.8v9.9h0.3c2-4.7,7.3-11.6,18.3-11.6c3.6,0,8.3,0.5,11.8,1.9v25.3l-16.8,1v-8.8c0-1.8-0.1-2.3-1-2.7
  c-0.6-0.3-1.4-0.4-2.7-0.4C202.6,311.7,199.6,316.1,199.6,322z"/>
  <path class="st0" d="M296.4,314.9c0,18.2-15.6,22.8-34.9,22.5c0.6,6,4.5,10.9,12.8,10.9c6.5,0,12.2-2.4,16.3-5.1l5.6,14.2
  c-0.6,0.6-10.4,6.8-24.8,6.8c-22.4,0-31.1-14-31.1-32.9c0-19.2,11.4-36,33.5-36C287.2,295.4,296.4,301.5,296.4,314.9z M272.6,310.6
  c-6.7,0-11,6-11.4,14.3c11.5,0.4,16.9-2.7,16.9-8.8C278.1,312.1,275.8,310.6,272.6,310.6z"/>
  <path <!-- 省略 -->
</svg>

<script src="vivus.js">
<script type="text/javascript">
  new Vivus('wreath', { //ここにsvgタグにつけたIDを書き込む
    type: 'oneByOne',
    start: 'inViewport',
    duration: 200,
    forceRender: false,
    animTimingFunction: Vivus.LINEAR,
  });
</script>

vivus.jsの使い方ですが、プラグインを読み込んで、その後は先ほどのコードのように、svgタグにつけたIDと、オプションを書きこむと、

これだけで、こんなアニメーションが作れます。簡単ですね。

vivus.jsのオプション

Name Type Description
type string delayed(遅延),sync(同時),oneByOne(一筆ずつ)
file string SVGを外部から適応することが可能
start string アニメーションのトリガーを定義します。inViewport(viewport内で発火),manual(手動で設定),autostart(自動再生)
duration integer アニメーションの長さを設定(デフォルト:200)
delay integer 最初と最後のパスの描画間のフレーム間の時間を設定
onReady function 再生準備ができたときに呼び出される関数
pathTimingFunction function easing設定用の関数
dashGap integer 空白ダッシュの間に余分なマージン。 アニメーションの初期状態で不具合が発生した場合はそれを増やしてください
forceRender boolean ブラウザに、更新されたすべてのパス項目を再レンダリングさせます
reverseStack boolean 実行順序を逆にできます。最初のパスから最後のパスまでレンダリングした後に実行できます
selfDestroy boolean SVGのすべての余分なスタイリングを削除し、元のままにします

筆記体を今書いているようなアニメーション

最近WEBで見る機会の増えた演出ですね。これを実装してみましょう。

今回は、先ほどのパスをひく技術と、マスク機能を組み合わせて作ります。

マスクしたい画像はこちら

マスクしたい画像はこちら

パス作成の様子

このように、マスクしたい文字の部分を、覆い隠すようにパスを作成します。

出来上がったSVGを先ほどのようにテキストエディタで開き、必要なタグをHTMLに書き込みます。
この時に、先ほどと違う部分が2カ所あります。

imageタグとmaskタグです。
※imgタグではありません。

  • imageタグ:マスクしたい画像を読み込むタグ
  • maskタグ:マスクさせるパスを囲むタグ

↓コードはこちら

<style type="text/css">
  .st0{fill:none;stroke:#FFFFFF;stroke-width:50.1251;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
  .st1{fill:none;stroke:#FFFFFF;stroke-width:36.0901;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
  .st2{fill:none;stroke:#FFFFFF;stroke-width:33;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
  .st3{fill:none;stroke:#FFFFFF;stroke-width:32;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
  .st4{fill:none;stroke:#FFFFFF;stroke-width:32.0801;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
  .st5{fill:none;stroke:#FFFFFF;stroke-width:40.1001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
</style>

<svg version="1.1" id="wreath-1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1280 960" style="enable-background:new 0 0 1280 960;" xml:space="preserve">
  <image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="マスクしたい画像のURL" width="100%" height="100%" mask="url(#clipmask)"></image><!-- mask="url(#clipmask)" が重要 -->
  <mask id="clipmask" maskUnits="objectBoundingBox"><!-- id="clipmask" が重要 -->
    <path class="st0" d="M164.8,252.8c6,20.1-50.1,162.4-29.1,175.4c43,26.6,97.4-173.4,126.3-152.4c22.1,16-58.1,122.3-28.1,144.4
      c23,16.9,140.4-186.5,170.4-184.5"/>
    <path class="st1" d="M328.2,408.2c12-12,32.1-44.1,32.1-56.1c0-12,5.8,10.6,26.1,8c16-2,10,6,2,20.1s-29.3,44.9-16,54.1
      c20.1,14,58.1-54.1,70.2-50.1s20.1,20.1,38.1,4s14-32.1,0-34.1s-58.1,50.1-50.1,64.2c8,14,32.1,36.1,70.2-4"/>
    <path class="st2" d="M578.9,376.1c-6-10-5.6-25.3-28.1-14c-32.1,16-46.3,60.5-24.1,72.2c23.1,12.2,47.1-69.2,63.2-71.2
      s-52.5,66.1-29.1,73.2c17.3,5.2,43.2-8.3,61.4-34.6c22.3-32.2,48.8-73.7,48.8-73.7s-18.6,24.5-40.6,24.5c-16.8,0,67.7-3.9,48,0
      c-51,10-58.1,79.8-51.5,83.7c13.1,7.8,43.8-4.2,57.2-26.1c11.8-19.3,44-64.8,66.4-94.7c14.3-19.1,23.8-29.6,23.8-29.6
      s-104.3,137.3-90.2,143.4s111.3-101.2,95.2-61.1c-16,40.1-44.9,48.4-29.1,65.2c13.6,14.4,57.1-25.1,59.1-35.1"/>
    <!-- pathは省略 -->
  </mask>
</svg>

<script src="vivus.js">
<script type="text/javascript">
  new Vivus('wreath-1', { //ここにsvgタグにつけたIDを書き込む
    type: 'oneByOne',
    start: 'inViewport',
    duration: 200,
    forceRender: false,
    animTimingFunction: Vivus.LINEAR,
  });
</script>

imageタグもmaskタグも、hrefなどが見慣れない書き方ですが、
重要なのは、maskタグのIDをimageタグのmask要素のurl内に書き込むことです。

写真を変わった形でマスキングアニメーション

早速作ってみましょう。

マスクしたい画像はこちら
マスクしたい画像

今回もまた、Illustratorでマスクさせる形をパスで作りましょう。

パス作成の様子

出来上がったSVGをテキストエディタで開き、必要な部分をHTML内に書き込みます。

↓コードはこちら

<style type="text/css">
  .st0{
    fill: none;
    stroke: #FFFFFF; /* ここは白でないといけません。 */
    stroke-width: 186.3333;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-miterlimit: 10;
  }
</style>

<svg version="1.1" id="wreath-2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1280 960" style="enable-background:new 0 0 1280 960;" xml:space="preserve">
  <image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="マスクしたい画像のURL" width="100%" height="100%" mask="url(#clipmask)"></image><!-- mask="url(#clipmask)" が重要 -->
  <mask id="clipmask" maskUnits="objectBoundingBox"><!-- id="clipmask" が重要 -->
    <path class="st0" d="M226,253c55-49,219.4-94.1,143-17c-108,109-228.7,376.8-68,237c207.6-180.5,315-343,251.6-190
    C450.4,529.7,336.7,725,521,538c158.4-160.7,210-244,134.1-51.2C611.2,598.4,667,596,720,546c57.9-54.7,77.3-21.6,56,13
    c-28,45.4,8,75,51,34c69.9-66.7,233.4-202.9,120.4,5.6s-99.2,156.4,93.2,1.2c89.6-72.3-164,189.9,1.4,105.2"/>
  </mask>
</svg>

<script src="vivus.js">
<script type="text/javascript">
  new Vivus('wreath-2', { //ここにsvgタグにつけたIDを書き込む
    type: 'oneByOne',
    start: 'inViewport',
    duration: 200,
    forceRender: false,
    animTimingFunction: Vivus.LINEAR,
  });
</script>

複数のパスとマスクを同時に組み合わせてみる

ここで使う要素は全部で5種類

  • マスクしない背景画像×1
  • マスクしたい画像×2
  • マスクさせるパス×2

全ての要素を重ねてアニメーションするので、CSSを使って画像はこのように重ねます。

画像の重なり方

↓コードはこちら

<style type="text/css">
  .st0{
    fill: none;
    stroke: #FFFFFF;
    stroke-width: 160;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-miterlimit: 10;
  }
  .st1{
    fill:none;
    stroke:#FFFFFF;
    stroke-width:10;
    stroke-linecap:round;
    stroke-linejoin:round;
    stroke-miterlimit:10;
  }
  .st2{
    fill:none;
    stroke:#FFFFFF;
    stroke-width:8;
    stroke-linecap:round;
    stroke-linejoin:round;
    stroke-miterlimit:10;
  }
</style>

<svg version="1.1" id="wreath-3" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1280 960" style="enable-background:new 0 0 1280 960;" xml:space="preserve">
  <image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="マスクしたい画像①" width="100%" height="100%" mask="url(#clipmask-1)"></image>
  <image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="マスクしたい画像②" width="100%" height="100%" mask="url(#clipmask-2)"></image>
  <mask id="clipmask-1" maskUnits="objectBoundingBox">
    <path class="st0" d="M-69.4,299.5C27.5,170,464.2,0,522.1,53.6C599,124.8,29.3,280.7,47.2,451.5C66.1,632.4,692.5-22.3,827.1,77.6
      C1023.1,223.2-53.7,511.5,56.5,750.2c54.8,118.7,732.4-583.1,889.2-483.9c102.4,64.8-810.3,523-696,598.1
      C428.9,982.2,852.4,417.9,1012,427.7c184.6,11.3-406.5,309.2-391,437.6s423.5-358.6,526.5-367.1c103.1-8.5-316.9,369.3-249.9,389.2
      c52.2,15.5,273.2-246.6,321.2-240.9c48,5.6-67.9,131.3-36,213.2" />
  </mask>
  <mask id="clipmask-2" maskUnits="objectBoundingBox">
    <path class="st1" d="M758.4,255.1c-2.5,8-8.3,17.1-13.4,16.3s-2.6-10.4,4.1-21.3s25.3-16.5,37.7-15.7s30.9-10.3,32.3-14.3
      s-21.8,28.4-33.9,57c-3.3,7.8-14,30.6-11.5,32.5c2.5,1.9,15.4-6.3,33.5-36.9c18.2-30.6,20.7-15.9,17.5-5.6c-4,13-7.8,39.9-10.5,39.1
      c-1.7-0.6,30.4-56.7,58-84.4c7.5-7.5,14.3-11.7,20-14c9.4-3.9,16.8,4.1,16.2,10.7" />
    <path class="st2" d="M852.1,280.8c5.7-4.9,15.4-16.8,16.7-13.5s-6.1,19.8-7,20.5c-0.9,0.8,20.1-32.9,21.6-28.6
      c1.6,4.3,2.9,17,14.9,9.8c12-7.3,18.9-15.3,15.6-18.3c-0.8-0.7-8.4,0.4-11.1,12.6c-2.6,12.2,10.6,9.6,17.2,5.2
      c6.6-4.4,6.7-6.1,6.7-6.1" />
    <path class="st2" d="M949.9,250.9c1.1-3.4,1.3-9.8-5.7-5.1c-4.7,3.1-13.3,12.1-11,16.1c2.3,3.9,11.9-1.4,14.5-5.6s1.9,3.1,5.1,3
      c3.2-0.1,20.7-13,45.4-51.1c25.6-39.5-3.4,10.8-6,14.5c-2.6,3.7-12.5,24.1-4.8,27.3c2.8,1.1,22.6-8.8,37.1-27.4
      c5.4-7,11.2-10.1,15.8-14.5c7.7-7.2,11.9-15.7,15.6-24.2c5.9-13.7,14-30.9-4.5-17.6c-8.1,5.8-16.3,22-18.7,33.8
      c-2.3,11.5-3.2,18.9-4.9,24.9c-3.4,11.9-6.4,11-8.1,16.3c-1.3,3.9,8.1-3.5,13.2-8.7c5.1-5.2,9.9-10.4,10.2-7c0.3,3.3,1.1,21,26-3.6" />
  </mask>
</svg>

<script src="vivus.js">
<script type="text/javascript">
  new Vivus('wreath-3', { //ここにsvgタグにつけたIDを書き込む
    type: 'oneByOne',
    start: 'inViewport',
    duration: 300,
    forceRender: false,
    animTimingFunction: Vivus.LINEAR,
  });
</script>

ポイントは、svgタグの中には、複数のimageタグとmaskタグを入れられることです。
ただしその場合は、maskタグのIDなどがかぶらないように気を付けてください。
また、vivus.jsのオプション[type:oneByOne]は、別のmaskタグの中であっても、pathを上から順番にアニメーションしてくれます。便利ですね。

背景画像

SVGのアニメーションは、このようなマスクアニメーションだけでなく、もっと複雑なものも可能です。
もしSVGアニメーションを使用したWEBサイト制作に興味がありましたら、是非下のボタンから、お問い合わせください。

板垣
担当者:板垣
JavaScript、webページ上のアニメーションなど諸々ギミックが得意なデザイナー。 好きな事は Web技術情報収集、映画視聴、合気道。