Fast forward timer - javascript

I'm having trouble with fast forwarding a timer. It is very basic at this stadium. I have a interval that add numbers. Like this:
setInterval(function () {
//+1 second
//Format output to 00:00
//Handle minute update
}, 1000);
This works perfect. The timer is going at normal speed. What I want to do is fast forwarding this timer. I want a timer minute to take 1 real second. I have tried:
setInterval(function () {
//+1 second
//Format output to 00:00
//Handle minute update
}, 15);
That works sometimes and sometimes not. Sometimes it stops att 01:02 instead of 01:00. It may be my lack of math knowledge but I don't know. How would you do it? I am going to stop and start the timer every "timer minute" so it's important that the interval is correct.
EDIT
Here is a fiddle of how I want it to work: http://jsfiddle.net/tbleckert/pF4gs/
EDIT 2
Maybe I should just adjust the time when I stop the timer?
EDIT 3
It seems like 15 ms works most of the times. But something makes ut unreliable, I think the best way is to just adjust the time.

I think what you should be doing is storing your interval in a variable so that you can clear it, and start it again with a different delay.
var delay = 1000; // JavaScript uses milliseconds, so 1000 = 1 second
var theTimer = '';
function startTimer(){
theTimer = setInterval(function () {
// Do awesome stuff here
}, delay);
}
startTimer();
Now when you want to change the interval, or fast forward the timer, all you have to do is clear the current setInterval and define it again -
clearInterval(theTimer); // stop and clear the current timer
delay = 500; // Crank it up to twice the speed! 0.5 seconds!
startTimer(); // start a new setInterval();
Here is a simple demo

<!DOCTYPE html>
<html>
<head>
<script>
function myTimer(){
this.startTime=0;
this.intervalID=0;
this.timePassed=0;
this.multiplier=1;
this.outputElement=null;
this.start=function(){
clearInterval(this.intervalID);
this.timePassed=0;
this.outputElement=document.getElementById("output");
this.startTime=new Date();
var me = this;
this.intervalID=setInterval(function(){
me.update(me);
},100);
}
this.toTwoDigit=function(num){
if(num<10){
return "0"+num;
}
return new String(num);
}
this.toThreeDigit=function(num){
if(num<10){
return "00"+num;
}
if(num<100){
return "0"+num;
}
return new String(num);
}
this.update=function(me){
me.timePassed=me.timePassed+(100*me.multiplier);
var seconds=Math.floor(me.timePassed/1000);
var hours = Math.floor(seconds/3600);
var minutes = seconds-(hours*3600);
seconds = seconds%60;
minutes=Math.floor(minutes/60);
me.outputElement.innerHTML= me.toTwoDigit(hours)+":"
+me.toTwoDigit(minutes)+":"
+me.toTwoDigit(seconds)
+":"+me.toThreeDigit(Math.floor(me.timePassed%1000));
}
this.speedup=function(){
this.multiplier=this.multiplier*2;
}
this.slowDown=function(){
this.multiplier=this.multiplier/2;
}
this.stop=function(){
clearInterval(this.intervalID);
this.update(this);
}
}
var t = new myTimer();
</script>
</head>
<body onload="t.start();">
<input type="button" value="speed up" onclick="t.speedup()"></input>
<input type="button" value="slow down" onclick="t.slowDown()"></input>
<input type="button" value="stop" onclick="t.stop()"></input>
<input type="button" value="restart" onclick="t.start()"></input>
<input type="button" value="(re)start times 60" onclick="t.multiplier=60;t.start()"></input>
<div id="output"></div>
</body>
</html>

Ok so I'm going to answer this myself. I don't think I was clear enough. When I start the timer a timeout starts at the same time, that after one second stops the timer. This is where it goes wrong, the timer doesn't always show 01:00 when it stops.
So, the final solution is the set the seconds to 00 every time it stops, and because it all happens so fast, you wont notice.
setTimeout(function () {
clearInterval(interval);
$('.clock').html(rMin.slice(-2) + ':00');
}, 1000);
Check my updated fiddle:
http://jsfiddle.net/tbleckert/pF4gs/2/

Related

Using a clock for Auto click

I am using the code below to execute an Autoclick for an interval, now I want to add the specific time to start and stop the clicking. It would be great if somebody could help me to do that.
there is a clock in the website which the time is different from the system clock(by 1-2 seconds), so I would prefer to use the website clock as the reference.
I appreciate that.
let timerId = setInterval(() => {
let Quant = “1000”;
let Ptag = “10000”;
document.getElementById("send_order_txtCount").value = Quant;
document.getElementById("send_order_txtPrice").value = Ptag;
$("#send_order_btnSendOrder").click();
console.log('clicked');
}, 1000);
// 1000 is the time span to clicking (Mili seconds)
// 4000 is the total time to stop the code
let stop = 4000;
setTimeout(() => {
clearInterval(timerId);
alert('stop');
}, stop);
I am wondering whether this will work or not.
"Start": "9:46:56",
"Stop": "9:47:00",

javascript setTimeout function doesn't work inside a loop

I'm making a Simon Game and I'm trying to make the button presses have 1 second interval. But It seems that my setTimeout function is not doing its job and all clicks are performed at once without the 1s interval. I tried alerting something outside the loop and it works just fine. Can anyone help me with this?
This is my JavaScript code:
for (var count = 1; count <= 20; count++) {
$("#count").html(count);
seq.push(Math.floor(Math.random() * 4));
seq.forEach(function(press) {
setTimeout(function() {
eval('$("#button' + press + '").click();');
}, 1000);
});
}
and the corresponding html:
<p>count: <span id="count">0</span></p>
<button id="button0" onclick="sound1.play()"></button>
<button id="button1" onclick="sound2.play()"></button>
<button id="button2" onclick="sound3.play()"></button>
<button id="button3" onclick="sound4.play()"></button>
Thank you!
The problem is the way you do setTimeout.
The for loop iterates within a few milliseconds and you basically request all the clicks to run one second later, so they all happen one second later but at the same time.
If you request the first click after one, the second click after two seconds and so forth, you'll get what you want:
seq.forEach(function(press, i) {
setTimeout(function() {
$("#button" + press).click();
}, 1000 * i);
});
Also note that you probably want to restructure your code to not do this twenty times over:
for (var count = 1; count <= 20; count++) {
$("#count").html(count);
seq.push(Math.floor(Math.random() * 4));
}
seq.forEach(function(press, i) {
setTimeout(function() {
$("#button" + press).click();
}, 1000 * i);
});
Your eval function is running after 1 second but all of them are.
What happens:
loop from 1 to 20
add an item to the seq array
loop through the seq array
define the setTimeout to happen in 1 second.
Your code does not sleep while wating for the setTimeout to execute. So all of them are defined on the loop and happen as near as possible to the 1 second requested.
You could make an asynchronous loop, by calling a function repeatedly from within a setTimeout: that way the sequencing and delay will be as desired.
Here is a working snippet with some other ideas:
// First generate the array (only 8 to not annoy SO public):
var seq = Array.from(Array(8), _ => Math.floor(Math.random() * 4));
function replay() {
// Iterate seq asynchronously
(function loop(i) {
if (i >= seq.length) return; // all done
$("#count").text(i+1);
$("#buttons>button").eq(seq[i]).click();
setTimeout(loop.bind(null, i+1), 1000);
})(0);
}
$("#buttons>button").click(function () {
// Play sound here...
playNote([523, 659, 784, 880][$(this).index()], 800);
// Some visual effect:
$(this).addClass("clicked");
setTimeout($(this).removeClass.bind($(this), "clicked"), 800);
});
// Sound support
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
function playNote(frequency, duration) {
// create Oscillator node
var oscillator = audioCtx.createOscillator();
oscillator.type = 'square';
oscillator.frequency.value = frequency; // value in hertz
oscillator.connect(audioCtx.destination);
oscillator.start();
setTimeout(oscillator.stop.bind(oscillator), duration);
}
// Play the sequence on page load
replay();
button {
border: 2px solid silver;
}
button.clicked {
border: 2px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>count (up to 8): <span id="count">0</span></p>
<div id="buttons">
<button>A</button>
<button>B</button>
<button>C</button>
<button>D</button>
</div>

Using javascript/jQuery, wait 3 seconds for click, then proceed

I've been trying to figure out how to run an infinite loop while pausing for user click, then allow for a break out.
When the loop starts, the user is presented with an image, and must choose the identical image from one of 4 displayed. If they successfully click the match within 5 seconds, they are presented another image, and the game goes on.
If they either choose an incorrect image, or 5 seconds elapses, the game ends.
I've got all of the functionality worked out, except this pause while waiting for a click or the time to expire.
Ideally, I'd also like the time to be adjustable on each iteration. Say start at 5 seconds, then shorten the time slightly (10ms) on each loop.
I believe it must be solvable using setTimeout() or setInterval(), but just can't wrap my head around it.
Here is a minimal concept of what I'm trying to accomplish.
$('#playnow').on('click',function(){
var speed = 5000;
var speed_reduce = 10;
var game_running = true;
/* create array of images */
var imgs = ['puppy.png','kitten.png','bunny.png','goldfish.png'];
var runnow = setInterval(
function(){
//get random image from loaded theme
rand_img = imgs[Math.floor(Math.random() * imgs.length) ];
//display chosen image
$('#goal_image').html('<img src="'+theme_dir+rand_img+'" />');
// wait up to 5 seconds for user to click or time to expire
if(*clicked and matched*){
//get new random image and reset timer (less 10ms)
}
if(*time expired*){
//bail out and game ends
}
/* reduce time */
speed -= speed_reduce;
},
speed);
});
You'll want something like this I think:
var speed = 5000, // the initial time
currentimage,
timer,
gamerunning;
function newimage(){
var imgs = ['puppy.png','kitten.png','bunny.png','goldfish.png'];
currentimage=Math.floor(Math.random() * imgs.length);
$('#goal_image').html('<img src="'+theme_dir+imgs[currentimage]+'" />');
timer = setTimeout(speed, lost)
}
function answer(id){
if(!gamerunning){return}
clearTimeout(timer)
if(id==currentimage){
speed -= 10; // time decrease every time.
newimage();
}else{
lost()
}
}
function lost(){
gamerunning=0;
speed=5000;
// what to do when lost.
}
$("#puppy").on("click",function(){answer(0)}); // here #puppy is the id of the answer image, and 0 the index in the imgs array.
$("#kitten").on("click",function(){answer(1)});
$("#bunny").on("click",function(){answer(2)});
$("#fish").on("click",function(){answer(3)});
$("#gamestartbutton").on("click",function(){gamerunning=1})
One way to solve this problem is to use setTimeout() and clearTimeout() rather than setInterval. Also, you need some event for the successful button click (I've pretended you have a special "#successfulmatch" button):
var speed = 5000;
var speed_reduce = 10;
var game_running = true;
var imgs = ['puppy.png','kitten.png','bunny.png','goldfish.png'];
var myTimeout;
function runNow(speed){
rand_img = imgs[Math.floor(Math.random() * imgs.length) ];
$('#goal_image').html('<img src="'+theme_dir+rand_img+'" />');
// Keep track of the timeout so we can cancel it later if the user clicks fast enough.
myTimeout = window.setTimeout(function(){
game_running = false;
gameEnds();
},speed);
}
$('#successfulmatch').on('click',function(){
if(game_running){
// Cancel the timeout because the user was fast enough
window.clearTimeout(myTimeout);
// Give the user less time than before
runNow(speed - speed_reduce);
}
else{
// Throw an error: you forgot to hide the clickable buttons when the game ended.
}
}
$('#playnow').on('click',function(){
runNow(speed);
}
Looks like you are mixing the logic for checking "has the user clicked the image? was it correct?" with the one for checking "has time expired?"
You can listen for onclick events on the images
and set a timeout event for the game over
so the user has to cancel that timer, to cancel imminent game over, by clicking on the images
if the right image is clicked the timer is reset
if not, it's game over
you can cancel a timeout event before it runs with cancelTimeout()
see W3C here for a reference.
here is a quick prototype:
$('#playnow').on('click', function() {
var speed = 5000;
var speed_reduce = 10;
var game_running = true;
/* create array of images */
var imgs = ['puppy.png', 'kitten.png', 'bunny.png', 'goldfish.png'];
// function that ends the game if it's called
function gameover() {
alert("GAME OVER");
game_running = false;
}
// in order to use clearTimeout() you must store the timer in a global variable
// setting a timeout that will end the game if it's not cleared before
window.timer = setTimeout(gameover, speed);
// function that is called whenever the user clicks on a image
function onclickimage(event) {
if (!game_running) return;
if ( /*clicked right img*/ ) {
// get random image from loaded theme
var rand_img = imgs[Math.floor(Math.random() * imgs.length)];
// display chosen image
$('#goal_image').html('<img src="' + theme_dir + rand_img + '" />');
// delete timer, user now has one more opportunity
clearTimeout(timer);
// speed is less 10ms
speed -= speed_reduce;
// launch timer again
window.gametimer = setTimeout(loop, speed);
} else { // if click did not match correct image
gameover();
}
}
});
Well, firstly, you need to clearInterval() when they either click or fail in order to stop the current interval. Then, you can restart an interval with the new speed. The interval seems to be working for.
Every 5 seconds a new picture is displayed. So, you want an onclick event for the picture that clears the interval and starts a new one. So, you may want to use setTimeout instead of setInterval since it is only a single iteration at a time.
You could use setInterval, I suppose, but there's no real benefit to it. This way also makes it relatively easy to reduce the speed each time.

Get the time show animation how much duration is currntly running

In jquery i use following code:
j=-(i)
if(j%2==1)
{
$("#caption1").hide();
$("#caption1").fadeIn(1000);
$('#main_div').hide();
$('#main_div').show(5000);
}
}
if(i%2==0)
{
$("#caption1").hide();
$("#caption1").fadeIn(1000);
$('#main_div').hide();
$('#main_div').show(5000);
}
while show animation i want the duration of animation completed?
for Example:
i set it show animation for 5secs.
show animation now started.
2 secs animation completed[ 3secs remaining]
in this case i need this completed duration[2secs] on button click??
Mark down the time when the animation started:
var animationStarted = new Date();
$('#main_div').show(5000);
....
When you need to show how much time has passed, take the current time and subtract the time saved in the previous step.
var now = new Date();
var elapsed = ( now.getTime() - animationStarted.getTime() ) / 1000;
Demo: http://jsfiddle.net/NZGU6/

Combine ASP.net AJAX timer with javascript countdown

I am currently working on porting a vb.net winforms program over to a web based version, and one of the functions in the original program has be stumped.
In the original program, every 5 minutes, a form pops up for user input. There is also a label control on the main form which counts down to the next popup. This is accomplished with a single timer control with a 1 second duration. every tick, it decrements the countdown, and when the countdown reaches 0, it pops up the form and then resets. Simple enough, but in my web app, I can't afford to be doing a postback every second, so what I am attempting is to combine a javascript countdown widget with an AJAX timer. Essentially, what should happen is that when the page loads, the countdown begins decrementing from 300 seconds, and the AJAX timer begins with a duration of 300 seconds. My idea is that when the timer ticks, it will run my function, as well as reset the countdown to 300 seconds again.
My problem, is that I am not able to reset the countdown with the code that I have, and I know that I am doing something (likely very simple) wrong, but I don't know enough Java to know what.
If I hardcode the Timer var to 300, the countdown works, and the timer ticks (fires the additional functons), but the countdown just keeps counting down (into negative numbers). How do I reset the countdown variable from code behind?
Here is the countdown function
var Timer = <%= CountDown %>;
function updateClock() {
// Update Countdown
Timer -= 1;
var TimerMin = Math.floor(Timer / 60);
var TimerSec = Timer - (TimerMin * 60);
TimerSec = (TimerSec < 10 ? "0" : "") + TimerSec;
var TimerFormat = TimerMin + ":" + TimerSec;
// Update the countdown display
document.getElementById("javaCountdown").firstChild.nodeValue = TimerFormat
}
Here is the body code
<body onload="updateClock(); setInterval('updateClock()', 1000 )">
And the Code Behind
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Countdown = 300
End Sub
PProtected Sub Timer1_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles Timer1.Tick
Countdown = 300
'Additional Functions
End Sub
This solution uses jQuery.
<script>
var intervalSecond = null;
var interval5minutes = null;
$(document).ready(function() {
// enable both intervals
enableIntervals();
// onsubmit event for your form
$("#popupForm").submit(function() {
// hide the form again
$("#popupForm").css("display", "none");
// enable intervals again.
enableIntervals();
});
});
function enableIntervals() {
// every second interval
intervalSecond = setInterval(function() {
$("#updateMeEverySecond").html(new Date());
}, 1000);
// every 5 minutes interval
interval5minutes = setInterval(function() {
// display form and shut off the interval timers
$("#popupForm").css("display", "block");
clearInterval(intervalSecond);
clearInterval(interval5minutes);
}, 5 * 60 * 1000);
}
</script>
<div id="popupForm" style="display:none;">
<form>
<input type="text" />
</form>
</div>
<label id="updateMeEverySecond">Test</label>

Categories

Resources