0

I have a simple fadeIn fadeOut animation, it's basically a blinking arrow. However, it doesn't loop. It just goes once, and it's done. I found an answer here -> How to repeat (loop) Jquery fadein - fadeout - fadein, yet when I try to follow it, mine doesn't work.

The script for the animation is
<script type="text/javascript">
$(document).ready(function() {
    $('#picOne').fadeIn(1000).delay(3000).fadeOut(1000);
   $('#picTwo').delay(5000).fadeIn(1000).delay(3000).fadeOut(1000);
});
</script>

the script given in the answer is

$(function () {
    setInterval(function () {
        $('#abovelogo').fadeIn(1000).delay(2000).fadeOut(1500).delay(2000).fadeIn(1500);
    }, 5000);
});

so I assume the end combination would be

 $(document).ready(function() {
   setInterval(function () {
        $('#picOne').fadeIn(1000).delay(3000).fadeOut(1000);
       $('#picTwo').delay(5000).fadeIn(1000).delay(3000).fadeOut(1000);
    }, 5000);
});
    </script>

Could someone please point out what I'm doing wrong? thanks

Community
  • 1
  • 1
Nata2ha Mayan2
  • 474
  • 1
  • 10
  • 23
  • I wouldn't expect that to work well at all. I mean, your animation runs for 10+ seconds but your interval is set to 5... – elclanrs Apr 14 '12 at 06:39

4 Answers4

4

Two details :

  • You have to set the interval to 10000 because your animation run 10s

  • If you want it to start now, you have to call it one time before executing the interval (the first execution of the interval is after the delay)

--

$(document).ready(function() {

   function animate() {
       $('#picOne').fadeIn(1000).delay(3000).fadeOut(1000);
       $('#picTwo').delay(5000).fadeIn(1000).delay(3000).fadeOut(1000);
   }

   animate();
   setInterval(animate, 10000);
});​

Demonstration here : http://jsfiddle.net/bjhG7/1/

--

Alternative code using callback instead of setInterval (see comments):

$(document).ready(function() {

   function animate() {
       $('#picOne').fadeIn(1000).delay(3000).fadeOut(1000);
       $('#picTwo').delay(5000).fadeIn(1000).delay(3000).fadeOut(1000, animate);
   }

   animate();
});​

Demonstration here : http://jsfiddle.net/bjhG7/3/

Thomas Guillory
  • 5,719
  • 3
  • 24
  • 47
  • 1
    A better idea would be to use a callback instead of a loop. Trigger the callback when the last animation is done. – fredrik Apr 14 '12 at 07:00
  • This shouldn't affect the position of the animation, should it? When it reappears, it's right above where it used to be. That's something else, right? – Nata2ha Mayan2 Apr 14 '12 at 07:06
  • Your problem is that `fadeOut()` set the delement to `display: none` at the end of the fade, so it goes out of the flow. Alternatively you can use `.fadeTo(1000, 0)` to change only opacity: http://jsfiddle.net/bjhG7/2/ – Thomas Guillory Apr 14 '12 at 07:12
  • 1
    (in this jsfiddle I've also used the `callback method` proposed by @fredrik to show it to you) – Thomas Guillory Apr 14 '12 at 07:13
  • @Artimuz Okay, I get it now, but how do I make it so that it **stays** in it's spot? – Nata2ha Mayan2 Apr 14 '12 at 07:21
  • The trouble with this approach is that it relies on the timing being perfect. In the event something caused the animation to take 12 seconds instead of 10, the setInterval would be triggered 2 seconds early and start fading in `picOne` before `picTwo` had even started to fade out. Using a callback is far more reliable to keep your animation in sync. – gilly3 Apr 14 '12 at 07:22
  • @Nata2haMayan2 Hum I don't get it... With the first implementation (with `.fadeOut`), the element stay in place, no ? – Thomas Guillory Apr 14 '12 at 07:28
  • @Artimuz It's not. For some reason, it goes up into the space exactly above the original spot..... – Nata2ha Mayan2 Apr 14 '12 at 07:31
  • @Nata2haMayan2 You can fix your elements with absolute positionning. – Thomas Guillory Apr 14 '12 at 07:33
  • @Artimuz I know, and it's already set to that. That is the part that is confusing me... – Nata2ha Mayan2 Apr 14 '12 at 07:35
1
function fadein(){
    $('#picOne,#picTwo').animate({'opacity':'1'},1000,fadeout())
}
function fadeout(){
    $('#picOne,#picTwo').animate({'opacity':'0'},1000,fadein())
}
fadein()
socrateisabot
  • 837
  • 2
  • 10
  • 28
  • 1
    you want to change your callbacks to pointers rather than execution - i.e. removed the "()" on the "fadeout/fadein" arguments on the animate() call. – webnesto Apr 14 '12 at 06:50
  • This answer is close, but not quite. The original code first fades in pic1, leaves it for 3 seconds, then fades it out. Then it does the same with pic2. – gilly3 Apr 14 '12 at 06:58
1

Take advantage of the callback argument of .fadeOut(). Pass a reference to the function that does the fading as the callback parameter. Choose which image to fade based on a counter:

$(function() {
    var imgs = $('#picOne,#picTwo');
    var fadeCounter = 0;

    (function fadeImg() {
        imgs.eq(fadeCounter++ % 2).fadeIn(1000).delay(3000).fadeOut(1000, fadeImg);
    })();
});

Demo: http://jsfiddle.net/KFe5h/1

gilly3
  • 87,962
  • 25
  • 144
  • 176
0

As animation sequences get more complex, I've found using async.js leads to more readable and maintainable code. Use the async.series call.

Joe Parry
  • 241
  • 2
  • 7