【簡単実装】Block Reveal EffectsをJavaScriptをCSSで作る【コピペでOK】

こんにちは、福岡で筋肉と会話しながらウェブデザインしています、ケンタロウ(@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



Posted

in