1

I have the following code that I apply on click:

$("#search").click(function()
{
  if (searchForth)
  {
    animateRotate(45,"#search");
    searchForth = false;
  }
  else
  {
    animateRotate(-45,"#search");
    searchForth = true;
  }
});

And the function being called:

function animateRotate(d,element)
{
  var elem = $(element);
  $({deg: 0}).animate({deg: d},{
      duration: 600,
      step: function(now)
      {
        elem.css({
            transform: "rotate(" + now + "deg)"
        });
      }
  });
}

When the function gets called, the element rotates 45 degrees from the default position, which is what I want. However, when I click on the element again, the function applies a rotation of -45 degrees, but it does so from the default position of the element instead of the position the element was left in from the previous rotation. Why is that and how can I fix it so the second animation 'picks off' from the final position of the first animation?

Bogdan
  • 379
  • 2
  • 5
  • 19

3 Answers3

0
  1. You should save rotation angle
  2. You shouldn't find elem by deg

var searchForth = false;
var angle=0;
$("#search").click(function()
{
  if (searchForth)
  {
    angle += 45;
    animateRotate(angle,"#search");
    searchForth = false;
  }
  else
  {
    angle -= 45;
    animateRotate(angle,"#search");
    searchForth = true;
  }
});

function animateRotate(d,element)
{
  var elem = $(element);
  $(elem).animate({deg: d},{
      duration: 600,
      step: function(now)
      {
        elem.css({
            transform: "rotate(" + now + "deg)"
        });
      }
  });
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="search">Search</button>
mrgrechkinn
  • 883
  • 8
  • 19
0

You need to get the current rotated position first and than add/remove 45 degrees from it, according to the value of searchForth.

Look at this for more info: Get element -moz-transform:rotate value in jQuery

var searchForth=false;
$("#rotate").click(function()
{
  if (searchForth)
  {
    animateRotate(45,this);
    searchForth = false;
  }
  else
  {
    animateRotate(-45,this);
    searchForth = true;
  }
});
function animateRotate(d,element)
{
var startDeg = getRotationDegrees($(element));
  var elem = $(element);
  $(elem).animate({deg: (startDeg + d)},{
      duration: 600,
      step: function(now)
      {
        elem.css({
            transform: "rotate(" + now + "deg)"
        });
      }
  });
}

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;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="rotate">Rotate me!</div>
T. Dirks
  • 3,566
  • 1
  • 19
  • 34
0

How about just using CSS3 transition and transform?

$(function() {
  var deg = 45;
  var srh = $('#search').on('click', function(e) {
    srh.css('transform', 'rotate(' + (deg) + 'deg)');
    deg = -(deg);
  });
});
#search {
  transition: transform 1s ease;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="search">Search</button>