Sasha Sofin
Sasha Sofin

Reputation: 108

Return CSS animation starting position

I wanted to finish the animation and smoothly return to its original state, but there is a jump.

Required condition, duration of the animation can be anything.

I tried to do this using CSS features.

setTimeout(function() {
    $('div').addClass('stop');
}, 2500);
div {
    width: 50px;
    height: 300px;
    margin: 50px 150px;
    background-color: green;
    -webkit-animation: wiggle 2s linear infinite;
            animation: wiggle 2s linear infinite;
}
.stop {
    -webkit-animation: none;
            animation: none;
}

@-webkit-keyframes wiggle {
    0% {
        -webkit-transform: rotate(0);
                transform: rotate(0);
    }
    100% {
        -webkit-transform: rotate(360deg);
                transform: rotate(360deg);
    }
}
@keyframes wiggle {
    0% {
        -webkit-transform: rotate(0);
                transform: rotate(0);
    }
    100% {
        -webkit-transform: rotate(360deg);
                transform: rotate(360deg);
    }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div></div>

Upvotes: 2

Views: 4039

Answers (1)

misterManSam
misterManSam

Reputation: 24692

I have created a stop and start animation that rotates back to the beginning. It starts and stops with buttons and could easily start on load. There is a complete demo at the bottom of this answer :)

The div looks like this:

<div class="rotate"></div>

The infinite animation

.play {
  -webkit-animation: wiggle 2s linear infinite;
  animation: wiggle 2s linear infinite;
}

The jQuery

  1. Start the animation:

    $(".start").on("click", function() {            
      //Add infinite rotation animation classes
      $('div').addClass('play rotate');
    });
    
  2. Stop the animation:

    Get the current rotation of the element. Adapted from this answer here by @twist

    function getRotationDegrees(obj) {
      var matrix = obj.css("-webkit-transform") ||
        obj.css("-moz-transform") ||
        obj.css("-ms-transform") ||
        obj.css("-o-transform") ||
        obj.css("transform");
      if (matrix !== 'none') {
        var values = matrix.split('(')[1].split(')')[0].split(',');
        var a = values[0];
        var b = values[1];
        var angle = Math.round(Math.atan2(b, a) * (180 / Math.PI));
      } else {
        var angle = 0;
      }
      return (angle < 0) ? angle += 360 : angle;
    }
    

    Get the current angle and then stop the current animation by removing the classes:

    $(".stop").on("click", function() {
    
      //Get the current rotation value
      angle1 = getRotationDegrees($('.rotate'));
    
      //Stop current animation
      $('div').removeClass('play rotate');
    
  3. Create new stop animation: It looks a bit messy. Basically, it is creating a new animation with the current rotation as the starting point. The animation then takes it back to 0deg.

    //Create stop animation and apply to new class "rotated"
      var animation = '<style type="text/css" title="stopAnimation">.rotated { -webkit-animation: stop 2s forwards; animation: stop 2s forwards; }  @-webkit-keyframes stop {  0% { transform: rotate(' + angle1 + 'deg);} 100% { transform: rotate(-0deg); } } @keyframes stop {  0% { transform: rotate(' + angle1 + 'deg);} 100% { transform: rotate(-0deg); } }</style>';          
    
      //Append new styles to the header
      $('head').append(animation);
    
  4. Restart the animation:

    $(".start").on("click", function() {
    
      //Remove stopping animation class
      $('div').removeClass('rotated');
    
      //Add infinite rotation animation classes
      $('div').addClass('play rotate');
    });
    

The added <style> tag is removed after the animation is complete:

  //Garbage man - Remove the style tags after the animation is done
  // Important - The timeout should match the duration of the stop animation.      
  setTimeout(
  function() 
  {   
    $('style[title="stopAnimation"]').remove();    

  }, 2000);

Full Example

function getRotationDegrees(obj) {
  var matrix = obj.css("-webkit-transform") ||
    obj.css("-moz-transform") ||
    obj.css("-ms-transform") ||
    obj.css("-o-transform") ||
    obj.css("transform");
  if (matrix !== 'none') {
    var values = matrix.split('(')[1].split(')')[0].split(',');
    var a = values[0];
    var b = values[1];
    var angle = Math.round(Math.atan2(b, a) * (180 / Math.PI));
  } else {
    var angle = 0;
  }
  return (angle < 0) ? angle += 360 : angle;
}


$(".stop").on("click", function() {
  
  //Get the current rotation value
  angle1 = getRotationDegrees($('.rotate'));
  
  //Stop current animation
  $('div').removeClass('play rotate');
  
  //Add class "rotated" for new animation
  $('div').addClass('rotated');


  //Create stop animation and apply to new class "rotated"
  var animation = '<style type="text/css" title="stopAnimation">.rotated { -webkit-animation: stop 2s linear forwards; animation: stop 2s linear forwards; }  @-webkit-keyframes stop {  0% { transform: rotate(' + angle1 + 'deg);} 100% { transform: rotate(-0deg); } } @keyframes stop {  0% { transform: rotate(' + angle1 + 'deg);} 100% { transform: rotate(-0deg); } }</style>';
  
  
  //Append new styles to the header
  $('head').append(animation);
  
  //Garbage man - Remove the style tags after the animation is done
  // Important - The timeout should match the duration of the stop animation.  
  setTimeout(
  function() 
  {   
    $('style[title="stopAnimation"]').remove();    

  }, 2000);
  
  


});

$(".start").on("click", function() {
  
  //Remove stopping animation class
  $('div').removeClass('rotated');
  
  //Add infinite rotation animation classes
  $('div').addClass('play rotate');
});
div {
  width: 50px;
  height: 300px;
  margin: 50px 150px;
  background-color: green;
}
.play {
  -webkit-animation: wiggle 2s linear infinite;
  animation: wiggle 2s linear infinite;
}
@-webkit-keyframes wiggle {
  0% {
    -webkit-transform: rotate(0);
    transform: rotate(0);
  }
  100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}
@keyframes wiggle {
  0% {
    -webkit-transform: rotate(0);
    transform: rotate(0);
  }
  100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button class="stop">Stop!</button>
<button class="start">Start!</button>

<div class="rotate"></div>

Upvotes: 4

Related Questions