How do you prevent horizontal interfearing of JS movement? - javascript

I'm working on a school project, we have just started learning JavaScript. I have to make a script that makes something move with JS. Well, I made the following script:
var object = document.getElementById("object");
var omhoog = document.getElementById("omhoog");
var omlaag = document.getElementById("omlaag");
var links = document.getElementById("links");
var rechts = document.getElementById("rechts");
object.style.left = '0px';
object.style.top = '0px';
omlaag.onclick = function()
{
var positiehuidigtop = parseInt(object.style.top);
setInterval(function()
{
if (parseInt(object.style.top)<positiehuidigtop+100)
{
object.style.top = (parseInt(object.style.top) + 10) + 'px';
}
}, 10);
}
links.onclick = function()
{
var positiehuidigleft = parseInt(object.style.left);
setInterval(function()
{
if (parseInt(object.style.left)>positiehuidigleft-100)
{
object.style.left = (parseInt(object.style.left) - 10) + 'px';
}
}, 10);
}
rechts.onclick = function()
{
var positiehuidigleft = parseInt(object.style.left);
setInterval(function()
{
if (parseInt(object.style.left)<positiehuidigleft+100)
{
object.style.left = (parseInt(object.style.left) + 10) + 'px';
}
}, 10);
}
Sorry for the Dutch stuff in there, but it's variables, so the name doesn't really matter.
Anyways, at first I just had the part of the script that made the div move right. Worked like a charm. But when I started adding left, it would interfear. Both directions are sort of fighting.
I really don't know what to do and this stuff is getting my a headache :/

You should use clearInterval to stop the already running interval timer before starting the new one.
var currentInterval;
omlaag.onclick = function() {
clearInterval(currentInterval);
currentInterval = setInterval(
...
);
};
rechts.onclick = function() {
clearInterval(currentInterval);
currentInterval = setInterval(
...
);
};

Related

I have some JavaScript function that keeps repeating itself, I can't find why

This is code that generates a selected image when a function is run, but the image keeps changing, I want this code to let me have one image and keep it that way instead of it changing randomly every 0.5 - 3 seconds, and I don't know why!
const imageSelector = document.querySelector("#changeHeron")
function spinMachine() {
document.getElementById('spinner').disabled = 'disabled';
spinner.style.transform = "rotate(90deg)";
setInterval(enterBall, 1000)
var protmt = prompt("What's your name?")
alert("Hey there " + protmt + ", " + "its great to see you here")
}
function enterBall() {
var ball = document.getElementById("changeHeron");
ball.style.opacity = "100%";
ball.style.transform = "ScaleX(50%) ScaleY(50%)";
setInterval(liftBall, 1000);
}
function liftBall() {
var ball = document.getElementById("changeHeron");
ball.style.transform = "translateY(-250%)";
ball.style.transform = "ScaleX(200%) ScaleY(200%)";
ball.style.top = "40%";
setInterval(changeImage, 1500);
}
function changeImage() {
var images = ["./Images/Football.png", "./Images/Mousetache.png", "./Images/OG.svg"];
var randomNum = Math.floor(Math.random() * images.length);
var ball = document.getElementById("changeHeron");
ball.src = images[randomNum];
ball.style.borderRadius = "5%";
ball.style.backgroundColor = "white";
}
I found that you can place the images varible outside and change it inside when the code has ran so that the rest can just work outside of this problem

Getting the width of an Object and offseting not working

So I'm attempting to set up a rotating banner on my website (viewable at https://www.leapcraft.net) and I have a variable that gets the width of the element and should be offsetting the element not inside of the div by the number of pixels.
I've tried setting the values back to their original offset which fixes it.
var bannerStatus = 1;
var bannerTimer = 4000;
var element = document.getElementById("main-banner");
var positionInfo = element.getBoundingClientRect();
var o = positionInfo.width;
window.onload = function() {
bannerLoop();
}
var startBannerLoop = setInterval(function() {
bannerLoop();
}, bannerTimer);
function bannerLoop() {
if (bannerStatus === 1) {
document.getElementById("imgban2").style.opacity = "0";
setTimeout(function() {
document.getElementById("imgban1").style.right = "0px";
document.getElementById("imgban1").style.zIndex = "1000";
document.getElementById("imgban2").style.right = "-"+ o;
document.getElementById("imgban2").style.zIndex = "1500";
document.getElementById("imgban3").style.right = o;
document.getElementById("imgban3").style.zIndex = "500";
}, 500);
setTimeout(function(){
document.getElementById("imgban2").style.opacity = "1";
}, 1000);
bannerStatus = 2;
}
Expected Results: Rotating banner that is responsive to Width of device that is defined in style.css
Why you can't use css styles to rotate image? Look on my solution, maybe will be useful to you.
function bannerLoop() {
imgBanner[imgNum].style.opacity=1;
imgBanner[imgNum].style.WebkitTransitionDuration='';
imgBanner[imgNum].style.webkitTransform = '';
setTimeout(()=>{
imgBanner[imgNum].style.WebkitTransitionDuration='1s';
imgBanner[imgNum].style.webkitTransform = 'rotate(360deg)';
imgBanner[imgNum].style.opacity=0;
(imgNum<imgBanner.length-1)?imgNum++:imgNum=0
},3000)
}
And here is a working fiddle: https://jsfiddle.net/udtr659y/

Javascript how to end a function

There are 4 horses on my track. https://i.imgur.com/xKFTZ8a.png
I press start and the horses are supposed to complete a lap. I have managed to make them go around the first corner and make them stop at the second corner like so https://i.imgur.com/4uwrBiN.png
Heres my code for the white horse, my problem is that the functions are calling each other constantly and due to this I am unable to go around the second corner due to
positionTop >= window.innerHeight * 0.84 - 50
from horse1 function running and preventing the horse from going left.
var interval = 0;
function startRace() {
var raceTimer = setInterval(100);
var raceActive = true;
loop();
}
function loop() {
interval = setInterval(horse1, 10);
interval = setInterval(horse2, 10);
interval = setInterval(horse3, 10);
interval = setInterval(horse4, 10);
}
function horse1() {
var horse1 = document.getElementById('horse1');
var positionLeft = horse1.offsetLeft;
var positionTop = horse1.offsetTop
horse1.className = 'horse runRight'
if (positionLeft >= window.innerWidth * 0.84 - 50) {
horse1down();
} else {
horse1.style.left = positionLeft + 1 + 'px';
}
}
function horse1down() {
var horse1 = document.getElementById('horse1');
var positionTop = horse1.offsetTop;
horse1.className = 'horse runDown'
if (positionTop >= window.innerHeight * 0.85 - 50) {
horse1left()
} else {
horse1.style.top = positionTop + 1 + 'px';
}
}
function horse1left() {
var horse1 = document.getElementById('horse1');
var positionLeft = horse1.offsetLeft
horse1.style.left = positionLeft - 1 + 'px';
horse1.className = 'horse runLeft'
}
function myLoadFunction() {
var startButton = document.getElementById('start');
startButton.addEventListener('click', startRace);
}
document.addEventListener('DOMContentLoaded', myLoadFunction);
What I have tried:
I have tried clear intervals but I might be doing them wrong.
function horse1down() {
var horse1 = document.getElementById('horse1');
var positionTop = horse1.offsetTop;
horse1.className = 'horse runDown'
if (positionTop >= window.innerHeight * 0.85 - 50) {
horse1left()
clearInterval(interval);
interval = setInterval(horse1, 10);
} else {
horse1.style.top = positionTop + 1 + 'px';
}
}
You are overwriting variable interval.Create an array with 4 different intervals and you will be able to clear them separately.
In general its better to use setTimeout insead of setInterval. You can easily rewrite setInterval function to safer setTimeout. setInterval doesn't care whether the callback is still running or not.
In some cases, the function might need longer than the interval time to finish execution. What would happen is that you'll end up with a bunch of queued requests that may not necessarily return in order.

Javascript help, Trying to animate two different sprites at same time

I need some javascript help. I am trying to set up two sprite animations with different frame rates in two separate div.
Here is a fiddle I started and i am very much stuck.
How do I combine the two div IDs into one statement? OR Should I be using ClassName in the statement to run on both divs?
http://jsfiddle.net/akwilinski/3t7d6qbL/1/
<div id="animate" class="animation"></div>
<div id="animate2" class="animation2"></div>
onload = function startAnimation() {
var frameHeight = 400;
var frames = 27;
var frame = 0;
var div = document.getElementById("animate");
setInterval(function () {
var frameOffset = (++frame % frames) * -frameHeight;
div.style.backgroundPosition = "0px " + frameOffset + "px";
}, 100);
}
Thank you for any assistance!
Simplest way to do this using the method you have already started using is to define 2 new variables, 1 for the second div and one for the second frame count. Then you can just add the call to your function.
Updated js:
onload = function startAnimation() {
var frameHeight = 400;
var frames = 27;
var frame = 0;
var div = document.getElementById("animate");
var div2 = document.getElementById("animate2");
setInterval(function () {
var frameOffset = (++frame % frames) * -frameHeight;
var frameOffset2 = (++frame % frames) * -frameHeight - 10;
div.style.backgroundPosition = "0px " + frameOffset + "px";
div2.style.backgroundPosition = "0px " + frameOffset + "px";
}, 100);
}
Fiddle
http://jsfiddle.net/f4v1vy7x/5/
I made a Can object to store the configuration for each can (so you can have different frameHeights, frames and frameRates.
I used window.requestAnimationFrame because it's far more efficient than setInterval. On each available frame I check whether it's time to animate based on each Can's set frame rate:
var Can = function( selector, frameHeight, frames, frameRate )
{
this.domCan = document.getElementById( selector );
this.frameHeight = frameHeight;
this.frames = frames;
this.frameRate = frameRate;
this.frame = 0;
};
onload = function startAnimation() {
var can1 = new Can( 'animate', 400, 27, 20 );
var can2 = new Can( 'animate2', 400, 27, 100 );
var cans = [ can1, can2 ];
window.requestAnimationFrame( function() {
can1.start = can2.start = new Date();
animate( cans );
} );
};
var animate = function( cans ) {
for( var i = 0; i < cans.length; i++ ) {
var now = new Date();
var can = cans[i];
if( now - can.start >= 1000 / can.frameRate ) {
can.start = now;
var frameOffset = (++can.frame % can.frames) * -can.frameHeight;
can.domCan.style.backgroundPosition = "0px " + frameOffset + "px";
}
}
window.requestAnimationFrame( function() {
animate( cans );
} );
}
You could do something like this:
var div = document.getElementById("animate");
var div2 = document.getElementById("animate2");
function anim(div) {
setInterval(function () {
var frameOffset = (++frame % frames) * -frameHeight;
div.style.backgroundPosition = "0px " + frameOffset + "px";
}, 100);
}
anim(div);
anim(div2);
You could then pass in additional parameters like frameHeight, frame, and frames to further customize each animation.

Javascript gradual width increase

I'm trying to gradually increase the elements of 2 id's in javascript using a Timeout. I can get one working but when trying to call another element into the same function it only does one iteration then crashes after the first recursive call.
I'm passing two id's for the elements. and I want the left element to gradually increase while the right element gradually increases in width.
Heres what ive got
function grow(elementL, elementR)
{
var htL = parseInt(document.getElementById(elementL).style.width,10);
var htR = parseInt(document.getElementById(elementR).style.width,10);
var movementL = htL + 5;
var movementR = htR - 5;
document.getElementById(elementL).style.width = movementL + 'px';
document.getElementById(elementR).style.width = movementR + 'px';
if (movementL > 1000) {
clearTimeout(loopTimer);
return false;
}
var loopTimer = setTimeout('grow(\''+elementL+','+elementR+'\')',50);
}
You could simplify this (removing the script-generation) by using setInterval -- this repeats the function call until you cancel it.
function grow(elementL, elementR)
{
var loopTimer = setInterval(function() {
if (!growStep(elementL, elementR)) {
clearInterval(loopTimer);
}
}, 50);
}
function growStep(elementL, elementR) {
var htL = parseInt(document.getElementById(elementL).style.width,10);
var htR = parseInt(document.getElementById(elementR).style.width,10);
var movementL = htL + 5;
var movementR = htR - 5;
document.getElementById(elementL).style.width = movementL + 'px';
document.getElementById(elementR).style.width = movementR + 'px';
if (movementL > 1000) {
return false;
}
return true;
}
(Fiddle)
Edit
Yeah, I guess the only problem with the OP code is that it passes a string to setTimeout, rather than the function itself:
var loopTimer = setTimeout(function() {
grow(elementL, elementR);
},50);
setTimeout('grow(\''+elementL+','+elementR+'\')',50)
would need to be
setTimeout('grow(\''+elementL+'\',\''+elementR+'\')',50)
// ^^ ^^
to work. But don't do that. Pass a function expression to setTimeout:
setTimeout(function() {
grow(elementL, elementR);
}, 50)

Categories

Resources