My aim is to create identify a piece of code that increments a number by 1, every 1 second:
We shall call our base number indexVariable, I then want to: indexVariable = indexVariable + 1 every 1 second; until my indexVariable has reached 360 - then I wish it to reset to 1 and carry out the loop again.
How would this be possible in Javascript? - if it makes a difference I am using the Raphael framework.
I have carried out research of JavaScript timing events and the Raphael delay function - but these do not seem to be the answer - can anyone assist?
You can use setInterval() for that reason.
var i = 1;
var interval = setInterval( increment, 1000);
function increment(){
i = i % 360 + 1;
}
edit: the code for your your followup-question:
var interval = setInterval( rotate, 1000);
function rotate(){
percentArrow.rotate(1,150,150);
}
I'm not entirely sure, how your rotate works, but you may have to store the degrees in a var and increment those var too like in the example above.
var indexVariable = 0;
setInterval(function () {
indexVariable = ++indexVariable % 360 + 1; // SET { 1-360 }
}, 1000);
Try:
var indexVariable = 0;
setInterval(
function () {
indexVariable = (indexVariable + 1) % 361;
}, 1000}
Related
i would like to add another counter in this code:
function animateValue(id) {
var obj = document.getElementById(id);
var counter = getLocalStoregaValue();
var current = counter ? +counter : obj.innerHTML;
obj.innerHTML = counter;
setInterval(function() {
var counter = current--;
obj.innerHTML = counter;
localStorage.setItem('counter', counter);
}, 1000);
}
function getLocalStoregaValue() {
return localStorage.getItem('counter');
}
animateValue('value');
I would like it to scale once every second (as in this case) and once every 5 seconds. How can I? And then, how can I make it stop at 0? So without negative numbers. Thank you very much.
EDIT: I explained myself wrong.
I would like a single counter that drops in number from a minimum of 10 to a maximum of 20.
Example: the counter marks 50. After 15 seconds it marks 49. After 18 seconds it marks 48. After 11 seconds it marks 47. And so up to 0.
I hope I explained myself well this time :)
Ok, I was interrupted while posting my answer. Here now the explanation:
I left out the localStorage part of your question and concentrated on the generation of "independent countdowns" first:
function cntdwn(sel,stp,intv){
let el=document.querySelector(sel),
n=el.textContent-stp,
cd=setInterval(()=>{
el.textContent=n;
if((n-=stp)<0) clearInterval(cd);
}, intv);
}
cntdwn('#one',1,1000) ;
setTimeout(()=>cntdwn('#two',1,3000), 12000);
<p>first countdown:<br>step: 1, interval: 1s</p>
<p id="one">15</p>
<p>second countdown:<br>step: 1, action after: 15, 18, 21, 24 ... s (as mentioned in comment)</p>
<p id="two">50</p>
The cntdwn() function provides a scope in which individual countdowns can be set up for arbitrary DOM elements, each with their own counter (it starts with the value found in the DOM element), step-width and interval (in milliseconds).
Each countdown is generated with let cd=setInterval(...). The reference cd can then be used to stop the countdown (in clearInterval(cd)), once the value of n is found to be below zero.
Edit:
Assuming you made a typo in your sequence of intervals and you really meant: 15, 18, 21 seconds, then the edited second countdown should be the correct solution.
I used a setTimeout() function to delay the action by 12 seconds, then, after the first of the regular 3 second intervals (i. e. after a total of 15 seconds) the first change occurs. The countdown then continues in 3 second intervals until it reaches zero.
Yet another edit:
Ok, so you want: "A countdown with random time intervals (range 10 to 20s each) that will stop at zero"
This should do it:
function cntdwn(sel,int1,int2){
let el=document.querySelector(sel),
n=el.textContent-1,
cd=()=>setTimeout(()=>{
el.textContent=n;
if(n--) cd();
}, 1000*(int1+Math.random()*(int2-int1)));
cd();
}
cntdwn('#one',10,20);
<p>countdown:<br>step: 1, intervals: between 10 and 20 s</p>
<p id="one">5</p>
If you can use ES2017, you can use an asynchronous function to do it, like this:
async function animateValue(id) {
function timeout(t){
return new Promise(r => setTimeout(r, t))
}
var obj = document.getElementById(id);
var counter = getLocalStoregaValue();
for(let i = +counter || +obj.innerHTML || 0; i >= 0; i--){
obj.innerHTML = i;
localStorage.setItem('counter', i);
await timeout((Math.random() * 10 + 10) * 1000); //Pause for 10 to 20 seconds. For an integer second value, wrap `Math.random() * 10` into a `Math.floor` call
};
}
function getLocalStoregaValue() {
return localStorage.getItem('counter');
}
animateValue('value').catch(console.error);
<div id="value">50</div>
Try it (I commented out the localStorage part, as it isn't allowed in Stack Snippets):
async function animateValue(id) {
function timeout(t){
return new Promise(r => setTimeout(r, t))
}
var obj = document.getElementById(id);
var counter = getLocalStoregaValue();
for(let i = +counter || +obj.innerHTML || 0; i >= 0; i--){
obj.innerHTML = i;
//localStorage.setItem('counter', i);
await timeout((Math.random() * 10 + 10) * 1000); //Pause for 10 to 20 seconds. For an integer second value, wrap `Math.random() * 10` into a `Math.floor` call
};
}
function getLocalStoregaValue() {
//return localStorage.getItem('counter');
}
animateValue('value').catch(console.error);
<div id="value">50</div>
I have written this code to change an image:
change = function(){
for (r=0; r<6; r++){
for (i = 0; i < 6 ; i++) {
setInterval(imgfile(number=i+1), 5000);
}
}
}
imgfile= function(number){
a = 'document.getElementById("imgdiv").src = "images/'+number+'.svg"';
eval(a);
}
The function change() is called when a button is clicked.
When I press the button the image changes straight to 6.svg, when I want it to go through the images 1, 2, 3, 4, 5, 6 and to repeat it 6 times. When I change setInterval to change.setInterval or imgfile.setInterval it doesn't work at all. How do I fix this?
change = function(i=0){
imgfile(i%6+1);//change image
if(i<36) setTimeout(change,5000,i+1);//next image in 5 seconds
}
imgfile= function(number){
document.getElementById("imgdiv").src = "images/"+number+".svg";//no need to use ev(i||a)l
}
Instead of loop/interval mess you can simply start a timeout that restarts itself after changing the image... This code will loop over 6 images with a delay of 5 seconds and that 6 times...
Something like this, perhaps?
var index, imgCount, loopCount, imgTag, countdown;
index = 0;
imgCount = 6;
loopCount = 6;
imgTag = document.getElementById('imgdiv');
countdown = function () {
if (index < imgCount * loopCount) {
imgTag.src = 'images/' + index % imgCount + '.svg';
index = index + 1;
setTimeout(countdown, 5000);
}
};
countdown();
Here we're avoiding the double loop and using modular math (index % imgCount) to get the right file number.
For another question I wrote a nice utility function that has quite a number of uses, but can also handle this scenario very easily. The main issue is that there is no time elapsing between the different delays being set. So you are setting 6 different actions to all happen within 5000ms, and all will occur at the same moment.
Here's my original answer
Here's the utility function for that answer, along with its application to your problem.
function doHeavyTask(params) {
var totalMillisAllotted = params.totalMillisAllotted;
var totalTasks = params.totalTasks;
var tasksPerTick = params.tasksPerTick;
var tasksCompleted = 0;
var totalTicks = Math.ceil(totalTasks / tasksPerTick);
var initialDelay = params.initialDelay;
var interval = null;
if (totalTicks === 0) return;
var doTick = function() {
var totalByEndOfTick = Math.min(tasksCompleted + tasksPerTick, totalTasks);
do {
params.task(tasksCompleted++);
} while(tasksCompleted < totalByEndOfTick);
if (tasksCompleted >= totalTasks) clearInterval(interval);
};
// Tick once immediately, and then as many times as needed using setInterval
if (!initialDelay) doTick();
if (tasksCompleted < totalTicks) interval = setInterval(doTick, totalMillisAllotted / totalTicks);
}
// Do 6 actions over the course of 5000 x 6 milliseconds
doHeavyTask({
totalMillisAllotted: 5000 * 6,
totalTasks: 6,
tasksPerTick: 1,
initialDelay: false, // Controls if the 1st tick should occur immediately
task: function(n) { console.log('Set image to "images/' + (n + 1) + '.svg"'); }
});
You want to do setTimeout().
setTimeout pauses for the millesecond value and then does the code. Where setInterval runs the code every whatever milleseconds.
Yeah, don't do change.setInterval or whatever, it is just setInterval.
An example for you would be this inside the for loop to replace the setInterval function.
setTimeout(imgfile(i+1), 5000);
I've got the following variable JS:
http://jsfiddle.net/c8u8wLsL/13/
$(document).ready(function () {
var total = 15.5,
value = 0,
elem = $('div');
var interval = setInterval(function () {
elem.text(value.toFixed(1) + '$');
if (value >= total) {
clearInterval(interval);
}
value = value + 0.1;
}, 5);
});
Two questions:
The resulting number is 15.6 why?
How can I make the incrementation spend the same amount of time from 0 to the target value? (from 0 to 25 spends the same time as from 0 to 250)
You forget to exit from function. Also you should probably update node's text after checking total.
if (value >= total) {
return clearInterval(interval);
}
elem.text(value.toFixed(1) + '$');
fiddle http://jsfiddle.net/Lqxsh39q/
To solve second problem you can pre-calculate duration of each interval before it setup. And use it like second argument in setInterval. Something like duration = 1000 / (total * 10); or any formula that you want.
fiddle: http://jsfiddle.net/Lqxsh39q/1/
#Glen Swift's answer is correct but I have to point out regarding your original code:
You get the resulting number as 15.6 because:
When you think you are getting 15.5 as the result, you are actually getting 15.4999999, which is smaller than 15.5 and hence the if condition is false even if you think it is true. So it gets incremented once again, giving the final result as 15.6.
As far as the second part is concerned, to get the same time, you need to have the same number of steps for each addition rather than the fixed 0.1. Let's say you want to reach the target in 100 steps everytime, you can divide the total interval by 100 and then replace it in the code where you are writing 0.1 currently.
The final code should look something like:
$(document).ready(function () {
var total = 15.5,
value = 0,
ment=(total-value)/100,
elem = $('div');
var interval = setInterval(function () {
if (value >= total) {
return clearInterval(interval);
}
elem.text(value.toFixed(1) + '$');
value = value + ment;
}, 5);
});
See the fiddle here
Your existing code:
var interval = setInterval(function () {
elem.text(value.toFixed(1) + '$');
if (value >= total) {
clearInterval(interval);
}
value = value + 0.1;
}, 5);
It should check for the >= total condition first. if condition fails then exit the function.
But you are modifying the text element before the check. thus your error.
This would do.
var interval = setInterval(function () {
value = value + 0.1;
if (value <= total) {
elem.text(value.toFixed(1) + '$');
} else {
clearInterval(interval);
}
}, 5);
How can I run this every few second , without blocking the rest of the pagefrom loading.
function Create() {
var SomeArray = [];
for ( var i=0; i<=1 ; i ++) {
SomeArray[i] = (Math.random() * 10) + 1;
//alert(arr[0]);
}
return SomeArray;
}
var x = Create();
alert(x[0] + x[1]);
I was trying this var timer = setInterval(Create, 5000); it prevent loading rest of the page.
i want to get new values every few seconds
A basic example would be:
var counter = 0;
var timerRef;
var increment = function() {
counter += 1;
console.log(counter);
timerRef = setTimeout(increment, 1000);
}
setTimeout(increment, 1000);
// clearTimeout(timerRef);
Please avoid document.write refer the screencast for further details.
setInterval() can be configured to repeatedly call any function you designate at whatever time interval you request. But, you can't retrieve a return value from that function. Instead, you need to process the results from within the callback that you pass to setInterval() or call some other function and pass the results you generate inside the callback. This is how asynchronous functions work in JavaScript. I've provided several examples below of your options:
If you just want to generate two random decimal values between 1 and 10 (inclusive) every 5 seconds, you can do that like this:
var interval = setInterval(function() {
var rand1 = (Math.random() * 10) + 1;
var rand2 = (Math.random() * 10) + 1;
// now insert code here to do something with the two random numbers
}, 5000);
If you wanted the random values to be integers (which is more common), then you would do this:
var interval = setInterval(function() {
var rand1 = Math.floor(Math.random() * 10) + 1;
var rand2 = Math.floor(Math.random() * 10) + 1;
// now insert code here to do something with the two random numbers
}, 5000);
If you want to call a function and pass it those two random numbers, you can do this:
function processRandoms(r1, r2) {
// code here to do something with the two random numbers
}
var interval = setInterval(function() {
var rand1 = Math.floor(Math.random() * 10) + 1;
var rand2 = Math.floor(Math.random() * 10) + 1;
processRandoms(rand1, rand2);
}, 5000);
You can then stop the recurring interval at any time with this:
clearInterval(interval);
Forgive me if this sounds a little confusing ... I am trying to adjust the value of a progress bar based on my randomize variable.
var randomize = Math.round(Math.random() * (3000 - 2000) + 1000);
How do I then get javascript to count from 0 to 'randomize' in seconds, so that I can apply it to my progress bar?
You could do something like this:
var randomize = Math.round(Math.random() * (3000 - 2000) + 1000);
var counter = 0;
var timer = setInterval( function(){
if ( counter <= randomize ){
// update progress bar
counter += 1;
}else{
clearInterval( timer );
}
}, 1000 );
Basically what I'm doing here is setting up a function to be called every second ( 1000 = 1 second in JavaScript). The timer will check if the counter variable has reached the value of randomize and if not, it will increment it's value by one.
Once counter is equal to randomize, the timer will be cleared.
References -
setInterval()
clearInterval()
var seconds = 0;
var timer = setInterval(function() {
seconds = seconds + 1;
if (seconds == randomize) {
clearInterval(timer);
}
}, 1000);