こんにちは、福岡で筋肉と会話しながらウェブデザインしています、ケンタロウ(@kentaro_koga)です
今回、「スクロールしたら横からブロックがスライドで出てきて、横にスライドして消えると同時に下の文字・画像が表示されるやつ」というよく見るやつを作ってみました
こんなやつです。
「Block Reveal Effects」からサンプルのコードをダウンロードして使えば簡単にできますが、今回は自分で作ってみました。
やったことは簡単で、JavaScriptでスクロールの値を取って、要素が半分見える位置にきたらCSSを追加して、そのCSSにanimationを仕込んでいるだけです。
コピペで使い回せるかと思うので、自分の好みにカスタマイズしてみてください
HTMLの準備
サンプルなので簡単なhtmlです
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>BlockReveal - without Plugin</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div style="display: block; height: 100vh;"></div>
<div class="revealItem">
<h2 class="revealContent">Hello World!!</h2>
</div>
<div style="display: block; height: 100vh;"></div>
<div class="revealItem">
<h2 class="revealContent">Good evening World!!</h2>
</div>
<div style="display: block; height: 100vh;"></div>
<div class="revealItem">
<h2 class="revealContent">こんにちは。これは長文です。これは長文です。これは長文です。これは長文です。これは長文です。これは長文です。これは長文です。これは長文です。これは長文です。</h2>
</div>
<div style="display: block; height: 100vh;"></div>
<div class="revealItem">
<img src="moon.jpg" class="revealContent revealImg">
</div>
<div style="display: block; height: 100vh;"></div>
<script src="main.js"></script>
</body>
</html>
*例なのでスクロールできるように高さ50vhを付けたdivを間に置いています。
エフェクトをつけたい要素に「revealItem」とクラスをつけて、その中身にもrevealContentというクラスをつけておきます。
CSSの準備
こんな感じ
/* revealContentを最初は消しておく */
.revealContent {
opacity: 0;
}
/* revealActiveクラスが追加されて.3s後に表示する */
.revealActive .revealContent {
-webkit-transition-delay: .3s;
-o-transition-delay: .3s;
transition-delay: .3s;
opacity: 1;
}
.revealItem {
display: block;
position: absolute;
overflow: hidden;
}
/* before擬似要素の黒いblockにanimationをつけておく */
.revealItem.revealActive::before {
-webkit-animation: hideFromLeft .3s forwards, showFromLeft .3s forwards .3s;
animation: hideFromLeft .3s forwards, showFromLeft .3s forwards .3s;
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #000;
margin: 1px;
}
/* before擬似要素を左から右にスライドイン */
@-webkit-keyframes hideFromLeft {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(0%);
}
}
@keyframes hideFromLeft {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(0%);
}
}
/* before擬似要素を左から右にスライドアウト */
@-webkit-keyframes showFromLeft {
0% {
-webkit-transform: translateX(0%);
transform: translateX(0%);
}
100% {
-webkit-transform: translateX(100%);
transform: translateX(100%);
}
}
@keyframes showFromLeft {
0% {
-webkit-transform: translateX(0%);
transform: translateX(0%);
}
100% {
-webkit-transform: translateX(100%);
transform: translateX(100%);
}
}
/* 画像を使うときはvertical-align bottomをしないと下に余白ができてしまうので注意!! */
.revealImg {
width: 300px;
height: 200px;
-o-object-fit: cover;
object-fit: cover;
vertical-align: bottom;
}
.revealContentをopacity: 0;で非表示にしておきます。
.revealActiveというクラスを後からJavaScriptでつけるので、そのクラスがついた時に、時間差で.revealContentをopacity: 1;にします。
JavaScriptの準備
こんな感じでスクロールしてreveal要素がスクリーンに入ってきたらへんで.revealActiveというクラスをつけます。
クラスをつけるだけなので別に違う実装方法でも大丈夫です。
var timeoutId;
var revealElems = document.querySelectorAll('.revealItem');
window.addEventListener("scroll", function () {
if(timeoutId) return;
timeoutId = this.setTimeout( function() {
timeoutId = 0;
for (const revealElem of revealElems) {
const heightOfRevealElem = revealElem.clientHeight;
const revealPoint = (window.scrollY + window.innerHeight) - heightOfRevealElem / 2;
const halfShown = revealPoint > revealElem.offsetTop;
if (halfShown) {
if (!revealElem.classList.contains('revealActive')) {
revealElem.className += ' revealActive';
}
}
};
}, 300);
});
こんな感じでCSSアニメーションだけでBlock Reveal Effectみたいなのができました。
JSでスクロールに応じてクラスをつけていますが、これはお好みのタイミングでrevealActiveのクラスをつければいいのでカスタマイズしてみてください。
transformのtranslateをXからYに変えたり、100%から-100%に変えたりすることでスライドする方向を上下左右に変えれます。
以上、”「Block Reveal Effects」をCSSとJSで作ってみた”でした
他にいい実装方法があれば教えてくださいませ〜〜m(_ _)m