javascript setinterval not going back - javascript

//change the speed at which the animations are moving
function spd()
{
var stuff = document.getElementById("speed");
//if start is enabled
//change speed
if ((document.getElementById("stop").disabled == false) && (turbochecker == 0))
{
speed = 50;
interval = setInterval(function(){next(currani);}, speed);
turbochecker = 1;
}
else
{
speed = 250;
interval = setInterval(function(){next(currani);}, speed);
}
}
setting interval the second time keeps increasing the speed by 50. Anyway to make the speed reset back to 250 rather than keep increasing for every 50?

When you want to change the interval frequency, you should clear it first, then set it again:
clearInterval(interval)
interval = setInterval(function(){next(currani);}, speed);

Related

How to have the element removed from the dom in javascript?

I need to make it so that the event here removes the element after it fades out but how would I do that? I got it so that the element fades out from a grid that I am using but I want it to be removed completely as well.
function fadeOut(event){
var op = 1; // initial opacity
var timer = setInterval(function () {
if (op <= 0.1){
clearInterval(timer);
}
event.style.opacity = op;
op -= 0.1;
}, 50);
}
You just need to .remove() it, but you'd want the interval to go for 50 more ms so that there's time for the element to be visible at 0.1 opacity, else it might look a bit off:
function fadeOut(event){
var op = 1; // initial opacity
var timer = setInterval(function () {
if (!op){
clearInterval(timer);
event.remove();
}
event.style.opacity = op;
op -= 0.1;
}, 50);
}
see this article
you can use
elementID.parentNode.removeChild(elementID);
You are catching the event here. Thats means you can get the target. You can use ev.target.remove() to remove it. Hope its work for you.
function fadeOut(event){
var op = 1; // initial opacity
var timer = setInterval(function () {
if (op <= 0.1){
clearInterval(timer);
event.target.remove();
}
event.style.opacity = op;
op -= 0.1;
}, 50);
}

Pure JavaScript - Timed Animation - Consistent height?

I have created a script that animates the height of an element in 500ms.
The timer works fine but I am struggling to make the height increase consistently.
How do I animate the height smoothly within the time period? It jumps at the moment.
I want to replace the following with something smarter:
self.startHeight + 5
I imagine it has something to do with the speed and elapsed time?
https://jsfiddle.net/zrm7xena/1/
(function () {
'use strict';
var animator = {};
animator.endHeight = 200; //The end height
animator.interval = null; //Create a variable to hold our interval
animator.speed = 500; //500ms
animator.startHeight = 0; //The start height
animator.animate = function (el) {
var self = this,
startTime = Date.now(); //Get the start time
this.interval = setInterval(function () {
var elapsed = Date.now() - startTime, //Work out the elapsed time
maxHeight = self.maxHeight; //Cache the max height
//If the elapsed time is less than the speed (500ms)
if (elapsed < self.speed) {
console.log('Still in the timeframe');
//If the client height is less than the max height (200px)
if (el.clientHeight < self.endHeight) {
self.startHeight = self.startHeight + 5; //Adjust the height
el.style.height = self.startHeight + 'px'; //Animate the height
}
} else {
console.log('Stop and clear the interval');
el.style.height = self.endHeight + 'px';
clearInterval(self.interval);
}
}, 16); //60FPS
};
animator.animate(document.getElementById('box'));
}());
Thanks in advance!
Carorus gave a great answer below. I have updated my jsfiddle so you can see the final code working:
https://jsfiddle.net/zrm7xena/8/
Typhoon posted a great link in relation to the browser FPS:
How to determine the best "framerate" (setInterval delay) to use in a JavaScript animation loop?
I would probably use request animation frame instead of a setInterval:
http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
Cheers all!
The harcoded 5 that you are using for the height increment doesn't allow the animation to complete the entire final height (200) in the time that you are setting (500ms), you need to calculate the height increment based on the final height, the animation time and the interval to make it consistent:
(function () {
'use strict';
var animator = {};
animator.endHeight = 200; //The end height
animator.interval = null; //Create a variable to hold our interval
animator.speed = 500; //500ms
animator.startHeight = 0; //The start height
animator.interval = 16;
animator.animate = function (el) {
var self = this,
startTime = Date.now(); //Get the start time
//calculating height variation
self.deltaHeight = (animator.endHeight / animator.speed) * animator.interval;
this.intervalId = setInterval(function () {
var elapsed = Date.now() - startTime, //Work out the elapsed time
maxHeight = self.maxHeight; //Cache the max height
//If the elapsed time is less than the speed (500ms)
if (elapsed < self.speed) {
console.log('Still in the timeframe');
//If the client height is less than the max height (200px)
if (el.clientHeight < self.endHeight) {
self.startHeight = self.startHeight + self.deltaHeight; //Adjust the height
el.style.height = self.startHeight + 'px'; //Animate the height
}
} else {
console.log('Stop and clear the interval');
el.style.height = self.endHeight + 'px';
clearInterval(self.intervalId);
}
}, animator.interval); //60FPS
};
animator.animate(document.getElementById('box'));
}());

How to make function work when the mouse not moving?

$(document).ready(function() {
var score = 0;
$("body").mousemove(function() {
score++;
$("#result").val(score);
console.log(score);
});
});
The score will increase every time when I move the mouse, but how should I add a function to decrease the score until 0 when the mouse is not moving?
You could set an interval that decreases the value if the mouse does not move, and clear it when it moves, and reset it, something like this:
$(document).ready(function() {
var score = 0, decreaseInterval, intervalTime = 1000;
function decrease() {
if (score > 0) score--;
$("#result").val(score);
};
decreaseInterval = setInterval(decrease, intervalTime);
$("body").mousemove(function(){
clearInterval(decreaseInterval);
score ++;
$("#result").val(score);
decreaseInterval = setInterval(decrease, intervalTime);
console.log(score);
});
});
Here is a fiddle to demonstrate it working: https://jsfiddle.net/0swrae76/1/
Option: Use elapsed time. When the mouse is moved, check now() vs last time mouse was moved. Use elapsed time to decrease the score in a chunk.

Make repeated scrollBy smoother like jQuery's animate scrollTop

How can I make a repeated scrollBy call smoother like when animating with jQuery's animate scrollTop?
Currently it is jumpy, the page jumps to and from the different scroll positions. How can I make it smoother?
Here is the scrollBy code:
window.scrollBy(0, -10*(scrollCount ? scrollCount<0 ? -1 : 1 : 0)) , 600*x); })(i);
And here is the for loop that contains it:
for(var i = 0; i < Math.abs(scrollCount); i++){
(function(x){
setTimeout(
window.scrollBy(0, -10*(scrollCount ? scrollCount<0 ? -1 : 1 : 0))
, 600*x); })(i);
}
}
Usage
First add this to your page.
scrollByAnimated = function(scrollY, duration){
var startTime = new Date().getTime();
var startY = window.scrollY;
var endY = startY + scrollY;
var currentY = startY;
var directionY = scrollY > 0 ? 'down' : 'up';
var animationComplete;
var count = 0;
var animationId;
if(duration === undefined){
duration = 250;//ms
}
//grab scroll events from the browser
var mousewheelevt=(/Firefox/i.test(navigator.userAgent))? "DOMMouseScroll" : "mousewheel" //FF doesn't recognize mousewheel as of FF3.x
//stop the current animation if its still going on an input from the user
var cancelAnimation = function () {
if(animationId!==undefined){
window.cancelAnimationFrame(animationId)
animationId=undefined;
}
}
if (document.attachEvent) {
//if IE (and Opera depending on user setting)
document.attachEvent("on"+mousewheelevt, cancelAnimation)
} else if (document.addEventListener) {
//WC3 browsers
document.addEventListener(mousewheelevt, cancelAnimation, false)
}
var step = function (a,b,c) {
var now = new Date().getTime();
var completeness = (now - startTime) / duration;
window.scrollTo(0, Math.round(startY + completeness * scrollY));
currentY = window.scrollY;
if(directionY === 'up') {
if (currentY === 0){
animationComplete = true;
}else{
animationComplete = currentY<=endY;
}
}
if(directionY === 'down') {
/*limitY is cross browser, we want the largest of these values*/
var limitY = Math.max( document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight );
if(currentY + window.innerHeight === limitY){
animationComplete = true;
}else{
animationComplete = currentY>=endY;
}
}
if(animationComplete===true){
/*Stop animation*/
return;
}else{
/*repeat animation*/
if(count > 500){
return;
}else{
count++;
animationId = window.requestAnimationFrame(step);
}
}
};
/*start animation*/
step();
};
Then use it;
scrollByAnimated(100, 250);// change in scroll Y, duration in ms
Explanation
Here's a more robust version than your original code suggested you needed. Additional features include stop scrolling at the top and bottom of the page, uses requestAnimationFrame().
It also only supports scrolling up and down because thats all I need at this time. You'd be a cool, cool person if you added left and right to it.
It has only been tested in Chrome, so your milage may vary.
This code leverages requestAnimationFrame(). First scrollByAnimated() sets variables, then runs step() which loops until the duration has been reached.
At each frame it calculates the animation's completeness as a number from 0 to 1. This is the difference between the startTime and now, divided by duration.
This completeness value is then multiplied by the requested scrollY. This gives us our amount to scroll for each frame. Then we add the startY position to achieve a value that we can use window.scrollTo() to set the frame's position, rather than increment the current position.
try to use animate like this
$('html,body').animate({scrollTop: currentoffset},400);

How do I change my interval within the function itself?

So, this is the code I'm using to set my interval which triggers draw() every 0.1s
var intervalTime = 100;
setInterval(draw, intervalTime);
function draw() {
if( i == 1 ) intervalTime = 50;
}
I want to know how I can change that intervalTime to 50 when i becomes 1. The code above doesn't seem to work like that. It stays at an interval time of 0.1s
var intervalTime = 100;
var interval = setInterval(draw, intervalTime);
function draw() {
if( i == 1 ) {
clearInterval(interval);
interval = setInterval(draw, intervalTime);
}
}

Categories