マウスホイールで切り替わる全画面コンテンツをつくってみた
- 2019.03.22
- javascript+css つくったもの
- 脱jQuery
マウスホイールで切り替わる全画面表示のコンテンツをつくってみました。
マウスホイールに反応して、次のページがフェードインしてくるようにしています。
スマホの場合は上下のフリックで切り替わるようにしました。
まずはデモをご確認ください。
コードと解説
html
<div class="contents page1 show">1</div> <div class="contents page2">2</div> <div class="contents page3">3</div> <div class="contents page4">4</div> <div class="contents page5">5</div> <div class="contents page6">6</div> <div class="contents page7">7</div> <div class="contents page8">8</div> <div class="contents page9">9</div> <div class="contents page10">10</div>
10個のコンテンツを用意しました。
.show というクラスを付け外しすることで、コンテンツを切り替えます。
一番最初のコンテンツはあらかじめ .show を付けておき、表示させておきます。
css
body { position: relative; width: 100%; height: 100vh; margin: 0; padding: 0; } .contents { width: 100%; height: 100vh; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); opacity: 0; transition: 1s; text-align: center; line-height: 100vh; } .page1 { background-color: aquamarine;} .page2 { background-color: lightsalmon;} .page3 { background-color: wheat;} .page4 { background-color: cornflowerblue;} .page5 { background-color: gold;} .page6 { background-color: olive;} .page7 { background-color: khaki;} .page8 { background-color: orange;} .page9 { background-color: gainsboro;} .page10 { background-color: yellow;} .show { opacity: 1; }
body にposition: relative; を入れておきます。
.contents に各コンテンツのスタイルを指定。
幅・高さを画面いっぱいに。
position: absolute; で画面固定。
opacity: 0; にしておき、あらかじめ非表示とします。
transition: 1s; を入れ、フェードインのアニメーションするように。
.show に opacity: 1; を入れ、この .show を付け外しすることでコンテンツを入れ替えます。
javascript
var contents = document.querySelectorAll('.contents'); // コンテンツの取得 var count = 1; // 表示させるコンテンツの番号を設定 // スマホの場合、タッチスライドで動かす if ((navigator.userAgent.indexOf('iPhone') > 0 && navigator.userAgent.indexOf('iPad') === -1) || navigator.userAgent.indexOf('iPod') > 0 || navigator.userAgent.indexOf('Android') > 0) { // タッチの位置を取得するための変数 var touchStart, touchMove, touchDistance; // タッチし始めた位置 window.addEventListener('touchstart', function (e) { touchStart = event.touches[0].pageY; touchMove = event.touches[0].pageY; }); // タッチし、動かした位置 window.addEventListener('touchmove', function (e) { touchMove = event.touches[0].pageY; }); // タッチ終了時に window.addEventListener('touchend', function (e) { // タッチの開始位置から、移動後の位置を引く touchDistance = touchStart - touchMove; // タッチスライドが上方向だったら if (touchDistance > 70) { // countの値をプラス count++; // countの値の上限をコンテンツの数にする if (count >= contents.length) { count = contents.length; } } // タッチスライドが下方向だったら else if (touchDistance < -70) { // countの値をマイナス count--; // countの値の下限を1とする if (count <= 1) { count = 1; } } // タッチスライドがなかったら、何もしない else { } // 一旦コンテンツを全部非表示にして for (var i = 0; i < contents.length; i++) { contents[i].classList.remove('show'); // showクラスを削除して非表示に } // 該当のコンテンツのみ表示 contents[count - 1].classList.add('show'); // showクラスを付与して表示 }); } // PCの場合、ホイールで動かす else { var countFlg = false; // ホイールのイベントをやたらめったに取得しないためのフラグ // ホイールの動きがあったら window.addEventListener('wheel', function (e) { // countFlgがfalseの場合だけ動く if (!countFlg) { // ホイールが下方向だったら if (e.deltaY > 0) { // countの値をプラス count++; // countの値の上限をコンテンツの数とする if (count >= contents.length) { count = contents.length; } } // ホイールが上方向だったら else if (e.deltaY < 0) { //countの値をマイナスにする count--; // countの値の下限を1とする if (count <= 1) { count = 1; } } // countFlgをtrueにする countFlg = true; // 数秒後、countFlgをfalseにして、またホイールのイベントで動くように setTimeout(function () { countFlg = false; },1000 ); // 秒数を指定。ミリ秒 // 一旦コンテンツを全部非表示にし、 for (var i = 0; i < contents.length; i++) { contents[i].classList.remove('show'); // showクラスを削除して非表示に } // 該当コンテンツのみ表示 contents[count - 1].classList.add('show'); // showクラスを付与して表示 } }); }
スマホの場合は上下のフリックで、PCの場合はマウスホイールで反応させます。
スマホはフリックで
まずはスマホの場合。
touchstart でタッチを開始した位置を記録。
touchmove でタッチして移動した位置を記録。
touchend でタッチが離れたときに、touchstart(タッチの開始位置)からtouchmove(タッチして移動した位置)を引き算。移動距離を測ります。
上方向に動いたらcountの数値をプラス、下方向に動いたらマイナス。
一旦全コンテンツから .show を削除し非表示。
コンテンツの count番目に .show を付与して表示させます。
このときtransition: 1s; が効いているので、フェードインのアニメーションになります。
スマホの場合のポイント
touchstart でタッチを開始した時点で、
touchstart(タッチを開始した位置)と一緒に、touchmove(タッチして移動した位置)にもタッチを開始した位置を代入しておきます。
これをしておかないと、二回目のタッチの時に、ひとつ前の touchmove の値が残ってしまい、正しく動いてくれません。
PC時のホイールでの制御
wheelイベントで、マウスホイールの動きを取得。
event.deltaYの移動距離が上方向か下方向かで、countの値とプラスもしくはマイナス。
一旦全コンテンツから .show を削除し非表示に。
count番目のコンテンツに .show を付与して表示させます。
PCホイール取得時のポイント
何も気にせずやってしまうと、マウスホイールをぐりぐりっとたくさん動かしたときに、countの値をたくさん変化してしまいます。
なので一回目のホイールの動きだけを検知しするようにします。
countFlg という変数を用意。これが false の時だけホイールが反応するようにします。
反応したら countFlg を true にします。
setTimeout を使用し、trueになってから1秒後に countFlg を false に戻しています。
バリエーション
cssを変更するだけで、いろんな表示の仕方が可能です。
たとえば、フェードインしながら下からせり上がってくるようなバージョンを作ってみました。
以下、デモです。
css
cssだけ変更をしています。
body { position: relative; width: 100%; height: 100vh; margin: 0; padding: 0; overflow: hidden; } .contents { width: 100%; height: 100vh; position: absolute; top: 50%; left: 50%; transform: translate(-50%, 100%); opacity: 0; transition: 1s; text-align: center; line-height: 100vh; } .page1 { background-color: aquamarine;} .page2 { background-color: lightsalmon;} .page3 { background-color: wheat;} .page4 { background-color: cornflowerblue;} .page5 { background-color: gold;} .page6 { background-color: olive;} .page7 { background-color: khaki;} .page8 { background-color: orange;} .page9 { background-color: gainsboro;} .page10 { background-color: yellow;} .show { transform: translate(-50%, -50%); opacity: 1; }
.contents に transform: translate(-50%, 100%); を追加。
あらかじめ画面の下の外に配置しておきます。
.show に transform: translate(-50%, -50%); を追加。
.show が付与されて表示されるときに、位置を画面内に持ってきます。
-
前の記事
振ると色が変わるスマホ用コンテンツをつくってみた 2019.03.21
-
次の記事
スクロールで要素が画面の中に入ったらふわっとフェードインするコンテンツ 2019.03.23