I have to have two images start on the left side of the screen and move to the right side and stop. Its like a race and whoever get to the right side first wins. I am generating a random number for this just, the images only move to the right once. I cant figure out why they are only moving once, and dont know how I would get them to stop on the right side.
Here's my code:
var myVar1 = setInterval(fly, 250);
function fly() {
var ranNum = Math.floor(Math.random()*2);
if(ranNum == 0){
document.getElementById("race").style.left = '25px';
} else if (ranNum == 1){
document.getElementById("race1").style.left = "25px";
}
}
body { background-image: url(images/stars.jpg); }
.img1 {
position: absolute;
bottom: 0px;
left: 0px;
}
.img2 {
position: absolute;
bottom: 200px;
left: 0px;
}
.img3 {
position: absolute;
top: 0px;
right: 0px;
}
<img src="images/tie.png" class="img1" id="race" alt="tie"></br>
<img src="images/xwing.png" class="img2" id="race1" alt="xwing">
<img src="images/death.png" class="img3" alt="dstar">
The third image(death.png aka death star), when its clicked it changes color and starts the "race" which I would use the onClick method for that, right? So once either the tie fighter or x-wing reaches the "finish line" on the right side, both images stop so we will have a winner. Also if the x-wing wins, I am going to have the dstar change to a dstar blowing up.
You need to increment the values in order to get it to move.
var leftIncrement = parseInt(document.getElementById("race").style.left) + ranNum + "px";
document.getElementById("race").style.left = leftIncrement;
At the moment you are setting it to "25px" every interval.
Try this:
var els = [document.getElementById("race"), document.getElementById("race1")],
timer = setInterval(fly, 250);
function fly() {
var el = els[Math.floor(Math.random()*2)],
newPos = (parseInt(el.style.left) || 0) + 1;
el.style.left = newPos + 'px';
if(newPos == 25) {
clearInterval(timer);
el.classList.add('winner');
}
}
var els = [document.getElementById("race"), document.getElementById("race1")],
timer = setInterval(fly, 250);
function fly() {
var el = els[Math.floor(Math.random()*2)],
newPos = (parseInt(el.style.left) || 0) + 1;
el.style.left = newPos + 'px';
if(newPos == 25) {
clearInterval(timer);
el.classList.add('winner');
}
}
body { background-image: url(images/stars.jpg); }
.img1 {
position: absolute;
bottom: 0px;
left: 0px;
}
.img2 {
position: absolute;
bottom: 200px;
left: 0px;
}
.img3 {
position: absolute;
top: 0px;
right: 0px;
}
.winner {
outline: 3px solid #0f0;
}
<img src="images/tie.png" class="img1" id="race" alt="tie"></br>
<img src="images/xwing.png" class="img2" id="race1" alt="xwing">
<img src="images/death.png" class="img3" alt="dstar">
It's because regardless of what random numbers you are generating, you are always assigned a left style value of 25px.
var left = document.getElementById("race").style.left;
left = left.replace('px','');
left += parseInt(left) + 25;
document.getElementById("race").style.left = left + "px";
Untested but should work.
This works
var racers = [ document.getElementById("race"), document.getElementById("race1") ];
var interval = setInterval( fly, 250 );
function fly() {
var racer = racers[ Math.floor(Math.random() * racers.length) ];
var newPos = parseInt( racer.style.left || 0 ) + 25;
racer.style.left = newPos + "px";
if( (newPos + racer.clientWidth) >= window.innerWidth){
clearInterval( interval );
alert( "And the winner is " + racer.id );
}
}
Here you got it in a JsFiddle http://jsfiddle.net/5poa7tnt/10/
Ask if you need help to understand
Edit : Looks similar to Oriol's post thought
Edit 2 : The race is most beautiful the a step of "1" instead of "25" and an interval of "5" or "10" instead of 250 .. I don't know what final result you want
Related
I have a variable count that triggers a function positiveBar if the value of count is > 0. If the value of count is < 0, it triggers a function negativeBar.
positiveBar changes a div's position using
progressBar.style.left = '50%';
negativeBar changes that same div's position using
progressBar.style.right = '50%';
This gives me the result I want; however, if at any point count becomes greater than 0, the positioning on negativeBar stops working, and it uses the positioning of the positiveBar function instead.
Video to explain:
var count = 0;
// Show count on the page
document.getElementById("countDisplay").innerHTML = count;
// Update count
function updateDisplay() {
countDisplay.innerHTML = count;
};
// Change negative count to an absolute
function absCount() {
return Math.abs(count);
};
function positiveBar() {
progressBar.style.backgroundColor = "#77eb90";
progressBar.style.width = (count * 10) + 'px';
progressBar.style.left = '50%';
};
function negativeBar() {
progressBar.style.backgroundColor = "#ef5c3f";
progressBar.style.width = (absCount() * 10) + 'px';
progressBar.style.right = '50%';
};
// Count up and down when + and - buttons are clicked and edit bar
add1.addEventListener("click", () => {
count++;
updateDisplay();
if (count > 0) {
positiveBar();
} else {
negativeBar();
}
});
subtract1.addEventListener("click", () => {
count--;
updateDisplay();
if (count > 0) {
positiveBar();
} else {
negativeBar();
}
});
.progressBar__Container {
height: 10px;
margin: 20px auto;
border: 1px solid black;
position: relative;
}
#progressBar {
height: 10px;
width: 0;
position: absolute;
}
<div id="countDisplay"></div>
<button id="add1">+</button>
<button id="subtract1">-</button>
<div class="progressBar__Container">
<div id="progressBar"> </div>
</div>
I tried reordering statements. I also tried creating a condition for if count = 0, but that didn't change the result. I'm very confused because it initially works how I intend, but if count becomes greater than 0 at any point, progressBar.style.right = '50%'; stops being applied.
You aren't clearing any previously set left or right styles when you switch from negative to positive and vice versa.
I would use CSS classes to control the position and colour as it's easier to toggle them based on the state of count.
let count = 0;
const countDisplay = document.getElementById("countDisplay");
const progressBar = document.getElementById("progressBar");
// Update count
function updateDisplay() {
countDisplay.textContent = count;
progressBar.style.width = `${absCount() * 10}px`;
progressBar.classList.toggle("positive", count > 0);
progressBar.classList.toggle("negative", count < 0);
};
// Change negative count to an absolute
function absCount() {
return Math.abs(count);
};
// Count up and down when + and - buttons are clicked and edit bar
add1.addEventListener("click", () => {
count++;
updateDisplay();
});
subtract1.addEventListener("click", () => {
count--;
updateDisplay();
});
.progressBar__Container {
height: 10px;
margin: 20px auto;
border: 1px solid black;
position: relative;
}
#progressBar {
height: 10px;
width: 0;
position: absolute;
}
#progressBar.positive {
background-color: #77eb90;
left: 50%;
}
#progressBar.negative {
background-color: #ef5c3f;
right: 50%;
}
<div id="countDisplay">0</div>
<button id="add1">+</button>
<button id="subtract1">-</button>
<div class="progressBar__Container">
<div id="progressBar"> </div>
</div>
See MDN:
When both left and right are defined, if not prevented from doing so by other properties, the element will stretch to satisfy both. If the element cannot stretch to satisfy both — for example, if a width is declared — the position of the element is over-constrained. When this is the case, the left value has precedence when the container is left-to-right; the right value has precedence when the container is right-to-left.
Because you are setting style.left when you then come to set style.right the above applies - i.e. the style.right setting will get overridden.
I am trying to make me character moving left and up and I think jump() and slideLeft()
functions are working properly and the problem is in the controller(e) function (else if (e.KeyCode===37)) . The first function is avaible but it isn't able to acces the second conditon function. Also, I would want to make the grid solid after I will make an slideRight() similar function ,so if my character is jumping on it, the platform would sustain the square . Has anyone any ideea for either of my questions ?
Code snippet:
var square = document.querySelector('.square');
var grid = document.querySelector('.grid');
var bottom = 0;
let isJumping = false;
let isGoingLeft = false;
var newBottom;
let left = 0;
let leftTimerId;
function jump() {
if (isJumping) return
let timerUpId = setInterval(function() {
if (bottom > 250) {
clearInterval(timerUpId);
let timerDownId = setInterval(function() {
if (bottom < 0) {
clearInterval(timerDownId);
isJumping = false;
}
bottom -= 5;
square.style.bottom = bottom + 'px';
}, 20)
}
isJumping = true;
bottom += 30;
square.style.bottom = bottom + 'px';
}, 20)
}
function slideLeft() {
console.log('da');
isGoingLeft = true;
leftTimerId = setInterval(function() {
left -= 5;
square.style.left = left + 'px';
}, 20)
}
function controller(e) {
if (e.keyCode === 32)
jump();
else if (e.KeyCode === 37)
slideLeft();
}
document.addEventListener('keydown', controller);
.grid {
position: absolute;
background-color: chartreuse;
height: 20px;
width: 500px;
bottom: 100px;
left: 100px;
}
.square {
position: absolute;
background-color: darkblue;
height: 100px;
width: 100px;
bottom: 0px;
left: 150px;
}
`
<div class="grid"></div>
<div class="square"></div>
EDIT:
There is a typo:
The second time you've written KeyCode
function controller(e) {
if(e.keyCode===32) {
jump();
}
else if(e.keyCode===37) {
slideLeft();
}
}
I don't really understand what you mean by the second part of your question. If you want a character to have the ability to jump on a square, you'll have to implement a collision detection. Something like this:
if ( isNotOnGround() ) {
fall()
}
I am new to using javascript and jquery so I'm having some problems figuring this one out.
I am trying to use the animate function in jquery to move a box from one corner to the next.
The box begins on the top-left corner of the screen and upon clicking the 'go' button, it will move to the next corner (top-right).
Clicking the same 'go' button then moves the box to the next corner (bottom-right).
Clicking the 'go' button once more will move it to the next corner (bottom-left).
Clicking the 'go' button once more will move it to the next corner (top-left, which is the start).
I've included a picture to show exactly what I mean by this:
What the program should do!
So, this is what I've got so far:
$(document).ready(function () {
$('#go').click(function(){
var dest = parseInt($('#block').css('margin-left').replace('px', '')) + 100;
if (dest > 0) {
$('#block').animate({
marginLeft: '1800px'
}, 0 );
}
else {
$('#block').animate({
marginLeft: dest + 'px'
}, 0 );
}
});
});
#block {
width: 100px;
height: 100px;
background: red;
margin: 0px;
top: 0px;
left: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="block"></div>
<button id="go">» Run</button>
I've got the box to move to the top-right corner but cannot figure out how to make it now move down using the same button.
I've tried something with a toggle but it did not work. That looked something like this:
$(document).ready(function () {
$('#go').click(function(){
var toggle = 1
if (toggle == 1){
$("#block").animate({left: "80px"});
toggle = 0;
} else{
$("#block").animate({right: "80px"});
toggle = 1;
}
});
I was thinking of maybe using cases to switch between which coordinates the button will move the box to. However, I have no knowledge of how this works with jquery and the animate function.
If anyone has any other ideas or knows how to use the case switches in this scenario, I would really appreciate it and thank you in advance!
P.S. I've tried searching this answer on here for a couple of hours now and have not found much that will help me. I am hoping this question will serve to help others who are having a similar problem to mine!
Please try this example:
$(document).ready(function () {
var leftValue = window.innerWidth - 115; // 115 is a temp value
var topValue = window.innerHeight - 115;
var actionNum = 0;
var movingBlock = $('#block');
$('#go').click(function () {
if (actionNum < 4) {
actionNum++;
} else {
actionNum = 1;
}
switch (actionNum) {
case 1:
// move to the top right
movingBlock.animate({
left: leftValue + 'px',
top: 0
}, 1000);
break;
case 2:
// move to the bottom right
movingBlock.animate({
left: leftValue + 'px',
top: topValue + 'px'
}, 1000);
break;
case 3:
// move to the left bottom
movingBlock.animate({
top: topValue + 'px',
left: 0
}, 1000);
break;
case 4:
// move to the top left
movingBlock.animate({
left: 0,
top: 0
}, 1000);
break;
default:
break;
}
});
});
#block {
width: 100px;
height: 100px;
background: red;
margin: 0px;
top: 0px;
left: 0px;
position: relative;
z-index: 1;
}
#go {
z-index: 2;
position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="block"></div>
<button id="go">» Run</button>
There is a multi solution for your problem ,
So I suggest some simple solution , is that you pput position absolute to your div ,
then change (annimate) the left or top of this last after checking conditions ,
you can get top left position in Jquery using .position() funcion ,
See belwon Snippet (added , 1000 milisseconde in order to show annimation transition )
var widh_annimation = "400px";
var hieght_annimation = "100px";
$(document).ready(function () {
$('#go').click(function(){
var position = $("#block").position();
var annimation = {};
if(position.left == 0 && position.top == 0) {
annimation = { left:widh_annimation};
}else if(position.left > 0 && position.top == 0) {
annimation = { top:hieght_annimation};
}else if(position.left > 0 && position.top > 0) {
annimation = { left:"0"};
}else if(position.left == 0 && position.top > 0) {
annimation = { top:"0"};
}
$('#block').animate(annimation, 1000 );
});
});
#block {
width: 100px;
height: 100px;
background: red;
margin: 0px;
top: 0px;
left: 0px;
position:absolute;
}
#go {
position:absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="block"></div>
<button id="go">» Run</button>
I have programmed a bit in JS, but found my projects to become really long and unnecessarily complex. I want to learn OOP JS, and find it much easier to learn when my code get pictured in colors and figures. Here is a little example program:
var box1Left1 = 0;
var box1Left2;
var box2Left1 = 0;
var box2Left2;
setInterval(box1Fly, 10);
function box1Fly() {
// Fly Right
if ( box1Left1 < 300 ) {
box1Left1++;
document.getElementById("box1").style.left = box1Left1 + "px";
box1Left2 = box1Left1;
}
// Fly Left
if ( box1Left1 >= (300) ) {
box1Left2--;
document.getElementById("box1").style.left = box1Left2 + "px";
}
// Fly Right Again
if( box1Left2 == 0 ) { box1Left1 = box1Left2; }
}
setInterval(box2Fly, 10);
function box2Fly() {
// Fly Right
if ( box2Left1 < 300 ) {
box2Left1++;
document.getElementById("box2").style.left = box2Left1 + "px";
box2Left2 = box2Left1;
}
// Fly Left
if ( box2Left1 >= (300) ) {
box2Left2--;
document.getElementById("box2").style.left = box2Left2 + "px";
}
// Fly Right Again
if( box2Left2 == 0 ) { box2Left1 = box2Left2; }
}
<div id="box1" style="position:absolute; top: 10px; left: 0px; width: 50px; height: 50px; background-color: #aa39fc;"></div>
<div id="box2" style="position:absolute; top: 100px; left: 0px; width: 50px; height: 50px; background-color: #2c79f1;"></div>
As you can see, simple things get quite messy! Here is the deal: Can I make only one function, some sort of general function, that can handle both of these two flying boxes at the same time? Instead of, as now, having two functions ( box1Fly & box2Fly ) that are almost duplicates?
Thank you very much, Best Regards!
Would feel happier if the downvoter says why the answer is downvoted and more than happy to edit the answer to make it alright. :)
Why can't you just pass a parameter, which takes in which id should it use? By the way, there's no OO JS in this.
var box1Left1 = 0;
var box1Left2;
var box2Left1 = 0;
var box2Left2;
setInterval('boxFly("box1")', 10);
setInterval('boxFly("box2")', 10);
function boxFly(box_id) {
// Fly Right
if ( box1Left1 < 300 ) {
box1Left1++;
document.getElementById(box_id).style.left = box1Left1 + "px";
box1Left2 = box1Left1;
}
// Fly Left
if ( box1Left1 >= (300) ) {
box1Left2--;
document.getElementById(box_id).style.left = box1Left2 + "px";
}
// Fly Right Again
if( box1Left2 == 0 ) { box1Left1 = box1Left2; }
}
<div id="box1" style="position:absolute; top: 10px; left: 0px; width: 50px; height: 50px; background-color: #aa39fc;"></div>
<div id="box2" style="position:absolute; top: 100px; left: 0px; width: 50px; height: 50px; background-color: #2c79f1;"></div>
To convert into Object Oriented JavaScript, use this:
var box1Left1 = 0;
var box1Left2;
var box2Left1 = 0;
var box2Left2;
var box = function (id) {
this.id = id;
this.fly = function () {
// Fly Right
if ( box1Left1 < 300 ) {
box1Left1++;
document.getElementById(id).style.left = box1Left1 + "px";
box1Left2 = box1Left1;
}
// Fly Left
if ( box1Left1 >= (300) ) {
box1Left2--;
document.getElementById(id).style.left = box1Left2 + "px";
}
// Fly Right Again
if( box1Left2 === 0 ) { box1Left1 = box1Left2; }
};
this.startFlying = function () {
console.log(id);
setInterval(this.fly, 10);
};
};
box1 = new box("box1");
box2 = new box("box2");
box1.startFlying();
box2.startFlying();
<div id="box1" style="position:absolute; top: 10px; left: 0px; width: 50px; height: 50px; background-color: #aa39fc;"></div>
<div id="box2" style="position:absolute; top: 100px; left: 0px; width: 50px; height: 50px; background-color: #2c79f1;"></div>
Help! I've no idea what's going wrong here, I'm following along a tutorial video from Tuts+ The code is exact, yet the blue box is not animating to the left.
When I put an alert inside of the moveBox function, I see in the console the alert firing off the same message over and over again.
Here is my test link:
> Trying to animation a blue box left using Javascript <
Here is a screenshot from the video:
Here is my code:
(function() {
var speed = 10,
moveBox = function() {
var el = document.getElementById("box"),
i = 0,
left = el.offsetLeft,
moveBy = 3;
//console.log("moveBox executed " +(i+1)+ " times");
el.style.left = left + moveBy + "px";
if (left > 399) {
clearTimeout(timer);
}
};
var timer = setInterval(moveBox, speed);
}());
HTML:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>JavaScript 101 : Window Object</title>
<style>
#box {
position: abosolute;
height: 100px;
left: 50px;
top: 50px;
width: 100px;
background-color: Blue;
}
</style>
</head>
<body>
<div id="box"></div>
<script src="js/animation.js"></script>
You mispelled "absolute" in your positioning:
#box {
position: absolute; // Your mispelling here
height: 100px;
left: 50px;
top: 50px;
width: 100px;
background-color: Blue;
}
Once I fixed that, it worked fine.
A word of advice -- put a second condition in loops like this so that if the animation fails for some reason you don't end up in an infinite loop. For example, you might have done this:
(function() {
var maxTimes = 1000;
var loopTimes = 0;
var speed = 10,
moveBox = function() {
var el = document.getElementById("box"),
i = 0,
left = el.offsetLeft,
moveBy = 3;
//console.log("moveBox executed " +(i+1)+ " times");
el.style.left = left + moveBy + "px";
loopTimes += 1;
if (left > 399 || loopTimes > maxTimes) {
clearTimeout(timer);
}
};
var timer = setInterval(moveBox, speed);
}());