Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Direction of rotation in CSS Animation\Transformation

I'm trying to understand CSS animations and I'm running into the following issue:

I've got a simple div with animation attached to it in CSS, like below:

<div id="learn">LEARN</div>

#learn {
    width: 100px;
    height: 100px;
    background: blue;
    position: relative;
    animation: test1 5s ease-in 2s infinite;
}

Case 1:

@keyframes test1 {
    0% {
        transform: rotate(179deg);
    }
    100% {
        transform: rotate(357deg);
    }
}

Case 2 (the 0% transform is split into 90+89 deg instead of 179):

@keyframes test1 {
    0% {
        transform: rotate(90deg) rotate(89deg);
    }
    100% {
        transform: rotate(357deg);
    }
 }

Why is the first case rotating clockwise and the second case rotating counter clockwise?

like image 504
Don Woodward Avatar asked Aug 02 '15 17:08

Don Woodward


1 Answers

This might just be a bug with rotation transforms, which I'll address after some background.

Background

First off, the way rotations are supposed to work is with relation to a circle. If you specify a number of degrees, that will place the element in the position dictated by a how much rotation the degrees specify. When not animating a rotation, there are many ways to represent the element's placement. Code Uniquely is half-right in their comment in that the placement of 357 degrees and -3 degrees is the same, but when animating, they're very different. Going from 0 degrees to -3 degrees is a small counter-clockwise rotation, whereas going from 0 degrees to 357 degrees is a large clockwise rotation.

Findings

What you've found seems to ignore this calculation (in both Firefox and Chrome from what I've tested out). From what I'm seeing, combining rotate transforms effectively reverses the direction that the rotation should be going in, even if you're combining with a 0deg rotation:

transform: rotate(90deg); //rotates clockwise
transform: rotate(0deg) rotate(90deg); //rotates counter-clockwise

It seems that you can fix this by "combining" the rotation transforms in both animation steps:

// this performs a clockwise rotation
@keyframes test3 {
    0% {
        transform: rotate(0deg) rotate(90deg);
    }    
    100% {
        transform: rotate(0deg) rotate(357deg);
    }
}

Finally, it seems that the number of "combinations" matters. If you combine 2 rotations in one step, but 3 in another, the unexpected behavior occurs:

// rotates counter-clockwise since there are unequal rotation transforms
@keyframes test4 {
    0% {
        transform: rotate(0deg) rotate(0deg) rotate(90deg);
    }
    100% {
        transform: rotate(0deg) rotate(357deg);
    }
}

Conclusion

This likely isn't the greatest answer, but combining rotations like this just doesn't appear to be documented anywhere. I would suggest not combining the same rotate transforms (you can still combine rotateX and rotateY without this weirdness) and stick with the sum of the degree values.

In case anyone finding this explanation wants to perhaps find out more about this behavior than I have, here's a fiddle with the examples above as a starting point.

like image 96
Jonathan Michalik Avatar answered Oct 07 '22 14:10

Jonathan Michalik