Pause and changing timer value of running timeout function in a recursion - javascript

I have tried a lot of thing like codding timer class, callback functions etc. but I have never success.
My code:
function paint(node, direction, color, isB) {
var treePoint = document.getElementById(node.obj.circleId);
i++;
timeStack.push(setTimeout(function () {
paint2(node, direction, color, isB, treePoint);
}, timer * i));
i++;
timeStack.push(setTimeout(function () {
paint3(node, direction, color, treePoint);
}, timer * i));
}
}
I calling this function several time in a recursive function like:
function recursion(...){
//do something
if(condition){
paint(...)
recursion();
)
//do something
paint(...)
//do something
paint(...)
//...
//...
if(condition)
recursion();
}
The code running perfectly but I need to add pause button and change the timer value with a range input. I have tried some solutions but the solutions are not for recursion. I think the code are already run just waiting for timer. I need to access and change the timer value after running via pause button. Is it possible?
By the way the timeStack.push() part to keep timer ids to clearTimeouts for stop button and my stop button is working well.

Related

request animation frame loop

I came across this code
https://gist.github.com/joelambert/1002116 and i thought of playing around with it
I tried to create a loop and stop it
var tick = 0;
var dor = requestInterval(function(){
tick++;
console.log("hi", tick)
if (tick > 10){
stop();
}
},300)
function stop(){
console.log("stop")
clearRequestInterval(dor);
}
But the clearRequestInterval is not clearing the timer. But when i tried to call it from a button's event handler its working. Am I missing something?
I have attached a codepen
http://codepen.io/srajagop/pen/KgbbpR
#Bergi is right that the example code you tried to use is broken, it doesn't support cancelling the interval timer from within the interval function itself. You can work around that by invoking the clearRequestInterval asynchronously:
function stop() {
console.log("stop");
window.setTimeout(function() {
clearRequestInterval(dor);
}, 0);
}
Or perhaps better, you could fix the example code not to reschedule itself even if it was cancelled from within the interval function.

JavaScript Timer clearInterval complications

So I'm attempting to make a Pomodoro Timer without using an API (I know, stupid choice) but I feel as if I'm over-complicating this issue.
I forked my CodePen so I could post the current code here without confusing anyone. My Code Pen
To see my issue: Just set Timer to .1 and Break to .1 - You'll see the Start to Resume works fine, but the Resume to start has issues.
I built in consoleLogs to track it and I see the Work Timer TRIES to start but then breakTimer over-runs it, and duplicates on every pass.
Why isn't my clearInterval working?
Things I've tried:
Adjusting names of clearInterval,
Setting it so it goes back to startTimer instead of start
force quitting it (instead of looping it back to startInterval.
The function is virtually identical to my startFunction yet fails to work properly. Would appreciate any input (I'm new to clearInterval but I believe I am using it right.)
function breakTimer() {
$('.jumbotron').css('visibility', 'visible');
setInterval(function() {
console.log("Break Timer...");
breakTime--;
if (breakTime < 0) {
clearInterval(timer);
working = false;
start();
} else {
showTime(breakTime);
}
}, 1000);
}
Edit:
To answer the reply:
function start() {
if (working == true){ //This keeps it from being spammable
return;
} //Else
workTime = $('#work').val()*60;
breakTime = $('#break').val()*60;
working = true;
checkStatus();
timer = startTimer();
}
Unsure if I should post every Function here
As per definition, the value returned by setInterval(...) is the ID of the created timer. As such, with your code you can only stop the last created timer because the ID in the timer variable gets overwritten, causing it to lose control over the previously created (and still running) timers.
The ID is what you pass on to clearInterval(...) to stop a timer. You will have to do this in a different way. You may ask for a different way in https://codereview.stackexchange.com/

Stopping a running function in javascript/jquery on click event

I have a slideshow function in jquery that I want to stop on a particular click event. The slideshow function is here:
function slider(){
setInterval(function(){
var cur = $('img.active');
cur.fadeOut('fast');
cur.removeClass('active');
cur.css('opacity','0');
cur.addClass("hidden");
var nextimg;
if (!cur.hasClass("last")){
nextimg = cur.next("img");
}
else {
nextimg = cur.prev().prev().prev();
}
nextimg.removeClass("hidden").fadeIn('slow').css('opacity','1').addClass('active');
},5000);
}
I have been reading about .queue but not sure how I can use it exactly, can I call my function from a queue and then clear the queue on a click event? I cannot seem to figure out the syntax for getting it to work of if thats even possible. Any advice on this or another method to stop a running function on a click would be appreciated.
For what it's worth, it's generally advisable to use a recursive setTimeout instead of a setInterval. I made that change, as well as a few little syntax tweaks. But this is a basic implementation of what I think you want.
// Store a reference that will point to your timeout
var timer;
function slider(){
timer = setTimeout(function(){
var cur = $('img.active')
.fadeOut('fast')
.removeClass('active')
.css('opacity','0')
.addClass('hidden'),
nextimg = !cur.hasClass('last') ? cur.next('img') : cur.prev().prev().prev();
nextimg.removeClass('hidden')
.fadeIn('slow')
.css('opacity','1')
.addClass('active');
// Call the slider function again
slider();
},5000);
}
$('#someElement').click(function(){
// Clear the timeout
clearTimeout(timer);
});
Store the result of setInterval in a variable.
Then use clearInterval to stop it.
Store the value returned by setInterval, say intervalId to clear it, your click handler should look like this:
function stopSlider() {
//prevent changing image each 5s
clearInterval(intervalId);
//stop fading the current image
$('img.active').stop(true, true);
}

How can I exit out from an infinitely runnng loop in JavaScript?

Is it possible to stop an infinite loop from running at all?
Right now I am doing something like this:
var run = true;
loop ({
if(run) {
whatever
}
}, 30),
Then when I want to stop it I change run to false, and to true when I want to start it again.
But the loop is always running whatever I do. It just not executing the code inside.
Is there a way to stop it completely? and make it start again when I want?
If I am understanding your question correctly, what you need is the break keyword. Here's an example.
SetInterval will give you a loop you can cancel.
setInterval ( "doSomething()", 5000 );
function doSomething ( )
{
// (do something here)
}
Set the interval to a small value and use clearinterval to cancel it
function infiniteLoop() {
run=true;
while(run==true) {
//Do stuff
if(change_happened) {
run=false;
}
}
}
infiniteLoop();
It may not be exactly what you are looking for, but you could try setInterval.
var intervalId = setInterval(myFunc, 0);
function myFun() {
if(condition) {
clearInverval(intervalId);
}
...
}
setInterval will also not block the page. You clear the interval as shown with clearInterval.
Use a while loop
while(run){
//loop guts
}
When run is false the loop exits. Put it in a function and call it when you want to begin the loop again.
The problem is that javascript only has a single thread to run on. This means that while you are infinitely looping nothing else can happen. As a result, it's impossible for your variable to ever change.
One solution to this is to use setTimeout to loop with a very small time passed to it. For example:
function doStuff(){
if(someFlag){
// do something
}
setTimeout(doStuff,1);
}
doStuff();
This will give the possibility for other actions to make use of the thread and potentially change the flag.

capture multiple "onkeydown" and wait until "onkeyup" to execute

In my web app, I use the onkeydown event to capture key strokes.
For example, I capture the 'j' key to animate a scroll down the page (and do some other stuff meanwhile).
My problem is the user might keep the 'j' key down to scroll further down the page (this is equivalent to fast multiple key strokes).
In my app, this result in a series of animations that doesn't look that good.
How can I know when the key has been released, and know the amount of key stokes I should have captured? This way I could run one long animation instead of multiple short ones.
Building on #JMD:
var animate = false;
function startanimation()
{
animate = true;
runanimation();
}
function stopanimation()
{
animate = false;
}
function runanimation()
{
if ( animation_over )
{
if ( !animate )
{
return;
}
return startanimation();
}
// animation code
var timeout = 25;
setTimeout(function(){runanimation();},timeout);
}
document.onkeydown = startanimation;
document.onkeyup = stopanimation;
You'll need to add some checks for starting/ending animations, however.
Edit: added a return to the JS; would've recursed endlessly.
Rather than trying to stack up the animations, you could start an animation on keyDown, and if at the end of the animation you haven't yet received keyUp then start another animation. As soon as you reach the end of an animation and you do have keyUp then you're done.
setTimeout returns a timer ID. So what I would do is after you receive a keyDown event, I would start a timer with a very short wait period, like so:
var globalTimerId = -1;
var keyDownCount = 0;
function handleKeyDown(e) {
if (globalTimerId != -1) {
clearTimeout(globalTimerId);
keyDownCount++;
}
/* 500 means 1/2 a second, adjust for your needs */
globalTimerId = setTimeout(handleKeyDownAfterWait, 500);
keyDownCount = 1;
}
function handleKeyDownAfterWait() {
globalTimerId = -1;
/* keyDownCount will have the number of times handleKeyDown was called */
}
So the idea is that each time a keyDown event is received, the timer is cleared (assuming it hasn't elapsed yet) and restarted. If the timer expires, the user has let go of the key and you can handle that in handleKeyDownAfterWait.
There may be other more elegant solutions with jQuery or another JS library however. This is just something quick and dirty (and possibly buggy ;))
you can try using my repsonsiveness plugin see:
http://notetodogself.blogspot.com/2008/12/jquery-responsiveness-plugin-for-fast.html
see the demo here:
http://doesthatevencompile.com/current-projects/jquery.responsiveness/
the one where you type stuff fast. you can adapt that to your needs. like so:
the animation event will be bound with the plugin, and execute when the user stops doing something fast. you can count how many times he does the fast thing by normal binding of the event.

Categories

Resources