背景画像のSVGがスライドショーのようにフェードで切り替わっていく、というのをやりたかった。
CSSのanimationで実装したらiOSのChromeでバグが出たので、
結果的にjQueryでやることになった。
CSS animationでやってみた
参考:https://webparts.cman.jp/box/bgfade/
だいたいこんなような感じだったと思う。
画像5枚が30秒でゆっくり1周する。
html
<div class="fade_img"> <div class="bgImg src1"></div> <div class="bgImg src2"></div> <div class="bgImg src3"></div> <div class="bgImg src4"></div> <div class="bgImg src5"></div> </div><!-- /fade_img -->
.fade_img{ position: relative; width: 330px; height: 330px; margin: 0 auto; } .fade_img .bgImg{ position: absolute; width: 100%; height: 100%; background-repeat: no-repeat; background-position: center; background-size: cover; top : 0; left : 0; bottom : 0; right : 0; opacity : 0; } .fade_img .src1{ background-image : url('../../../img/img00.svg'); animation: bgAnime 30s ease 0s infinite; } .fade_img .src2{ background-image : url('../../../img/img01.svg'); animation: bgAnime 30s ease 6s infinite; } .fade_img .src3{ background-image : url('../../../img/img02.svg'); animation: bgAnime 30s ease 12s infinite; } .fade_img .src4{ background-image : url('../../../img/img03.svg'); animation: bgAnime 30s ease 18s infinite; } .fade_img .src5{ background-image : url('../../../img/img04.svg'); animation: bgAnime 30s ease 24s infinite; } @keyframes bgAnime { 0% { opacity: 0; } 8% { opacity: 1; } 20% { opacity: 1; } 28% { opacity: 0; } 100% { opacity: 0; } }
できたが、iPhone (iOS)のChromeで見た時に、
1周目だけチラついてしまうというバグが発生した。
- iOSなどでアニメーションさせるとチラつく - console.lealog();
- [CSS]iphoneでアニメーションがちらついた時の解決法 | ma-ya's CREATE / WEB DESIGN
- transitionをかけたホバーアクションのopacityがちらつく問題を解消する | 仙台を代表するホームページ制作会社|AndHA(アンドエイチエー)
↑
これらの記事を参考に、
transformやperspectiveなどを一通り指定してみたが、治らなかった。
jQueryを採用
参考:
jQuery : 背景画像のクロスフェード (プラグイン無し) - Web - HomeMadeGarbage
html
<div class="fade_img"> </div>
.fade_img{ position: relative; width: 330px; height: 330px; margin: 0 auto; } .fade_img .slides { position: absolute; width: 100%; height: 100%; background-repeat: no-repeat; background-position: center; } .fade_img .slides:not(:first-child) { display: none; }
script
jQuery(function($){ var speed = 4000; var times = 6000; var className = '.fade_img'; var bgArray = [ "/img/img00.svg", "/img/img01.svg", "/img/img02.svg", "/img/img03.svg", "/img/img04.svg" ]; $.each(bgArray.reverse(), function(i, value) { $(className).prepend('<div class="slides" style="background-image:url(' + value + ');"></div>'); }); var bgNo = 1; var bgLength = bgArray.length; setInterval(function(){ $(className + ' .slides:nth-child(' + bgNo + ')').fadeOut(speed); $(className + ' .slides:nth-child(' + ( bgNo === bgLength ? 1 : bgNo + 1) + ')').fadeIn(speed/3); if ( bgNo >= bgLength ) { bgNo = 1; } else { bgNo += 1; } }, times); });
これで無事に動いたが、しかし
残った課題
MacのChromeでの閲覧時、
別のタブにしばらく行ってから戻ってくると、
なんかバグって遷移のスピードが速くなったりしている時がある。
しばらく眺め続けていると治る。
SetIntervalの挙動
別タブにいる間、SetIntervalは途中を省略しつつも動き続けていて、
戻ってきた時に、
「あんたが離脱していた間にたまった処理を、まとめて見せたげるね!」
とやってくれるらしい。やめてくれい
参考:
ブラウザのタブが非アクティブ時のTweenMaxとsetIntervalについて | なんかいろいろデザインする人
解決を試みたが…
【jQuery】ブラウザのタブが非アクティブ時でもsetIntervalの挙動について! - Web.fla
↑こちらの記事のおかげで、なんとかなりそうに思えたが、ならなかった。
- window読み込み時にfocusを当てる
- タブのfocusが外れたら、タイマーを止める
→ 別タブで戻ってきた時は動いてくれたが、読み込み時に動かなかった。
Script部分を以下のように変更したのだった
jQuery(function($){ var speed = 4000; var times = 6000; var className = '.fade_img'; var bgArray = [ "/img/img00.svg", "/img/img01.svg", "/img/img02.svg", "/img/img03.svg", "/img/img04.svg" ]; $.each(bgArray.reverse(), function(i, value) { $(className).prepend('<div class="slides" style="background-image:url(' + value + ');"></div>'); }); var bgNo = 1; var bgLength = bgArray.length; $(window).on("load", function () { focus(); }); //読み込まれたらフォーカスを当てる $(window).bind("focus",function(){ //フォーカスが当たったらタイマーを設定 var timer=setInterval(animeFunc,times); }).bind("blur",function(){ //フォーカスが外れたらタイマーを解除 clearInterval(timer); }); function animeFunc(){ $(className + ' .slides:nth-child(' + bgNo + ')').fadeOut(speed); $(className + ' .slides:nth-child(' + ( bgNo === bgLength ? 1 : bgNo + 1) + ')').fadeIn(speed/3); if ( bgNo >= bgLength ) { bgNo = 1; } else { bgNo += 1; } } });