jQuery animation timeout - javascript

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);
}

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).

How to use setInterval and clearInterval as functions

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

JS : Using a setTimeout inside a setInterval, the setTimeout has no effect

I'm trying to make random images move upwards then return to their original position.
<script>
var looper = setInterval(animateAll, 2000, myArray);
function animateAll(myArray) {
// Gets a random image ID
var randomId = myArray[Math.floor(Math.random()*myArray.length)];
// Make that random icon bounce
bounce(randomId) ;
}
function bounce(randomId) {
var icon = document.getElementById(randomId)
var top = icon.offsetTop;
setTimeout ( icon.style.top = top-20 + "px", 500) ;
setTimeout ( icon.style.top = top + "px", 500) ;
}
</script>
Both setTimeout lines work fine. With only one line, well the images will move without returning to their original position. With both lines, images don't move at all, probably because there's no delay between each.
Thanks for your help !
The problem is that you're executing the code in your setTimeout calls immediately. You're effectively saying "execute the result of setting the icon.style.top = whatever in 500 milliseconds" ... which does nothing.
Try this instead:
icon.style.top = top-20 + "px";
setTimeout ( function() { icon.style.top = top + "px"; }, 500) ;
... and I just blew 15 minutes on this, lol:
var steps = 7;
var increment = (Math.PI) / steps;
var bounceHeight = 20;
function doStep(icon, start, major, minor, height) {
if (minor == steps) {
major--;
height /= 2;
minor = 0;
icon.style.top = start;
}
if (major < 0) {
return;
}
if (minor < steps) {
pos = Math.sin((minor + 1) * increment);
icon.style.top = (start - height * pos) + "px";
setTimeout( function() { doStep(icon, start, major, minor + 1, height); }, 500/steps );
}
}
function bounce(randomId) {
var icon = document.getElementById(randomId)
var top = icon.offsetTop;
setTimeout ( function() { doStep(icon, top, 3, 0, bounceHeight); }, 500/steps ) ;
}
How about moving the image up immediately when you call bounce and then returning it to the original position after a timeout?
function bounce(randomId) {
var icon = document.getElementById(randomId)
var top = icon.offsetTop;
icon.style.top = top-20 + "px";
setTimeout ( icon.style.top = top + "px", 500) ;
}

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);
}
}
};

Categories

Resources