How to use setInterval and clearInterval as functions - javascript

I'm using setInterval with jQuery to change the position of a background-image onLoad but I want to use it as a function so I can call clearInterval to stop it when an element is clicked and to call the function again when another element is clicked but panRight() isn't working on load.
function moveImage() {
var x = 0;
x-=1;
$('.bg-img').css('background-position-x', x + 'px');
}
function panRight(){
setInterval(moveImage(),25);
}
// moveImage onLoad
panRight();
$("#stop-animation").click(function(){
clearInterval(panRight);
});
$("#start-animation").click(function(){
panRight();
});
The following code works as intended onLoad and is what I'm trying to refactor as functions.
$(function(){
var x = 0;
setInterval(function(){
x-=1;
$('.bg-img').css('background-position', x + 'px 0');
}, 25);
})

You can do it like this:
function moveImage() {
var x = 0;
x-=1;
$('.bg-img').css('background-position-x', x + 'px');
}
var panInterval; //timer id
function panRight(){
panInterval = setInterval(moveImage,25);
}
// moveImage onLoad
panRight();
$("#stop-animation").click(function(){
clearInterval(panInterval);
});
$("#start-animation").click(function(){
panRight();
});
Here var panInterval is timer id which get returned whenever we call setInterval and which can be use to clear the interval

Related

How do I create several shrek images in a row?

So, I have a page, where when a user holds left mouse button, Shrek images are drawn where his/her cursor is. The problem is, only one picture is created when the mouse is down, but I need an ENDLESS CURRENT OF SHREKS.
Here is the code:
var shrekId = 0;
document.onmousemove = function(event) {
mouseX = event.clientX;
mouseY = event.clientY;
}
window.addEventListener('selectstart', function(e){ e.preventDefault(); });
document.body.onmousedown = function(event) {
shrekId = 0;
interval = setInterval(draw(event), 100);
}
document.body.onmouseup = function() {
clearInterval(interval);
}
function draw(event) {
this["img" + shrekId] = document.createElement("img");
this["img" + shrekId].src = "http://pngimg.com/uploads/shrek/shrek_PNG3.png";
this["img" + shrekId].style = "height: 100px; width: 100px; position: absolute; left: " + (mouseX - 50) + "px; top: " + (mouseY - 50) + "px; x-index: 100;";
this["img" + shrekId].ondragstart = function() { return false; };
document.body.appendChild(this["img" + shrekId]);
shrekId += 1
}
setInterval() takes a function as a parameter, this is done by passing the function name (without the brackets) like so:
myFunc()
{
console.log('hello');
return 1;
}
setInterval(myFunc, 100);
When you do include the brackets (like you did in your example), it will run the function, take the return of that function, and provide that to the setInterval instead.
For example:
myFunc()
{
console.log('hello');
return 1;
}
setInterval(myFunc(), 100);
turns into
setInterval(1, 100);
because myFunc() returns 1.
So you should be able to fix your code by removing the brackets from your interval:
interval = setInterval(draw(event), 100);
// to
interval = setInterval(draw, 100);
Which also means you have to remove the parameter from the function:
function draw(event) {
// to
function draw() {
The problem is with this line: interval = setInterval(draw(event), 100);
The first parameter of setInterval should be a function, but you're calling the function here and passing in the result, try the following instead:
interval = setInterval(() => { draw(event) }, 100);
Or if you aren't supporting ES6:
interval = setInterval(function() { draw(event) }, 100);
It doesn't look like you're using event inside of the draw function though, if that's the case you can just pass the draw function itself:
interval = setInterval(draw, 100);
You are passing the result of executing the function instead of the function itself. Since the result of the function is undefined, you are executing draw and then passing undefined to setInterval which doesn't do anything.
Instead of this:
setInterval(draw(), 100);
Your statement should be this:
setInterval(draw, 100);
without the parentheses at the end of the function name.
When you pass draw() that calls the function immediately and gets it's return value. When you pass draw that passes a reference to the function so setInterval can invoke it in future(which is what you expect).

Image animation with speed control

We have some problem with our image animation with speed control.
It make use of a timeout to change the image, but we want to change the timeout value with a slider, but for some sort of reason, it doesn't work. Can someone help us out ?
We have a Jfiddle here: http://jsfiddle.net/Kbroeren/fmd4xbew/
Thanks! Kevin
var jArray = ["http://www.parijsalacarte.nl/images/mickey-mouse.jpg", "http://www.startpagina.nl/athene/dochters/cliparts-disney/images/donad%20duck-106.jpg", "http://images2.proud2bme.nl/hsfile_203909.jpg"];
var image_count = 0;
function rollover(image_id, millisecs) {
var image = document.getElementById(image_id);
image.src = jArray[image_count];
image_count++;
if (image_count >= jArray.length) {
image_count = 0;
}
var timeout = setTimeout("rollover('" + image_id + "'," + millisecs + ");", millisecs);
}
rollover("img1", 200);
$(function () {
var value;
var $document = $(document),
$inputRange = $('input[type="range"]');
// Example functionality to demonstrate a value feedback
function valueOutput(element) {
var value = element.value,
output = element.parentNode.getElementsByTagName('output')[0];
output.innerHTML = value;
}
for (var i = $inputRange.length - 1; i >= 0; i--) {
valueOutput($inputRange[i]);
};
$document.on('change', 'input[type="range"]', function (e) {
valueOutput(e.target);
rollover("img1", 200);
});
// end
$inputRange.rangeslider({
polyfill: false
});
});
You keep creating more and more infinite function calls without stopping them.
After you call your function the first time, it keeps calling itself.
then you call it again with different interval (millisecs) and it will also start call itself....
You can try two different approach.
1.Use setInterval instead of setTimeout. Use clearInterval to clear the interval before setting it with a new value.
/// Call animation() every 200 ms
var timer = setInterval("Animation()",200);
function ChageSpeed(miliseces){
///Stop calling Animation()
clearInterval(timer);
/// Start calling Animation() every "miliseces" ms
timer = setInterval("Animation()",miliseces);
}
function Animation(){
/// Animation code goes here
}
2.Or, Instead, Set your interval as a global variable (not cool) and just change it value when the user want to change the animation speed.
var millisecs = 200;
function rollover(image_id) {
var image = document.getElementById(image_id);
image.src = jArray[image_count];
image_count++;
if (image_count >= jArray.length) {
image_count = 0;
}
var timeout = setTimeout("rollover('" + image_id + "'," + millisecs + ");", millisecs);
}
$document.on('change', 'input[type="range"]', function (e) {
valueOutput(e.target);
millisecs = YourNewValue;
});

JavaScript simple parameter error

function moveDoi(n) {
var delay = -1;
var left = document.getElementById("One");
var currentLeft = parseInt(getComputedStyle(left).left, 10);
setTimeout(move, delay);
function move(){
if (currentLeft <= n ) {
currentLeft+=3;
left.style.left = currentLeft + "px";
setTimeout(move, delay);
}
}
};
In this code I have n as a parameter of the function, that is used in the if conditional statement.
For this function i need to have one more parameter x that will change the "One" so i need to obtain something like this: document.getElementById(""+x+"") . However, this is not working?
How can I add one more parameter to the function that needs to be in quotes (" ") in function?
First, you need to pass x into the function. Then, you simply need to reference it when calling document.getElementById. There are is no need to append/prepend quotes, since x is already a string.
function moveDoi(n, x) {
var delay = -1;
var left = document.getElementById(x);
var currentLeft = parseInt(getComputedStyle(left).left, 10);
setTimeout(move, delay);
function move(){
if (currentLeft <= n ) {
currentLeft+=3;
left.style.left = currentLeft + "px";
setTimeout(move, delay);
}
}
};

Overriding CSS onclick with while and setTimeOut

I am wanting to change/override the .left property of my css with javascript onclick. This I have managed to do, only I want the property to change in stages (every 1 sec) decrementing by 5em until it reaches 0em. Unfortunately, when I click on the ID to start the function, it just jumps from 30em to 0em. Instead of 30,25,20,15,10,5 etc every 1 sec. Any ideas? (No Jquery please!)
window.onload = function(){
document.getElementById("objection1").onclick = firstScroll;
}
function firstScroll(){
var content = document.getElementById("intB");
var thisNum = 30;
var em = "em";
function doScroll(){
content.style.left = thisNum+em;
}
while(thisNum > 0){
setTimeout(doScroll, 1000);
thisNum -= 5;
}
}
Your problem is when you call the while loop, the next interval is not fired yet, but your thisNum is already set to 0 after finishing the loop. So when the doScroll is fired, thisNum is 0 already.
Try:
window.onload = function(){
document.getElementById("objection1").onclick = firstScroll;
}
var thisNum = 30;
var em = "em";
function firstScroll(){
setTimeout(doScroll, 1000);
}
function doScroll(){
thisNum -= 5;
var content = document.getElementById("intB");
content.style.left = thisNum+em;
if (thisNum > 0){
setTimeout(doScroll, 1000);
}
}
Yes, you're repeatedly decrementing thisNum in a while loop. setTimeout is a function which is called in one second, but the while loop keeps going. doScroll should be decrementing the em value, not a while loop outside. This uses setInterval instead of setTimeout, but either will do..
var intTimer;
function doScroll(){
thisNum -= 5;
content.style.left = thisNum+"em";
if (thisNum <= 0){
window.clearInterval(intTimer);
}
}
intTimer = setInterval( doScroll, 1000);

jQuery animation timeout

I have an animation script implemented with jQuery. The issue is that it does not complete the animation before returning to the parent function. To clarify: the js changes a background color, the js function calls the animate function, the animation function begins, before it finishes it has already returned to the parent and continues on with the next line of js.
function step5(){
/*code*/
currentNode.obj.style.backgroundColor="white";
movePacket(currentNode, objects[currentNode.switchName]);
objects[currentNode.switchName].obj.style.backgroundColor="#ADEBFF";
/*code*/
}
function movePacket(obj1, obj2){
var x = obj2.x - obj1.x;
var y = obj2.y - obj1.y;
$("#packet").animate({"left": "+="+x+"px", "top": "+="+y+"px"}, 3000);
}
I need for the code to wait for the animation to complete and then proceed. Any suggestions?
You should pass it in as a callback function to the animate method:
function step5() {
currentNode.obj.style.backgroundColor = "white";
movePacket(currentNode, objects[currentNode.switchName], function() {
objects[currentNode.switchName].obj.style.backgroundColor = "#ADEBFF";
});
}
function movePacket(obj1, obj2, callback) {
var x = obj2.x - obj1.x;
var y = obj2.y - obj1.y;
$("#packet").animate({
left: "+=" + x + "px",
top: "+=" + y + "px"
}, 3000, callback);
}

Categories

Resources