BLOG

CSSだけで車を走らせてみた

Written by mizuno

INDEX

今回は車を走らせるアニメーションをCSSのbackground-image@keyframesanimation-timelineを使用して3通り作成してみたいと思います。

  1. background-imageでアニメーションを付ける方法
  2. 要素毎に@keyframesを指定してアニメーション付ける方法
  3. animation-timeline(Scroll-driven Animations )を指定してスクロールと連動する方法

それでは、どうぞ。

1.background-imageでアニメーションを付ける方法

background-imageにアニメーションを付けるには、animation-timing-functionsteps()関数を使用します。

steps()関数は、アニメーションを一定のステップ数で分割して動かすことができます。つまり、コマ送りのアニメーションを作ることができます。

GIFアニメーションと似ていますが、いくつかの違いがあります

  • GIF画像は256色以上の表示ができませんが、この方法の場合はPNG・SVG形式の画像が使うことができるため、GIF画像より綺麗に表示ができ、Retinaディスプレイにも対応することができます
  • CSSでタイミングを調整することができます

コマ送りする画像

今回は12コマ用意して、1コマずつタイヤの角度30度ずらしたり、車の揺れもつけてみました。実際に使用する画像はこちら

HTML

HTML構造は下記のようにしました。

<div class="wrapper">
 <div class="car"></div>
</div>

CSS

@keyframesでコマ送り画像の高さをbackground-positionで上から下まで動かすよう指定します。そして、animation-timing-functionsteps()を指定し、アニメーションを付けます。

@keyframes drive_step {
    0% {
        background-position: 0 0;
    }
    100% {
        background-position: 0 -2424px; //コマ送り画像の高さ
    }
}

.car {
    width: 300px;
    height: 202px;
    background-image: url('コマ送り画像のパス');
    background-size: 300px 2424px;
    animation: drive_step 1s steps(12, end) infinite;
}

完成

2.要素毎に@keyframesを指定してアニメーション付ける方法

コマ送り画像で作って修正入った場合、画像の作り直しが必要になり調整が大変ですが、こちらの方法の場合はCSSで対応できるため調整が簡単になります。

画像

ボディ、タイヤとパーツ毎に画像を用意します。

HTML

HTML構造は下記のようにしました。車のボディ、タイヤにそれぞれアニメーションを付けていきます。

<div class="wrapper">
 <div class="car">
  <div class="body">
   <img src="ボディのパス" alt="" />
  </div>
  <div class="tire-front">
   <img src="タイヤのパス" alt="" />
  </div>
  <div class="tire-rear">
   <img src="タイヤのパス" alt="" />
  </div>
 </div>
</div>

CSS

@keyframesでタイヤの回転する動きと車の揺れる動きのキーフレームを定義して、animationプロパティで要素にアニメーションを付けていきます。

@keyframes spin {
    0% {
        rotate: 0deg;
    }
    100% {
        rotate: -360deg;
    }
}

@keyframes shaking {
    0% {
        translate: 0 0;
    }
    20% {
        translate: 0 1px;
    }
    40% {
        translate: 0 0;
    }
    60% {
        translate: 0 1.5px;
    }
    80% {
        translate: 0 0;
    }
    100% {
        translate: 0 0;
    }
}

@keyframes driving {
    0% {
        translate: 300px 0;
    }
    100% {
        translate: -100vw 0;
    }
}

.car {
  animation: driving 8s linear infinite;
}

.body {
  animation: shaking 1s linear infinite;
}

.tire-front {
  animation: spin 1s linear infinite;
}

.tire-rear {
  animation: spin 1s linear -0.5s infinite;
}

完成

3.animation-timeline(Scroll-driven Animations )を指定してスクロールと連動する方法

animation-timelineとはChrome 115から実装されたCSSのプロパティで、スクロールと連動したアニメーションを付けることができます。(※2023年10月現在Safari、Firefoxは非対応)

HTML

<div class="wrapper">
  <div class="car">
    <div class="body">
      <img src="ボディのパス" alt="" />
    </div>
    <div class="tire-front">
      <img src="タイヤのパス" alt="" />
    </div>
    <div class="tire-rear">
      <img src="タイヤのパス" alt="" />
    </div>
  </div>
  <!-- ここから下の内容は省略 -->
  .
  .
  .
</div>

CSS

事前の準備としてスクロールを発生させるためbody要素に適当な高さを確保し、.wrapperfixedを指定しています。

スクロールアニメーションを付けたい要素に@keyframesでキーフレームを定義し、要素にanimationを指定するまでは同じですが、ここにanimation-timeline:scroll()を指定します。

これだけで、スクロールと連動してアニメーションを付けることができます。

	.car {
		position: relative;
		width: 300px;
		height: 202px;
		margin: 0 auto;
		animation: drive linear;
		animation-timeline: scroll();
	}

完成

下にスクロールしてみてください(※Chrome、Edge 115以上のブラウザ以外は動かないのでご注意ください)

まとめ

今ままでのアニメーションの付け方として、背景画像を扱うbackground-imageを使用する必要があり、手間がかかっていました。しかし、今ではCSSで要素ごとに動きを付けることができるようになったため実装が簡単になりました。さらに、最新のChromeブラウザでは、スクロールとアニメーションを連動させることも可能になっています!

以上、参考になれば幸いです。

参考サイト

CSSだけでスクロールアニメーションが作れる!?新技術Scroll-driven Animationsとは

Scroll-driven Animations

animation-timeline