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.
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.
Share Improve this question edited Jan 18, 2014 at 10:34 Tomas 59.7k54 gold badges250 silver badges382 bronze badges asked Jan 18, 2014 at 9:38 Itay GalItay Gal 10.8k6 gold badges42 silver badges77 bronze badges 03 Answers
Reset to default 6First, 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/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/q9VXC/1/
http://jsfiddle/NNq3z/13/
var i = -135,box = $("#box"),prec;
setTimeout(function(){
if($("#circle").is(":hover"))
loopit("c");
else
loopit("nc");
},1);
function loopit(dir){
if (dir=="c")
i++;
else
i--;
if(i<-135)
i=-135;
if(i>225)
i=225;
prec = (100*(i + 135))/360;
$(".prec").html(Math.round(prec)+"%");
box.css("transform","rotate("+i+"deg)")
.css("-ms-transform","rotate("+i+"deg)")
.css("-moz-transform","rotate("+i+"deg)")
.css("-webkit-transform","rotate("+i+"deg)");
setTimeout(function(){
if($("#circle").is(":hover"))
loopit("c");
else
loopit("nc");
},1);
}
Removed transition:all 1s
.
In your code, the percentage of the box immediately change to 100% because you use for loop. For loop will be executed very fast as if it immediately change to 100% so it is not remended.
You should use setInterval
, and you have to increment percentage
each time:
var percentage = 0;
var timer = setInterval(function() {
percentage++;
if (percentage > 100) {
clearInterval(timer);
} else {
$("div.prec").html(percentage + "%");
}
}
You could also call actions()
inside there.