初めに
学習した内容をもとにスライドーアニメーションを作ってみました。
※内容に間違いなどがある場合はご指摘をよろしくお願いします。
完成形のイメージ
Main Concept
① イメージが入っている箱を横に並べます。(親要素のpositionをrelativeにし、子要素のイメージ箱をabsoluteにする)
② イメージコンテナ(イメージが入っている5つの箱の親要素)にclip-pathで四角い形で切り抜きます。これが可視領域になります。
③ ボタンをクリックした時にsetIntervalを使って、イメージの位置(left)が徐々に増えるようにします。また、一定の数(count)が実行されたらclearIntervalを指定し止まるようにします。
④image0.jpg 〜 image4.jpgの絶対位置(left)を全て左から右へずらすことによってスライド効果が生まれます。
#htmlで箱を用意する
slide_mainタグの中にイメージが入るslide_main__imagesとボタンになるslide_button__next要素を作成します。ボタンの場合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