考え方
- 4枚ともhtmlにimgタグを生成する
- cssの
position: absolute
で重ねる
- 順番に
opacity
を0
<--> 1
を入れ替えていく
コード例(JavaScript編)
html
1<div id="main-visual" class="main-visual">
2 <img class="img" id="default" src="https://cdn.shopify.com/s/files/1/0600/3310/6102/t/2/assets/top_1.jpg?ver=220320&v=24797785482821047691647782404" alt="">
3</div>
css
1.main-visual {
2 max-width: 600px;
3 aspect-ratio: 2 / 1;
4 position: relative;
5}
6
7.img {
8 width: 100%;
9 height: 100%;
10 object-fit: cover;
11 position: absolute;
12 top: 0;
13 left: 0;
14}
javascript
1// アニメーションの秒数
2const DURATION = 4;
3
4// 画像の情報が格納された配列(昇順)
5const imgArray = [
6 {src: 'https://cdn.shopify.com/s/files/1/0600/3310/6102/t/2/assets/top_1.jpg?ver=220320&v=24797785482821047691647782404'},
7 {src: 'https://cdn.shopify.com/s/files/1/0600/3310/6102/t/2/assets/top_2.jpg?ver=220320&v=53756209350512176351647782414'},
8 {src: 'https://cdn.shopify.com/s/files/1/0600/3310/6102/t/2/assets/top_3.jpg?ver=220320&v=152939468448035609741647782426'},
9 {src: 'https://cdn.shopify.com/s/files/1/0600/3310/6102/t/2/assets/top_4.jpg?ver=220320&v=3071968281155817841647782437'}
10];
11
12// イベントリスナーの設定(ページロード時に発火)
13window.addEventListener('DOMContentLoaded', setAllImgs);
14
15// 画像を設置する関数
16function setAllImgs() {
17 // 必要な要素を取得
18 const mainvisualArea = document.getElementById('main-visual');
19 const defaultImg = document.getElementById('default');
20
21 // デフォルトの画像を削除
22 defaultImg.remove();
23
24 // <img>を生成
25 for (const obj of imgArray.reverse()) { // 配列を逆順にして
26 const newElm = document.createElement('img'); // <img>を生成
27 newElm.src = obj.src; // src属性をつける
28 newElm.className = 'img'; // classをつける
29 newElm.style.opacity = 1; // opacityを1にする
30 newElm.style.transition = `opacity ${DURATION/2}s linear`; // transitionをつける
31 mainvisualArea.appendChild(newElm); // #main-visualの中の末尾に<img>を挿入
32 }
33
34 // 生成した<img>を取得
35 const imgElms = document.getElementsByClassName('img');
36 // フェードアニメーションさせる
37 fadeElements(imgElms, DURATION);
38}
39
40// 複数の要素をフェードで表示・非表示を切り替える関数
41function fadeElements(elements, sec) {
42 // 要素の配列を逆順にする
43 const reversedElements = [...elements].reverse();
44 let count = 0;
45
46 setInterval(() => {
47 reversedElements[count].style.opacity = 0; // opacityを0にする
48 count = count < reversedElements.length - 1 ? count + 1 : 0; // countを+1、または0にする
49
50 setTimeout(() => {
51 reversedElements[count].style.opacity = 1; // opacityを1に戻す
52 }, sec * 1000 * (elements.length - 1));
53 }, sec * 1000);
54}
コード例(CSS編)
CSSのみによる実装もお知りになりたいとのことで、コードをご紹介いたします。
html
1<div id="main-visual" class="main-visual">
2 <img class="img" src="https://cdn.shopify.com/s/files/1/0600/3310/6102/t/2/assets/top_1.jpg?ver=220320&v=24797785482821047691647782404" alt="">
3 <img class="img" src="https://cdn.shopify.com/s/files/1/0600/3310/6102/t/2/assets/top_2.jpg?ver=220320&v=53756209350512176351647782414" alt="">
4 <img class="img" src="https://cdn.shopify.com/s/files/1/0600/3310/6102/t/2/assets/top_3.jpg?ver=220320&v=152939468448035609741647782426" alt="">
5 <img class="img" src="https://cdn.shopify.com/s/files/1/0600/3310/6102/t/2/assets/top_4.jpg?ver=220320&v=3071968281155817841647782437" alt="">
6</div>
css
1/* アニメーションのスピードを設定(画像1枚分の秒数) */
2:root {
3 --animation-speed: 4s;
4}
5
6.main-visual {
7 max-width: 600px;
8 aspect-ratio: 2 / 1;
9 position: relative;
10}
11
12.img {
13 width: 100%;
14 height: 100%;
15 object-fit: cover;
16 position: absolute;
17 top: 0;
18 left: 0;
19 opacity: 0;
20
21 animation-name: fadeImg;
22 /* アニメーションの秒数は、1枚分の秒数 × 画像の枚数 */
23 animation-duration: calc(var(--animation-speed) * 4);
24 animation-iteration-count: infinite;
25}
26
27.img:nth-child(1) {
28 animation-delay: 0;
29}
30
31.img:nth-child(2) {
32 animation-delay: calc(var(--animation-speed) * 1);
33}
34
35.img:nth-child(3) {
36 animation-delay: calc(var(--animation-speed) * 2);
37}
38
39.img:nth-child(4) {
40 animation-delay: calc(var(--animation-speed) * 3);
41}
42
43@keyframes fadeImg {
44 0% {opacity: 0;}
45
46 /* ここの%は、100% / 画像の枚数 */
47 /* 例)100% / 4枚 = 25% */
48 25% {opacity: 1;}
49
50 /* ここの%は、↑の2倍 */
51 50% {opacity: 0;}
52}