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);
}());
Related
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>
There is a pattern game in which the user is supposed to find 1 missed picture from right side while the location is shown on left, then if the user guessed correctly they will go to the next level.
My problem is that, even though I clicked on correct picture, the popup for wrong choice is appearing after the first iteration.
I tried to define body as the initial child but still popup is displaying regardless of correct or wrong choice.
var numberOfFaces = 5;
var theLeftSide = document.getElementById("leftSide");
var theRightSide = document.getElementById("rightSide");
var theBody = document.getElementsByTagName("body")[0];
function generateFaces() {
for (var i = 0; i < numberOfFaces; i++) {
var createImg = document.createElement("IMG");
var randPositionTop = Math.floor(Math.random() * 400);
var randPositionleft = Math.floor(Math.random() * 400);
createImg.setAttribute("src", "http://home.cse.ust.hk/~rossiter/mooc/matching_game/smile.png");
createImg.style.top = randPositionTop + "px";
createImg.style.left = randPositionleft + "px";
theLeftSide.appendChild(createImg);
}
var leftSideImages = theLeftSide.cloneNode(true);
leftSideImages.removeChild(leftSideImages.lastChild);
theRightSide.appendChild(leftSideImages);
theLeftSide.lastChild.onclick =
function nextLevel(event) {
event.stopPropagation;
numberOfFaces += 5;
alert("Next level!");
while (theLeftSide.firstChild) {
theLeftSide.removeChild(theLeftSide.firstChild);
}
generateFaces();
}
theBody.onclick =
function gameOver() {
theBody.onclick = null;
theLeftSide.lastChild.onclick = null;
alert("Game Over!");
};
}
#leftSide {
background-color: red;
position: absolute;
width: 500px;
height: 500px;
left: 50px;
}
#rightSide {
position: absolute;
left: 600px;
width: 500px;
height: 500px;
--border-left: solid 10px;
}
img {
position: absolute;
width: 50px;
height: 50px;
}
<link rel="stylesheet" href="style.css">
<body onload="generateFaces()">
<h3>Matching Game</h3>
<h5>Please choose missed smile !</h5>
<div id="leftSide">
</div>
<div id="rightSide">
</div>
<script src="jsCode.js"></script>
</body>
Updated your fiddle. Is this how you want it?
https://jsfiddle.net/ychq5rkm/12/
Specifically it uses document.ready() in the js instead of in the onload in the html. As was mentioned in the comments, you needed to actually call event.stopPropegation() because it was continuing up to the body each time and ending your game.
I'm trying to learn Java Script Animations and I found really good examples on this site: http://javascript.info/tutorial/animation#maths-the-function-of-progress-delta
But the problem is, as a beginner, I don't understand how the functions and objects work with each other.
Question 01
I copied the example "Let’s create a movement animation on it’s base:" But my version does not work.
<!DOCTYPE HTML>
<html>
<head>
<style>
.example_path{
position: relative;
width: 600px;
height: 100px;
border-style: solid;
border-width: 5px;
}
.example_block{
position: absolute;
width: 100px;
height: 100px;
background-color: yellow;
}
</style>
</head>
<body>
<div onclick="move(this.children[0])" class="example_path">
<div class="example_block"></div>
</div>
<script>
function move(element, delta, duration) {
var to = 500
animate({
delay: 10,
duration: duration || 1000, // 1 sec by default
delta: delta,
step: function(delta) {
element.style.left = to*delta + "px"
}
})
}
</script>
</body>
</html>
output console: ReferenceError: animate is not defined
Does anyone know what the problem is?
Question 02
My second wish is, to integrate the easeInOut function
function makeEaseInOut(delta) {
return function(progress) {
if (progress < .5)
return delta(2*progress) / 2
else
return (2 - delta(2*(1-progress))) / 2
}
}
bounceEaseInOut = makeEaseInOut(bounce)
How can I link both code snippets? The code is also from this page: http://javascript.info/tutorial/animation#maths-the-function-of-progress-delta
Add animate and makeEaseInOut into your script tag then you can use them. You may want to include the functions in a separate JavaScript file eventually.
<script>
function animate(opts) {
var start = new Date
var id = setInterval(function() {
var timePassed = new Date - start
var progress = timePassed / opts.duration
if (progress > 1) progress = 1
var delta = opts.delta(progress)
opts.step(delta)
if (progress == 1) {
clearInterval(id)
}
}, opts.delay || 10)
}
function makeEaseInOut(delta) {
return function(progress) {
if (progress < .5)
return delta(2*progress) / 2
else
return (2 - delta(2*(1-progress))) / 2
}
}
bounceEaseInOut = makeEaseInOut(bounce)
</script>
that's what I tried.
I still have problems.
output console: delta is not a function. bounce is not a function.
I know I have to learn more about creating functions. But right now I'm not that good to solve the problem.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
.example_path{
position: relative;
width: 600px;
height: 100px;
border-style: solid;
border-width: 5px;
}
.example_block{
position: absolute;
width: 100px;
height: 100px;
background-color: yellow;
}
</style>
<script>
function move(element, delta, duration) {
var to = 500;
animate({
delay: 10,
duration: duration || 1000, // 1 sec by default
delta: delta,
step: function(delta) {
element.style.left = to*delta + "px"
}
});
}
function animate(opts) {
var start = new Date;
var id = setInterval(function() {
var timePassed = new Date - start;
var progress = timePassed / opts.duration;
if (progress > 1) progress = 1
var delta = opts.delta(progress);
opts.step(delta);
if (progress == 1) {
clearInterval(id);
}
}, opts.delay || 10);
}
function makeEaseInOut(delta) {
return function(progress) {
if (progress < .5)
return delta(2*progress)/2;
else
return (2 - delta(2*(1-progress)))/2;
};
}
varbounceEaseInOut = makeEaseInOut(bounce);
</script>
</head>
<body>
<div onclick="move(this.children[0], makeEaseInOut(bounce), 3000)" class="example_path">
<div class="example_block"></div>
</div>
</body>
</html>
I've made a very simple animation using javascript, hope it helps, try to "Run code snippet" for better understanding.
/*JavaScript*/
function myMove() {
var elem = document.getElementById("animate");
var pos = 0;
var id = setInterval(frame, 5);
function frame() {
if (pos == 350) {
clearInterval(id);
} else {
pos++;
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
}
}
}
function Back() {
var elem1 = document.getElementById("animate");
var id1 = setInterval(frame2, 5);
var pos1 = 350;
function frame2() {
if (pos1 == 0) {
clearInterval(id1);
} else {
pos1--;
elem1.style.top = pos1 + 'px';
elem1.style.left = pos1 + 'px';
}
}
}
/*CSS*/
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
/*HTML*/
<button onclick="myMove()">Click Me</button>
<button onclick="Back()"> roll back</button>
<div id ="container">
<div id ="animate"></div>
</div>
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
This is a function thats supposed to move an image slowly to the right, it isnt working... what did i mess up?
<script type="text/javascript">
var userWidth = window.screen.width;
function moveRight(id, speed) {
var pp = document.getElementById(id);
var right = parseInt(pp.style.left);
var tim = setTimeout("moveRight(id, speed)",50);
right = right+speed; // move
if (right > window.screen.height / 2)
{
right=0;
pp.style.left = right+"px";
}
}
</script>
Looks like id and speed aren't getting passed into moveRight(). When they're in the string as you have them they won't get evaluated. Have a look at this, it seems to do the trick. I stripped it down a little.
<div id="test" style="width: 50px; height: 50px; left: 0px; background-color: #000; position: absolute;"> </div>
<script type="text/javascript">
function moveRight(id, speed) {
var pp = document.getElementById(id);
var right = parseInt(pp.style.left) || 0;
right += speed; // move
pp.style.left = right + "px";
var move = setTimeout(function() {
moveRight(id, speed);
}, 50);
}
moveRight('test', 1);
</script>
A jsfiddle to play with. You can tweak it to your liking.