Smooth CSS Transition Animation Rotation

20,038

Solution 1

I needed to think a lot to solve your request; but I have finally find the solution

demo

The relevant CSS code :

.spin {
    animation: spin 2s linear 0s infinite reverse;
    -moz-animation: 2s linear 0s reverse none infinite spin;
    -webkit-animation: spin 2s linear 0s infinite reverse;
    -0-animation: spin 2s linear 0s infinite reverse;
    -webkit-animation-play-state: paused;
    -o-animation-play-state: paused;
    -moz-animation-play-state: paused;
    animation-play-state: paused;
}
.spin:hover {
    -webkit-animation-play-state: running;
    -o-animation-play-state: running;
    -moz-animation-play-state: running;
    -webkit-animation-play-state: running;
}
.yin-yang {
    animation: spin 4s linear 0s infinite normal;
    -moz-animation: 4s linear 0s normal none infinite spin;
    -webkit-animation: spin 4s linear 0s infinite normal;
    -0-animation: spin 4s linear 0s infinite normal;
}

The trick: since you already had 2 elements (spin and yin-yang) I set one of them to rotate in one direction, and the other one to rotate in reverse, and more fast. When both are running, the net effect is to rotate in one direction; when only one is rotating, the net effect is the opposite.

Now, the only thing that is left is to pause and restart the fast rotation (not setting reseting it !)

Detected one mistake on the above, the fourth line of .spin:hover should be the un-prefixed:

.spin:hover {
    -webkit-animation-play-state: running;
    -o-animation-play-state: running;
    -moz-animation-play-state: running;
    animation-play-state: running;
}

corrected demo

Adding an extra element in the HTML I have been able to make the rotation change smooth.

smooth transition demo

The extra CSS is:

.acc {
    transition: all 4s ease-out;
}
.spin:hover .acc {
    -webkit-transform: rotate(-360deg);
    transform: rotate(-360deg);
}

Solution 2

well, this out:

css:

#test {
    margin: 100px;
    height: 200px; width: 200px;
    background: black;
    -webkit-transition: all 1s ease;
    -moz-transition: all 1s ease;
    -o-transition: all 1s ease;
    -ms-transition: all 1s ease;
    transition: all 1s ease;
}

#test:hover {
    background: gray;
    -webkit-transform: rotate(1080deg);
    -moz-transform: rotate(1080deg);
    -o-transform: rotate(1080deg);
    -ms-transform: rotate(1080deg);
    transform: rotate(1080deg);

    -webkit-border-radius: 100px;
    -moz-border-radius: 100px;
    border-radius: 100px;
}

html:

<div id="test"></div>

DEMO

The problem that you are having is due to the slowness of the transition. Since css can have any logic, when you hover the elm will start again from "0" or "360" or whatever your setup was. So will never be smooth because css can't know what was the last "deg num" before the hover happened...

However! you can try stylus

"Stylus features powerful in-language function definitions."

Hope this help :/

Share:
20,038
Go Nate
Author by

Go Nate

Updated on July 09, 2022

Comments

  • Go Nate
    Go Nate almost 2 years

    I have created this fiddle to demonstrate the problem:

    http://jsfiddle.net/NfX56/

    Animation ROTATION and HOVER seems to work fine for changing direction but the TOGGLE when I hover over the item for transition is jumpy and not a smooth reverse of direction like I would like.

    Here is the basic code without browser prefix:

    @keyframes spin {
        0% { transform: rotate(0deg); }
        100% { transform: rotate(360deg); }
    }
    .spin {
        animation: spin 3.5s linear 0s infinite normal;
        width: 100px;
        height: 100px;
        border-radius: 50px 50px 50px 50px;
        overflow: hidden;
        margin-left: -50px;
        margin-top: -50px;
        top: 50%;
        left: 50%;
        position: absolute;
    }
    .spin:hover {
        animation: spin 3.5s linear 0s infinite reverse;
    }
    

    I have been trying to play around with the following:

    transition-property: transform;
    transition-duration: 0s;
    transition-timing-function: ease-in-out;
    

    In an attempt to smooth the animation so that the symbol smoothly reverses direction but I can't quite seem to get it right... any help would be great!

    http://jsfiddle.net/NfX56/

  • Go Nate
    Go Nate almost 11 years
    Cool, I like your demo! I think using transition is a better method when transitioning from one static state to another, it just seems that with animations maybe its not possible to have an object smoothly transition without jumping back to its original point. I am going to look into javascript function to handle this feature
  • Go Nate
    Go Nate almost 11 years
    If you change the animation time to be the same (ie: 2s) the animation freezes in the position it was at when hovered over... kinda a cool effect! css animations are fuN!!!! thanks for the help vals!
  • Go Nate
    Go Nate almost 11 years
    there is a bit of a glitch in chrome when hovering rapidly where the symbol seems to glitch and jump around, possible because the animation starts at 360deg and ends at 0?
  • vals
    vals almost 11 years
    Sorry for the late answer, I have been on holidays :-) I have corrected the IE issue, it was a stupid mistake. I don't see the glitch in Chrome; may be it depens on something else. What I am almost suer is that it doesn't depend on the change from 360 to 0.
  • vals
    vals almost 11 years
    I have been investigating the glith in chrome. Haven't find out anything about it, but in the process I have find a way to make a smooth change in the rotation speed; see new demo.
  • secondman
    secondman over 10 years
    Thats sick! Nice job!
  • Catherine Nyo
    Catherine Nyo over 9 years
    Oh my.. this is great!