LoginSignup
1
1

More than 3 years have passed since last update.

年末まで毎日webサイトを作り続ける大学生 〜42日目 記事のレコメンドとかで使われている画面の端から端までループするスライダーを作る〜

Last updated at Posted at 2019-11-29

はじめに

こんにちは!@70days_jsです。

記事のレコメンドとかで使われているあの、画面の端から端までループするスライダーを作りました。
分かりづらいですよね。。。作ったものはこれです。↓
test2.gif
苦戦した挙句、なんとか機能自体はcssで完結できたものの、コードがとても汚くなってしまいました。
さらに、1つ変更すれば動かなくなったり、あまりレスポンシブでなかったり、とりあえず形にしたという状態です。

今回は説明もかなり分かりづらいと思うので、直接すベてのコードが見たいという方はこちらへ→(html, css, JavaScript)

今日は42日目。(2019/11/29)
よろしくお願いします。

サイトURL

やったこと

もう一回になりますが、今日はこれを作りました。↓
test2.gif

htmlの全体はこんな感じです。↓

    <div class="wrapper">
        <ul class="listWrapper first">
            <li><a href="#"><img src="day31_image/1.jpg">
                    <div>
                        <p>記事タイトル</p><div>記事の内容</div>
                    </div>
                </a>
            </li>
  <!-- 以下、画像分だけ同じようにliを繰り返す -->
        </ul>
  <!-- 上にあるulとクラス名以外、全て同じ! -->
        <ul class="listWrapper second">
            <li><a href="#"><img src="day31_image/1.jpg">
                    <div>
                        <p>記事タイトル</p><div>記事の内容</div>
                    </div>
                </a>
            </li>
  <!-- 以下、画像分だけ同じようにliを繰り返す -->
        </ul>
     <div>

ulが2つあります。
ulの中身はどちらも同じもので、違うのはクラス名だけです。(最初にfirst, 2つ目にsecondクラスをつけた)
同じものが2つあるのは途切れなくループしているように見せるためです。
1つ目のulのliの数と、2つ目のulのliの数は同じにします。(cssのanimationの関係で)

次はcssです。animationが冗長な感じになってしまいました。
大事なところだけ抜き出します↓

.wrapper {
    width: calc(100vw / 5);
}

.first {
    animation: cat 16s -8s ease infinite;

}

.second {
    animation: mountain 16s ease infinite;
}

.wrapper:hover ul {
    animation-play-state: paused;
}


@keyframes cat {
    0% {
        transform: translateX(100%);
    }
    5% {
        transform: translateX(80%);
    }
    10% {
        transform: translateX(80%);
    }
    15% {
        transform: translateX(60%);
    }
    20% {
        transform: translateX(60%);
    }
    25% {
        transform: translateX(40%);
    }
    30% {
        transform: translateX(40%);
    }
    35% {
        transform: translateX(20%);
    }
    40% {
        transform: translateX(20%);
    }
    45% {
        transform: translateX(0%);
    }
    50% {
        transform: translateX(0%);
    }
    55% {
        transform: translateX(-20%);
    }
    60% {
        transform: translateX(-20%);
    }
    65% {
        transform: translateX(-40%);
    }
    70% {
        transform: translateX(-40%);
    }
    75% {
        transform: translateX(-60%);
    }
    80% {
        transform: translateX(-60%);
    }
    85% {
        transform: translateX(-80%);
    }
    90% {
        transform: translateX(-80%);
    }
    95% {
        transform: translateX(-100%);
    }
    100% {
        transform: translateX(-100%);
    }
}

@keyframes mountain {
    0% {
        transform: translateX(0%);
    }
    5% {
        transform: translateX(-20%);
    }
    10% {
        transform: translateX(-20%);
    }
    15% {
        transform: translateX(-40%);
    }
    20% {
        transform: translateX(-40%);
    }
    25% {
        transform: translateX(-60%);
    }
    30% {
        transform: translateX(-60%);
    }
    35% {
        transform: translateX(-80%);
    }
    40% {
        transform: translateX(-80%);
    }
    45% {
        transform: translateX(-100%);
    }
    50% {
        transform: translateX(-100%);
    }
    55% {
        transform: translateX(-120%);
    }
    60% {
        transform: translateX(-120%);
    }
    65% {
        transform: translateX(-140%);
    }
    70% {
        transform: translateX(-140%);
    }
    75% {
        transform: translateX(-160%);
    }
    80% {
        transform: translateX(-160%);
    }
    85% {
        transform: translateX(-180%);
    }
    90% {
        transform: translateX(-180%);
    }
    95% {
        transform: translateX(-200%);
    }
    100% {
        transform: translateX(-200%);
    }
}

.wrapper {
width: calc(100vw / 5);
}

ここはulの中にあるliの数を5つにしたので、5で割っているだけです。

.first {
animation: cat 16s -8s ease infinite;
}
.second {
animation: mountain 16s ease infinite;
}

animation名の指定と、もう一つfirstだけに-8sを書いています。
この8はanimationの時間(16秒)を2で割った数字です。
ループっぽく見せるために時間の調整をしています。

.wrapper:hover ul {
animation-play-state: paused;
}

ul(スライダー)にマウスを乗せたら停止するようにしています。

次は@keyframesですが、これは5%刻みで、20%移動しては停止する、というのを繰り返しています。
多分もっといい書き方があると思うのですが、今回は作るだけで精一杯でした・・・。

最後に、機能とは一切関係ないですが、色の装飾にJavaScriptを使ったので紹介しておきます。

// .one-boxクラスは全てのliについているクラス名
let oneBox = document.getElementsByClassName('one-box');

for (var i = 0; oneBox.length > i; i++) {
    let content = oneBox[i];
    randomColor(content);
}

function randomRGB() {
    let r = Math.floor(Math.random() * 256);
    let g = Math.floor(Math.random() * 256);
    let b = Math.floor(Math.random() * 256);
    let rgb = [r, g, b];
    return rgb;
}

function randomColor(element) {
    let rgb = randomRGB();
    let r = rgb[0];
    let g = rgb[1];
    let b = rgb[2];
    element.style.backgroundColor = 'rgba(' + r + ', ' + g + ',' + b + ', .3)';
}

このコードで背景の色をそれぞれランダムに設定しています。

感想

将来自分のサイトを作ったときに、記事のレコメンド機能があればいいなと思って作ったんですが、なかなか大変でした。

最後までお読みいただきありがとうございます。明日も投稿しますのでよろしくお願い致します。

参考

1.写真が画面の端から端へ流れる無限ループするアニメーション | chocolat | Freelance Frontend Engineer

とても分かりやすかったです。ありがとうございます!

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1