Kevin Bishop | CSS Animation – Mario Kart

CSS Animation – Mario Kart


  • 20 Apr


  • KevinBish

From the previous CSS Animation Tutorial (One) you learn about keyframe and applying them to create animations. Now we will use this knowledge to create Mario Kart Animations. 

So, first create a folder mario and inside it two files index.html and style.css

Next, put this basic html in index.html

<!DOCTYPE html>
<head>
  <title>Mario Kart Animations</title>
  <link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
  <div class="sky"></div>
  <div class="grass"></div>
  <div class="road"></div>
</body>
<style>

html, body{
  height: 100%;
  width:100%;
  overflow: hidden;
  margin: 0;
}
.grass, .sky, .road{
  position: relative;
}
.sky{
  height: 40%; background: skyblue;
}
.grass{
  height: 30%;
  background: seagreen;
}
.road{
  height: 30%;
  background: dimgrey;
  box-sizing: border-box;
  border-top: 10px solid grey;
  border-bottom: 10px solid grey;
  width: 100%;
}
.lines{
  box-sizing: border-box;
  border: 5px dashed #fff;
  height: 0px;
  width: 100%;
  position: absolute;
  top: 60%;
}
</style>

Next, put these basic styles in style.css

Now, it’s time to put Mario image in the tracks. We already have some images:

https://kevin-bish.com/repo/cloud.png

https://kevin-bish.com/repo/mario.png

https://kevin-bish.com/repo/luigi.png

<!DOCTYPE html>
<head>
  <title>Mario Kart Animations</title>
  <link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
  <div class="sky"></div>
  <div class="grass"></div>
  <div class="road">
  <div class="lines"></div>
   <img class="mario" src="https://kevin-bish.com/repo/mario.png">
  </div>
</body>

Now, it will show our hero Mario in the tracks.

Now, we will animate Mario but first will fix him a bit by moving him up.

.mario{
  position: absolute;
  top: -40px;
  left: 0px;
}

It will move him a bit up.

Now, we will add our animation by keyframes. We declare a keyframe animation drive and then have a from and to properties in it. We put translateX inside them. It means Mario will start from 0 on x-axis and go till 1200px on x-axis.

We then add that in our mario class by giving animation-name: drive . We also add an animation-duration: 3s

.mario{
  position: absolute;
  top: -40px;
  left: 0px;
  animation-name: drive;
  animation-duration: 3s;
  animation-fill-mode: forward;
 }

@keyframes drive{
  from{ transform: translateX(0)}
  to{transform: translateX(1200px)}
}

It will show this nice Mario animation.

As, you might have seen in the above animation that after Mario reaches to the end i.e. 1200px, he returns back to his original position.

We can change this by animation-fill-mode: forwards; It means that it should stay at the to position i.e. 1200px after the animation is over.

.mario{
  position: absolute;
  top: -40px;
  left: 0px;
  animation-name: drive;
  animation-duration: 3s;
  animation-fill-mode: forwards;
 }

@keyframes drive{
  from{ transform: translateX(0)}
  to{transform: translateX(1200px)}
}

It will show the below animation.

Now, we will use animation-fill-mode: both;to make Mario extend the animation property in both directions. We are also using animation-iteration-count: infinite; to achieve the infinite loop.

We are also staring Mario off screen and ending him off screen.

.mario{
  position: absolute;
  top: -40px;
  left: 0px;
  animation-name: drive;
  animation-duration: 3s;
  animation-fill-mode: both;
  animation-iteration-count: infinite;
 }

@keyframes drive{
  from{ transform: translateX(-200px)}
  to{transform: translateX(1600px)}
}

It will show our hero Mario, moving nicely on the track infinitely.

We will leave Mario with his infinite animation and bring his brother Luigi, to learn further animation. So, go ahead and add Luigi in index.html

<!DOCTYPE html>
<head>
  <title>Mario Kart Animations</title>
  <link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
  <div class="sky"></div>
  <div class="grass"></div>
  <div class="road">
  <div class="lines"></div>
   <img class="mario" src="https://kevin-bish.com/repo/mario.png">
   <img class="luigi" src="https://kevin-bish.com/repo/luigi.png">
  </div>
</body>

Next, also add styles for him in style.css

.luigi {
  position: absolute;
  top: 86px;
  left: 0px;
}

It will show Luigi in browser.

We will use the same animation for Luigi as Mario, but we will give his direction as reverse.

.luigi {
  position: absolute;
  top: 86px;
  left: 0px;
  animation-name: drive;
  animation-duration: 5s;
  animation-fill-mode: both;
  animation-iteration-count: infinite;
  animation-direction: reverse;
}

The animation-direction: reverse property, will have Luigi go from right to left.

Now, you might have noticed from Mario that he is slowing down towards the right end.

This is because of animation-timing-function.

It is by default ease, which slow start, then fast, then end slowly.

We will make Mario travel with linear speed i.e. with the same speed from start to end.

.mario{
  position: absolute;
  top: -40px;
  left: 0px;
  animation-name: drive;
  animation-duration: 3s;
  animation-fill-mode: both;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
}

So, Mario travel at linear speed now.

All the different animation properties which we have used for Mario and Luigi, can be used in a single line with shorthand notation.

We will learn it with clouds. So, let’s add two clouds images in our sky.

https://kevin-bish.com/repo/cloud.png

<!DOCTYPE html>
<head>
  <title>Mario Kart Animations</title>
  <link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
  <div class="sky">
    <img class="cloud" src="https://kevin-bish.com/repo/cloud.png">
    <img class="cloud" src="https://kevin-bish.com/repo/cloud.png">
  </div>
  <div class="grass"></div>
  <div class="road">
    <div class="lines"></div>
    <img class="mario" src="https://kevin-bish.com/repo/mario.png">
    <img class="luigi" src="https://kevin-bish.com/repo/luigi.png">
  </div>
</body>

It will show these two clouds.

 

Let’s give the two clouds some positioning so that they overlap each other.

.cloud {
  position: absolute;
}

.cloud:nth-child(1) {
  width: 200px;
  top: 120px;
  opacity: 0.5;
  animation: wind 80s linear infinite reverse;
}

.cloud:nth-child(2) {
  width: 300px;
  top: 0;
  animation: wind 50s linear infinite reverse;
}

It will show them as below.

Now, we will animate them with the shortcuts. The animation shortcut takes animation name, duration, timing-function, iteration-count, direction in order.

.cloud {
  position: absolute;
}

.cloud:nth-child(1) {
  width: 200px;
  top: 120px;
  opacity: 0.5;
  animation: wind 80s linear infinite reverse;
}

.cloud:nth-child(2) {
  width: 300px;
  top: 0;
  animation: wind 50s linear infinite reverse;
}

@keyframes wind{
  from{ left: -300px}
  to{left: 100%}
}

It will show these clouds moving slowly from right to left.

We will now learn about chaining two animations. We will create a jump animation for Mario. Now, it will have 3 states. So, we cannot use from and to. We will use percentages in such cases.

@keyframes jump {
  0%{ top: -40px }
  50%{ top: -100px }
  100%{ top: -40px }
}

Now, we will chain it. As you can see, we are using shorthand notation for Mario’s earlier drive animation. After that, we are using a comma(,) and putting the jump animation.

.mario{
  position: absolute;
  top: -40px;
  left: 0px;
  animation-name: drive;
  animation-duration: 3s;
  animation-fill-mode: both;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
  animation: drive 3s both infinite linear,
             jump 0.3s 1.2s ease;
}

Now, our Mario will jump once for 0.3s after a delay of 1.2s, with ease timing.

The End

Resources credited: W3Schools, Flaviocopes, Nabendu Blog