よくある画像スライダーですが、先日、ズームインしながらフェードで切り変わるという少し特殊なスライダーを実装する必要があったのでその時の備忘録として。

スライダー系のプラグインは様々ありますが、プラグインを使用して実現する方法がパッと浮かばなかったので、1から自分でスクリプトを組みました。

と言いっても、スクリプトの処理自体はタイミングを合わせてクラスを付け外しするだけのシンプルもので、アニメーション部分はCSSに任せてあります。

また、jQueryは使わずに実装してみました。

目次

動作デモ

まずは完成したスライダーの実物を載せておきます。

See the Pen ズームインしながらフェードで切り替わるスライダー by LOOS WEB STUDIO (@loos) on CodePen.

 

スクリプトとそれに対応するHTML・CSS

まず、HTML側はスライダーの親要素に slide_wrapp という名前のIDがついているとし、スライダーとして機能する要素に slide_itemという名前のクラスがついているとします。

HTML

<ul id="slide_wrapp">
  <li class="slide_item"><!-- スライド1の中身 --></li>
  <li class="slide_item"><!-- スライド2の中身 --></li>
  <li class="slide_item"><!-- スライド3の中身 --></li>
</ul>

表示したい内容をliタグに突っ込んでください。

次いで、スクリプトです。

処理の内容としては、スライド要素.slide_itemに対して、順番にshow_zoom_という2種類のクラスを付け外していくだけのものです。

JS

window.addEventListener('load', function () {
   sliderStart();
});

function sliderStart() {

    const slide = document.getElementById('slide_wrapp');      //スライダー親
    const slideItem = slide.querySelectorAll('.slide_item');   //スライド要素
    const totalNum = slideItem.length - 1;                     //スライドの枚数を取得
    const FadeTime = 2000;                                     //フェードインの時間
    const IntarvalTime = 5000;                                 //クロスフェードさせるまでの間隔
    let actNum = 0;                                            //現在アクティブな番号
    let nowSlide;                                              //現在表示中のスライド
    let NextSlide;                                             //次に表示するスライド

    // スライドの1枚目をフェードイン
    slideItem[0].classList.add('show_', 'zoom_');

    // 処理を繰り返す
    setInterval(() => {
        if (actNum < totalNum) {

            let nowSlide = slideItem[actNum];
            let NextSlide = slideItem[++actNum];

            //.show_削除でフェードアウト
            nowSlide.classList.remove('show_');
            // と同時に、次のスライドがズームしながらフェードインする
            NextSlide.classList.add('show_', 'zoom_');
            //フェードアウト完了後、.zoom_削除
            setTimeout(() => {
                nowSlide.classList.remove('zoom_');
            }, FadeTime);

        } else {

            let nowSlide = slideItem[actNum];
            let NextSlide = slideItem[actNum = 0];

            //.show_削除でフェードアウト
            nowSlide.classList.remove('show_');
            // と同時に、次のスライドがズームしながらフェードインする
            NextSlide.classList.add('show_', 'zoom_');
            //フェードアウト完了後、.zoom_削除
            setTimeout(() => {
                nowSlide.classList.remove('zoom_');
            }, FadeTime);

        };
    }, IntarvalTime);

}

*上記のコードはES2015の記法を用いています。

slideStart()を呼び出せばスライダーが開始します。上記ではwindowのloadイベントで呼び出していますが、どのタイミングで呼び出すべきかについては後述します。

最後に、CSSでズームフェードの各アニメーションを担当します。

先ほどのスクリプトで指定したFadeTimeIntarvalTimeに秒数合わせて transitionプロパティ を指定するので注意して下さい。

CSS(下のコードはSCSS)

#slide_wrapp{
  position: relative;
  overflow: hidden;
  
  .slide_item{
    opacity: 0;
    transform: scale(1);
    transition: opacity 2s linear, transform 7.5s linear;  //秒数に注意
    position: relative;
    z-index: 1;
    
    &:not(:first-child){
      position: absolute;
      top: 0;
      left : 0;
    }
  
    &.show_{
      opacity: 1;
    }
    &.zoom_{
      transform: scale(1.1);
    }
    img{
      display: block; //下に余白ができないように
    }
  }
}

フェードに対応する opacityプロパティ に対するトランジションの長さはFadeTimeと同じ時間(ここでは2秒)にし、ズームに対応する transformプロパティ に対するトランジションの長さは、最低でもFadeTimeIntarvalTimeを合わせた秒数(ここでは計7秒)にしてください。

上記では余裕を持って + 0.5秒 の 7.5秒 を指定しています。

スライダーを開始するタイミングについて

先に示したコードでは、windowのloadイベントで呼び出しています。

この場合、スライダー機能自体になんら影響はありませんが、サイトの読み込み速度が遅い場合はスライダーの表示がその分遅れてしまいます。

DOM読み込み時に呼び出しても大丈夫ですが、1枚目の読み込みに時間がかかる場合、その初回表示のみ表示時間が短くなります。
また、初回のみ、ズームがうまく動作しないことがあります。

DOM読み込み時に呼び出す場合

//これだと初回動作が安定しない
document.addEventListener('DOMContentLoaded', function () {
    sliderStart();
});

そこで、一番良いのはスライダーの1枚目を読み込んだ時点でスライダーを開始することです。

スライダーの中身が画像だけの場合はこのタイミングがベストでしょう。

imgタグのonloadイベント属性を使います。

1枚目のスライダー画像の読み込み時に呼び出す

<ul id="slide_wrapp">
    <li class="slide_item"><img src="image.jpg" alt="" onload="sliderStart()"></li>
    <!-- その他のスライド... -->
</ul>

動作デモのCodePenでもこのタイミングで呼び出していますので、参考にしてみて下さい。

- Thank you for reading. -

あなたの1クリックが励みになります\( ̄ー ̄)/

コメント

コメントする

CAPTCHA


TOPへ Top