How do you make JavaScript animation scroll both to the bottom of an element and back to the top? I am still learning about JavaScript and found an example code from w3schools, which, when I modified it to scroll back to the top, worked in the Tryit Editor, using the exact same code for the myUP function I have below. Though I know that in its current state, combined with the other function, this same code is not currently working.
I have a hunch that there was something not good about the code, even when it worked fine by itself in the Tryit Editor. I feel that in the future it would not work properly. Am I right to assume this, and, if so, what should I be doing to achieve this in JavaScript instead?
<html>
<style>
#myContainer {
width: 500px;
height: 500px;
position: relative;
background: black;
}
#tester {
width: 500px;
height: 50px;
position: absolute;
background-color: gray;
}
</style>
<body>
<p>
<button onmousedown="myMove()">DOWN</button>
</p>
<p>
<button onmousedown="myUP()">UP</button>
</p>
<div id ="myContainer">
<div id ="tester"></div>
</div>
<script>
function myMove() {
var elem = document.getElementById("tester");
var pos = 0;
var id = setInterval(frame, 20);
function frame() {
if (pos == 500) {
clearInterval(id);
} else {
pos++;
elem.style.top = pos + 'px';
}
}
}
function myUP() {
var elem = document.getElementById("tester");
var pos = 0;
var id = setInterval(frame, 20);
function frame() {
if (pos == 500) {
clearInterval(id);
} else {
pos++;
elem.style.bottom = pos + 'px';
}
}
}
</script>
</body>
Check the working code now,
Your code were making problem in UP function.
function myUP() {
var elem = document.getElementById("tester");
var pos = 500;// Changed the max position.
var id = setInterval(frame, 20);
function frame() {
console.log(pos);
if (pos == 0) { //reverse condition to 0
clearInterval(id);
} else {
pos--; // reverse the position
elem.style.top = pos + 'px'; // that should be back to top
}
}
}
<html>
<style>
#myContainer {
width: 500px;
height: 500px;
position: relative;
background: black;
}
#tester {
width: 500px;
height: 50px;
position: absolute;
background-color: gray;
}
</style>
<body>
<p>
<button onmousedown="myMove()">DOWN</button>
</p>
<p>
<button onmousedown="myUP()">UP</button>
</p>
<div id ="myContainer">
<div id ="tester"></div>
</div>
<script>
function myMove() {
var elem = document.getElementById("tester");
var pos = 0;
var id = setInterval(frame, 20);
function frame() {
if (pos == 500) {
clearInterval(id);
} else {
pos++;
elem.style.top = pos + 'px';
}
}
}
function myUP() {
var elem = document.getElementById("tester");
var pos = 500;
var id = setInterval(frame, 5);
function frame() {
console.log(pos);
if (pos == 0) {
clearInterval(id);
} else {
pos--;
elem.style.top = pos + 'px';
}
}
}
</script>
</body>
Related
How to wait for my first function to end before I can click "Click me" button again. I have been searching for a way to let my function end first before I can let the new function run again.
document.getElementById("myBtn").addEventListener("click", myFunction);
setTimeout(function() {
myFunction();
}, 3000);
var id = null;
function myFunction() {
var elem = document.getElementById("myAnimation");
var pos = 0;
clearInterval(id);
id = setInterval(frame, 10);
function frame() {
if (pos == 350) {
clearInterval(id);
} else {
pos++;
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
}
}
}
#myContainer {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#myAnimation {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
<h2>JavaScript addEventListener()</h2>
<button id="myBtn">Click Me</button>
<div id="myContainer">
<div id="myAnimation"></div>
If we disable and enable the button in the correct place, it will work quite nicely
I also cleaned up the code a bit to make it more contained.
window.addEventListener('DOMContentLoaded', () => {
const myBtn = document.getElementById("myBtn");
const elem = document.getElementById("myAnimation");
let id = null;
let pos = 0;
const frame = () => {
if (pos == 350) {
clearInterval(id);
myBtn.disabled = false;
} else {
pos++;
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
}
}
const myFunction = () => {
pos = 0;
clearInterval(id);
id = setInterval(frame, 10);
myBtn.disabled = true;
}
id = setTimeout(myFunction, 3000);
myBtn.addEventListener("click", myFunction);
});
#myContainer {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#myAnimation {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
<h2>JavaScript addEventListener()</h2>
<button id="myBtn">Click Me</button>
<div id="myContainer">
<div id="myAnimation"></div>
</div>
As a first implementation you could disable the button before you start the animation, and you only enable it after you are done
var myBtn = document.getElementById("myBtn")
myBtn.addEventListener("click", myFunction);
setTimeout(function() {
myFunction();
}, 3000);
var id = null;
function myFunction() {
var elem = document.getElementById("myAnimation");
var pos = 0;
clearInterval(id);
id = setInterval(frame, 10);
// disable the button
myBtn.disabled = true;
function frame() {
if (pos == 350) {
clearInterval(id);
// enable the button again
myBtn.disabled = false;
} else {
pos++;
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
}
}
}
#myContainer {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#myAnimation {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
<h2>JavaScript addEventListener()</h2>
<button id="myBtn">Click Me</button>
<div id="myContainer">
<div id="myAnimation"></div>
You should disable your button during your function.
edited: If you don't want to disable maybe with a lock.
document.getElementById("myBtn").addEventListener("click", myFunction);
setTimeout(function() {
myFunction();
}, 3000);
var id = null;
var lock = false;
function myFunction() {
if(!lock){
lock = true;
var elem = document.getElementById("myAnimation");
var pos = 0;
clearInterval(id);
id = setInterval(frame, 10);
function frame() {
if (pos == 350) {
clearInterval(id);
lock = false;
} else {
pos++;
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
}
}
}
}
#myContainer {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#myAnimation {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
<h2>JavaScript addEventListener()</h2>
<button id="myBtn">Click Me</button>
<div id="myContainer">
<div id="myAnimation"></div>
edited: Try making your animation with CSS it's a better practice.
let sum = 0;
const x = 10;
async function firstFunction() {
for (i = 0; i < x; i++) {
sum = sum + i;
}
return sum;
}
async function secondFunction() {
await firstFunction();
console.log('After firstFunction executed sum is', sum);
}
secondFunction();
I have made a progress bar with decrease from width 100 to 0 using setInterval function. So basically every 20ms my width decrease from 1. Then when the width arrives at 0, I set the width to 100 to run the progress bar again. At every loop, I change the text inside my progress bar. What I'd like to do now is change the time interval (the 20ms) at every loop.
Si in my code, when I increase from one, my 20 is replaced by interval[i]... but I am stack to put setInterval inside a loop...
The code below works to change the text at every loop, but don't know how to improve it to change the time interval at every iteration of i...
function move() {
var message = ['test', 'test2', 'test3'];
var interval = [10, 20, 30]
var elem = document.getElementById("myBar");
var width = 100;
var i = 0;
var id = setInterval(frame, 20);
function frame() {
width = width - 1;
elem.style.width = width + "%";
elem.textContent = message[i];
if (width == 0 && i < 3) {
width = 100;
i++;
}
if (i == 3) {
clearInterval(id);
}
}
}
#myProgress {
width: 100%;
background-color: #ddd;
}
#myBar {
width: 100%;
height: 30px;
background-color: #4CAF50;
}
<h1>JavaScript Progress Bar</h1>
<div id="myProgress">
<div id="myBar"> </div>
</div>
<br>
<button onclick="move()">Click Me</button>
<html>
<style>
#myProgress {
width: 100%;
background-color: #ddd;
}
#myBar {
width: 100%;
height: 30px;
background-color: #4CAF50;
}
</style>
<body>
<h1>JavaScript Progress Bar</h1>
<div id="myProgress">
<div id="myBar"> </div>
</div>
<br>
<button onclick="move()">Click Me</button>
<script>
function move() {
var message = ['test','test2','test3'];
var interval = [10,20,30]
var elem = document.getElementById("myBar");
var width = 100;
var i = 0;
var id = setInterval(frame, interval[i]);
function frame() {
width = width - 1;
elem.style.width = width + "%";
elem.textContent = message[i];
if (width == 0 && i < 3) {
width = 100;
i++;
clearInterval(id);
id = setInterval(frame, interval[i]);
}
if (i == 3) {
clearInterval(id);
}
}
}
</script>
</body>
</html>
You could declare a variable outside function move that holds the iteration time step, like:
let iterationStep = 0;
Then inside
let iterationStep = 0;
function move() {
//...blabla
var id = setInterval(frame, interval[iterationStep]);
function frame() {
// blablabla
if (width == 0 && i < 3) {
width = 100;
i++;
// HERE
iterationStep = i;
}
//blablabla
}
}
So each time you are increasing i you are also increasing the value of iterationStep by i value. And it is the value that will be used to access the postition inside the array of intervals of the iteration once you click in move().
I cannot get this to make the square move, I do not get errors, and I have no clue why. I believe the problem originates from the way the keyboard input is processed or the method it is taken in with.
<!DOCTYPE html>
<html>
<style>
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
</style>
<body>
<div id ="container">
<div id ="animate"></div>
</div>
<script>
var pos = 0;
function myMove() {
var elem = document.getElementById("animate");
var id = setInterval(frame, 5);
function frame() {
if (pos == 350) {
clearInterval(id);
} else {
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
}
}
}
function myEventHandler(e) {
var keyCode = e.keyCode;
if(keyCode == 37) {
pos = pos - 1
}
if(keyCode = 39) {
pos = pos + 1
}
}
</script>
</body>
</html>
</body>
</html>
You have not added onkeydown event listener and you haven't called function to update position of element and really don't need setInterval function to do that.
var pos = 100;
function myMove() {
var elem = document.getElementById("animate");
if (pos == 350) {
clearInterval(id);
}
else {
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
}
}
function myEventHandler(e){
var keyCode = e.keyCode;
if(keyCode == 37){
pos = pos - 1;
myMove();
}
if(keyCode = 39){
pos = pos + 1;
myMove();
}
}
document.onkeydown = myEventHandler;
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
<div id ="container">
<div id ="animate"></div>
</div>
You need to make sure you call your routines to initialise the page. So your script should be:
var pos = 0;
function myMove() {
var elem = document.getElementById("animate");
var id = setInterval(frame, 5);
function frame() {
if (pos == 350) {
clearInterval(id);
}
else {
elem.style.top = pos + "px";
elem.style.left = pos + "px";
}
}
}
function myEventHandler(e){
var keyCode = e.keyCode;
if(keyCode == 37){
pos = pos - 1
}
if(keyCode = 39){
pos = pos + 1}
}
// added these initialisation calls
myMove();
document.onkeyup = myEventHandler;
I'm working on a progress bar. It has a label. I want to adjust that label a certain script is finished. After finding some answers of probable solution, I came up with the following script. The first initiates and works as expected. However, the second one doesn't. What's wrong with it? Here's the code:
HTML:
<form method ="post">
<input class=generate type="submit" value="Upload" onclick="move();finalize()"/>
</form>
Javascript:
<script>
function move() {
var elem = document.getElementById("myBar");
var myFunc01 = function() {
var i = 1;
while (i < 101) {
(function(i) {
setTimeout(function() {
i++;
elem.style.width = i + '%';
elem.innerHTML = i + '%';
}, 600 * i)
})(i++)
}
};
myFunc01();
}
</script>
<script>
function finalize() {
var elem = document.getElementById("myBar");
var myFunc02 = function() {
elem.innerHTML = 'Finalizing...';
};
setTimeout(myFunc02, 600);
}
</script>
var elem = document.querySelector('#myBar');
function done() {
elem.innerText = 'UPLOAD HAS FINISHED';
}
var upload = function(callback) {
var width = 1;
var id;
var frame = function() {
if (width >= 100) {
clearInterval(id);
callback();
} else {
width++;
elem.style.width = width + '%';
}
};
id = setInterval(frame, 10);
};
/*
upload(function() {
elem.innerText = 'UPLOAD HAS FINISHED';
});
*/
#myProgress {
width: 100%;
background-color: grey;
}
#myBar {
width: 1%;
height: 30px;
background-color: green;
text-align: center;
line-height: 27px;
}
<button onclick="upload(done)">START UPLOAD</button>
<div id="myProgress">
<div id="myBar"></div>
</div>
You could use a callback. A callback is a function that runs upon completion.
function move(callback) {
//code you want to happen first
}
move(function(){
//code you want to have happen after completion
})
thats the basic idea of how a simple callback works
Thanks James, that's it!
After some re-arranging, this is what the second script looks like. And it works as expected.
<script>
function finalize() {setTimeout(function(){
var elem = document.getElementById("myBar");
var myFunc02 = function() {
elem.innerHTML = 'Finalizing...';
};
myFunc02();
}
, 600);}
</script>
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>