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

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

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

# 完成形のイメージ
矢印ボタンを押すとイメージが左から右へとスライドします。
![スクリーンショット 2021-05-11 23.22.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/4d380258-722f-e294-221f-5dbf9580c65f.png)
![スクリーンショット 2021-05-11 23.22.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/9c226afa-11ad-c0ef-d22c-c95e0f1f1e8b.png)
![スクリーンショット 2021-05-11 23.22.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/c95f4c15-8572-7c08-6b8e-e99b35ee3f08.png)

# Main Concept
① イメージが入っている箱を横に並べます。（親要素のpositionをrelativeにし、子要素のイメージ箱をabsoluteにする）
② イメージコンテナ（イメージが入っている５つの箱の親要素）にclip-pathで四角い形で切り抜きます。これが可視領域になります。
③ ボタンをクリックした時にsetIntervalを使って、イメージの位置（left)が徐々に増えるようにします。また、一定の数（count)が実行されたらclearIntervalを指定し止まるようにします。
![スクリーンショット 2021-05-11 23.30.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/abc27423-c673-b4b3-807a-8044ad979e77.png)
④image0.jpg　〜 image4.jpgの絶対位置（left)を全て左から右へずらすことによってスライド効果が生まれます。
![スクリーンショット 2021-05-11 23.40.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/6c763e5e-ba6f-e85c-f567-7c5eb1fa3ee6.png)

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

```html
<!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のイメージが入る部分とボタンの部分を分けて記述します。ボタンの作り方は前回の記事の通りです。

https://qiita.com/redrabbit1104/items/86420bfd0087cc7dd742

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

https://qiita.com/redrabbit1104/items/e64ecce322dd7b0b4c98


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

```css
.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を止めます。

```javascript
"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