6

I am trying to have an animation run only when the mouse is over an object. I can get one iteration of the animation and then have it set back to normal on mouse out. But I'd like the animation to loop on mouseover. How would I do it, using setInterval? I'm a little stuck.

V_H
  • 1,793
  • 3
  • 34
  • 59

4 Answers4

9

It could be done like this:

$.fn.loopingAnimation = function(props, dur, eas)
{
    if (this.data('loop') == true)
    {
       this.animate( props, dur, eas, function() {
           if( $(this).data('loop') == true ) $(this).loopingAnimation(props, dur, eas);
       });
    }

    return this; // Don't break the chain
}

Now, you can do this:

$("div.animate").hover(function(){
     $(this).data('loop', true).stop().loopingAnimation({ left: "+10px"}, 300);
}, function(){
     $(this).data('loop', false);
     // Now our animation will stop after fully completing its last cycle
});

If you wanted the animation immediately stop, you could change the hoverOut line to read:

$(this).data('loop', false).stop();
anar khalilov
  • 16,993
  • 9
  • 47
  • 62
Doug Neiner
  • 65,509
  • 13
  • 109
  • 118
  • I had to switch my answer due to problems wtih recursion. I can't seem to get you answer to work with the loopingAnimation method - if I change it to "animate", it does one iteration. – V_H Feb 10 '10 at 01:56
  • Doug, the *animate* call was missing closing parenthesis so I added it but it wasn't enough to save since you need at least 6 chars modifications so I indented your code for that purpose. FYI. – anar khalilov Sep 03 '13 at 09:05
4

setInterval returns an id that can be passed to clearInterval to disable the timer.

You can write the following:

var timerId;

$(something).hover(
    function() {
        timerId = setInterval(function() { ... }, 100);
    },
    function() { clearInterval(timerId); }
);
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
4

I needed this to work for more then one object on the page so I modified a little Cletus's code :

var over = false;
$(function() {
  $("#hovered-item").hover(function() {
    $(this).css("position", "relative");
    over = true;
    swinger = this;
    grow_anim();
  }, function() {
    over = false;
  });
});

function grow_anim() {
  if (over) {
    $(swinger).animate({left: "5px"}, 200, 'linear', shrink_anim);
  }
}

function shrink_anim() {
  $(swinger).animate({left: "0"}, 200, 'linear', grow_anim);
}
tsi
  • 41
  • 1
1

Consider:

<div id="anim">This is a test</div>

with:

#anim { padding: 15px; background: yellow; }

and:

var over = false;
$(function() {
  $("#anim").hover(function() {
    over = true;
    grow_anim();
  }, function() {
    over = false;
  });
});

function grow_anim() {
  if (over) {
    $("#anim").animate({paddingLeft: "100px"}, 1000, shrink_anim);
  }
}

function shrink_anim() {
  $("#anim").animate({paddingLeft: "15px"}, 1000, grow_anim);
}

You can achieve this using timers too.

cletus
  • 616,129
  • 168
  • 910
  • 942
  • Cool solution. I'm still a novice at JS. How would I make this generic so if I had several anims, I would assume I would pass in the id in the function and then call it each time for each type? can the function() part there take parameters, and hwo would I call it for each kind, is that really the best solution? – V_H Jan 11 '10 at 06:30