表現の幅を広げよう! 〜SVG編〜


SVG

こんにちは、アンドレです。
表現の幅を広げよう! と思いつつ、日々だけが過ぎ去っていたのですが、今年ももうすぐ終わりということで、とりあえずSVGの学習を始めました。
今回はそのアウトプットとして、簡単な導入およびライブラリ(SVG.js)を使ったサンプル等をご紹介したいと思います。

SVGとは(ざっくり)

キチンとした説明はWikipediaにお任せするとして、Web的に重要な特性は、

  • 拡大・縮小しても粗くならない(レスポンシブ向き)
  • CSSの指定が有効
  • JavaScriptで操作できる

あたりでしょうか。
構成要素は基本的に、「点」とそれを結ぶ「線」と線に囲まれた部分の「塗り」です。
※imgタグや背景(background-image)として読み込んだ場合は無効です。

SVGアニメーション

SVGアニメーションというと、線がだんだん描画されていくものが思い浮かぶかと思います。
そういうシンプルなアニメーションは、vivus.jsを使えば簡単に実装できます。
早速見てみましょう。

See the Pen vivus.js by Takamasa Okada (@NP-okada) on CodePen.

※アイコンSVGはSimple Iconsのものを使用しています。

シンプルですね(一応最後にclass追加して塗りをフェードインさせています)。

上記アニメーションの原理についての説明

線(stroke)を扱うCSSプロパティに「stroke-dasharray」および「stroke-dashoffset」というものがあります。
前者は破線の間隔を、後者は破線の始点を指定するものです。
破線の間隔を線の長さと同じにし、それと同じだけ破線の始点をずらした状態から、破線の始点をだんだん戻していくことで、線がだんだん描画されていくアニメーションとなります(下図参照)。
アニメーションの原理解説のイメージ
vivus.jsはJavaScriptを通してstroke-dasharrayおよびstroke-dashoffsetを操作することで、自動でアニメーションさせてくれているというわけです。

SVG.jsを使って操作

SVGのライブラリで一番メジャーなのは、スポンサー的にもSnap.svgかと思うのですが、GitHubでここ2年ほど更新がないので、今回は

  • 最近も更新されている(2018/12にバージョン3が出ました)
  • It’s speedy.
  • あまり解説記事がない

の3点から、SVG.jsを使っていくつかサンプルを作ってみます。
ただし今回は、執筆時の公式ドキュメントのバージョンである2.7系の2.7.1を使用することとします。

上記vivus.jsのサンプルと同じアニメーション

See the Pen SVG.js by Takamasa Okada (@NP-okada) on CodePen.

解説

adopt()を使って既存のpath要素をSVG.jsで扱えるように取り込み、length()でpathの長さを取得。
その後、取得したpathの長さをstroke-dasharrayおよびstroke-dashoffsetに指定し、animate()を利用してstroke-dashoffsetを0に戻していくことで、同様のアニメーションにしています。

画像のマスキング

CSSでのマスキングは対応ブラウザに難がありますが、SVGでもマスキングできます。

See the Pen SVG.js – mask by Takamasa Okada (@NP-okada) on CodePen.

解説

今回ややコードが長いので、区切りつつ解説すべく、CodePenのほうにコメントしましたので、そちらをご参照ください。
ちなみに、ほぼ同じ機能のclip()およびclipWith()というのもありますが、clipは

  • マスクの透過度を変えられない
  • オンマウスなどのイベント感知範囲がマスク通りになる(maskはならない)

という違いがあります。

パスの変形

See the Pen SVG.js – pathmorphing by Takamasa Okada (@NP-okada) on CodePen.

解説

plot()に変形後のパスのデータを渡してやるだけでOKです(上記は対角線上のポイントを入れ替えています)。
ただし、ポイントの数が違ったり(下記)、渡すデータによってはうまく補完できない場合があるので、基本的には「svg.pathmorphing.js」プラグインを読み込んでおくのが無難かと思います。

See the Pen SVG.js – pathmorphing2 by Takamasa Okada (@NP-okada) on CodePen.

おまけ・スクロールに応じて描画させる

これまで2回ほど記事にした、僕御用達のScrollMagicで、スクロールとstroke-dashoffsetの値を連動させることができます。

See the Pen SVG with ScrollMagic by Takamasa Okada (@NP-okada) on CodePen.

こちらもややコードが長いので、CodePenのほうにコメントしました。
ScrollMagic Examplesにある通り、TimelineMaxを使えば複数の要素を、タイミングをずらしつつ操作することも可能です。

最後に

初めてsvg要素を見た時は、path要素のd属性の点の記述がずらずら並んでいるのを見て、「なにこれ難しそう…」と思ったものですが、改めてキチンと向き合ってみると、意外とシンプルで扱いやすいかも? という印象です。
実案件でもうまく活用できるよう、これからも理解を深めていきたいと思います。
次回はcanvasについて書く予定です!