tips / css

写真が画面の端から端へ流れる無限ループするアニメーション

公開日 : 2017/10/5 最終更新日 : 2019/8/28

サイトに何か動きを取り入れたい場合に、マウスオーバー時のボタンやスクロール時に見出しがフェードインするなど、ユーザーの操作に伴うアニメーション以外に、画面上で常に動きのある要素を取り入れると訪問者に違った印象を与えられるかもしれません。

本記事では一列に並んだ要素が右から左あるいは上から下など、画面の端から端へ流れるように動く無限ループアニメーションを4パターン作成します。写真は途切れることなく無限にループします。記事内のコード、デモサイトはいずれも右から左へ動きます。

記事内のコードについて

※ ベンダープレフィックスは省略しています。

目次

CSSアニメーションで作る無限ループアニメーション
CSSアニメーションで作る無限ループアニメーション(複数要素)
jQueryプラグイン「TweenMax」

CSSアニメーションについて

CSSアニメーションは animation プロパティでアニメーションの名前やタイミングなどを指定します。アニメーション本体は keyframes で定義します。

animation で指定できるプロパティは以下になります。

プロパティ 説明
animation-name @keyframesで定義したアニメーションの名前を指定
animation-duration 1回のアニメーションに要する時間の長さ
animation-timing-function アニメーションの進め方。3次ベジェ曲線を使用した進行速度の割合
animation-delay 要素が読み込まれてからアニメーションを始めるまでの遅延時間
animation-iteration-count アニメーションを繰り返す回数
animation-direction 繰り返す際に、逆方向にアニメーションして繰り返すか、始めの状態にリセットしてアニメーションを繰り返すか
animation-fill-mode 実行前後にどのようにスタイルを適用するか
animation-play-state 一時停止や再開など

上記のプロパティは一括で指定することができます。以下はプロパティ一括指定の一例です。

/* 要素が読み込まれて1秒後に、fadeinというアニメーションを3秒かけてlinearの進め方で実行する */
/* duration | timing-function | delay | name */
.element {
  animation: 2s linear 1s fadein;
}

アニメーション本体の @keyframes はアニメーションの開始から終了までを % (パーセント)あるいは fromto で指定します。%で指定する場合必ずしも0から100までを記述する必要はありません。

最初は非表示になっている要素が徐々に表示されるアニメーションの例です。

@keyframes fadein {
  from {
    opacity: 0;
  }
  
  to {
    opacity: 1;
  }
}

より詳しい説明はMDNのCSS アニメーションの使用をご覧ください。

CSSアニメーションで作る無限ループアニメーション

CSSアニメーションを利用する無限ループでは、動かしたい要素は一列に並べた横長(あるいは縦長)の1枚の画像にします。用意した画像をhtmlで2回続けて読み込みます。画像を div で囲みます。

html
<div class="loop_wrap">
  <img src="img.jpg"><img src="img.jpg">
</div>

ウィンドウ幅いっぱいに画像を表示させたいので、全体を囲う divwidth: 100vw;overflow: hidden; を指定します。画像を横並びにしたいので display: flex; も指定します。高さは任意の高さを設定してください。

css
.loop_wrap {
  display: flex;
  width: 100vw;
  height: 300px;
  overflow: hidden;
}

.loop_wrap img {
  width: auto;
  height: 100%;
}

画面の端から端へと流れる動きは transform プロパティの translateX でX軸方向の移動距離を変えることで横にスライドして流れるような動きを実現します。開始と終了地点の異なるアニメーションを2つ用意します。

css
@keyframes loop {
  0% {
    transform: translateX(100%);
  }
  to {
    transform: translateX(-100%);
  }
}

@keyframes loop2 {
  0% {
    transform: translateX(0);
  }
  to {
    transform: translateX(-200%);
  }
}

アニメーションを作成したら、動かしたい要素にアニメーションを指定します。作成した2種類のアニメーションをhtmlで読み込んだ画像それぞれに設定します。このとき animation-duration を同じ数値にして片方の画像にdurationの半分の時間の animation-delay を設定します。数値は任意で設定してください。無限にループさせたいので動かす要素に対して animation プロパティに infiniteを指定します。 animation-timing-function は一定に変化する linear を指定します。

css
.loop_wrap img:first-child {
  animation: loop 50s -25s linear infinite;
}

.loop_wrap img:last-child {
  animation: loop2 50s linear infinite;
}

【画像を2回読み込む理由】

スタート地点の異なるアニメーションを2つ用意し、片方の画像にdelayを設定しましたが、2つの画像の動きを分けて図解してみます。画像1(緑)はX軸方向100%から-100%へ移動し100%に戻り再び-100%へ移動するという動きを繰り返し、画像2(黄)はX軸方向を0から-200%へ移動し、0に戻り再び-200%へ移動するという動きを繰り返します。これにより画像が途切れることなく横に流れているように見せています。

※ ウィンドウサイズを変更した際に画像がウィンドウ幅より小さくなると、ループの繰り返しのなかで余白が生じるため、ウィンドウ幅いっぱいに表示する可変レイアウトの場合は対処が必要です。

デモ

CSSアニメーションで作る無限ループアニメーション

CSSアニメーションで作る無限ループアニメーション(複数要素)

ギャラリーのように画像やリンク要素などひとつひとつが独立した要素を並べてループさせることも可能です。ここではリンク要素にもなっている画像+テキストの集まりをループさせてみます。

ループさせたい要素群を2グループに分けます。以下では同じものを2回読み込んでいますが、要素のグループが2つあれば中身は同じでなくても構いません。要素のグループを div で囲みます。

html
<div class="loop_wrap">
  <ul>
    <li><a href="#"><img src="img_01.jpg" alt="">CAR</a></li>
    <li><a href="#"><img src="img_02.jpg" alt="">CITY</a></li>
    <li><a href="#"><img src="img_03.jpg" alt="">TAXI</a></li>
    <li><a href="#"><img src="img_04.jpg" alt="">NEON</a></li>
  </ul>
  <ul>
    <li><a href="#"><img src="img_01.jpg" alt="">CAR</a></li>
    <li><a href="#"><img src="img_02.jpg" alt="">CITY</a></li>
    <li><a href="#"><img src="img_03.jpg" alt="">TAXI</a></li>
    <li><a href="#"><img src="img_04.jpg" alt="">NEON</a></li>
  </ul>
</div>

CSSのアニメーションは最初の例と同じです。img タグの部分を ul に変えてください。 ul 内の横並びなどのスタイルの設定の詳細は省きます。適宜調整してください。

リンク要素を並べてループさせる場合、このままでは流しそうめんのようになってしまうので、クリックしやすいようにマウスをのせたときにアニメーションが一時停止するようにします。

ここで最初のCSSアニメーションについての表にもあった animation-play-state プロパティを使用します。一時停止の paused を指定するのですが、全体を囲う divhover 時のプロパティに指定します。グループを囲う ul に指定しまうと、マウスが乗っていないもう片方のグループは一時停止せず動き続けてしまうためです。

css
.loop_wrap:hover ul {
  animation-play-state: paused;
}

デモ

CSSアニメーションで作る無限ループアニメーション

TweenMaxで作る無限ループアニメーション

アニメーションのライブラリ「TweenMax」を利用してループを作成します。

ループさせたい画像を横に並べた1枚の画像を用意して、htmlで読み込みます。

html
<div id="loop" class="loop_wrap">
  <img src="img.jpg" alt="">
</div>

後ほどJavaScriptで画像を複製して横に並べてループさせるので、CSSでは画像を囲む全体の幅と横並びの指定をします。基本的にはCSSアニメーションで作る場合と同じ設定で問題ありません。

アニメーションの設定は、TimeLineMaxでタイムラインを作成して、オプションでrepeat: -1(繰り返し=無制限)を設定します。横に流れるアニメーション部分は、TweenMaxでX軸の移動を設定します。

TimeLineMaxのオプションのpaused: true/falseを使用すると、CSSと同様にマウスをのせた場合/はずれた場合でアニメーションの一時停止/再開を設定することもできます。

JavaScript
$(function () {
  const loop = document.getElementById('loop_js');

  //タイムラインを作成
  const loopAnim = new TimelineMax({
    repeat: -1 //繰り返し無制限
  });

  //画像を複製してdiv内に挿入
  let loopItem = (window.innerWidth, loop.children[0]);
  loop.appendChild(loopItem.cloneNode(true));
  loop.appendChild(loopItem.cloneNode(true));

  //アニメーションの設定
  loopAnim
    .to(loop, 50, { ease: Power0.easeNone, xPercent: -66.66666 })
    .to(loop, 0, { ease: Power0.easeNone, x: 0 });
});

デモ

TweenMaxで作る無限ループアニメーション

< Prev PostNext Post >