Yesterday we styled our character; now it's time to animate it! First, let’s change our character map name to
adamSalute
and add a new map for Adam.
$pixel-character: (
...
adam: (
( t t t t t t t t t t t t t d d d d d d t t t t t t t t )
( t t t t t t t t t t t d d s s s s s s d d t t t t t t )
( t t t t t t t t t t d s s s s s s s s s d t t t t t t )
( t t t t t t t t d d s s s s s s s s s s s d d t t t t )
( t t t t t t t t d s s s s s s s s s s s s s s d t t t )
( t t t t t t t t d s s s s s s s s s s s s s s d t t t )
( t t t t t t t t d b b b b b b b b b b b b b b d t t t )
( t t t t t t t t d s s b b b b b b b b b b s s d t t t )
( t t t t t t t d s s s s b b b s s b b b s s s s d t t )
( t t t t t t t d s d s s s b s s s s b s s s d s d t t )
( t t t t t t t d s d s s s s s s s s s s s s d s d t t )
( t t t t t t t t d d s m m m m m m m m m m s d d t t t )
( t t t t t t t t t d m m m s s s s s s m m m d t t t t )
( t t t t t t t t t d m m m s b b b b s m m m d t t t t )
( t t t t t t t t t t d m m s s s s s s m m d t t t t t )
( t t t t t t t t t d d f m m m m m m m m f d d t t t t )
( t t t t t t t t d f f f f m m m m m m f f f f d t t t )
( t t t t t t t d s d d f f f m m m m f f f d d s d t t )
( t t t t t t t d s s s d f f d m m d f f d s s s d t t )
( t t t t t t t d s s s d f f d d d d f f d s s s d t t )
( t t t t t t t t d s s d f f f f f f f f d s s d t t t )
( t t t t t t t t t d d f f f f f f f f f f d d t t t t )
( t t t t t t t t t d n n n n n n n n n n n n d t t t t )
( t t t t t t t t t d n n n n n n n n n n n n d t t t t )
( t t t t t t t t d n n n n n n n n n n n n n n d t t t )
( t t t t t t t t d n n n n n j j j j n n n n n d t t t )
( t t t t t t d d d n n n n j j j j j j n n n n d d d t )
( t t t t t d b b b b b b b b d t t d b b b b b b b b d )
( t t t t t d d b b b b b b d d t t d d b b b b b b d d )
( t t t t t t d d d d d d d d t t t t d d d d d d d d t )
)
Then we open our
_tools.scss
file and create a
@kreyframe
with the name
salute
. What we want is to see our character in normal position half of the time and saying "peace" the other half; to do so, we define four time points in our keyframe:
0% - 45% - 50% - 100%
. Why four? Because we want to control the velocity and the moment of the transition. If we just use two — for example,
0% - 50%
— the transition will be slow. We don't want that; we want to make it look like a natural action. We could use a low time duration like
1s
, but that would be too repetitive, and it's better to just define the time points we want with the behavior we want. So the value for
0%
and
45%
will be our normal character, and the value for
50%
and
100%
will be our salute character. We just have to change the value of
box-shadow
using our function
build_character
and pass the maps for both characters.
@keyframes salute {
0%,
45% {
box-shadow: build_character(map-get($pixel-character, adam), $pixel-size);
}
50%,
100% {
box-shadow: build_character(
map-get($pixel-character, adamsalute),
$pixel-size
);
}
}
Now we add the animation to
pixel-adam
to make our character say peace; nice! We can still make it even more interesting, though. Let's make our character fall and produce an earthquake, and salute after that.
&:after {
animation: salute 6s infinite alternate;
...
}
To achieve that, we come back to our
_tools.scss
and create a couple more animations. The first animation will be the fall; we just need two time points, so we can use
from
and
to
. The first one will have a negative top to hide our character and simulate the fall, and the second one will be the "floor"; to maintain the final state of the animations, we'll use
animation-fill-mode
with
fordwars;
as value.
@keyframes fall {
from {
top: -60rem;
}
to {
top: 4rem;
}
}
The second animation is the earthquake. Just like before, we will use various time points, in this case eight:
0% 15%, 30%, 45%, 60%, 75%, 90%
and
100%
. We set the normal position of the container in the first and last time point, and we simulate the "vibrations" of the earthquake with the others, using
transform: rotate;
.
@keyframes earthquake {
0%,
100% {
transform: rotate(0);
}
15%,
45%,
75% {
transform: rotate(2.5deg);
}
30%,
60%,
90% {
transform: rotate(-2.5deg);
}
}
Now we add both animations
//--assets/components/_pixel-adam.scss/
.pixel-adam {
animation: fall .5s forwards;
...
}
//--assets/components/_character-container.scss/
.character-container {
animation: earthquake .5s forwards;
...
}
And we have some problems: the earthquake and the fall aren't synchronized. To fix that, we're going to use
animation-delay
.
It's time to do some math. I'll give a delay of
3s
to our fall animation, which means a total time of
3.5s
for the delay plus the duration of the animation itself. This means our earthquake should start after that time. If we set the start a little early, it will look like the earthquake is caused by the force of the fall;
3.4s
should be good.
//--assets/components/_pixel-adam.scss/
.pixel-adam {
animation: fall .5s forwards;
animation-delay: 3s;
...
}
//--assets/components/_character-container.scss/
.character-container {
animation: earthquake .5s forwards;
animation-delay: 3.4s;
...
}
We have another problem now: the character is not hidden from the start, and it's making the salute while falling. Not good, so let's fix that by changing the
top
of
pixel-adam
to a negative value high enough to hide the draw; then we define an
animation-delay
of
3s
.
.pixel-adam {
animation: fall .5s forwards;
animation-delay: 3s;
...
top: -60rem;
&:after {
animation: salute 6s infinite alternate;
animation-delay: 3s;
...
}
}
Now it looks a lot better, but the shadow has some issues. It should come from the bottom, at the same time our character falls. To fix that, we're going to make another animation called
up
, which is basically the inverted version of
fall
.
Up
also modifies opacity, which makes it looks like a real shadow.
@keyframes up {
from {
opacity: 0;
top: 80rem;
}
to {
opacity: 1;
top: 35%;
}
}
Now we add the animation to our
boots-shadow
, set the opacity to 0, and change the top to
60rem
. We’ll also set the same delay as the
fall
, so they synchronize.
.boots-shadow {
...
&:after,
&:before {
animation: up .5s forwards;
animation-delay: 3s;
...
opacity: 0;
top: 60rem;
...
}
}
And we have our character animated! But what if we have various characters? Well, that’s a problem we’re going to fix in tomorrow’s video!
Comments for Build your own 8-bit character using Sass part III