💧

おしゃれサイトで見かけるSVGがグニョーンってなるアニメーションをドロワーメニューで使ってみた

2022/07/17に公開

デザインスタジオ・エルさんのコーポレートサイトをはじめ、おしゃれサイトで見かけるSVGアニメーションがカッコよかったので、Twitterで質問したところありがたいことにいくつかの実装方法を教えていただけました。
https://twitter.com/jookalubi24/status/1541759044456960000

その中でもSTUDIO DETAILSさんのこちらのCodePenを参考に自分なりに解釈・応用して作成し、実務の案件に取り入れられたのでご紹介します。

デモ

何をしているのか

ざっくりと説明すると

  1. ハンバーガーボタンをクリック
  2. メインコンテンツ(今回は<main><footer>)が下へ移動しながら非表示になる
  3. 画面いっぱいを覆っている<path>を画面上部から下部に現れるようにd属性の値をGSAPタイムラインで変えて黒で塗る
  4. メニュー画面を移動させながら表示すると同時に5.を処理
  5. 画面を黒く塗っていた<path>を画面上部から下部に消えていくようにd属性の値をGSAPタイムラインで変える
  6. (閉じるボタンではこれを逆行させる)

Web制作では多くの場合は固定ヘッダーかと思います。もし固定ヘッダーもグニョーンさせたい場合は、<header>のCSSを整えた上で、JSの下記の部分を修正してください。(その他wrapper直下に他の要素を置きたい場合も同様)

const CONTENTS = {
  HEADER: document.getElementById("header"),
  MAIN: document.getElementById("main"),
  FOOTER: document.getElementById("footer")
};

gsap.timeline()
//(中略)
.to(
  [CONTENTS.HEADER, CONTENTS.MAIN, CONTENTS.FOOTER], // CONTENS.HEADERを追加

コード解説

HTML要素

HTMLの全体要素wrapperの中に

  • ハンバーガーボタン
  • メニュー
  • メインコンテンツ
  • フッター
  • SVG要素(グニョーン要素)

を入れています。
SVGは固定なので基本的にはどこに置いても問題ないと思われます。

index.html
<div class="wrapper">
  <button></button>
  <nav></nav>
  <main></main>
  <footer></footer>
  <svg class="overlay" width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="none">
    <path id="overlayPath" class="overlayPath" vector-effect="non-scaling-stroke" d="M 0 100 V 100 Q 50 100 100 100 V 100 z" />
  </svg>
</div>

SVGについて

実際に黒色で変化しているのは<path>の要素になります。(試しに<path>fillを変更するとグニョーンの色が変わります。)
<path>の中のd属性の値を変えることで色や塗りの形を変えることができます。

また参考コードではSVGがposition:absoluteになっていましたが、これは高さが固定されているレイアウトやページに限定されます。

今回のドロワーメニューに実装する場合、<body>wrapperの高さがコンテンツ量によって可変します。すると仮にabsoluteしていると<body>の高さすべてにかけてグニョーンと伸びてカーブが鋭くなりダサくなってしまうので、position:fixedに変更しました。

d属性については説明が長くなってしまうかと思いますので気になる方は下記ページをご参照ください。
https://developer.mozilla.org/ja/docs/Web/SVG/Attribute/d

preserveAspectRatio="none" is 何

<svg>についているこちらの属性は、viewBoxviewportの適合関係のようなものらしいです。

The preserveAspectRatio attribute indicates how an element with a viewBox providing a given aspect ratio must fit into a viewport with a different aspect ratio.

https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio

vector-effect="non-scaling-stroke" is 何

pathについているこちらの属性は、描画するときのベクトル効果の指定らしいです。

The vector-effect property specifies the vector effect to use when drawing an object. Vector effects are applied before any of the other compositing operations, i.e. filters, masks and clips.

https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/vector-effect

GSAPを使っていい感じにアニメーションさせる

参考コードではGSAPタイムラインを使ってアニメーションさせていました。

GSAPタイムラインのイージングは基本的に参考コードをそのまま流用しています。
気持ち良く感じる動きにするために、GSAPのpowerイージングと時間の制御だけで作り込んでいてすごいなと思いました。

工夫点

今回はハンバーガーボタンとメニューに対してaria-hiddenaria-labelを変更する必要があったので、CSSでは最小限のスタイルだけ当てて基本的にはGSAPタイムライン内で処理を行うようにしました。GSAPでクラス付与してCSSで制御させてもよかったのですが、個人的に一連の流れが分かりにくかったのであえてタイムライン上でCSSも制御しました。

まとめ

少し前にSVGのpathアニメーションで苦戦した際に色々調べたのである程度理解したと思っていましたが、まだまだ理解できていない部分が多く、SVGは本当に奥が深いなと思いました💦

またThree.jsなどを使った実装方法もあるらしいので、そっち系が強い方はもっとおしゃれなグニョーンが表現できそうですね。

参考

https://codepen.io/shirasawa/pen/vYegodM

Discussion