Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make JQuery wait inside a loop in rotation animation

I have a circle and in it a percentage text, starts with 0%. Once I hover the circle it goes from 0 to 100% (with another effect around the circle). As for now, the percentage goes from 0 to 100 directly and I want it to show the progress (0,1,2...,99,100) but I can't manage to make JQuery wait between each for iteration.

This is what I've tried: JSFiddle demo.

Note: My code works with chrome for now.

That's one iteration:

function actions(i){
    var box = $('#box');
    box.css('transform','rotate(' + i + ' deg)');
    box.css('-ms-transform','rotate(' + i + 'deg)');
    box.css('-webkit-transform','rotate(' + i + 'deg)');
    prec = (100*(i + 135))/360;
    $("div.prec").delay(100).html(Math.round(prec)+"%");
}

I understand that delay() needs to be queued and html() is not queued so I already tried setTimeout, but that it didn't work either. I also tried setInterval - see the next code snippet:

setInterval(function () {
    $("div.prec").html(Math.round(prec)+"%");
},100);

To be more clear, I want the percentage to fit the effect progress - if the triangle that goes around travels half of the way, the percentage should be 50, and so, when I'm not hovering the circle anymore it should gradually go back to 0.

like image 405
Itay Gal Avatar asked Feb 15 '23 01:02

Itay Gal


1 Answers

First, remove the surplus transition: all 1s css rule! This is making trouble in all the solutions.

1. Educational - using setTimeout

The for loop will not work as you expect, javascript is not build for active-wait loop like this:

for (var i = -135; i < 225; i++){
    actions(i);
    sleep(some time);      
}

You have to use timeout and callbacks. Disable the .delay function call and rewrite your for loop to iterative setTimeout callback as shown here:

function loopit(dir, i){
    if (typeof i == "undefined") 
        i = -135;
    if (i >= 225)
        return;
    actions(i);
    setTimeout(function () {
        loopit(dir, i + 1);
    }, 1);
}

The back-rotation would be written analogically - you can write it yourself as a homework :-)

http://jsfiddle.net/NNq3z/10/

2. Easy - using jQuery .animate()

The easiest way is to use jQuery .animate() function, that will do the animation "loop" with timing for you. To animate the percent text, use progress callback. Animating rotation is tricky though, you need to use special trick:

$({ deg: deg_from } ).animate({
    deg: deg_to
}, {
    duration: 1000,
    progress: function (animation, progress) {
        $("div.prec").html(Math.round(progress*100)+"%");
    },
    step: function(now) {
        $('#box').css({
            transform: 'rotate(' + now + 'deg)'
        });
    }
});

http://jsfiddle.net/q9VXC/1/

like image 187
Tomas Avatar answered Feb 17 '23 03:02

Tomas