How to stop JavaScript progress bar at a certain point - javascript

I'm using the example progress bar shown in W3Schools.com.
How would I make the progress bar stop at a fixed point, let's say, 90%? I see that it has something to do with the width of the bar, but I can't figure out how to change it to a fixed point, or even a variable.
function move() {
var elem = document.getElementById("myBar");
var width = 10;
var id = setInterval(frame, 10);
function frame() {
if (width >= 100) {
clearInterval(id);
} else {
width++;
elem.style.width = width + '%';
document.getElementById("label").innerHTML = width * 1 + '%';
}
}
}
#myProgress {
position: relative;
width: 100%;
height: 30px;
background-color: #ddd;
}
#myBar {
position: absolute;
width: 10%;
height: 100%;
background-color: #4CAF50;
}
#label {
text-align: center;
line-height: 30px;
color: white;
}
<h1>JavaScript Progress Bar</h1>
<div id="myProgress">
<div id="myBar">
<div id="label">10%</div>
</div>
</div>
<br>
<button onclick="move()">Click Me</button>

Change the condition to width >= 90.
Code:
function move() {
var elem = document.getElementById("myBar");
var width = 10;
var id = setInterval(frame, 10);
function frame() {
/* CHANGE THIS TO 90 */
if (width >= 90) {
clearInterval(id);
} else {
width++;
elem.style.width = width + '%';
document.getElementById("label").innerHTML = width * 1 + '%';
}
}
}
Working sample: https://jsfiddle.net/mspinks/vLfhno9x/

Related

How can I draw JavaScript graphical elements on top of custom image?

I have some Javascript drawing random square elements in the DOM. I have a gif (Image) I want these elements to appear over but they keep appearing underneath the gif. I tried defining z-depth and layout parameters to move these elements on top of the image here, but this produced no difference.
Any assistance in achieving the result (drawing elements onclick, on top of this gif) would be much appreciated.
I ultimately want to draw various other images over this image onclick, restricted to this particular area on top of the gif. If someone can suggest a solution to this as well I would be very much grateful!
(Code features some unused elements from my past attempts)
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="div.css" />
</head>
<body>
<div style="cursor: pointer;" id="boxy" >
<img src="bg.gif" alt="unfinished bingo card" onclick="create()" />
</div>
</div>
<script>
var body = document.getElementsByTagName("body")[0];
var canvas = document.createElement("canvas");
canvas.height = 1300;
canvas.width = 1300;
var context = canvas.getContext("2d");
body.appendChild(canvas);
var rects = [];
function create() {
// Opacity
context.globalAlpha = 0.7;
var color = '#' + Math.round(0xffffff * Math.random()).toString(16);
context.fillStyle = color;
//Each rectangle's size is (20 ~ 100, 20 ~ 100)
var coordx = Math.random() * canvas.width;
var coordy = Math.random() * canvas.width;
var width = Math.random() * 80 + 20;
var height = Math.random() * 80 + 20;
var rect = {
x: coordx,
y: coordy,
w: width,
h: height
}
var ok = true;
rects.forEach(function (item) {
if (isCollide(rect, item)) {
console.log("collide");
ok = false;
} else {
console.log("no collision");
}
})
if (ok) {
context.fillRect(coordx, coordy, width, height);
rects.push(rect);
} else {
console.log('rect dropped');
}
console.log(rects);
}
function isCollide(a, b) {
return !(
((a.y + a.h) < (b.y)) ||
(a.y > (b.y + b.h)) ||
((a.x + a.w) < b.x) ||
(a.x > (b.x + b.w))
);
}
document.getElementById('boxy').addEventListener('click', create);
document.getElementById('canvas').style.position = "relative";
document.getElementById('canvas').style.zIndex = "10";
</script>
</body>
</html>
#my-div {
width: 1300x;
height: 1300px;
z-index: -1;
}
a.fill-div {
display: block;
height: 100%;
width: 100%;
text-decoration: none;
}
#boxy {
display: inline-block;
height: 100%;
width: 100%;
text-decoration: none;
z-index: -1;
}
.canvas {
display: inline-block;
height: 100%;
width: 100%;
text-decoration: none;
z-index: 10;
}
You have to use position:absolute; to take it out of the html flow.
Now anything added after the image will be placed like the image was never there.
img {
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
left: 0;
z-index: -10;
}
div {
font-size: 2rem;
color: white;
}
<img src="https://images.unsplash.com/photo-1664273107076-b6d1fbfb973b?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1171&q=80">
<div>Hello i am on top of the image
</div>

Replace jumping with sliding and then change modes

I was tasked with creating an animation in javascript using an existing code and altering to do two things. Switch modes, and go on until the person closes the program. The four modes are:
mode 0 - left to right
mode 1 - top to bottom
mode 2 - right to left
mode 3 - bottom to top
Switching from mode 0 - 1 is where the trouble starts. It's supposed to slide, but it jumps when I get there.
Below is my code as is.
<!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>
<p><button onclick="myMove()">Click Me</button></p>
<div id ="container">
<div id ="animate"></div>
</div>
<script>
function myMove() {
var elem = document.getElementById("animate");
var pos = 350;
var id = setInterval(frame, 5);
}
function frame() {
if (pos == 0) {
pos++;
elem.style.bottom= pos + 'px';
} else {
pos--;
elem.style.left = pos + "px";
if (pos == 49.985) {
pos++;
elem.style.left = pos + "px";
}
}
I suggest you use two variables for both x and y, and replace posBottom with a variable for top style.
The issue before was that when pos was equal to 0 and thus triggered the if statement, it immediately incremented, causing it to instead trigger the else, and then decremented, going back to if, and so on. It jumped because the style.bottom = 0px was causing it to go straight down to the bottom.
function myMove() {
var elem = document.getElementById("animate");
var posLeft = 350;
var posTop = 0;
var id = setInterval(frame, 5);
function frame() {
if (posLeft == 0 && posTop != 350) {
stage=1;
posTop++;
elem.style.top= posTop + 'px';
} else if (posTop == 0) {
posLeft--;
elem.style.left = posLeft + "px";
} else if (posLeft != 350) {
posLeft++;
elem.style.left = posLeft + "px";
} else if (posTop != 0) {
posTop--;
elem.style.top= posTop + 'px';
}
}
}
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
<p><button onclick="myMove()">Click Me</button></p>
<div id ="container">
<div id ="animate"></div>
</div>

window scroll in not working with if else if

I'm using the scroll function, but the code in my else if blocks do not appear to be executing.
I'm trying to hide one div and show another, once the user scrolls past a certain point.
Here's my code - what am I doing wrong?
var scrolTop = $('.content').offset().top;
var showOneHeight = $('.showOne').height();
var showTwoHeight2 = $('.showTwo').height();
var showThreeHeight3 = $('.showThree').height();
var showFourHeight4 = $('.showFour').height();
var offSetValue = scrolTop + (showOneHeight - 50);
var offSetValue2 = scrolTop + (showTwoHeight2 - 50);
var offSetValue3 = scrolTop + (showThreeHeight3 - 50);
var offSetValue4 = scrolTop + (showFourHeight4 - 50);
// alert(offSetValue3)
$(window).scroll(function() {
var height = $(window).scrollTop();
if (height > offSetValue) {
$('.showOne').fadeOut();
$('.showTwo').fadeIn('slow');
} else if (height > offSetValue2) {
$('.showOne').fadeOut();
$('.showTwo').fadeOut();
$('.showThree').fadeIn('slow');
} else if (height > offSetValue3) {
$('.showOne').fadeOut();
$('.showTwo').fadeOut();
$('.showThree').fadeOut();
$('.showFour').fadeIn();
}
});
body {
margin: 0px;
}
.contentArea {
display: flex;
height: 100vh;
}
.boxes {
width: 50%;
}
.pinned {
background: rgb(72, 91, 35);
}
h1 {
position: relative;
top: 50%;
transform: translateY(-50%);
margin: 0;
padding: 20px;
text-transform: capitalize;
font-family: system-ui;
color: #fff;
}
.content {
position: relative;
}
.box {
position: absolute;
left: 0px;
top: 50%;
transform: translateY(-50%);
display: none;
}
.showOne {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div style="height: 500px; background: violet;"></div>
<div style="height: 500px; background:yellowgreen;"></div>
<div class="contentArea">
<div class="pinned boxes">
<h1>i am pinned side</h1>
</div>
<div class="content boxes">
<div class="box showOne">
<strong>paragraph one</strong>
<p>i am a paragraph. i have more text then a heading mostly too lines i have.</p>
</div>
<div class="box showTwo">
<strong>paragraph two</strong>
<p>i am a paragraph. i have more text then a heading mostly too lines i have.</p>
</div>
<div class="box showThree">
<strong>paragraph three</strong>
<p>i am a paragraph. i have more text then a heading mostly too lines i have.</p>
</div>
<div class="box showFour">
<strong>paragraph three</strong>
<p>i am a paragraph. i have more text then a heading mostly too lines i have.</p>
</div>
</div>
</div>
<div class="test" style="height: 500px; background: rgb(39, 96, 106);"></div>
<div style="height: 500px; background: rgb(46, 35, 46);"></div>
if (height > offSetValue) {
$('.showOne').fadeOut();
$('.showTwo').fadeIn('slow');
} else if (height > offSetValue2) {
$('.showOne').fadeOut();
$('.showTwo').fadeOut();
$('.showThree').fadeIn('slow');
} else if (height > offSetValue3) {
$('.showOne').fadeOut();
$('.showTwo').fadeOut();
$('.showThree').fadeOut();
$('.showFour').fadeIn();
}
The problem is the else if conditions. The else if is not executed because the first condition is ever true when the second and third is true.
You need to specify the range beetween heights are really true:
if ( (height > offSetValue) && (height < offSetValue2)) {
//exec
}
else if ( (height > offSetValue2) && (height < offSetValue3)) {
//exec
}
else if (height > offSetValue3) {
// exec
}
This resolve the problems whit if/else if (Y)
Edit 1:
Try this for confirm:
var scrolTop = $('.content').offset().top;
var showOneHeight = $('.showOne').height();
var showTwoHeight2 = $('.showTwo').height();
var showThreeHeight3 = $('.showThree').height();
var showFourHeight4 = $('.showFour').height();
var offSetValue = scrolTop + 500;
var offSetValue2 = scrolTop + 700;
var offSetValue3 = scrolTop + 900;
var offSetValue4 = scrolTop + 1100;
$(window).scroll(function() {
var height = $(window).scrollTop();
if ( (height > offSetValue) && (height < offSetValue2)) {
console.log(1)
$('.showOne').fadeOut();
$('.showTwo').fadeIn('slow');
$('.showThree').fadeOut();
$('.showFour').fadeOut();
} else if ( (height > offSetValue2) && (height < offSetValue3)) {
console.log(2)
$('.showOne').fadeOut();
$('.showTwo').fadeOut();
$('.showThree').fadeIn('slow');
$('.showFour').fadeOut();
} else if (height > offSetValue3) {
console.log(3)
$('.showOne').fadeOut();
$('.showTwo').fadeOut();
$('.showThree').fadeOut('slow');
}
});

how to make a box reach the edge of a bigger box

javascript beginner here! so i'm trying to do a box(that is inside a larger box) move from the top to the edge of the box. Here's the code:
var boxcont = document.getElementById("boxcont");
var boxbtn = document.getElementById("boxbtn");
boxbtn.addEventListener("click", function() {
var loc = 0;
var timebox = setInterval(boxmove, 5);
function boxmove() {
if (loc == 320) {
clearInterval(timebox);
} else {
loc++;
boxcont.style.top = loc + "px";
boxcont.style.left = loc + "px";
}
}
});
#movebox {
width: 300px;
height: 350px;
background-color: grey;
}
#boxcont {
width: 30px;
height: 30px;
background-color: indianred;
position: relative;
}
<div id="movebox">
<div id="boxcont"></div>
</div>
<button id="boxbtn">Move the box</button>
The problem is that the small box doesn't exactly ends up at the edge, it goes more to the right. I tried doing
boxcont.style.left = (loc - 0.5) + "px";
but doesn't work. pretty sure the solution is simple but as a newbie here it's confusing me :p. Oh and i also tried doing ++ to the 0.5 and Number(0.5) so it reads it as a decimal but still doesn't work!
the big gray box is not set to the correct height and width that corresponds with the small red box's movement. You have it going down 1 and to the right 1 every 5 however, your actually going across a rectangle, not a square. set your width and height the same for the gray box and slightly adjust the stopping point to a little bit less.
var boxcont = document.getElementById("boxcont");
var boxbtn = document.getElementById("boxbtn");
boxbtn.addEventListener("click", function() {
var loc = 0;
var timebox = setInterval(boxmove, 5); // every five milliseconds
function boxmove() {
if (loc == 290) {
clearInterval(timebox);
} else {
loc++;
boxcont.style.top = loc + "px";
boxcont.style.left = loc + "px";
}
}
});
#movebox {
width: 300px;
height: 350px;
background-color: grey;
}
#boxcont {
width: 30px;
height: 30px;
background-color: indianred;
position: relative;
}
<div id="movebox" style = "height: 320px; width: 320px">
<div id="boxcont" ></div>
</div>
<button id="boxbtn">Move the box</button>
if (loc == 270) {
instead of
if (loc == 320) {
Gets you there.
300px is the width of the containing div and the moving div is 30px wide so 300-30=270px
var boxcont = document.getElementById("boxcont");
var boxbtn = document.getElementById("boxbtn");
boxbtn.addEventListener("click", function() {
var loc = 0;
var timebox = setInterval(boxmove, 5);
function boxmove() {
if (loc == 270) {
clearInterval(timebox);
} else {
loc++;
boxcont.style.top = loc + "px";
boxcont.style.left = loc + "px";
}
}
});
#movebox {
width: 300px;
height: 350px;
background-color: grey;
}
#boxcont {
width: 30px;
height: 30px;
background-color: indianred;
position: relative;
}
<div id="movebox">
<div id="boxcont"></div>
</div>
<button id="boxbtn">Move the box</button>

Ribbon animation code too repetitive

I spent the last two days getting a ribbon animation to work with divs so that I can later add li link elements to them to act as a menu. I used the progess bar animation code as inspiration from w3schools. The animation works great, only issue is that the code is very un-DRY. I tried to simplify the code by not repeating myself in the CSS and especially not in the javascript but I kept getting closure issues even after using self invoked functions. I would be greatful if anyone can give me some advice or even a solution that will greatly shorten my code to have the same animation effect. I know that I will have several ribbons on the page, each with different number of ribbon layers, so the code as it is can get very complicated very fast. N.B the code below is the working version.
function move1() {
var width = 0;
var elem = document.getElementById("ribbon-part-1");
var id = setInterval(frame, 1);
function frame() {
if (width >= 100) {
clearInterval(id);
} else {
width++;
elem.style.width = width + '%';
}
}
}
function move2() {
var width = 0;
var elem = document.getElementById("ribbon-part-2");
var id = setInterval(frame, 1)
function frame() {
if (width >= 100) {
clearInterval(id);
} else {
width += 2;
elem.style.width = width + '%';
}
}
}
function move3() {
var width = 0;
var elem = document.getElementById("ribbon-part-3");
var id = setInterval(frame, 1)
function frame() {
if (width >= 100) {
clearInterval(id);
} else {
width += 2;
elem.style.width = width + '%';
}
}
}
function move4() {
var width = 0;
var elem = document.getElementById("ribbon-part-4");
var id = setInterval(frame, 1)
function frame() {
if (width >= 100) {
clearInterval(id);
} else {
width += 2;
elem.style.width = width + '%';
}
}
}
function move5() {
var width = 0;
var elem = document.getElementById("end-ribbon");
var id = setInterval(frame, 1)
function frame() {
if (width >= 100) {
clearInterval(id);
} else {
width += 2;
elem.style.width = width + '%';
}
}
}
function move() {
setTimeout(move1, 300);
setTimeout(move2, 600);
setTimeout(move3, 900);
setTimeout(move4, 1200);
setTimeout(move5, 1500);
}
* {
box-sizing: border-box;
}
.front-ribbon {
position: relative;
/*background-color: grey;*/
height: 23px;
width: 160px;
z-index: 1;
transform: skewY(-11deg);
}
.back-ribbon {
position: relative;
/*background-color: grey;*/
height: 23px;
width: 160px;
transform: skewY(4.7deg);
z-index: -1;
}
#ribbon-part-1 {
background-color: rgb(70, 125, 76);
height: 23px;
width: 0%;
}
#ribbon-part-2 {
background-color: rgb(89, 166, 101);
height: 23px;
width: 0%;
}
/*Including the code below will allow for a reverse progressive bar*/
.front-ribbon #ribbon-part-2 {
display: block;
float: right;
}
#ribbon-part-3 {
background-color: rgb(70, 125, 76);
height: 23px;
width: 0%;
}
#ribbon-part-4 {
background-color: rgb(89, 166, 101);
height: 23px;
width: 0%;
}
/*Including the code below will allow for a reverse progressive bar*/
.front-ribbon #ribbon-part-4 {
display: block;
float: right;
}
#end-ribbon {
fill: rgb(70, 125, 76);
width: 0%;
}
<h1>JavaScript ribbon animation</h1>
<div class="back-ribbon">
<div id="ribbon-part-1"></div>
</div>
<div class="front-ribbon">
<div id="ribbon-part-2"></div>
</div>
<div class="back-ribbon">
<div id="ribbon-part-3"></div>
</div>
<div class="front-ribbon">
<div id="ribbon-part-4"></div>
</div>
<svg id="end-ribbon">
<path d="M-6 17 L35 24 L24 10 Z" />
</svg>
<br>
<br>
<br>
<button onclick="move()">Click Me</button>
Perhaps automate the creation of the different ribbons and their styles with DOM manipulation in the JS body, using ReactJS or similar.

Categories

Resources