I have a countdown timer, in the style of a bar, that slowly decreases in width.
Check the following code:
HTML
<div id="timer"><span></span></div>
CSS
#timer {
height: 30px;
display: block;
overflow: hidden;
background: grey;
}
#timer span {
width: 100%;
height: 100%;
display: block;
background: green;
-webkit-animation-name: decreasewidth;
animation-name: decreasewidth;
-webkit-animation-iteration-count: 1;
animation-iteration-count: 1;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
-webkit-animation-duration: 20000ms;
animation-duration: 20000ms;
}
@keyframes decreasewidth {
to { width: 0% }
}
@-webkit-keyframes decreasewidth {
to { width: 0% }
}
Sadly, the animation will halt when the page isn't in use, eg. browsing another tab or window. I understand this is ordinary among browsers and helps save processing power.
Problem is, I want my timer to be accurate. That means holding true to its position even when the user flicks to other tabs during. How would I go about achieving this?
At first, my thoughts were along the lines of calculating the amount of ms the user was absent from the page and then updating the timer's span accordingly on return. But this would only happen on the focus event, which relies on user activity.
I also tried a good ol' javascript setInterval technique which simply updated the width of the span every second. Not only did this look terrible - the same problem occurred. Most browsers increase the interval time when inactive.
Interested to hear some ideas on how to handle this.
TL;DR
I need an animated countdown timer bar, that keeps true to its position even when the page is inactive.
EDIT
I know this is noticeable in Safari.
How about using standard CSS transitions and one line of jQuery?
You can start the loading bar at 100%, with a width transition of 20 seconds. Then, when the page is loaded, add a class that overrides the width and sets it to 0. Because of our transition, it will decrease from 100% to 0% over the course of 20 seconds.
Here's a JSFiddle.
$(document).ready(function() {
setTimeout(function() {$("#timer span").addClass("load");}, 1);
});
#timer {
height: 30px;
display: block;
overflow: hidden;
background: grey;
}
#timer span {
height: 100%;
display: block;
background: green;
transition: 20s width linear;
width: 100%;
}
#timer span.load{
width: 0%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="timer"><span class="init"></span></div>
Looks like the Page Visibility API paired with time absent calculations will do it. Documentation can be found here: https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
The events get trigged when the window is visible / invisible, you don't have to click the page in order for it to detect. Exactly what I need.
IE 10+ mind. Although, not a problem for my app :p