usha
usha

Reputation: 29349

Bootstrap animation every 20 seconds

I am using twitter bootstrap in my app. I have a requirement to animate an icon every 20 seconds.

Here is the code i have. Its in coffee script. But its very basic and can easily be related to javascript.

@updateCountIndicator = () ->
  data = Math.floor (Math.random() * 10) + 1
  countIndicator = $("#count-indicator")
  countIcon = $("#count-icon")
  countIcon.removeClass("icon-animated-vertical")
  countIndicator.html data
  countIcon.toggleClass "icon-animated-vertical"
  timedCountUpdate()

@timedCountUpdate = () ->
  setTimeout(updateCountIndicator, 20000)

The problem is, icon animates the first time(20 seconds after page refresh). But doesn't animate after that. It works properly when i debug using breakpoints. Am i doing something wrong here?

Upvotes: 1

Views: 785

Answers (1)

mu is too short
mu is too short

Reputation: 434685

I think I (finally) see the problem. We'll look at your fiddle:

$(document).ready(function(){
    setTimeout(animateIcon, 20000);
});

function animateIcon() {
    $("#change-color").addClass("animate-color");
    setTimeout(animateIcon, 20000);
}

and go from there. Each time animateIcon is called, it will:

$("#change-color").addClass("animate-color");

But that does nothing if #change-color already has the animate-color class so you only see the animate-color animation once. That would lead us to try this CoffeeScript version:

animateIcon = ->
    $('#change-color').removeClass('animate-color')
    $('#change-color').addClass('animate-color')
    setTimeout(animateIcon, 20000)
$(animateIcon)

That looks like it should re-add the animate-color class and re-trigger the CSS animation but it won't. Why not? Well, the second time that animateIcon runs, #change-color will have animate-color at the beginning of the function and it will have animate-color at the end when the browser gets control again; since #change-color's classes haven't changed (i.e. it will have the same classes before and after), nothing will happen.

To get around that problem, you need to sort of trick the browser into thinking that the classes have actually changed. One way to get that to happen goes like this:

  1. Reset the classes and colors on #change-color.
  2. Hand control back to the browser.
  3. Add animate-color.
  4. Restart the timer.
  5. Hand control back to the browser.

So how do we hand control back to the browser? A setTimeout(..., 0) call is a common trick for that. Converting the above to CoffeeScript gives us:

addClassAndRestart = ->
    $('#change-color').addClass('animate-color')
    setTimeout(animateIcon, 20000)
animateIcon = ->
    $('#change-color').removeClass('animate-color').css('background', 'transparent')
    setTimeout(addClassAndRestart, 0)
$(animateIcon)

The .css('background', 'transparent') may or may not be needed but that's what #change-color starts with so I added it.

Demo: http://jsfiddle.net/ambiguous/BByJD/

Sorry about the delay, I lost track of this question.

Upvotes: 3

Related Questions