Andrei F
Andrei F

Reputation: 4394

Animating keyframes with transition for rotation in CSS3

I'm trying out a simple example of continuous spin animation (infinite) using steps, but I cannot seem to make a smooth transition between states. So what I'm trying is to animate the rotation (infinite) of a textbox from 0 to 360 degrees, with pause between each step: demo jsfiddle. But jump is instant, I cannot make them transition smooth from one to another. How can I achieve this, using only CSS?

My code so far is:

<input type="text" id="textbox" class='textbox animate' value="Text box"/> 


body, html {
  width: 100%;
  height: 100%;
  background: #ccc;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction:column;
}
input {
  margin-top: 70px;
  clear: both;
}

.textbox {
   width: auto;
   display:block;
   text-align: center;
}

.textbox.animate {
   animation:spin 30s steps(30, end) infinite;
   transition: rotate 0.3s ease;
}
@keyframes spin { 
   100% { transform: rotate(360deg); } 
}

Upvotes: 0

Views: 3492

Answers (2)

Harry
Harry

Reputation: 89780

The effect that you are trying to achieve is not something that can be achieved with steps() function as far as I am aware because the steps function works like a stair-case with one sharp jump between each step of the animation.

You'd need to manually write the keyframes such that there is a smooth movement between the start and end points of a step which is then followed by a pause till the next step starts. The below snippet does this and this is how:

  • At 0%, the rotation is specified as 0 degree and at 1.66% of the animation's duration, the rotation is specified as 12 degree (1/30th). This means there is a smooth rotation from 0deg to 12deg.
  • For both 1.66% and 3.33%, the rotation is specified as 12 degree. So there is no rotation between these two states (the pause).
  • Then at 4.99%, the rotation is specified as 24 degree. So between 3.33% and 4.99% the element rotates gradually from 12 deg to 24 deg. Then till 6.65%, it stays in same position and so on.

I have chosen the keyframe selectors (the percentage values) based on the no. of steps. There must be a total of 30 steps and so each step (the rotate + the pause) should be over 3.33% span. Then I've given equal time for the rotate and the pause, so 1.66% is when rotation completes and 3.33% is when pause completes.

If say you need 40 steps the the rotation should be increments of 9 degrees and each steps should be over 2.5% of animation's duration. So the rotate ends at 1.25% and pause ends at 2.5% (then the next step's rotate ends 3.75% and it's pause ends at 5% and so on).

body,
html {
  width: 100%;
  height: 100%;
  background: #ccc;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}
input {
  margin-top: 70px;
  clear: both;
}
.textbox {
  width: auto;
  display: block;
  text-align: center;
}
.textbox.animate {
  animation: spin 30s linear infinite;
}
@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  1.66%,
  3.33% {
    transform: rotate(12deg);
  }
  4.99%,
  6.66% {
    transform: rotate(24deg);
  }
  8.32%,
  9.99% {
    transform: rotate(36deg);
  }
  11.65%,
  13.32% {
    transform: rotate(48deg);
  }
  14.98%,
  16.65% {
    transform: rotate(60deg);
  }
  18.31%,
  19.98% {
    transform: rotate(72deg);
  }
  21.65%,
  23.31% {
    transform: rotate(84deg);
  }
  24.98%,
  26.65% {
    transform: rotate(96deg);
  }
  28.31%,
  29.98% {
    transform: rotate(108deg);
  }
  31.65%,
  33.33% {
    transform: rotate(120deg);
  }
  34.98%,
  36.65% {
    transform: rotate(132deg);
  }
  38.33%,
  39.98% {
    transform: rotate(144deg);
  }
  41.65%,
  43.33% {
    transform: rotate(156deg);
  }
  44.98%,
  46.65% {
    transform: rotate(168deg);
  }
  48.33%,
  50% {
    transform: rotate(180deg);
  }
  51.65%,
  53.33% {
    transform: rotate(192deg);
  }
  54.99%,
  56.65% {
    transform: rotate(204deg);
  }
  58.33%,
  59.99% {
    transform: rotate(216deg);
  }
  61.65%,
  63.33% {
    transform: rotate(228deg);
  }
  64.99%,
  66.66% {
    transform: rotate(240deg);
  }
  68.33%,
  69.99% {
    transform: rotate(252deg);
  }
  71.66%, 73.33% {
    transform: rotate(264deg);
  }
  74.99%,
  76.66% {
    transform: rotate(276deg);
  }
  78.33%,
  79.99% {
    transform: rotate(288deg);
  }
  81.66%,
  83.33% {
    transform: rotate(300deg);
  }
  84.99%,
  86.66% {
    transform: rotate(312deg);
  }
  88.33%,
  89.99% {
    transform: rotate(324deg);
  }
  91.66%,
  93.33% {
    transform: rotate(336deg);
  }
  94.99%,
  96.66% {
    transform: rotate(348deg);
  }
  98.33%,
  100% {
    transform: rotate(360deg);
  }
}
<script>
  function startAnimation() {

    document.getElementById("textbox").className = "textbox animate";
  }
</script>

<input type="text" id="textbox" class='textbox animate' value="Text box" />

Upvotes: 1

Saurabh Sonawane
Saurabh Sonawane

Reputation: 951

As said by Harry you have to add keyframe animation here as,

checkout your updated fiddle here

Your CSS will be like this

.textbox.animate {
   -webkit-animation: circle infinite .75s linear;
      -moz-animation: circle infinite .75s linear;
        -o-animation: circle infinite .75s linear;
           animation: circle infinite .75s linear;
    transition: rotate 0.3s ease;}

@-webkit-keyframes circle
{
    0%
        {
            -webkit-transform: rotate(0);
                -ms-transform: rotate(0);
                 -o-transform: rotate(0);
                    transform: rotate(0);}
   100%
       {
            -webkit-transform: rotate(360deg);
                -ms-transform: rotate(360deg);
                 -o-transform: rotate(360deg);
                    transform: rotate(360deg);}}
@-moz-keyframes circle
{
    0%
       {
            -webkit-transform: rotate(0);
                -ms-transform: rotate(0);
                 -o-transform: rotate(0);
                    transform: rotate(0);}
    100%
        {
            -webkit-transform: rotate(360deg);
                -ms-transform: rotate(360deg);
                 -o-transform: rotate(360deg);
                    transform: rotate(360deg);}}
@-o-keyframes circle
{
    0%
       {
            -webkit-transform: rotate(0);
                -ms-transform: rotate(0);
                 -o-transform: rotate(0);
                    transform: rotate(0);}
    100%
       {
            -webkit-transform: rotate(360deg);
                -ms-transform: rotate(360deg);
                 -o-transform: rotate(360deg);
                    transform: rotate(360deg);}}
@keyframes circle
{
    0%
        {
            -webkit-transform: rotate(0);
                -ms-transform: rotate(0);
                 -o-transform: rotate(0);
                    transform: rotate(0);}
    100%
       {
            -webkit-transform: rotate(360deg);
                -ms-transform: rotate(360deg);
                 -o-transform: rotate(360deg);
                    transform: rotate(360deg);}}

Upvotes: 0

Related Questions