こんにちは、アンドレです。
以前、ScrollMagicのパララックスサンプルを解説しましたが、やはり、「スクロールに応じて○○する」というのはよくあるご要望で、そういった際にScrollMagicはとても便利なライブラリです。
そこで今回は、ScrollMagicを使ってできることの一例として、ページの途中から追従するメニュー・サイドバーの実装例をご紹介したいと思います。
追従メニュー
See the Pen 追従メニュー by Takamasa Okada (@NP-okada) on CodePen.
コードと解説
var controller = new ScrollMagic.Controller(); var scene = new ScrollMagic.Scene({ triggerElement: '#menu', triggerHook: 0, }) .setPin('#menu') .addIndicators() .addTo(controller);
最初にスクロールの反応領域(Scene)を管理するオブジェクト(Controller)を変数に格納し、その後Sceneを生成してControllerに追加する、という基本の流れはいつも通りです。
Sceneを生成する際のオプションで、
triggerElement: ‘#menu’(Scene開始地点をid=”menu”の要素に指定)
triggerHook: 0(どの位置でScene開始地点を捉えるか、0なら画面最上部、1なら画面最下部)
を指定することで、id=”menu”の要素が画面最上部に来たら動作開始となります。
追従(=要素の固定)にはSceneが持っているメソッドのsetPinを使用します。setPinの第1引数に’#menu’を指定し、id=”menu”の要素を固定します。
たったこれだけです!
(addIndicatorsはデバッグ用にイベントトリガー等を可視化するだけです)
ちなみに追従ヘッダーがある場合は、Sceneのオプションに
offset: -(マイナス)ヘッダーの高さ
を指定してやると、画面最上部からヘッダーの高さ分ズレて追従するようになります。
追従サイドバー
See the Pen 追従サイドバー by Takamasa Okada (@NP-okada) on CodePen.
コードと解説
var controller = new ScrollMagic.Controller(); var scene = new ScrollMagic.Scene({ triggerElement: '#main', triggerHook: 0, duration: getDuration, }) .setPin('#aside__inner') .addIndicators() .addTo(controller); function getDuration() { return $('#main').height() - $('#aside__inner').innerHeight(); }
追従サイドバーは、メインコンテンツの間でのみ追従するように、durationを指定する必要があります。
durationには関数を指定することができ、動的に数値を返す関数を指定すれば、画面のリサイズ等にも対応できるようになります(再取得のタイミングはデフォルトで0.1秒毎)。
今回はgetDurationという関数を定義し、メインコンテンツ(#main)の高さからサイドバー(#aside__inner)自身の高さを引いた数値を返すことで、メインコンテンツの間でのみ追従するようにしています。
その他の注意点としては、setPinメソッドを指定した要素は、ScrollMagicが生成するdivでラップされ、そのdivには要素固定の為のstyleが当たるので、レイアウト系のCSSを指定している要素(今回だとfloat: rightを指定しているaside要素)を指定すると具合が悪かったりします。
そういう場合は、例の#aside__innerのように、divを1つ挟んでやると良いです。
まとめ
追従メニューに関しては、それ専用のプラグインを使ったこともあるのですが、専用の割にカスタマイズがしにくかったりしたので、結局ScrollMagicに落ち着きました(setPinメソッドが用意されているので、実際その用途も考慮されていると思います)。
また、追従サイドバーは自分でコードを書いたことがあるのですが、記述がなかなか煩雑になってしまった記憶があります。
そういった、複雑・煩雑になりがちなスクロールイベントを、簡単な指定でまとめて管理できるScrollMagicは非常に便利なので、皆さんもぜひ活用してみてください!