I am aiming for a loading progress bar that fluctuates in speed as it goes from 0 to 100%. I would like some variety in the way it loads to give the appearance of loading my app. The following code sorta gets me there, but just not with the variety I was looking for.
Any suggestions on how to improve upon or completely reconstruct this?
UPDATE:
I have altered the code myself to achieve what I'm looking for.
Here's a fiddle: JSFIDDLE
var counter = 0; var factor = 1;
var timer = setInterval(function () { // timer function for progress bar
counter = counter + factor;
$('.progressbar').val(counter);
if (counter >= 10 && counter <= 59) {
damping = Math.floor(Math.random() * (300 - 25)) + 6;
factor = Math.max((100 - counter) / damping, '0.5');
} else if (counter >= 60 && counter < 100) {
damping = Math.floor(Math.random() * (50 - 25)) + 3;
factor = Math.max((100 - counter) / damping, '0.5');
} else if (counter > 100) {
clearInterval(timer);
};
}, 30);
Related
I cant get my if statements to run it will only run the count down portion but the specifics like when it gets to 5 and 0 it just wont run those extra if statements.
function Countdown()
{
var currTime = 10;
var i = 10;
while (i>=0) {
if (currTime == 5)
{
setTimeout(function () {
document.getElementById("counter").innerHTML = "Warning Less than ½ way to launch, time left = " + currTime;
currTime = currTime - 1;
}, 1000 * i);
i -= 1;
}
if (currTime == 0)
{
document.getElementById("counter").innerHTML = "Blast OFF";
}
else
{
setTimeout(function () {
document.getElementById("counter").innerHTML = "the time left is " + currTime;
currTime = currTime - 1;
}, 1000 * i);
i -= 1; /* same as i = i-1 */
}
};
}
Actually your while loop execute the currTime 11 times here. The main issue is here you are using interval of 1 sec or 1 sec+ etc, but your loop runs very fast in ms of 100 or 500 which excecute currTime very fast. That's the issue here. I hope you got the issue.
how can I add storage in this code?
When a user refreshes the page, I wish that the countdown does not start from 0. Thanks
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function random_countdown(hour_sel, min_sel, sec_sel) {
random_hour = getRandomInt(3, 3)
random_min = getRandomInt(14, 14)
random_sec = getRandomInt(59, 59)
setInterval(function() {
random_sec = random_sec - 1;
if (random_sec < 0) {
random_sec = 59
random_min = random_min - 1
}
if (random_min < 0) {
random_min = 59
random_hour = random_hour - 1
}
jQuery(hour_sel).text(random_hour)
jQuery(min_sel).text(random_min)
jQuery(sec_sel).text(random_sec)
// console.log (random_hour+' '+random_min+' '+random_sec)
}, 1000)
}
random_countdown('.hours_sel', '.minutes_sel', '.seconds_sel')
You can use localStorage to do that in a browser.
This variable has setItem and getItem methods to save and recover data.
You can learn more here
I am trying to make a JS counter to reach a random number and reset it self once it reaches the number and repeat again in 5 seconds.
For example: Random Number is 0.05.
0.00 > 0.01 > 0.02 > 0.03 > 0.04 > 0.05 > 0.00
<div id="current">0</div>
JS
var randomNum = Math.random();
if ( current <= randomNum ) {
for (current = 0; current < randomNum; current+=0.01) {
setInterval(function(){
current += .01;
},1000); } }
else {
current = 0;
}
You could use a closure over the variables and make a check inside of the callback, if greater then the wanted result.
This proposal uses setInterval for counting and setTimeout for the waiting time of 5 sec and the restarting with a new random value.
function startInterval() {
var randomNum = Math.floor(Math.random() * 8) + 2,
current = 0,
interval = setInterval(function() {
current += .01;
if (current > randomNum / 100) {
current = 0;
clearInterval(interval);
setTimeout(startInterval, 5000);
}
document.getElementById('current').innerHTML = current.toFixed(2);
}, 1000);
}
startInterval();
<div id="current">0</div>
Keep a counter variable outside of the loop and then simply clear it, when the desired value is reached.
var randomNum = Math.random() * 25;
var currentValue = 0;
var counter;
counter = setInterval(function() {
if (currentValue < randomNum) {
//Carefull with "0.1" as JavaScript doesn't like it!
currentValue = (currentValue * 10 + 1) / 10
}
if (currentValue > randomNum) {
currentValue = randomNum;
clearInterval(counter);
}
console.log(currentValue, '/', randomNum)
}, 1000 / 60)
I'm trying to create a Roulette/CSGO type wheel, I've cobbled together some solutions I've found over the net. However I can't seem to figure out how to handle the animation / slowing down of the wheel to make it look as smooth as possible.
The basic premise is that I will pass in the winning result number, then the wheel will spin for a minimum desired time (_this.spinTime), then after that it "should" gracefully slow down and then of course land on the correct number.
Here's my code so far (i've commented the key area):
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback, element) {
window.setTimeout(callback, 1000 / 60);
};
})();
SpinWheel = function(id) {
var _this = this;
_this.el = $('.wheel-wrapper');
_this.speed = 0;
_this.startTime = new Date();
_this.items = 20;
_this.itemsWidth = 50;
_this.spinTime = 3000;
_this.running = false;
_this.motion = 20;
_this.resultId = id;
_this.resultOffset = null;
_this.setup = function() {
_this.resultOffset = _this.resultId * _this.itemsWidth;
_this.loop();
};
_this.loop = function() {
_this.running = true;
(function gameLoop() {
_this.update();
//this returns the translateX to 0 once wheel width is met
if (_this.speed >= (_this.items * _this.itemsWidth + _this.itemsWidth)) {
_this.speed = 0;
}
_this.speed += _this.motion;
if (_this.running) {
requestAnimFrame(gameLoop);
}
})();
};
_this.update = function() {
var now = new Date();
_this.el.css({
'transform': 'translateX(-' + _this.speed + 'px)'
});
//the key area!!
//if the time elapsed it greater than the spin time, start the slowing down
if (now - _this.startTime > _this.spinTime) {
//if the x pos == winning pos && the transition speed is at it's slowest
if (_this.speed == _this.resultOffset && _this.motion == 1) {
//stop the animation
_this.running = false;
//here we increment down the slowing down
} else if (_this.speed >= _this.resultOffset) {
if (_this.motion == 2) {
_this.motion = 1;
} else if (_this.speed % _this.motion == 0 && _this.motion > 1) {
_this.motion -= 2;
}
}
return;
}
};
_this.init = function() {
_this.setup();
};
_this.init();
return _this;
};
//will be passed in: 20 = number of items
var resultId = parseInt(Math.random() * 20);
var wheel = new SpinWheel(resultId);
Feel free to rip it apart, if there is a more ideal solution.
Fiddle Here
As can be seen in the fiddle, it kind of works, but it's just not smooth and inconsistent on how it slows down at times etc... So help would be much appreciated.
Thanks in advance!
You need to implement some friction.
Just multiply the speed by a fraction of the desired friction.
speed = speed * friction
speed = speed * 0.8
Higher the fraction, smaller the friction, and slower the deceleration.
EDIT: in your case you may want to apply friction to your motion value, but I'm not entirely sure without running your code.
EDIT 2:
Ok ran your fiddle and I think this is what you are looking for? https://jsfiddle.net/ywm3zbc4/7/
_this.update = function() {
var now = new Date();
_this.el.css({
'transform': 'translateX(-' + _this.speed + 'px)'
});
if (now - _this.startTime > _this.spinTime) {
if (_this.speed == _this.resultOffset && _this.motion == 1) {
_this.running = false;
} else if (_this.speed >= _this.resultOffset) {
_this.motion = _this.motion * 0.99;
}
return;
}
};
I applied the friction to your motion like I mentioned in the previous edit.
EDIT 3 (from comments):
The way to do it is to get the target position, and ease to that while using the modulo of the total width to translate. You can play around with many different animations with this technique, but I settled on the ease-out sine equation.
This can be called a "sliding window animation", think of it as a bar rolling down a track to a specific location.
New fiddle here:
https://jsfiddle.net/ywm3zbc4/10/
Here is the meat of it:
// t: current time
// b: start value
// c: change in value
// d: duration
function easeOutSine(t, b, c, d) {
return c * Math.sin(t/d * (Math.PI/2)) + b;
}
_this.update = function(rafTime) {
var deltaTime = rafTime - _this.startTime;
if (deltaTime >= _this.spinTime) {
_this.running = false;
return;
}
// t = timeFraction
var t = easeOutSine(deltaTime, 0, 1, _this.spinTime);
_this.position = Math.round(t * _this.totalDistance);
var translateX = _this.position % _this.totalWidth;
console.log('translateX:', translateX, 'position:', _this.position, 'deltaTime:', deltaTime);
_this.el.css({
'transform': 'translateX(-' + translateX + 'px)'
});
};
I am building a virtual joystick and this is part of the code that I made so that when the joystick is in between a certain value the x and y value will keep on incrementing by a certain value for instance when the joystick is between 1 and 20 for deltaX it will keep incrementing every second once or if it is in between 21 and 40 it will increment twice every second and I want it to keep incrementing and not staying at the same value of two. When I try this code, the x & y values just stick to 1, 2 or 3 and doesn't increment, could anyone suggest why this happens?
edit:
The If statements need to be outside the function as the joystick breaks and doesn't run if its inside.
if (joystick.deltaX() >= 1 && joystick.deltaX() <= 20) {
(function movex1() {
x = x + 1;
setTimeout(movex1, 1000);
})();
}
if (joystick.deltaX() >= 21 && joystick.deltaX() <= 40) {
(function movex2() {
x = x + 2;
setTimeout(movex2, 1000);
})();
}
if (joystick.deltaX() >= 41 && joystick.deltaX() <= 60) {
(function movex3() {
x = x + 3;
setTimeout(movex3, 1000);
})();
}
if (joystick.deltaY() >= 1 && joystick.deltaY() <= 20) {
(function movey1() {
y = y + 1;
setTimeout(movey1, 1000);
})();
}
if (joystick.deltaY() >= 21 && joystick.deltaY() <= 40) {
(function movey2() {
y = y + 2;
setTimeout(movey2, 1000);
})();
}
if (joystick.deltaY() >= 41 && joystick.deltaY() <= 60) {
(function movey3() {
y = y + 3;
setTimeout(movey3, 1000);
})();
}
When your code executes, joystick.deltaX() and joystick.deltaY() more likely have a value of 0, so no timeout is ever set.
Also, avoid so many ifs when you can just replace them with a division.
Why not use an interval?
var x = 0, y = 0;
// Execute every second
var intervalId = setInterval(function() {
x += Math.ceil(joystick.deltaX() / 20);
y += Math.ceil(joystick.deltaY() / 20);
}, 1000);
// Stop after 20 seconds
setTimeout(function() {
clearInterval(intervalId);
}, 20000)