Pause/Resume CSS Animations When Switching Tabs

Pause animation when leaving window or entering a new tab, continue animation upon re-entering?

You need to add event listeners to the window itself for the focus and the blur events.

Check this:

http://fiddle.jshell.net/6gdrQ/15

why does current tab pause every time when I switch tabs in browser?

This is a feature of setAnimationFrame at work. Browsers limit the processing on inactive tabs to save power consumption and CPU cycles. For more information: https://stackoverflow.com/a/5927432/7316502

It doesn't make sense to play an animation that people can't see. However, it might make sense to update the position of the creature in the background and display its current position when the user returns to the tab, given its target point and velocity.

If I understand correctly, the desired outcome is to click a point, have the monster start moving, and then when you tab away and tab back, it's as though the monster has moved the same amount as if you were watching.

You could use the Page Visibility API to help do this: https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API

On a visibilityChange, you can check to see if window.hidden===true. If so, pause the simulation and await another visibilityChange event for which window.hidden===false.

When focus returns to the tab, calculate the time difference between the current time and the time the window became hidden. Fast-forward your rendering to this time point. Then continue displaying animation.

Here is an example of what this might look like.

I placed this in your init() function.

function handleVisibilityChange() {
if (document.hidden) {
windowHidden=true;
hideTime=window.performance.now();
} else {
windowHidden=false;
var timeDiff=(window.performance.now()-hideTime)/1000;
console.log('Page invisible for ',timeDiff,' seconds, jump ahead.');
tick(timeDiff);
render();
}
}
document.addEventListener("visibilitychange", handleVisibilityChange, false);

Then I placed a check in your tick function to check the windowHidden flag:

if (!level||windowHidden) { return; }

(almost-complete) example: https://jsfiddle.net/thmsdnnr/thk80hsh/2/

Note that this does not quite work the way you'd intend: currently the monster just proceeds on the path toward the next node while the window is hidden. This is why when you tab back, the monster is off the path, proceeds back to the last node it was headed toward, and then continues.

Since the monster is following a path with multiple points and different directed segments, you'd need to refactor your tick function, or (better choice, I think) write another one entirely, that takes the time interval the window was hidden for and calculates the number of nodes on the path the monster would have passed given its velocity and time, removes those nodes, and renders the monster in the correct position.

How to restart css animation when user opens a new tab or is inactive in the website

Well after long months of figuring it out I finally fixed it.

The problem was the Query setInterval function.

So I just removed it and made a "animation-delay", and other functions, in my css for all the circles.

And now it works perfectly.

I believe the setInterval was making it restart when you leave the tab so the css fixed it.

I will add the code for others who might come across this problem.

CSS

.bubbles{
position: absolute;
z-index:0;
transform:translateZ(0);
-webkit-transform: translateZ(0);
-ms-transform: translateZ(0);
-moz-transform: translateZ(0);
-o-transform: translateZ(0);
}
.bubbles li{
list-style: none;
border-radius: 50%;
animation: fadeAndScale 26s ease-in infinite;
-ms-animation: fadeAndScale 26s ease-in infinite;
-webkit-animation: fadeAndScale 26s ease-in infinite;
-moz-animation: fadeAndScale 26s ease-in infinite;
-o-animation: fadeAndScale 26s ease-in infinite;
transition-timing-function: linear;
}
/* The first Circle animation------------------------------------------------------------------------------------------------ */
.bubbles li:nth-child(1) {
width: 1100px;
height: 1100px;
position: relative;
bottom:500px;
left: 0%;
background: -webkit-linear-gradient(45deg, #411AFA 4%, #9400FF 74%);
background: -ms-linear-gradient(45deg, #411AFA 4%, #9400FF 74%);
background: -o-linear-gradient(45deg, #411AFA 4%, #9400FF 74%);
background: -moz-linear-gradient(45deg, #411AFA 4%, #9400FF 74%);
background: linear-gradient(45deg, #411AFA 4%, #9400FF 74%);
animation-name: firstCircle;

}
/* Mozilla First Circle Animation */
@keyframes firstCircle {
0% {
z-index: 100;
transform: scale(0);

}

100%{
z-index: 0;
transform: scale(50);

}
}
@-moz-keyframes firstCircle {
0% {
z-index: 100;
-moz-transform: scale(0);

}

100%{
z-index: 0;
-moz-transform: scale(50);

}
}
/* Webkit First Circle Animation */
@-webkit-keyframes firstCircle {
0% {
z-index: 100;
-webkit-transform: scale(0);

}

100%{
z-index: 0;
-webkit-transform: scale(50);

}
}
@-ms-keyframes firstCircle {
0% {
z-index: 100;
-ms-transform: scale(0);

}

100%{
z-index: 0;
-ms-transform: scale(50);

}
}

@-o-keyframes firstCircle {
0% {
z-index: 100;
-o-transform: scale(0);

}

100%{
z-index: 0;
-o-transform: scale(50);

}
}
/* End first circle animation -------------------------------------------------------------------------------------- */

/* Begin Second Circle Animation ------------------------------------------------------------------------------------ */
.bubbles li:nth-child(2) {
width: 1100px;
height: 1100px;
position: absolute;
left: 20%;
bottom:50%;
animation-name: secondAnimation;
visibility: hidden;
animation-delay: 3.4s;

}
/* Webkit Second Animation */
@-webkit-keyframes secondAnimation {
0% {
visibility: visible;
background: linear-gradient(45deg, #F14545 0%, #E7219B 100%);
z-index: 100;
-webkit-transform: scale(0);

}

100%{
z-index: 0;
-webkit-transform: scale(50);

}
}

/* Mozilla Second Animation */
@-moz-keyframes secondAnimation {
0% {
z-index: 100;
-moz-transform: scale(0);

}

100%{
z-index: 0;
-moz-transform: scale(50);

}
}
/* Ms Second Animation */
@-ms-keyframes secondAnimation {
0% {
z-index: 100;
-ms-transform: scale(0);

}

100%{
z-index: 0;
-ms-transform: scale(50);

}
}

@-o-keyframes secondAnimation {
0% {
z-index: 100;
-o-transform: scale(0);

}

100%{
z-index: 0;
-o-transform: scale(50);

}
}
/* End of Second Circle ------------------------------------------------------------------------------------- */

/*Begin of Third Circle ----------------------------------------------------------------------------------- */

.bubbles li:nth-child(3) {
width: 1100px;
height: 1100px;
position: absolute;
left:70%;
bottom:35%;
visibility: hidden;
animation-delay: 7.4s;
animation-name: thirdAnimation;

}
/* Webkit Third Animation */
@-webkit-keyframes thirdAnimation {
0% {
visibility: visible;
background: linear-gradient(45deg, #01C961 0%, #00FFA2 100%);
z-index: 100;
-webkit-transform: scale(0);

}

100%{
z-index: 0;
-webkit-transform: scale(50);

}
}
/* Mozilla Third Animation */
@-moz-keyframes thirdAnimation {
0% {
z-index: 100;
-moz-transform: scale(0);

}

100%{
z-index: 0;
-moz-transform: scale(50);

}
}
/* MS Third Animation */
@-ms-keyframes thirdAnimation {
0% {
z-index: 100;
-ms-transform: scale(0);

}

100%{
z-index: 0;
-ms-transform: scale(50);

}
}

@-o-keyframes thirdAnimation {
0% {
z-index: 100;
-o-transform: scale(0);

}

100%{
z-index: 0;
-o-transform: scale(50);

}
}
/* End of the Third Circle --------------------------------------------------------------------------------------------------------- */

/* Begin of Fourth Circle Animation ----------------------------------------------------------------------------------------------- */

.bubbles li:nth-child(4) {
width: 1100px;
height: 1100px;
position: absolute;
left: 20%;
bottom:60%;
visibility: hidden;
animation-delay: 11.6s;
animation-name: fourthAnimation;
}
/* Webkit Fourth Animation */
@-webkit-keyframes fourthAnimation {
0% {
visibility: visible;
background: linear-gradient(45deg, #FFB100 0%, #FFE938 100%);
z-index: 100;
-webkit-transform: scale(0);

}

100%{
z-index: 0;
-webkit-transform: scale(50);

}
}
/* Mozilla Fourth Animation */
@-moz-keyframes fourthAnimation {
0% {
z-index: 100;
-moz-transform: scale(0);

}

100%{
z-index: 0;
-moz-transform: scale(50);

}
}
/* MS Fourth Animation */
@-ms-keyframes fourthAnimation {
0% {
z-index: 100;
-ms-transform: scale(0);

}

100%{
z-index: 0;
-ms-transform: scale(50);

}
}

@-o-keyframes fourthAnimation {
0% {
z-index: 100;
-o-transform: scale(0);

}

100%{
z-index: 0;
-o-transform: scale(50);

}
}
/* END of Fourth Animation ------------------------------------------------------------------------------------------------ */

/* Start of Fifth Animation -------------------------------------------------------------------------------------------------- */
.bubbles li:nth-child(5) {
width: 1100px;
height: 1100px;
position: absolute;
left: 60%;
bottom:70%;
visibility: hidden;
animation-delay: 14s;
animation-name: fifthAnimation;
}
/* Webki Fifth Animation */
@-webkit-keyframes fifthAnimation {
0% {
visibility: visible;
background: linear-gradient(-60deg, #ff5858 0%, #f09819 100%);
z-index: 100;
-webkit-transform: scale(0);

}

100%{
z-index: 0;
-webkit-transform: scale(50);

}
}
@-moz-keyframes fifthAnimation {
0% {
z-index: 100;
-moz-transform: scale(0);

}

100%{
z-index: 0;
-moz-transform: scale(50);

}
}
@-ms-keyframes fifthAnimation {
0% {
z-index: 100;
-ms-transform: scale(0);

}

100%{
z-index: 0;
-ms-transform: scale(50);

}
}

@-o-keyframes fifthAnimation {
0% {
z-index: 100;
-o-transform: scale(0);

}

100%{
z-index: 0;
-o-transform: scale(50);

}
}
/* End of the Fith Circle ----------------------------------------------------------------------------------------------------- */

/* Start of the Sixth Circle ------------------------------------------------------------------------------------------------- */

.bubbles li:nth-child(6) {
width: 1100px;
height: 1100px;
position: absolute;
left: 70%;
bottom:25%;
visibility: hidden;
animation-delay: 15s;
animation-name: sixthAnimation;
}
/* Webkit sixth animation */

@-webkit-keyframes sixthAnimation {
0% {
visibility: visible;
background-color: linear-gradient(45deg, #2500DA 0%, #009BFF 100%);
z-index: 100;
-webkit-transform: scale(0);
}
100%{
z-index: 0;
-webkit-transform: scale(50);
}
}
/* Mozilla Sixth Animation */
@-moz-keyframes sixthAnimation {
0% {
z-index: 100;
-moz-transform: scale(0);
}
100%{
z-index: 0;
-moz-transform: scale(50);
}
}
/* MS Sixth Animation */
@-ms-keyframes sixthAnimation {
0% {
z-index: 100;
-ms-transform: scale(0);
}
100%{
z-index: 0;
-ms-transform: scale(50);
}
}

@-o-keyframes sixthAnimation {
0% {
z-index: 100;
-o-transform: scale(0);
}
100%{
z-index: 0;
-o-transform: scale(50);
}
}
/* End of Sixth Animation ---------------------------------------------------------------------------------------------- */

jQuery animation function breaks when switching tabs

This is being caused by the jQuery animate function, which passes the animate options object to a function called speed. This function checks to see if the document is hidden - which it will be if the tab is inactive. If it is hidden, (or fx.off is set to true), all animation durations are set to 0.

You can see this on line 7137 in your plunkr's jQuery file.

    if ( jQuery.fx.off || document.hidden ) {
opt.duration = 0;

As the animation now has no duration, it becomes synchronous, and so the fact that your complete function comes after the call to animate, is an issue.

To fix this, you would need to move the complete function declaration above your call to animate.



Related Topics



Leave a reply



Submit