実現したいこと
①画面を描画したら、すぐにアニメーションの処理を開始。
②最初はmini_window_icon_wrap内の3枚の画像を表示しておき、一番上に重ねている1枚目の画像から2枚目までを順番に非表示にする処理を行う。3枚目にはアニメーションを適用しない。
③上記の非表示処理が終わったとき、3枚目の画像は表示したままの状態が正しい。
④その後、あまり間隔を空けずに、続けて表示の処理を開始し、2枚目の画像→1枚目の画像、の順番で表示の処理を行う。
⑤表示の処理が終わったら、あまり間隔を空けずに、続けて②の処理から繰り返す。
前提
以下セクションをHTML内に3つ(仮に上からA-B-Cとします)用意し、
mini_window_icon_wrap内の3枚の画像のうち、上から2枚の画像にのみアニメーションの処理を適用したい。
HTML
1<section class="hogehoge"> 2 <div class="mini_window_icon_wrap"> 3 <img 4 src="./assets/img/mini_window_icon_1.png" 5 alt="" 6 loading="lazy" 7 /> 8 <img 9 src="./assets/img/mini_window_icon_1.png" 10 alt="" 11 loading="lazy" 12 /> 13 <img 14 src="./assets/img/mini_window_icon_1.png" 15 alt="" 16 loading="lazy" 17 /> 18 </div> 19</section>
SCSS
1.mini_window_icon_wrap { 2 z-index: 9999; 3 position: relative; 4 max-width: 146px; 5 width: 100%; 6 min-height: 107px; 7 height: 100%; 8 margin: -8.53334vw 5.33334vw 2.133334vw auto; 9 10 img { 11 position: absolute; 12 top: 0; 13 left: 0; 14 // opacity: 0; 15 transition: opacity 1s ease-in-out; 16 17 &.active { 18 opacity: 1; 19 } 20 21 &:nth-child(1) { 22 z-index: 9999; 23 } 24 &:nth-child(2) { 25 z-index: 8888; 26 top: 2.66667vw; 27 left: -2.66667vw; 28 } 29 &:nth-child(3) { 30 z-index: 7777; 31 top: 5.33334vw; 32 left: -5.33334vw; 33 } 34 } 35 }
発生している問題・エラーメッセージ
・エラーは発生していないが、期待する挙動になっていない。
・A B Cの各セクションで、挙動が異なっている。
A B C全てで実現できていないこと:
①アニメーションの処理開始にやや時間がかかっている。画面を描画したらできるだけ早く処理を開始したい。
②mini_window_icon_wrap内の3枚の画像を最初から表示しておく処理ができていない。
AとBで実現できていないこと:
②最初は非表示の処理から開始したいが、最初は何も表示されていない状態で、④の表示の処理から開始してしまっており、かつ3枚目の画像にもアニメーションが適用されているため、3枚目→2枚目→1枚目の順番で表示の処理が行われている。
③3枚目の画像にはアニメーションを適用せず常に表示しておく、が正しい挙動だが、適用されてしまっており、かつ②の非表示の処理が終わるとHTMLのimgタグに自動的にstyle="display: none;"が追加され、非表示となってしまっている。
※参考動画
https://capture.dropbox.com/4rAH2Khu6SoOcluI
Cで実現できていないこと:
②最初は非表示の処理から開始したいが、一番下の3枚目のみが最初に表示されていて、④の表示の処理から開始してしまっている。
※参考動画:
https://capture.dropbox.com/ENrKLF1zCzR3yR93
※エラーメッセージなし
該当のソースコード
jQuery
1//ミニウィンドウに対するアニメーションの処理 2$(function () { 3 var images = $('.mini_window_icon_wrap img'); 4 var currentIndex = 0; // 最初は一枚目の画像から開始 5 var animationDirection = 'forward'; // 最初のアニメーション方向は前向き 6 7 function showImage(index) { 8 $(images[index]).addClass('active').show(); 9 } 10 11 function hideImage(index) { 12 $(images[index]).removeClass('active').hide(); 13 } 14 15 function animateImages() { 16 setTimeout(function () { 17 if (animationDirection === 'forward') { 18 if (currentIndex < images.length - 1) { 19 hideImage(currentIndex); 20 currentIndex++; 21 animateImages(); 22 } else { 23 animationDirection = 'backward'; // アニメーション方向を逆に変更 24 currentIndex = images.length - 2; // インデックスを初期化(最後から2枚目の画像から開始) 25 setTimeout(hideImageStep, 150); // 0.15秒後に非表示の段階的な処理を開始 26 } 27 } else { 28 if (currentIndex >= 0) { 29 showImage(currentIndex); 30 currentIndex--; 31 animateImages(); 32 } else { 33 animationDirection = 'forward'; // アニメーション方向を逆に変更 34 currentIndex = 1; // インデックスを初期化 35 setTimeout(showImageStep, 150); // 0.15秒後に表示の段階的な処理を開始 36 } 37 } 38 }, 300); // 0.3秒ごとにアニメーションを繰り返す 39 } 40 41 function hideImageStep() { 42 if (currentIndex >= 0) { 43 hideImage(currentIndex); 44 currentIndex--; 45 if (currentIndex >= 0) { 46 setTimeout(hideImageStep, 150); // 0.15秒後に次の画像を非表示にする 47 } else { 48 currentIndex = images.length - 1; 49 animateImages(); 50 } 51 } 52 } 53 54 function showImageStep() { 55 if (currentIndex < images.length) { 56 showImage(currentIndex); 57 currentIndex++; 58 if (currentIndex < images.length - 1) { 59 setTimeout(showImageStep, 150); // 0.15秒後に次の画像を表示する 60 } else { 61 currentIndex = 0; 62 setTimeout(animateImages, 150); // 0.15秒後にアニメーションを再開する 63 } 64 } 65 } 66 67 // 最初に表示しておく 68 images.each(function (index) { 69 if (index >= 1 && index < images.length - 1) { 70 hideImage(index); 71 } 72 }); 73 showImage(images.length - 1); // 最後の画像を表示しておく 74 setTimeout(animateImages, 0); // 画面描画後すぐにアニメーションの処理を開始 75});
試したこと
1)各セクションごとに挙動が異なるため、jsの記述の最後に以下のような記述を追加して、各セクションに対してアニメーションが適用されるように試した。
→解決できなかったどころか、アニメーションが動かなくなった。
// Aセクション animateMiniWindow($('#A .mini_window_icon_wrap img')); // Bセクション animateMiniWindow($('#B .mini_window_icon_wrap img')); // Cセクション animateMiniWindow($('#C .mini_window_icon_wrap img'));
2)念のため、HTML内のjQueryのとjsの呼び出し位置が問題ないかを確認。
→問題なさそう。headタグ内ではうまく動作しないことが過去にあったため、いつもbody閉じタグの直前に入れています。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <script src="./assets/js/common.js"></script> </body> </html>
2024/4/11時点:
以下のように、最初に各セクションに対しての画像処理を行う記述を追加したところ、A, B, Cの挙動を統一できました!
現時点で実現できていないことは、以下の内容のみになります。
②最初はmini_window_icon_wrap内の3枚の画像を表示しておき、一番上に重ねている1枚目の画像から2枚目までを順番に非表示にする処理を行う。
④その後、あまり間隔を空けずに、続けて表示の処理を開始し、2枚目の画像→1枚目の画像、の順番で表示の処理を行う。
追加したコード
jQuery
1animateImages('.pile_zipup_blouson .mini_window_icon_wrap img'); 2animateImages('.border_tee .mini_window_icon_wrap img'); 3animateImages('.hoodie_sweatshirts .mini_window_icon_wrap img');
修正後のコード全文
jQuery
1//ミニウィンドウに対するアニメーションの処理 2$(function () { 3 // 各セクションの画像処理を開始 4 animateImages('.pile_zipup_blouson .mini_window_icon_wrap img'); 5 animateImages('.border_tee .mini_window_icon_wrap img'); 6 animateImages('.hoodie_sweatshirts .mini_window_icon_wrap img'); 7 8 function animateImages(selector) { 9 var images = $(selector); 10 var currentIndex = 0; 11 var animationDirection = 'forward'; 12 13 function showImage(index) { 14 $(images[index]).addClass('active').show(); 15 } 16 17 function hideImage(index) { 18 $(images[index]).removeClass('active').hide(); 19 } 20 21 function animate() { 22 setTimeout(function () { 23 if (animationDirection === 'forward') { 24 if (currentIndex < images.length - 1) { 25 hideImage(currentIndex); 26 currentIndex++; 27 animate(); 28 } else { 29 animationDirection = 'backward'; 30 currentIndex = images.length - 2; 31 setTimeout(hideImageStep, 150); 32 } 33 } else { 34 if (currentIndex >= 0) { 35 showImage(currentIndex); 36 currentIndex--; 37 animate(); 38 } else { 39 animationDirection = 'forward'; 40 currentIndex = 1; 41 setTimeout(showImageStep, 150); 42 } 43 } 44 }, 300); 45 } 46 47 function hideImageStep() { 48 if (currentIndex >= 0) { 49 hideImage(currentIndex); 50 currentIndex--; 51 if (currentIndex >= 0) { 52 setTimeout(hideImageStep, 150); 53 } else { 54 currentIndex = images.length - 1; 55 animate(); 56 } 57 } 58 } 59 60 function showImageStep() { 61 if (currentIndex < images.length) { 62 showImage(currentIndex); 63 currentIndex++; 64 if (currentIndex < images.length - 1) { 65 setTimeout(showImageStep, 150); 66 } else { 67 currentIndex = 0; 68 setTimeout(animate, 150); 69 } 70 } 71 } 72 73 images.each(function (index) { 74 if (index >= 1 && index < images.length - 1) { 75 hideImage(index); 76 } 77 }); 78 showImage(images.length - 1); 79 setTimeout(animate, 0); 80 } 81});