Repeating the same animation 6s after first one using animate.css [Edited] - javascript

I want to repeat shake animation using animate.css after 6 seconds once.
Here is the code I've tried so far.
the first part of animating works great but the second one. it just doesn't.
With JavaScript, I can setTimeout to fire after 6 seconds, remove the shake animation, then add shake class back to the element, and the problem is exactly here, although setTimeout fires, second shake animation doesn't appear (The animation which is expected to appear after 6 seconds)
// First Part: Adding animation to the object
document.querySelectorAll(".profile")[userA_Index].classList.add('animated', 'shake', 'slow', 'delay-1s')
//Second Part: Now I remove the first shake animation and add the second one after 6 seconds, But unexpectedly the animation here doesn't work...
setTimeout(function(){
document.querySelectorAll(".profile")[userA_Index].classList.remove('animated', 'shake')
document.querySelectorAll(".profile")[userA_Index].classList.add('animated', 'shake', 'slow', 'delay-1s')
}, 6000);

In lack of proper vocabulary, i'll explain it like this:
This is treated as a single DOM modification, as you add and remove the same class in the same DOM update, and looks as as if nothing changes.
Add a second setTimeout, to push a separate DOm update, after the first has taken place :
setTimeout(function(){
document.querySelectorAll(".profile")[userA_Index].classList.remove('animated', 'shake');
setTimeout(function(){
document.querySelectorAll(".profile")[userA_Index].classList.add('animated', 'shake', 'slow', 'delay-1s')
}, 16); // can work for 0 also, but i usually like to leave a frame in between
}, 6000);

Related

Is there any way to await animation completion in Javascript

This is probably a long shot, however I need to fix this somehow, if you have any other tips that could help me achieve the same end result please let me know!
I have a with a bunch of items with unique IDs. These items are continously updated through a Cefsharp application (every 1000ms). I currently have a class named "show" that transitions the list item from 0 height to a specified height in 1 second. The same goes for when the item is removed (show is removed from classes). So everything here works as intended.
For some reason however, every now and then, my list animation seemed to cancel abruptly. I couldn't figure out why. Just a few minutes ago I realized it was my sortList function:
function sortList() {
$("#orderQueueList li").sort(function (a, b) {
return parseInt($(a).data('indexn')) - parseInt($(b).data('indexn'));
}).appendTo('#orderQueueList');
}
This function is executed everytime a new item is added to the list or a current item has it's "indexn" value updated. So if the animation is queued (the animation has a 5 second setTimeout) and the list is sorted during this time, or during the actual animation, it is cancelled.
I haven't really been able to figure out how to solve this. My initial thought was that the sortList would wait until all animations are completed. However the animations are .CSS sided so I'm not sure if this is possible. I've been Googling around a bit and can't really find an answer.
I either want the 5 second delay to execute immediately (so the animation is completed) or the sortList function to wait until the animation is complete. Is this possible somehow through JavaScript/jQuery?
Thank you!
You can add another parameter to the animate function that triggers a function once it has finished jquery doc explaining that here (5000) is the duration)
Note that the function is called once per matched elements
$( "#clickme" ).click(() => {
$( "#whatever" ).animate({
left: "+=50",
}, 5000, () => { // <--- other parameter is here
// Animation complete.
});
});

Wow.js not taking two classes for an element at different time intervals

I have an image element, on which I want to apply two animation classes, one on the arrival and one on some fixed time.
For Example, on arrival i want a fadeIn effect. So i do this:
img.classList.add("wow");
img.classList.add("fadeIn");
I again want to add a heartbeat effect on the same image after some time. So i tried something like this:
setTimeout(function () {
img.classList.remove("fadeIn");
img.classList.add("heartBeat");
},3000);
This is not working, and the hearbeat effect is not seen.
Note:
On the other hand, if I don't initially set up the fadeIn effect to the image, then the image does take the heartbeat effect after 3000ms.
So a standalone code like this one, is working perfectly fine.
setTimeout(function () {
img.classList.add("heartBeat");
},3000);
I am not being able to figure out the cause of this problem.
You can cuse the function inside the callback of the WOW instance.
According to the wow.js docs, it is fired every time an animation is started and the "the argument that is passed in is the DOM node being animated" (box, but in this case I'm directly using the img variable).
So, when it is triggered, we can immediately remove the .fadeIn class, which will not affect the animation because it was added inline with JavaScript. In addition, after 3 seconds, we remove the style attribute (that caused the "fade in" animation) and add the .heartBeat class that will trigger the next heartbeat animation.
img.classList.add("wow");
img.classList.add("fadeIn");
new WOW({
callback: function(box) {
img.classList.remove("fadeIn");
setTimeout(function () {
img.removeAttribute("style");
img.classList.add("heartBeat");
},3000);
}
}).init();

Adding a SetTimeout and transition to jQuery Show / Hide

I am trying to add a SetTimeout and animation type transition to jQuery Show / Hide call. Below is how I currently have it but am wanting to add the a specific amount of time the 'show' div remains displayed before it reverts back to the orginal #bg_dv. I also want to add animated transitions between the effects if possible.
function tilt(){
$("#area1").click(function(){
$("#bg_div").hide();
$("#bg_skew").show(); // I would like to show this Div for about 5 seconds
// and then have original back.
});
}
$("#bg_div").hide(0).delay(5000).show(0);
$("#bg_skew").show(0).delay(5000).hide(0);
If you want animations, you can replace the calls to hide() and show() with something appropriate. For example fadeIn() and fadeOut().
$("#area1").click(function(){
$("#bg_div").fadeOut('fast',function(){
$("#bg_skew").delay(5000).fadeIn('fast');
});
});
In order to prevent caching of multiple clicks and have the animation play many times
you should also take a look at
.stop(true,true)
before any animation.Also take a look at this animation option - property.
{cache:false}
it's so simple. just put milliseconds in show.delay(5000) it will delay it for 5 seconds.
syntax:
$(selector).delay(speed)
speed: time in millsecnds e.g. 5000 for 5 seconds.
$(selector).show(speed,easing,callback)
speed: here put time in milliseconds like 1000 for 1 second.
easing: it defins speed of elements at different points i.e. "linear" "swing".
callback: here you can put your function it will execute after completing show method. For example when you will click button to show image after showing image it will exexcute funxtion e.g. .show(1000,function(){alert("hello")};);
Hope i helped you.

interval between images in jquery

i'm starting to learn jquery and i am now working on an header image crossover with jquery. ive got the code working but what i now need is an interval between images, after the crossover i want the script to pause for a specific time and then continue with the next image.
ive got this code.
$(document).ready(function(e) {
$('.img:gt(0)').hide();
setInterval(function(){
$(".img:first-child").fadeOut(3000).next(".img").fadeIn(3000).end().appendTo("#kop")
}, 4000);
});
is it possible in this form or do i have to change the code completly.
i now got it running on a test server of mine. swinging.icwebdesign.nl
Currently what is happening is you're taking 3000ms to do your transition, and inbetween the transition function call is 4000ms - therefore, you'll only get a 1000ms "delay".
The second parameter in setInterval() is the delay time, which in the code below is equal to the fadeTime + delay time.
$(document).ready(function(e) {
var delay = 3000,
fadeTime = 3000;
$('.img:gt(0)').hide();
setInterval(function(){
$(".img:first-child").fadeOut(fadeTime).next(".img").fadeIn(fadeTime).end().appendTo("#kop")
}, delay+fadeTime);
});

setTimeout speeds up with multiple tabs

I’m having a setTimeout problem similar to this one. But that solution doesn't help me since I can’t use php in my file.
My site has a slider with a list of images that move every 8 seconds.However, when I have opened a few tabs in the browser and then switch back again, it goes nuts.
The slider proceeds to move the images one after the other immediately without the 8 second timedelay.
I'm only seeing it in Chrome and the latest Firefox.
**EDIT: I checked with console.log() and the setTimeout returns the same number before and after the clearTimeout. Not sure why. Maybe that also has something to do with it? **
EDIT 2: I added a fiddle: http://jsfiddle.net/Rembrand/qHGAq/8/
The code looks something like:
spotlight: {
i: 0,
timeOutSpotlight: null,
init: function()
{
$('#spotlight .controls a').click(function(e) {
// do stuff here to count and move images
// Don't follow the link
e.preventDefault();
// Clear timeout
clearTimeout(spotlight.timeOutSpotlight);
// Some stuff here to calculate next item
// Call next spotlight in 8 seconds
spotlight.timeOutSpotlight = setTimeout(function () {
spotlight.animate(spotlight.i);
}, 8000);
});
// Select first item
$('#spotlight .controls a.next:first').trigger('click');
},
animate: function(i)
{
$('#spotlight .controls li:eq(' + (spotlight.i) + ') a.next').trigger('click');
}
}
From the jQuery documentation:
Because of the nature of requestAnimationFrame(), you should never
queue animations using a setInterval or setTimeout loop. In order to
preserve CPU resources, browsers that support requestAnimationFrame
will not update animations when the window/tab is not displayed. If
you continue to queue animations via setInterval or setTimeout while
animation is paused, all of the queued animations will begin playing
when the window/tab regains focus. To avoid this potential problem,
use the callback of your last animation in the loop, or append a
function to the elements .queue() to set the timeout to start the next
animation.
I finally found my answer and it’s not at all what I was expecting.
It seems the culprit is jQuery’s .animate(), which I use to move the images in the slider.
I calculate and move my images positions with this:
$('.spotlight-inner')
.animate(
{ left: scrollToVal },
{duration: 'slow'}
)
;
Now the problem seems to be that in some browsers, after you switch to a new tab and back, jQuery’s .animate() saves up the animations and fires them all at once. So I added a filter to prevent queueing. That solutions comes from CSS-Tricks.com :
$('.spotlight-inner')
.filter(':not(:animated)')
.animate(
{ left: scrollToVal },
{duration: 'slow'}
)
;
The first slide you see when you go back can act a little jumpy but it’s better than the superspeed carousel from before.
Fiddle with the full code here
There is an easier way using the jquery animate queue property:
$(this).animate({
left: '+=100'
}, {duration:500, queue:false});
I don't know if this will help you, but it helped me with my slideshow. What I did was everytime I called an animation that was supposed to happen at a set interval because of the setTimeout, I called clearQueue() which would get rid of any other animations that had been set to happen. then i'd call the animation. That way when you come back to that tab, you don't have all these animations queued up and it goes crazy. at max you'll only have one set up.
So something like this:
spotlight.timeOutSpotlight = setTimeout(function () {
spotlight.clearQueue(); // get rid of other instances of the animation
spotlight.animate(spotlight.i);
}, 8000);
It may not work in all cases (depending on timing), but I hope that helps somebody!
You must also think you use clearTimeout.
As you call setTimeout function it returns an ID you can save this ID in a variable like
timeoutID = setTimeout(function () {
spotlight.animate(spotlight.i);
}, 8000);
and before setting a new timeout you can call the function like
clearTimeout(timeoutID)
My suspicion is that the browser queues input events like 'click' but only fires them when the tab where the event occurs actually has focus.
Perhaps you should try calling your click callbacks directly instead of using trigger('click').
Something like this:
spotlight: {
i: 0,
timeOutSpotlight: null,
clickFunc: function(element) {
// do stuff here to count and move images
// Clear timeout
clearTimeout(spotlight.timeOutSpotlight);
// Some stuff here to calculate next item
// Call next spotlight in 8 seconds
spotlight.timeOutSpotlight = setTimeout(function () {
spotlight.animate(spotlight.i);
}, 8000);
},
init: function()
{
$('#spotlight .controls a').click(function (e) {
// Don't follow the link
e.preventDefault();
spotlight.clickFunc(this);
});
// Select first item
spotlight.clickFunc($('#spotlight .controls a.next:first'));
},
animate: function(i)
{
var element = $('#spotlight .controls li:eq('+spotlight.i+') a.next');
spotlight.clickFunc(element);
}
}
What version of jQuery are you running? Apparently this problem was 'fixed' for version 1.6.3 - they reverted the change that caused this to happen. Discussions here and here.
Though this issue will likely have to be addressed in the future, it seems as though we're off the hook for now.

Categories