Javascript: Countdown by animation.width() - javascript

I am currently trying to make a visual countdown for my user for when the animation is finished. My current attempt looks somewhat like this:
function setClassAndFire(){
timer = setInterval(function () {
t--;
$(this).attr('class', 'timerAnimation');
countdownTimer();
if (t === 0) {
clearInterval(timer);
timer = undefined;
funcForCall();
}
}, 1000);
}
function countdownTimer(){
var timerCurrentWidth = $('.timerAnimation').width(),
timerMaxWidth = $("#awardQueueText").width(),
pxPerSecond = timerMaxWidth / 60,
currentCountdown = timerCurrentWidth / pxPerSecond;
currentCountdown = Math.round(currentCountdown);
document.getElementById("timer").innerHTML = "<span style='white-space : nowrap;'>Animation ends in:</br></span>"+
"<span style='white-space : nowrap;'>" + currentCountdown + " sec.</span>";
}
Important to know is that the animation only displays the time until we may be able to send an API call. So the animation will be re-engaged if we have something in queue.
So as you can see my current attempt works, but is some-what cluncky:
The countdown sometimes fails to subtract a second and "fixes"
that with a 2 seconds subtract in the next attempt.
This is probably caused by the Math.round() for currentCountdown, but is there a work around for that? I mean I have the max possible width of the animation object and can seperate it from the current width.
Is there a way to bring it to work? We need to relate the timer to the animation to achive desired behavior. So when the animation count hits 25, I want that the displayed number is 25 as well!

You got this problem because you got the number from the width andh the width can't have decimals (or better, they can be but they are gonna be truncated sometimes).
So my suggestion is to use a differente variable for the number you will show and the width of the DOM element.
It seems to me that the variable t is what I am talking about, so just try to use it.
function setClassAndFire(){
timer = setInterval(function () {
t--; //What is t?
$(this).attr('class', 'timerAnimation');
countdownTimer(t);
if (t === 0) {
clearInterval(timer);
timer = undefined;
funcForCall();
}
}, 1000);
}
function countdownTimer(t){
document.getElementById("timer").innerHTML = "<span style='white-space : nowrap;'>Animation ends in:</br></span>"+
"<span style='white-space : nowrap;'>" + t+ " sec.</span>";
}

Related

setTimeout executes itself right away/on clear

I'm making a webpage where user events are logged in.
To test the feature I made a small, independant webpage with a teaxtarea and a text input. The events logged are those performed on the input element.
I want to prevent the same event text to be shown multiple times in a row, but I can't seem to prevent them from showing up!
I also want to add a line to separate event groups 0.5 seconds after no other event happened, but the line seems to appear on every event trigger, evenif I use clearTimeout with the timeout ID.
Basically: I don't want any line to be repeated. If the last line is a separator line, then it must not add another one. Yet it doesn't see to work.
JSFiddle Demo
Here is my code:
JavaScript
var timerID = 0;
function addSeparateLine()
{
document.getElementById('listeEvenements').value += "--------------------\n";
}
function show(newEventText)
{
var eventListField = document.getElementById('listeEvenements');
var eventList = [];
if (eventListField.value.length > 0)
{
eventList = eventListField.value.split("\n");
}
var eventCounter = eventList.length;
if (eventList[eventCounter - 2] == newEventText)
{
clearTimeout(timerID);
newEventText = "";
}
timerID = setTimeout(addSeparateLine, 500);
if (newEventText !== "")
{
eventListField.value += newEventText + "\n";
}
return true;
}
HTML
<fieldset id="conteneurLogEvenements">
<legend>Events called from HTML attribute</legend>
<textarea id="listeEvenements" rows="25"></textarea>
<input id="controleEcoute" type="text" onBlur="show('Blur');" onchange="show('Change');" onclick="show('Click');" onfocus="show('Focus');" onMousedown="show('MouseDown');" onMousemove="show('MouseMove');" onMouseover="show('MouseOver');" onkeydown="show('KeyDown');"
onkeypress="show('KeyPress');" onkeyup="show('KeyUp');" />
</fieldset>
http://jsfiddle.net/z6kb4/2/
It sounds like what you want is a line that prints after 500 milliseconds of inactivity, but what your code currently says to do is "print a line 500 milliseconds after any action, unless it gets canceled". You can get better results by structuring the code more closely to your intended goal.
Specifically, instead of scheduling a new timeout every time an event occurs, simply start a loop when the first event occurs that checks the time that has elapsed since the most recent event received and then prints a line when the elapsed time exceeds the desired threshold (500 milliseconds). Something like:
function addSeparateLine() {
var elapsed = new Date().getTime() - lastEventTime;
if (elapsed >= 500) {
document.getElementById('listeEvenements').value += "--------------------\n";
clearInterval(timerID);
timerID = -1;
}
}
...and then you schedule it like:
if(newEventText !== "") {
lastEventTime = new Date().getTime();
eventListField.value += newEventText+"\n";
if (timerID == -1) {
timerID = setInterval(addSeparateLine,100);
}
}
Working example here: http://jsfiddle.net/z6kb4/4/
Because you are not actually stopping the show function in any way. The clearTimeout only applies to the separator add. I have updated your fiddle. You need to wrap your function with
if (+new Date() - lastfire < 500) return;
and
lastfire = +new Date();
(before the last return--see the updated fiddle). Also, make sure to stick the global definition var lastfire = -1; somewhere up top.

Difficulty with setInterval loop using class of Divs

$(document).ready(function fadeIt() {
$("#cool_content > div").hide();
var sizeLoop = $("#cool_content > div").length;
var startLoop = 0;
$("#cool_content > div").first().eq(startLoop).fadeIn(500);
setInterval(function () {
$("#cool_content > div").eq(startLoop).fadeOut(1000);
if (startLoop == sizeLoop) {
startLoop = 0
} else {
startLoop++;
}
$("#cool_content > div").eq(startLoop).fadeIn(1500);
}, 2000);
});
Here I want a class of divs to animate, infinitely!
However, because the interval is set to two seconds there is period where no div is showing!
What would be an appropriate way to loop the animation of these divs?
I thought about using a for loop but couldn't figure out how to pass a class of divs as arguments. All your help is appreciated.
Thanks!
Ok, generally, you should know that Javascript is a single threaded environment. Along with this, the timer events are generally not on time accurately. I'm not sure how jQuery is doing fadeIn and fadeOut, but if it's not using CSS3 transitions, it's going to be using timeOut and Intervals. So basically, there's a lot of timer's going on.
If you go with the for loop on this one, you'd be blocking the single thread, so that's not the way to go forward. You'd have to do the fade in/out by yourself in the setInterval.
Setting the opacity on each interval call. Like div.css('opacity', (opacity -= 10) + '%')
If you're trying to fade in and out sequentially, I think maybe this code would help
var opacity = 100,
isFadingIn = false;
window.setInterval(function() {
if (isFadingIn) {
opacity += 10;
if (opacity === 100) isFadingIn = false;
} else {
opacity -= 10;
if (opacity === 0) isFadingIn = true;
}
$('#coolContent > div').css('opacity', opacity + '%');
}, 2000);
Consider the following JavaScript / jQuery:
$(function(){
var divs = $('#cool_content > div').hide();
var curDiv;
var counter = 0;
var doUpdate = function(){
// Hide any old div
if (curDiv)
curDiv.fadeOut(1000);
// Show the new div
curDiv = divs.eq(counter);
curDiv.fadeIn(1000);
// Increment the counter
counter = ++counter % divs.length;
};
doUpdate();
setInterval(doUpdate, 2000);
});
This loops infinitely through the divs. It's also more efficient than your code because it only queries the DOM for the list of divs once.
Update: Forked fiddle
instead of
if (startLoop == sizeLoop)
{
startLoop = 0
}
else
{
startLoop++;
}
use
startLoop =(startLoop+1)%sizeLoop;
Check the demo http://jsfiddle.net/JvdU9/ - 1st div is being animated just immediately after 4th disappears.
UPD:
Not sure I've undestood your question, but I'll try to answer :)
It doesn't matter how many divs you are being looped - 4, 5 or 10, since number of frames are being calculated automatically
x=(x+1)%n means that x will never be greater than n-1: x>=0 and x<n.
x=(x+1)%n is just shorten equivalent for
if(x<n-1)
x++;
else
x=0;
as for me first variant is much readable:)
And sorry, I gave you last time wrong demo. Correct one - http://jsfiddle.net/JvdU9/2/

Showing timer countdown

In my game I have set the timer to 30000ms (30 secs). When the timer ends the game ends. I want to show the user the timer to give them some idea of how long they have left. How would I do this, I have tried to do it like this:
setTimeout(function() {
$("#message").html('Thank you for playing. </br> You answered </br>' + hit + '/' + attempted + ' correctly. </br> Press "Play" to start again.').fadeIn('slow');
$(".character").fadeIn('slow');
}, 500);
});
}, 30000).show('#timer'); //here I am trying to display the time in the "#timer"
}
I think I am approaching this all wrong can someone give me a point in the right direction?
Fiddle: http://jsfiddle.net/cFKHq/8/
Have a gander at this jsFiddle. You just need to change your timeout to an interval and keep a count of the seconds.
Instead of running the timer by all 30000 at once, run the timer in 1000ms increments. Each time it hits, subtract one from the counter, refresh the page, and if the counter is 0, end the game.
I changed the jsfiddle you posted to show a counter after pushing play button. See http://jsfiddle.net/cFKHq/10/
Inside your function startplay() I added a variable ttime with an initial value of 30 and I added the line $("#timer").text(--ttime); to the setInterval argument function that is called every second.
Look into using delta times. I have found this to be a great way to handle things that need to measure changes in time.
prevTime = curTime;
curTime += new Date();
deltaTime = curTime - prevTime;
This will also allow you to have a "x seconds remaining" counter if you fire off an event every 1 second, or even every 100ms. All depends on how fast you want it to go.
You need to seperate your timer logic from your "game over" logic, as the timer should tick regardless:
var secondsLeft = 30;
var timerElement = $('#timer');
(function timer() {
timerElement.text(secondsLeft);
secondsLeft--;
if (secondsLeft !== 0) {
setTimeout(function () {
timer();
}, 1000);
}
}());
http://jsfiddle.net/cFKHq/14/
Note that in this solution the 30 * 1 second timer countdown and 30 seconds of gameplay are not related or reliant on one another, which may cause some synchronicity issues if the user is on a slow machine.
You can use a global window.duration variable were you set the seconds the game will last, then decrement from that in the "one second" interval:
See working demo
At start of script:
var hit = 0;
var attempted = 0;
var target = $("#target");
window.cont = true;
window.duration = 30; //set your desired game duration in seconds
then on the "one second interval" we decrement the timer and print the timer text:
play = setInterval(function() {
if (window.cont) {
window.cont = false;
scramble();
}
window.duration--;
$('#timer').html(window.duration + ' seconds to go');
}, 1000);
Also display a "finished" text when the game ends, the relevant part follows:
setTimeout(function() {
$("#message").html('Thank you for playing. </br> You answered </br>' + hit + '/' + attempted + ' correctly. </br> Press "Play" to start again.').fadeIn('slow');
$(".character").fadeIn('slow');
$('#timer').html('Finished');
}, 500);
Here is an example: http://jsfiddle.net/RPSMJ/4/
JavaScript
var counter = 30,
timerOutput = document.getElementById('timerOutput');
(function timer() {
timerOutput.innerHTML = counter;
counter -= 1;
if (counter >= 0) {
setTimeout(function () {
timer();
}, 1000);
}
}());​
HTML
<div id='timerOutput'></div>​

Show div for 15 seconds then show another div

I have a gaming website and I want to put a advertisement before the game. So can someone tell me how to show the advertisement div for 15 seconds which says below it. "The game will start in [time left] seconds". Then one the time is up then it will show the div which holds the game. In javascript please.
Thank you
I would recommend taking a looking at setTimeout. It allows you do something after a certain time. If you need more help let us know.
EDIT: I'm sorry I misread your question. A more appropriate method you should use is setInterval so every second during the 15 seconds, you can show the time. Speransky's answer has the right idea.
Demo: http://jsfiddle.net/myDTK/1
var secondsLeft = 15;
var delay = 1000; // 1 second
var interval = setInterval(function () {
if (secondsLeft > 0) {
document.getElementById('timer').innerHTML = 'The game will start in ' + secondsLeft + ' seconds...';
secondsLeft -= 1;
} else {
document.getElementById('timer').style.display = 'none';
clearInterval(interval);
document.getElementById('game').style.display = 'block';
}
}, delay);​
function doSome() {
//do some
}
setTimeout(function(){
doSome();
}, 15000);
Have a look at the setTimeout function
eg.
setTimeout(function(){
//code to hide the div and how game div
}, 15000);
Here's a live example using jQuery.
Basically just make a function that adds the div, call that function whenever you need to, and then in that function do setTimeout(removeFunction, 15000) to call the remove function 15 secs later.
In order to do the countdown timer, you can call a function updateTimer once per second (again, setTimeout(updateTimer, 1000)) and have that function simply search for the timer and decrement the counter.

How to show first message on form load and next one after 1min?

As I don't have much knowledge of javascript and I need your help. My problem is like this:
I am using setInterval() for increasing the value of i every after 1 minutes and I am using this code:
var i = minutes;
function decrementMin() {
if(i>=0)
{
i--;
}
if(i==0)
{
alert('Minute = Congratulation your time begin now!');
}
document.getElementById('minutes').innerHTML = i + "minutes";
}
setInterval('decrementMin()',60000);
The problem is I want to show first message in <div id='minutes'></div> when page loads, but it shows the message after 1 minutes interval. If there is something that I am missing in my code please let me know.
Your problem is that you are setting the interval before the first message is displayed. Instead, you can call the function straight away and then set the interval. Also, you need to clear the interval once you've reached 0:
var i = minutes;
var intID;
function decrementMin() {
if(i>=0)
{
i--;
}
if(i==0)
{
clearInterval(intID);
alert('Minute = Congratulations my friend your time begins now!');
}
document.getElementById('minutes').innerHTML = i + "minutes";
}
decrementMin();
intID = setInterval(decrementMin, 60000);
This way you call your function straight away, and then set it to run every minute. Once you reach 0, you clear the interval so that the function doesn't count to "-1", etc.

Categories