I'm doing some interactive animation using HTML, CSS, and Javascript+Jquery.
I have several animations that I want to chain. So when first animation is done, the next starts, and so on.
The first function is triggered by a click:
function stepOne() {
console.log(" stepOne ran");
$('#myObject').attr('class', 'animation1');
$(".animation1").on("animationend", stepTwo);
}
function stepTwo() {
console.log("stepTwo ran");
$("#myObject").removeClass("animation1");
$("#myObject").addClass("animation2");
$("#scene").addClass("zoomAnimation");
$("#scene").on("animationend", stepThree);
function stepThree() {
// insert some exciting code here
console.log("crashes");
}
I can see in the console log, that it runs stepTwo and stepThree at the same time, and then Stepthree again when the animation actually ends. How do I prevent it from running stepThree together with stepTwo? This is only an issue if I run it in sequence. If i jump directly to stepTwo there's not issue.
After many hours, I found a work around.
Adding a tiny delay on the animationend listener at the end of the function seems to be the solution.
So it becomes
function stepTwo() {
console.log("stepTwo ran");
$("#myObject").removeClass("animation1");
$("#myObject").addClass("animation2");
$("#scene").addClass("zoomAnimation");
setTimeout(function () {
$(".zoomAnimation").on("animationend", stepThree);
}, 20);
}
function stepThree() {
$(".zoomAnimation").off("animationend", stepThree);
}
and so on. Might not be the best solution, and may cost me problems down the road, but it seems to be correct.
Related
I've been staring at my code for so long but i don't seem to understand what is happening.
Whenever the game ends, I do a cancelAnimationFrame to stop the game. Then I boot up the menu again.
Now the problem is that when I call requestAnimationFrame again, it seems like the code is calling it two times (the game runs doubly fast).
The following is my code:
This is the startup:
var areaJogo = {
beginGame: function(type) {
//...
this.myReq = requestAnimationFrame(updateArea);
//...
}
}
And this is the main function(for animation):
function updateArea(){
areaJogo.myReq=requestAnimationFrame(updateArea);
//....
if(/*conditionLoseGame*/) {
stop();
}
}
function stop() {
cancelAnimationFrame(areaJogo.myReq);
areaJogo.myReq=undefined;
}
Mind you these are the only times requestAnimationFrame and cancelAnimationFrame are used in the code. Thanks!
I have found the problem.
The reason why it was being called is because I had done a button in JavaScript to start the game.
To do this, I had to do a addeventlistener whenever I booted the menu. What I did wrong was forgetting to do cleareventlistener upon clicking the button.
setInterval(function () {
$("#bound").click(function () {
$(".top").toggleClass("one");
$(".middle").toggleClass("two");
$(".bottom").toggleClass("three");
$(".nav-menu").toggleClass("menu-show");
});}, 450);
What is wrong with it?
Transition lags too much and sometimes stops workin.
Incase you want the latency after click event, you should put setInterval function inside click function:
$("#bound").click(function () {
setInterval(function () {
$(".top").toggleClass("one");
$(".middle").toggleClass("two");
$(".bottom").toggleClass("three");
$(".nav-menu").toggleClass("menu-show");
}, 450);
});
What is wrong with it?
The thing is you are binding so many click events at the interval of 450ms which will lead the browser to consume so much memory and browser will be unresponsive eventually.
Other noticeable thing is that you will get the "n" the number of bound events. So, as it is a continued process so at each iteration it will bind an event means if two iterations then two callbacks execution.
I guess you might instead do this:
$("#bound").click(function () {
setTimeout(function () { // <------change it to setTimeout if u don't make it infinite
$(".top").toggleClass("one");
$(".middle").toggleClass("two");
$(".bottom").toggleClass("three");
$(".nav-menu").toggleClass("menu-show");
}, 450);
});
I have tried this code:
while (true) {
$(document).ready(function() {
setInterval(function () {
if ($("h2").text() == "Qu’est-ce qu’une année-lumière ?") {
$("#choice2").delay(200).queue(function () {
$(this).click().dequeue()
})
}
}, 10000)
}
. My aim is actually to send an answer as the page DOM is already ready if the element in the tag is verified, then i want to repeat this for as i am on that page. I tried many codes but my browser doesn't like them: it freezes... that is why i try to use an interval, but i am unable to control it yet. please i need your help...
The browser freezes because you have an infinite loop. It will just keep binding more and more ready events until the code is stopped for taking too long to run, or when the browser crashes because you have bound a zillion event handlers.
Adding the interval was the right move to make the code run more than once, but the while loop still kept it from working.
Remove the while loop, and your code will run. You don't need to dequeue a function that you queued, it will be dequeued when it runs.
$(document).ready(function() {
setInterval(function () {
if ($("h2").text() == "Qu’est-ce qu’une année-lumière ?") {
$("#choice2").delay(200).queue(function () {
$(this).click();
});
}
}, 10000);
}
The interval runs the code every 10 seconds, so there doesn't seem to be any reason to wait for 200 ms before invoking the click, though.
Actually in my project I have to reapeat few functions continiously,for that i have to use setinterval or call back.which one is the best way to repeat function either call back or setInterval.lightAnim() same kind of functions i have more than 8.If i use setInterval what will be happened and if use callback what will be happened with respect to browser.which way one is best.
1st way:Using setInterval
<script>
lightAnim();
setInterval(lightAnim,5000);
function lightAnim() {
$(".bulb1").fadeIn(1000, function() {
$(".bulb2").fadeIn(1000, function() {
$(".bulb3").fadeIn(1000, function() {
$(".bulb4").fadeIn(1000, function() {
$(".bulb5").fadeIn(1000, function() {
$(".bulb6").fadeIn(1000);
})
});
});
});
})
}
</script>
2nd way:On complete i am calling again
<script>
lightAnim();
function lightAnim() {
$(".bulb1").fadeIn(1000, function() {
$(".bulb2").fadeIn(1000, function() {
$(".bulb3").fadeIn(1000, function() {
$(".bulb4").fadeIn(1000, function() {
$(".bulb5").fadeIn(1000, function() {
$(".bulb6").fadeIn(1000);
lightAnim();
})
});
});
});
})
}
</script>
The callback is definitely the better choice.
You don't need to sum the delays manually, and don't need to maintain it when updating the code. It's much more error-prone, as your code demonstrates: six one-second delays are not 5000 milliseconds. Your first snippet would animate the first and sixth bulb simultaneously.
Also, when you are animating a single element the animations would get chained onto jQuery's animation queue. If the timers deviate (and setInterval is known to drift over longer periods), then you could easily build up a very long queue (animations are scheduled faster than they are executed) which is not good for performance.
so I'm trying to create a really simple animation using jQuery but the callback for fadeOut doesn't ever happen.
Here is the code below:
var move = function(target, speed) {
$(target).delay(200).animate({bottom: "-=20"},
speed,
function() {
$(this).fadeOut(200, function() {
$(this).css("bottom", "+=20");
});
$(this).fadeIn(200);
}
);
move(target, speed);
};
move(".fa-arrow-down", 500);
I've tried several different things like checking it out in the console, setting various breakpoints (mainly right at $(this).css("bottom", "+=20");, right above this line, and right below this line).
I'm not really sure why it's not happening. Any help is appreciated and if you could please also explain what the issue actually is so I can learn too. Here's a fiddle.
You need to move the call to move(target, speed) to inside the complete function of the fadeIn.
DEMO
var move = function (target, speed) {
$(target).delay(200).animate({
bottom: "-=20"
},
speed,
function () {
$(this).fadeOut(200, function () {
$(this).css("bottom", "+=20");
});
$(this).fadeIn(200, function () {
move(target, speed);
});
});
};
move(".fa-arrow-down", 500);
But I can't take all the credit... cookie monster was first to see the recursion error. Just like he said, this works because it adds a delay to each time you call move()
As I just said, you're invoking move() immediately instead of waiting
for the callback. This means it invokes move() at a rate of frequency
equal to the time it takes to invoke .delay().animate(), but without
waiting for them to finish. In other words, move() will be invoked
tens of thousands of times even before the first .delay() is finished -- cookie monster