【ScrollMagic】スクロールに応じてclassを付与しcssでアニメーション【ES6】
webサイトを閲覧していてスクロールに反応して要素がフェードインしてくるなどのアニメーションを見たことがありませんか?
今回の記事では僕が実際に案件で使用しているスクロールに反応するアニメーションの実装方法をご紹介していきます。
目次
今回実装するもの
- 特定の要素が画面内に入ってきたらそれに
is-animated
classを付与 is-animated
classが付与されたらその要素をcssでアニメーションさせる
上記2点です。シンプルですね!
アニメーションに使用するcssは主にtransition
もしくはanimation
となります。
注意事項
- ES6を使用するためWebpack+Babelなどのコンパイル環境推奨
- cssにscssの記法があります
サンプル
実装のサンプルです
htmlとcssを用意
htmlとcssを下記のものとします
※今回使用するhtmlとcssはサンプルなので各自書き換えてください。
html
アニメーションさせたい要素にjs-scrollAnimation
classを付与しておきます。
<div class="l-wrapper">
<div class="l-section js-scrollAnimation">
<p class="c-text">セクション1です。</p>
</div>
<div class="l-section js-scrollAnimation">
<p class="c-text">セクション2です。</p>
</div>
<div class="l-section js-scrollAnimation">
<p class="c-text">セクション3です。</p>
</div>
<div class="l-section js-scrollAnimation">
<p class="c-text">セクション4です。</p>
</div>
</div>
css(scss)
js-scrollAnimation
が画面内に入ってきたら1.5秒でフェードインしてくるcssです。
.l-wrapper {
max-width: 700px;
width: 100%;
margin: 0 auto;
}
.l-section {
height: 600px;
background: #ccc;
margin-bottom: 30px;
opacity: 0;
transform: translate3d(0, 100px, 0);
transition: opacity 1.5s, transform 1.5s;
&.is-animated {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
.c-text {
text-align: center;
}
スクロール用ライブラリ「ScrollMagic」を読み込み
ここからは最重要であるjavascriptの解説をやっていきます。
今回の方法にはScrollMagicというライブラリを使用します。
ScrollMagicとはスクロールに応じて何かをする為のライブラリです。
ScrollMagic公式
CDN(scriptタグ)の場合
<script src="//cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/ScrollMagic.min.js"></script>
NPMの場合
npm install scrollmagic
import ScrollMagic from "scrollmagic";
classを付与するスクリプトを記述
使いまわし出来るようにES6のクラス構文で記述してます。
class ScrollAddClass {
//初期値を設定
constructor() {
this.controller = new ScrollMagic.Controller();
this.settings = {
target: ".js-scrollAnimation",//アニメーションさせたい要素
addClassName: "is-animated",//アニメーションさせたい要素に付与するclass
triggerHook: "onEnter",//発火タイミング:画面下"onEnter"、画面中央"onCenter"、画面上"onLeave""
offset: 0//100だと100px早く発火-100だと-100px遅く発火
}
}
//実行
init(options) {
this.setup(options);
this.attachEvent(this.controller);
}
//外部から入力された設定をマージ
setup(options) {
this.settings = Object.assign({
target: this.settings.target,
addClassName: this.settings.addClassName,
triggerHook: this.settings.triggerHook,
offset: this.settings.offset
}, options || {});
}
//ScrollMagicを実行
attachEvent(controller) {
let targets = document.querySelectorAll(this.settings.target);
if (targets.length == 0) {
return;
}
for (let target of targets) {
let scene = new ScrollMagic.Scene({
triggerElement: target,
triggerHook: this.settings.triggerHook,
offset: this.settings.offset
})
.addTo(controller);
scene.on('enter', () => {
target.classList.add(this.settings.addClassName);
});
}
}
}
スクリプトを実行
let scrollAnimation = new ScrollAddClass();
scrollAnimation.init();
- new演算子を使用しインスタンスを作成
- 作成したインスタンスの
init
メソッドを実行
以上でjs-scrollAnimation
classが付いた要素が画面内に入って来るとそれにis-animated
クラスを付与します。
あとはcssでアニメーションさせてください。
オプション
下記のようにinit
メソッドの第一引数にオプション用のオブジェクトを渡すことでclassを付与したい要素の変更やそのタイミングを変更できます。
scrollAnimation.init({
target: '.js-hoge',
addClassName: "is-hoge",
triggerHook: "onCenter",
offset: 100
});
詳細
プロパティ | デフォルト | 説明 |
---|---|---|
target | ".js-scrollAnimation" | classを付与したい要素 |
addClassName | "is-animated" | targetに付与するclass ※.(ドット)を付けないで記述 |
triggerHook | "onEnter" | classを付与するタイミング "onEnter":targetが1%でも表示されたら "onCenter":targetが50%表示されたら "onLeave":targetが100%表示されたら |
offset | 0 | classを付与するタイミングの微調整 100だと100px早く発火-100だと-100px遅く発火 |
おまけ:モジュール化(外部ファイル化)
以上で説明は終わりですが先程のjavascriptをモジュール化して外部から読み込めるようにします。
外部ファイルを作成
ファイル名をここではscrollAddClass.jsとします。
import ScrollMagic from "scrollmagic";
const scrollAddClass = (() => {
//==================
//ここに先程のスクリプトを記述
//==================
return new ScrollAddClass();
})();
export default scrollAddClass;
作成したファイルをインポートし実行
以下のようにimportします。
/path/to/の箇所は各自パスを合わせてください。
import scrollAnimation from "/path/to/scrollAddClass.js";
scrollAnimation.init();
以上でモジュール化は終わりです。
こうすることでどこからでも今回作成したスクリプトを使用することができます。
最後に
今回ご紹介した方法はスクロールでclassを付与するだけのシンプルなものですが、外部ファイル化やオプションを渡して挙動を変更したかったので少々長くなってしまいました。
また、モジュール化といってもScrollMagicという外部ライブラリに依存しているため使いづらい点もあるかと思います。
今度はjQueryを使用した簡易版などをご紹介できればと思っています。