Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What are the problem?
@redrabbit1104

【Javascript】clip-pathでスライドアニメーションを作ってみた

初めに

学習した内容をもとにスライドーアニメーションを作ってみました。

※内容に間違いなどがある場合はご指摘をよろしくお願いします。

完成形のイメージ

矢印ボタンを押すとイメージが左から右へとスライドします。
スクリーンショット 2021-05-11 23.22.18.png
スクリーンショット 2021-05-11 23.22.22.png
スクリーンショット 2021-05-11 23.22.31.png

Main Concept

① イメージが入っている箱を横に並べます。(親要素のpositionをrelativeにし、子要素のイメージ箱をabsoluteにする)
② イメージコンテナ(イメージが入っている5つの箱の親要素)にclip-pathで四角い形で切り抜きます。これが可視領域になります。
③ ボタンをクリックした時にsetIntervalを使って、イメージの位置(left)が徐々に増えるようにします。また、一定の数(count)が実行されたらclearIntervalを指定し止まるようにします。
スクリーンショット 2021-05-11 23.30.47.png
④image0.jpg 〜 image4.jpgの絶対位置(left)を全て左から右へずらすことによってスライド効果が生まれます。
スクリーンショット 2021-05-11 23.40.30.png

htmlで箱を用意する

slide_mainタグの中にイメージが入るslide_main_imagesとボタンになるslide_buttonnext要素を作成します。ボタンの場合javascriptの処理が必要なのでslide_buttonという名前のidも用意します。

<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="css/app.css">
  <title>Slide</title>
</head>

<body>

  <section class="slide">
    <div class="slide_main">
      <div class="slide_main__images">
        <div class="s0"></div>
        <div class="s1"></div>
        <div class="s2"></div>
        <div class="s3"></div>
        <div class="s4"></div>
      </div>
      <div id="slide__button" class="slide_buttons__next"></div>
    </div>

  </section>

  <script src="main.js"></script>

</body>

</html>

sassの記述

slideのイメージが入る部分とボタンの部分を分けて記述します。ボタンの作り方は前回の記事の通りです。

また、clip-pathをslide_main__images要素に指定します。四角い形で大きさはそれぞれのイメージと同じです。

slide要素にpositionをrelativeにし、5つのイメージのdiv要素はabsoluteでそれぞれ親要素を基準にして位置を決めておきました。こうすることによってイメージの箱が横にずらりと並びます。はみ出るイメージはoverflow:hiddenを指定して隠します。

.slide {
  height: 400px;
  margin: 0 auto;
  position: relative;
  &_main {
    height: 400px;
    margin: 0 auto;
    &__images {
      position: relative;
      padding: 5% 0 5%;
      margin: 0 auto;
      width: 90%;
      height: 280px;
      clip-path: inset(10% 25% 10% 25%);
      overflow: hidden;
      & div {
        height: 280px;
        cursor: pointer;
        &.s0 {
          top: 70px;
          width: 50%;
          position: absolute;
        }
        &.s1 {
          top: 70px;
          width: 50%;
          position: absolute;
        }
        &.s2 {
          top: 70px;
          width: 50%;
          position: absolute;
        }
        &.s3 {
          top: 70px;
          width: 50%;
          position: absolute;
        }
        &.s4 {
          top: 70px;
          width: 50%;
          position: absolute;
        }
      }
    }
  }
}

.slide_buttons__next {
  position: absolute;
  top: 200px;
  right: 300px;
  cursor: pointer;
  color: lightgray;
  width: 30px;
  height: 30px;
  &:hover {
    transition-duration: 0.2s;
    transform: translateX(10px);
  }
  &::after {
    content: "";
    display: block;
    width: 15px;
    height: 15px;
    position: absolute;
    margin-top: 2.5px;
    border-top: 1px solid #ccc;
    border-right: 1px solid #ccc;
    transform: rotate(45deg);
  }
}

javascriptの記述

イメージファイルが入っている配列imagesを用意します。それぞれのイメージが入るdivタグをquerySelectorで指定し、styleでイメージをアサインします。また、ボタンをクリックしたらそれぞれのイメージのleft位置をずらすようにしました。setIntervalでクリックイベントが走る回数をcountでコントロールします。また、countが49回をオーバーするとclearIntervalでsetIntervalを止めます。

"use strict";

const images = [
  "images/0.jpg",
  "images/1.jpg",
  "images/2.jpg",
  "images/3.jpg",
  "images/4.jpg",
];

let increase = -1;
let init = -75;
const displayImage0 = document.querySelector(".s0");
displayImage0.style.backgroundImage = `url(${images[0]})`;
const displayImage1 = document.querySelector(".s1");
displayImage1.style.backgroundImage = `url(${images[1]})`;
const displayImage2 = document.querySelector(".s2");
displayImage2.style.backgroundImage = `url(${images[2]})`;
const displayImage3 = document.querySelector(".s3");
displayImage3.style.backgroundImage = `url(${images[3]})`;
const displayImage4 = document.querySelector(".s4");
displayImage4.style.backgroundImage = `url(${images[4]})`;

function slide_next() {
  increase = increase + 1;
  displayImage0.style.left = `calc(${init}% + ${increase}%)`;
  displayImage1.style.left = `calc(${init + 50}% + ${increase}%)`;
  displayImage2.style.left = `calc(${init + 100}% + ${increase}%)`;
  displayImage3.style.left = `calc(${init + 150}% + ${increase}%)`;
  displayImage4.style.left = `calc(${init + 200}% + ${increase}%)`;

  if (displayImage0.style.left == `calc(25%)`) {
    init = init - 200;
    displayImage4.style.backgroundImage = `url(${images[0]})`;
    displayImage2.style.backgroundImage = `url(${images[4]})`;
  }
}

slide_next();

document.getElementById("slide__button").addEventListener("click", () => {
  let count = 0;
  const intervalId = setInterval(() => {
    slide_next();
    count++;
    if (count > 49) {
      clearInterval(intervalId);
    }
  }, 25);
});

参考記事

https://developer.mozilla.org/ja/docs/Web/API/WindowOrWorkerGlobalScope/setInterval
https://techacademy.jp/magazine/5537
https://techplay.jp/column/548

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
1
Help us understand the problem. What are the problem?