• ベストアンサー
  • 困ってます

cssのanimationの設定の仕方

  • 質問No.9754569
  • 閲覧数82
  • ありがとう数2
  • 回答数1

お礼率 63% (7/11)

Animationの表示タイミングが合わないので教えてください。

今回初めてcssのanimationを使ってみました。
同時に、jQuery.BgSwitcher を使って背景画像5枚を5秒間づつ表示させてループさせています。(合計25秒間)そして、cssのanimation でテキストA,B,Cの3枚を25秒間表示させています。
表示タイミングは
【背景画像1を表示 テキストAを表示 テキストBを非表示 テキストCを非表示】
【背景画像2を表示 テキストAを非表示 テキストBを非表示 テキストCを非表示】
【背景画像3を表示 テキストAを非表示 テキストBを表示 テキストCを非表示】
【背景画像4を表示 テキストAを非表示 テキストBを非表示 テキストCを非表示】
【背景画像5を表示 テキストAを非表示 テキストBを非表示 テキストCを表示】

背景画像で使用しているjQuery.BgSwitcherの表示時間は1枚5秒です。5枚ですので25秒でループです。animationが適応されているテキストA,B,Cの animation-duration: 25s; にしています。
テキスト画像A,B,Cは表示されるタイミングではopacity:1 にしてそれ以外はopacity:0で非表示にして背景画像1,2,3とテキストA,B,Cとの表示タイミングが合わせたいです。
初めはタイミングよく背景画像とテキスト画像が表示されているのですが徐々に表示タイミングずれてしまい5分ぐらいするとanimationのテキストA,B,Cの表示タイミングが背景画像と大きくずれ、例えばテキストAが背景画像5で表示されるようになってしまいます。
jQuery.BgSwitcherでの背景画像5枚の1ループの時間は25秒。animationのテキストA,B,Cのanimation-duration: 25s; なのですが、徐々にずれてしまいます。
animation側の設定に問題があるかもしれませんので教えていただけないでしょうか?
現在のテストサイトは下記です。
http://cm-creation.net/yoshida/text-anime-test/index13.html

どうぞよろしくお願いいたします。Cssとhtml設定は下記です。

■cssの設定
.bg-slider {
width: 99.1vw;
height: 100vh;
background-position:center center;
background-size: cover;
display: flex;
justify-content: center;
position: relative;
}

.textA {
position: absolute;
  top: 5%;
   left:20%;
animation-name:animation1;
animation-duration:25s;
animation-timing-function: ease-in-out;
animation-delay: 0s;
   opacity: 0;
   animation-iteration-count: infinite;
animation-direction: normal;
animation-fill-mode: forwards;
}

.textB {
position: absolute;
top: 5%;
   right:20%;
animation-name:animation2;
animation-duration:25s;
animation-timing-function: ease-in-out;
animation-delay: 0s;
  opacity: 0;
  animation-iteration-count: infinite;
animation-direction: normal;
animation-fill-mode: forwards;
}

.textC {
position: absolute;
top: 5%;
animation-name:animation3;
animation-duration: 25s;
animation-timing-function: ease-in-out;
animation-delay: 0s;
    opacity: 0;
   animation-iteration-count: infinite;
animation-direction: normal;
animation-fill-mode: forwards;
}

@keyframes animation1 {
0% {
opacity: 0;
transform: translate3d(0, 30px, 0);
  }
5% {
opacity: 1;
transform: translate3d(0, 0, 0);
   }
26% {
opacity: 0;
transform: translate3d(0, 0, 0);
}
100% {
opacity: 0;
transform: translate3d(0, 0, 0);
}
}

@keyframes animation2 {
0% {
opacity: 0;
transform: translate3d(0, 0px, 0);
}
41% {
opacity: 0;
transform: translate3d(0, 30px, 0);
}
 45% {
opacity: 1;
transform: translate3d(0, 0, 0);
}
66% {
opacity: 0;
transform: translate3d(0, 0px, 0);
}
100% {
opacity: 0;
transform: translate3d(0, 0, 0);
}
}

@keyframes animation3 {
0% {
opacity: 0;
transform: translate3d(0, 0px, 0);
}
  81% {
opacity: 0;
transform: translate3d(0, 30px, 0);
}
85% {
opacity: 1;
transform: translate3d(0, 0, 0);
}
  101% {
opacity: 0;
transform: translate3d(0, 0px, 0);
}
 102% {
opacity: 0;
transform: translate3d(0, 0, 0);
}
}

■html
<script>
jQuery(function($) {
$('.bg-slider').bgSwitcher({
images: image/main10.jpg','image/main11.jpg','image/main12.jpg','image/main13.jpg','image/main14.jpg'], // 切り替える背景画像を指定
interval: 5000, // 背景画像を切り替える間隔を指定 5000=5秒
loop: true, //
shuffle: false, //
effect: "fade", // エフェクトの種類をfade,blind,clip,slide,drop,hideから指定
duration: 500, // エフェクトの時間を指定します。
easing: "swing" // エフェクトのイージングをlinear,swingから指定
});
});
</script>

<div class="container-fluid px-0 bg-slider " >
<div class="textA"><img src="image/item8.png" class="img-fluid" alt=""/></div>
<div class="textB"><img src="image/item9.png" class="img-fluid" alt=""/></div>
<div class="textC"><img src="image/item10.png" class="img-fluid" alt=""/></div>
</div>

質問者が選んだベストアンサー

  • 回答No.1
  • ベストアンサー

ベストアンサー率 71% (1052/1473)

他カテゴリのカテゴリマスター
10秒程度で1回流し切りの簡単なアニメーションならばCSS機能のみで問題なく再現可能ですが。5分以上の長時間や或いは今回の質問事例の様に、短い周期を何百回も繰り返す様な長周期ループアニメになると、CSSのみでは完全に制御する事は困難です。従ってそのアニメーションを表示させるwebページの該当箇所部分を、最初からCSSでは無く Javascript/jQuery によるスクリプト制御によって描画して連続的周期的に書き換える様な仕様にしなければ、無限ループさせた場合の複数表示タイミングの完全動機処理は不可能だと思われます。

簡単に解説しますと。CSSでアニメーションを行った場合、CSSファイル等に記述して指定したアニメ処理が記述された順番に上から解釈され、それが次々と連鎖的に処理されて行く事で人間の目にはあたかも連続的なアニメーションに見えます。しかしながら .textA{....} の様に括弧でくくられた中身はそれぞれ別途に解釈され処理されて行くため、どんなにそれが高速に処理されたとしてもAからBへ処理へ移行する瞬間に非常に僅かな「待ち時間」が発生します(1/1000秒の極僅かな時間です)。これは非常に短い "時差" なので数分程度ではズレは目立ちませんが、数百回数十分と続けば塵も積もれば何とやらで秒単位のズレとなって視認できるくらいの時差が発生して来ます。

これを回避し半永久的に時差やズレを生じさせないアニメーションを稼働させ続けるためには「タイミングチャート」を実装させ、それに合わせてそれぞれのアニメ処理を定期的にリセットさせ同期を取る必要があります。例文でCSS内に指定されたアニメーション処理の時間指定である animation-duration:25s; 等はプログラム内部ではそれに従って実行されますが、現実世界では必ず処理速度との僅かなズレが生じます。それは速過ぎる場合もあれば遅れる場合もあります。このズレは現代のPCや全てのプログラム、アプリケーションの基本的な仕組みなので回避する事は出来ません。

本当は全然違いますが、イメージして貰えれば分かり易いのは、この様な場合に .textA{....} の様に括弧でくくられた中身はそれぞれ単独で動くため、各自が各々に時間合わせてした腕時計を持っていると思ってください。そして .textA{} は1分が60秒の時計を見て動くのに、.textB{} は1分が59.98秒の別の時計に行動を合わせているみたいな感じです。こうして各処理が各自の時計に合わせて動くため、同じ「25s」と指示を出していても必ず時差が発生してズレて来るのです。そしてコレはプログラム上の仕様なので変える事は不可能です。

ですのでこれら複数処理を完全にタイミングを合わせるためには、各自の処理が1回終わった時点ですぐに2回目の処理に行かずに待機させ、遅れている他の処理が完全に終わるまで何もさせずに待たせます。そうして最後のランナーが完全にゴールへ到着した事を確認した後、改めてまた全員に同時にスタートする様に命令を出します。こうする事によって1秒以下のミクロン秒の世界ではバラバラになっていますが、実際の画面上では人間には感知出来ない極小時間なので見た目上は完全に同期している様に見せる事が可能になります。

P.S.
一口に「スクリプトで処理せよ」とは言いましたが…実際にはかなり大変なので、過去に似た様な処理を自作した経験が無いとすぐに実装させるのは難しいと思います。それでそのための初心者にも簡単にアニメ実装が可能なCSSなんですが、前述の通りそこまで完璧なアニメ処理は元から考慮されていないので、あくまでもちょっとした画面変化のお手伝いをするのが目的のCSSだとご理解ください。

まあ身も蓋もないですが、よほど作り込まれたストーリー性も有る様な凝ったアニメ変化をするwebページでも無い限り、普通はTOPページでもUserは1分も眺め続ける事はありませんので。5分以上放置して変になる程度でしたら、特に気にせずにこのままでも良いかと思います。或いは画像やテキストの中身を再検討し工夫して、例え時差やズレが生じたとしても違和感なく見える様な演出に変更するとかですかね。
お礼コメント
zion12345

お礼率 63% (7/11)

本当に分かり易くご説明頂きました。仕様上のもんだいで、cssのみでは完全な同期を計れないのでjavascriptが必要なのですね。トップに軽く表現する程度なので言われてみればユーザーが長期間見ることもないと思いますのでcssのみで行こうと思います。ありがとうございました!
投稿日時:2020/05/30 13:04
関連するQ&A
ページ先頭へ