Search code examples
csscss-animationskeyframe

CSS @keyframe, translateX() and rotateY() on both ends


I'm trying to make some kind of Mario Kart animation using only CSS, where I basically have a car starting from the left side of the screen going all the way across the screen.

Here is where the problem occurs:
I want the car to basically change direction (so going back from right to left).

This is simply done with an animation-direction of alternate. If you picture this, you see that the car is going backwards on the way from left to right.

What I want to do is to mirror it at the end of each path, so that the car turns and faces the opposite direction, which should take up like 0.1s and can be done using the rotateY(180deg).

I tried to combine several keyframe animations (one for the translate, and one for the rotate), but that wouldn't work, since my 'car' would just rotate and glitch and wouldn't move at all. I figured that the order of the two transform methods might be the problem, but it still didn't work the other way around.

After that, I tried to combine the two transform methods and alternate the animation, which looked somewhat like this:

div {
    animation: dirChange 5s linear infinite both alternate;
}

@keyframes dirChange {
    0% {
        transform: translateX(20vw) rotateY(0);
    }
    50% {
        transform: translateX(80vw) rotateY(0);
    }
    90% {
        transform: translateX(80vw) rotateY(.5turn);
    }
    100%{
        transform:translateX(80vw) rotateY(.5turn);
    }
}

As you can see I tried to translate the car to the end of 80vw first and tried to apply the rotateY afterwards. This looks somewhat okay on the first way from left to right (even though the car rotates a bit early which could easily be fixed using other percentages), but then on the alternate way back, the car of course rotates very early on and basically drives the rest of the way backwards.

So how can I have my car rotate at the end of each way, then keep that rotation for the alternate way and then rotate again at the starting point?
Is this even possible with CSS only or do I need JS?


Solution

  • I finally figured out how to do it. Here is my solution as it can be seen on my codepen https://codepen.io/xutocode/pen/poNGXam .

    @keyframes changeDir{
    0% {transform: translateX(0vw) rotateY(0);}
    49% {transform: translateX(89vw) rotateY(0);}
    50% {transform: translateX(90vw) rotateY(.5turn);}
    99% {transform: translateX(1vw) rotateY(.5turn);}
    100% {transform: translateX(0vw) rotateY(0);}
    }
    

    The trick was basically to put it all inside one keyframe and then taking the complete cycle (not only the way from left to right, but also the way back). Essentially I then just gave them the 1% from 49 to 50% and 99 to 100% to rotate along the y-axis, resulting in a mirrored car.