Animation using Javascript - javascript

I want the div to slide from left to right, and then back again from right left when it reaches the end of the browser using JavaScript.
var imgObj = null;
var animate;
function init() {
imgObj = document.getElementById('animate');
imgObj.style.position = 'fixed';
imgObj.style.left = '0px';
moveRight();
}
function moveRight() {
imgObj.style.left = parseInt(imgObj.style.left) + 1 + '%';
if (imgObj.style.left == '95%') {
clearTimeout(animate)
alert("i am here")
moveLeft();
}
animate = setTimeout(moveRight, 20);
}
function moveLeft() {
imgObj.style.left = parseInt(imgObj.style.left) - 1 + '%';
if (imgObj.style.right == '95%') {
clearTimeout(animate)
alert('i am here2')
moveRight();
}
animate = setTimeout(moveLeft, 20);
}
window.onload = init;
#animate {
width: 5%;
height: 10%;
background-color: red;
}
<div id="animate"></div>

This is an example of a similar animation, started by the button.You should always use variables to change values and not just hardcorde values to elements. In this case pos is the variable that gets changed (pos++ and pos--) and then added to the style-property.
In your Code i think you never stop increasing the % value. So it gets stuck in a scenario where it does +1 -1 +1 -1 forever.
function myMove() {
var elem = document.getElementById("myAnimation");
var pos = 0;
var id = setInterval(frame, 10);
function frame() {
if (pos == 100) {
clearInterval(id);
alert("done");
myMove2();
} else {
pos++;
elem.style.left = pos + '%';
}
}
}
function myMove2() {
var elem = document.getElementById("myAnimation");
var pos = 100;
var id = setInterval(frame, 10);
function frame() {
if (pos == 0) {
clearInterval(id);
alert("done2");
myMove();
} else {
pos--;
elem.style.left = pos + '%';
}
}
}
#myAnimation {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
<p>
<button onclick="myMove()">Click Me</button>
</p>
<div id ="myAnimation"></div>

Related

Stop javascript "animation" onclick div

I'm a beginner in javascript and I'm trying to make a very simple game. I know that my code is not the best, but i want to make it working. I want to stop function nahoru() or make it move to the other way and after it touches the bottom of the page/100%, make it repeat.
<html>
<head>
<script>
function naloud() {
var elem = document.getElementById("krtek");
elem.style.top = '100%';
var eleme = document.getElementById("krtek2");
eleme.style.top = '100%';
var elemen = document.getElementById("krtek3");
elemen.style.top = '100%';
}
var pos = 100;
var los = 0;
function nahoru() {
var elemend = document.getElementById("batn");
elemend.style.opacity = '0';
var elem = document.getElementById("krtek");
var id = setInterval(frame, 30);
function frame() {
if (pos == 0) {
clearInterval(id);
document.write('<center>GAME OVER<br>YOUR SCORE: ' + skore +
'<br>Press F5 for restart.')
} else {
pos = pos - 1;
elem.style.top = pos + '%';
}
}
}
var skore = 0;
function pric() {
skore++;
document.getElementById("skore").innerHTML = "Skore: " + skore;
elem.style.top = '+100%';
}
</script>
<style>
.prvni {
position: absolute;
width: 10%;
height: 110%;
left: 10%;
background-color: brown;
}
.druhy {
position: absolute;
width: 10%;
height: 110%;
left: 45%;
background-color: brown;
}
.treti {
position: absolute;
width: 10%;
height: 110%;
left: 80%;
background-color: brown;
}
</style>
</head>
<body onload="naloud()">
<button onclick="nahoru()" id="batn">START</button>
<div id="skore">Skore: 0</div>
<div id="krtek" class="prvni" onclick="pric()"></div>
<div id="krtek2" class="druhy" onclick="pric()"></div>
<div id="krtek3" class="treti" onclick="pric()"></div>
</body>
</html>
Declare id outside nahoru function,
like here
var pos = 100;
var los = 0;
var id = null;
Set interval in nahoru function,
like this (important, remove var from here)
id = setInterval(frame, 30);
Now clear interval in pric function
like this
function pric(elem) {
skore++;
clearInterval(id);
document.getElementById("skore").innerHTML = "Skore: " + skore;
elem.style.top = '+100%';
}
Working https://jsfiddle.net/ee1bdL5k/
You need declare this var outside from function, for the pric function:
var elem, eleme, elemen;
function naloud() {
elem = document.getElementById("krtek");
elem.style.top = '100%';
eleme = document.getElementById("krtek2");
eleme.style.top = '100%';
elemen = document.getElementById("krtek3");
elemen.style.top = '100%';
}

Can't start and stop animation that runs in a constant loop

To simplify this question I have created two divs: when you click on the orange box the blue box below it will move back and forth in a continuous loop. What I want to be able to do is:
Click the orange box to start and STOP the blue box loop
After starting and stopping, the blue box will stop and continue each time where it left off.
I've tried just about everything and can't get it to work. Any advice would be greatly appreciated.
var hoverSlideBox = document.getElementById("hover_slide_box");
var slidingBox = document.getElementById("sliding_box");
hoverSlideBox.onclick = function() {
var pos = 0;
var moveLeft = false;
var stopAnimate = false;
init();
function init() {
setInterval(boxRight, 5);
}
function boxRight() {
if (!moveLeft) {
pos++;
slidingBox.style.left = pos + 'px';
}
if (pos == 500 || moveLeft) {
moveLeft = true;
boxLeft();
}
}
function boxLeft() {
if (moveLeft) {
pos--;
slidingBox.style.left = pos + 'px';
}
if (pos == 0 || !moveLeft) {
moveLeft = false;
}
}
}
<div id="hover_slide_box" style="background-color: #ff931e; cursor: pointer; position: absolute; height: 100px; width: 100px;"></div>
<div id="sliding_box" style="top: 120px; background-color: #0071bc; cursor: pointer; position: absolute; height: 100px; width: 100px;"></div>
You need to move some variables out of the onclick function so that they are not reset each time you click on the orange box. That, together with clearInterval, will give you a start/stop button.
var hoverSlideBox = document.getElementById("hover_slide_box");
var slidingBox = document.getElementById("sliding_box");
var running = false;
var intervalId;
var pos = 0;
var moveLeft = false;
hoverSlideBox.onclick = function() {
init();
function init() {
if (!running) {
intervalId = setInterval(boxRight, 5);
running = true;
} else {
clearInterval(intervalId);
running = false;
}
}
function boxRight() {
if (!moveLeft) {
pos++;
slidingBox.style.left = pos + 'px';
}
if (pos == 500 || moveLeft) {
moveLeft = true;
boxLeft();
}
}
function boxLeft() {
if (moveLeft) {
pos--;
slidingBox.style.left = pos + 'px';
}
if (pos == 0 || !moveLeft) {
moveLeft = false;
}
}
}
<div id="hover_slide_box" style="background-color: #ff931e; cursor: pointer; position: absolute; height: 100px; width: 100px;"></div>
<div id="sliding_box" style="top: 120px; background-color: #0071bc; cursor: pointer; position: absolute; height: 100px; width: 100px;"></div>
To do this, you can use clearInterval to stop the movement. To make it resume when you click again, you just need to have your position variable in a permanent scope (I move it to the global scope for simplicity).
Changed code:
var pos = 0;
var moveLeft = false;
var stopAnimate = false;
var slideInterval;
hoverSlideBox.onclick = function() {
init();
function init() {
if (slideInterval) {
clearInterval(slideInterval);
slideInterval = null;
} else {
slideInterval = setInterval(boxRight, 5);
}
}
Snippet:
var hoverSlideBox = document.getElementById("hover_slide_box");
var slidingBox = document.getElementById("sliding_box");
var pos = 0;
var moveLeft = false;
var stopAnimate = false;
var slideInterval;
hoverSlideBox.onclick = function() {
init();
function init() {
if (slideInterval) {
clearInterval(slideInterval);
slideInterval = null;
} else {
slideInterval = setInterval(boxRight, 5);
}
}
function boxRight() {
if (!moveLeft) {
pos++;
slidingBox.style.left = pos + 'px';
}
if (pos == 500 || moveLeft) {
moveLeft = true;
boxLeft();
}
}
function boxLeft() {
if (moveLeft) {
pos--;
slidingBox.style.left = pos + 'px';
}
if (pos == 0 || !moveLeft) {
moveLeft = false;
}
}
}
<div id="hover_slide_box" style="background-color: #ff931e; cursor: pointer; position: absolute; height: 100px; width: 100px;"></div>
<div id="sliding_box" style="top: 120px; background-color: #0071bc; cursor: pointer; position: absolute; height: 100px; width: 100px;"></div>
setInterval returns interval id which you can use to cancel the interval using clearInterval
You could cancel the timer as the other answer says, or use requestAnimationFrame which is specifically designed for animations like these. See documentation here
This way we can simply check if stopAnimating is set before queueing up our next frame. You could do the same thing with setInterval if you wanted to, but requestAnimationFrame is probably better.
var hoverSlideBox = document.getElementById("hover_slide_box");
var slidingBox = document.getElementById("sliding_box");
hoverSlideBox.onclick = function() {
var pos = 0;
var moveLeft = false;
var stopAnimate = false;
init();
function init() {
animate();
}
function animate(){
// stop animating without queueing up thenext frame
if (stopAnimate) return;
//queue up theh next frame.
requestAnimationFrame(boxRight);
}
function boxRight() {
if (!moveLeft) {
pos++;
slidingBox.style.left = pos + 'px';
}
if (pos == 500 || moveLeft) {
moveLeft = true;
boxLeft();
}
animate();
}
function boxLeft() {
if (moveLeft) {
pos--;
slidingBox.style.left = pos + 'px';
}
if (pos == 0 || !moveLeft) {
moveLeft = false;
}
}
}
<div id="hover_slide_box" style="background-color: #ff931e; cursor: pointer; position: absolute; height: 100px; width: 100px;"></div>
<div id="sliding_box" style="top: 120px; background-color: #0071bc; cursor: pointer; position: absolute; height: 100px; width: 100px;"></div>
Your code doesn't clear the interval when box is clicked again. setInterval executes a function every number of given seconds. To stop it, you have use the function clearInterval, passing the timer id that the function setInterval returned.
Also, your code can be better organized. I've refactorized it base in the following advices:
Don't use different functions for each direction. Your code have two different functions (moveLeft and moveRight) that are almost the same. Instead, use a simpler function that increments position given the current direction. Use a simple variable with the position increment, using -1 for left movement and +1 for right movement. If you have to modify the way the box moves you only have to change the moveBox function.
Use a function to check if the box have reached the boundaries. In general is good to have small functions that do one simple thing. In your code, boundaries check is splited in the two movement functions. In the proposed code the check code is a separate function where you can modify boundaries easily in the future if needed, instead of changing them in different places of your code.
Don't put all your logic in the click listener. Again, use simple functions that perform one simple task. The click listener should do a simple task, that's switching animation on and off. Initialization code should be in its onw function.
Again, for simplicity, use a simple function as the function executed by setInterval. If not, you would have to change the function that is executed by the setInterval function: moveRight when box is moving to the right and moveLeft when the box is moving to the left. This makes the code more complex and hard to debug and mantain.
Those advices are not very useful with a small code like this, but its benefits are more visible when your code gets more complex.
var hoverSlideBox = document.getElementById("hover_slide_box");
var slidingBox = document.getElementById("sliding_box");
var pos = 0;
var direction = 1;
var animate = false;
var intervalHandler;
hoverSlideBox.onclick = function() {
if (animate) {
stop();
}
else {
init();
}
}
function init() {
animate = true;
intervalHandler = setInterval(moveBox, 5);
}
function stop() {
animate = false;
clearInterval(intervalHandler);
}
function tic() {
if (animate) {
moveBox();
}
}
function checkBoundaries() {
if (pos == 500) {
direction = -1;
}
else if (pos == 0) {
direction = 1;
}
}
function moveBox() {
pos += direction;
slidingBox.style.left = pos + 'px';
checkBoundaries();
}
<div id="hover_slide_box" style="background-color: #ff931e; cursor: pointer; position: absolute; height: 100px; width: 100px;"></div>
<div id="sliding_box" style="top: 120px; background-color: #0071bc; cursor: pointer; position: absolute; height: 100px; width: 100px;"></div>
Try this snippet, it should work aswell
var hoverSlideBox = document.getElementById("hover_slide_box");
var slidingBox = document.getElementById("sliding_box");
var moveLeft = false;
var pos = 0;
var intervalID = null;
hoverSlideBox.onclick = function(){
if (intervalID) {
clearInterval(intervalID);
intervalID = null;
} else {
intervalID = setInterval(function () {
pos += moveLeft ? -1 : 1;
slidingBox.style.left = pos + 'px';
moveLeft = pos >= 500 ? true : pos <= 0 ? false : moveLeft;
}, 5);
}
}
<div id="hover_slide_box" style="background-color: #ff931e; cursor: pointer; position: absolute; height: 100px; width: 100px;">
<div id="sliding_box" style="top: 120px; background-color: #0071bc; cursor: pointer; position: absolute; height: 100px; width: 100px;">

how to make progress Bar with numbers

i have a progress bar which has to finish at 100%, and this moment the number shows this progress, the problem is this number is 1.5(it has to show 0.1, 0,2 and so on till number - 1.5) and I don't know how bind the progress bar with this number
$(function() {
var x = document.getElementById("load");
var width = 0;
x.innerHTML = width;
var int = setInterval(move, 20);
function move() {
if (width == 100) {
clearInterval(int);
} else {
width += 1;
x.style.width = width + "%";
x.innerHTML = width + "%";
}
}
});
Do width/100 and use toFixed() to determine the number of decimals.
$(function() {
var x = document.getElementById("load");
var width = 0;
x.innerHTML = width;
var int = setInterval(move, 20);
function move() {
if (width == 100) {
clearInterval(int);
} else {
width += 1;
x.style.width = width + "%";
x.innerHTML = ((width / 100).toFixed(1)) + "%";
}
}
});
#load {
position: fixed;
height: 100%;
display: flex;
align-items: center;
background-color: #000;
color: #fff;
font-size: 50px;
justify-content: flex-end;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="load" />
This is more a math problem than a scripting one...
You have to tell the script that 1.5 is 100%.
I only added one line to your script in order to change the inner HTML displayed.
var showNumber = (1.5/100)*width;
x.innerHTML = showNumber.toFixed(1);
$(function() {
var x = document.getElementById("load");
var width = 0;
x.innerHTML = width;
var int = setInterval(move, 200); // Setted a longer delay...
function move() {
if (width == 100) {
clearInterval(int);
} else {
width += 1;
x.style.width = width + "%";
var showNumber = (1.5/100)*width;
x.innerHTML = showNumber.toFixed(1); // Only one decimal.
}
}
});
#load{
background-color:blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="load"></div>

Creating Toggle effect in Javascript

I am just starting to learn about Javascript for animation. I have created this super simple example, which when clicked moves 3 blocks from a central position, to top, top-left and top-right position (I am building up to a sort of Context Action button type thing). But I would now like to be able to click again and if the animation is "out", then it will execute in reverse. I tried adding an if else, using the elem1.style.bottom == 350 parameter to define whether pos would increment or decrement, but it didn't work. Similarly, I was unable to get a clicked boolean to persist between clicks.
JSFiddle
html:
<body>
<p>
<button onclick="myMove()">Click Me</button>
</p>
<div id ="container">
<div id ="animate1"></div>
<div id ="animate2"></div>
<div id ="animate3"></div>
</div>
</body>
css:
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate1 {
width: 50px;
height: 50px;
left: 175px;
bottom: 175px;
position: absolute;
background-color: red;
z-index:3;
}
#animate2 {
width: 50px;
height: 50px;
left: 175px;
bottom: 175px;
position: absolute;
background-color: blue;
}
#animate3 {
width: 50px;
height: 50px;
left: 175px;
bottom: 175px;
position: absolute;
background-color: green;
}
Javascript:
function myMove() {
var elem1 = document.getElementById("animate1");
var elem2 = document.getElementById("animate2");
var elem3 = document.getElementById("animate3");
var start = 350;
var pos = 175;
var id = setInterval(frame, 5);
var clicked = false;
function frame() {
if (pos == 350) {
clearInterval(id);
clicked = !clicked;
} else {
if (clicked == false){ pos++; } else { pos--;}
elem1.style.bottom = pos + 'px';
elem1.style.left = start - pos + 'px';
elem2.style.bottom = pos + 'px';
elem2.style.left = pos + 'px';
elem3.style.bottom = pos + 'px';
}
}
}
How would I achieve this?
I think this is what you want: http://jsfiddle.net/3pvwaa19/20/
It creates a variable to keep track of whether the animation has happened and it moves your pos variable to the same location - - outside of the main function, so that the values won't get lost after each click:
var moved = false;
var pos = 175;
Yes, you can do it with if(elem1.style.bottom =="350px") {...}else{...:
function myMove() {
var elem1 = document.getElementById("animate1");
var elem2 = document.getElementById("animate2");
var elem3 = document.getElementById("animate3");
if (elem1.style.bottom == "350px"){
var start = 175;
var pos = 350;
var id = setInterval(frame, 5);
function frame() {
if (pos == 175) {
clearInterval(id);
} else {
pos--;
elem1.style.bottom = pos + 'px';
elem1.style.left = 2*start - pos + 'px';
elem2.style.bottom = pos + 'px';
elem2.style.left = pos + 'px';
elem3.style.bottom = pos + 'px';
}
}
} else {
var start = 350;
var pos = 175;
var id = setInterval(frame, 5);
function frame() {
if (pos == 350) {
clearInterval(id);
} else {
pos++;
elem1.style.bottom = pos + 'px';
elem1.style.left = start - pos + 'px';
elem2.style.bottom = pos + 'px';
elem2.style.left = pos + 'px';
elem3.style.bottom = pos + 'px';
}
}
}
}

Less javascript code for this loop animation?

I've done this simple animation but i have a feeling i've writted to much lines of code for such a simple task. Is there a way to achieve the same result but with less code ?
https://jsfiddle.net/qw82Lwy0/1/
function myMove() {
var elem = document.getElementById("animate");
var pos = 0;
var id = setInterval(frame, 5);
var flag = true;
function frame() {
if (flag) {
pos++;
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
if (pos == 350) {
flag = false;
}
} else if (!flag) {
pos--;
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
if (pos == 0) {
flag = true;
}
}
}
}
P.S: No jquery or css animation, just javascript.
instead of using the flag and a seperate code for the 2 conditions you could just flip the incrementer like so:
function myMove() {
var elem = document.getElementById("animate");
var pos = 0;
var id = setInterval(frame, 5);
var changeVal = 1;
function frame() {
pos+=changeVal;
if ((pos >= 350) || (pos <= 0)) changeVal *= -1;
elem.style.top = elem.style.left = pos + 'px';
}
}
Animations can now be done in modern browsers using CSS. For example, your javascript animation can be condensed to just a few lines using a CSS transition.
See MDN for more details and examples of transitions and animations.
Run the code snippet below to try
window.ball.addEventListener('transitionend', toggle);
function toggle() {
window.ball.classList.toggle('move');
}
.animation {
position: relative;
background-color: lightyellow;
border: 1px solid gray;
height: 200px;
width: 200px;
}
#ball {
transition-property: left top background-color;
transition-duration: 2s;
position: absolute;
background-color: red;
border-radius: 12px;
height: 25px;
width: 25px;
left: 0;
top: 0;
}
#ball.move {
background-color: blue;
left: 175px;
top: 175px;
}
<button onclick="toggle()">Start</button>
<div class="animation"><div id="ball"></div></div>
Well, you could shorten your frame() function like so:
function myMove() {
var elem = document.getElementById("animate");
var pos = 0;
var id = setInterval(frame, 5);
var flag = true;
function frame() {
if (flag) {
pos++;
if (pos == 350) {
flag = false;
}
} else { // since you are checking if flag is true, the only other answer is false
pos--;
if (pos == 0) {
flag = true;
}
}
elem.style.top = pos + 'px'; // since this occurs in both cases
elem.style.left = pos + 'px'; // you can do it afterward
}
}
Use a function with 3 paraneters : posAdd, flagValue and posValue
function frame(posAdd,flagValue,posValue) {
if (flagValue) {
pos=pos+posAdd;
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
if (pos == posValue) {
flag = !flagValue;
}
}
}
And call it twice : frame(1,true,350)
And frame(-1,false,0)

Categories