How to make a circle progress bar with left side of percentage - javascript

const numb = document.querySelector(".numb");
let counter = 0;
setInterval(() => {
if (counter == 100) {
clearInterval();
} else {
counter += 1;
numb.textContent = counter + "%";
}
}, 80);
#import url('https://fonts.googleapis.com/css?family=Poppins:400,500,600,700&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
html,
body {
display: grid;
height: 100%;
text-align: center;
place-items: center;
background: #dde6f0;
}
.circular {
height: 100px;
width: 100px;
position: relative;
}
.circular .inner,
.circular .outer,
.circular .circle {
position: absolute;
z-index: 6;
height: 100%;
width: 100%;
border-radius: 100%;
box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.2);
}
.circular .inner {
top: 50%;
left: 50%;
height: 80px;
width: 80px;
margin: -40px 0 0 -40px;
background-color: #dde6f0;
border-radius: 100%;
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
}
.circular .circle {
z-index: 1;
box-shadow: none;
}
.circular .numb {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 10;
font-size: 18px;
font-weight: 500;
color: #4158d0;
}
.circular .bar {
position: absolute;
height: 100%;
width: 100%;
background: #fff;
-webkit-border-radius: 100%;
clip: rect(0px, 100px, 100px, 50px);
}
.circle .bar .progress {
position: absolute;
height: 100%;
width: 100%;
-webkit-border-radius: 100%;
clip: rect(0px, 50px, 100px, 0px);
}
.circle .bar .progress,
.dot span {
background: #4158d0;
}
.circle .left .progress {
z-index: 1;
animation: left 4s linear both;
}
#keyframes left {
100% {
transform: rotate(180deg);
}
}
.circle .right {
z-index: 3;
transform: rotate(180deg);
}
.circle .right .progress {
animation: right 4s linear both;
animation-delay: 4s;
}
#keyframes right {
100% {
transform: rotate(180deg);
}
}
.circle .dot {
z-index: 2;
position: absolute;
left: 50%;
top: 50%;
width: 50%;
height: 10px;
margin-top: -5px;
animation: dot 8s linear both;
transform-origin: 0% 50%;
}
.circle .dot span {
position: absolute;
right: 0;
width: 10px;
height: 10px;
border-radius: 100%;
}
#keyframes dot {
0% {
transform: rotate(-90deg);
}
50% {
transform: rotate(90deg);
z-index: 4;
}
100% {
transform: rotate(270deg);
z-index: 4;
}
}
<!DOCTYPE html>
<!-- Created By CodingNepal -->
<html lang="en" dir="ltr">
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<!-- Somehow I got an error, so I comment the title, just uncomment to show -->
<!-- <title>Circular Progress Bar | CodingNepal</title> -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="circular">
<div class="inner">
</div>
<div class="outer">
</div>
<div class="numb">
0%</div>
<div class="circle">
<div class="dot">
<span></span>
</div>
<div class="bar left">
<div class="progress">
</div>
</div>
<div class="bar right">
<div class="progress">
</div>
</div>
</div>
</div>
</body>
</html>
I want to make a progress bar like the one in the image below. The percentage should be on left side up to 90% and after 90%, it will go to the center.
How can I do that?

You can position the .numb at the desired place in the beginning, define another css class .numb-center which has top and left 50% to make it center and add that class to .numb when it's your desired percentage in setInterval function.
const numb = document.querySelector(".numb");
let counter = 0;
setInterval(() => {
if (counter == 100) {
clearInterval();
} else {
counter += 1;
if (counter > 90 && !numb.classList.contains('.numb-center')) {
numb.classList.add('numb-center')
}
numb.textContent = counter + "%";
}
}, 80);
#import url('https://fonts.googleapis.com/css?family=Poppins:400,500,600,700&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
html,
body {
display: grid;
height: 100%;
text-align: center;
place-items: center;
background: #dde6f0;
}
.circular {
height: 100px;
width: 100px;
position: relative;
}
.circular .inner,
.circular .outer,
.circular .circle {
position: absolute;
z-index: 6;
height: 100%;
width: 100%;
border-radius: 100%;
box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.2);
}
.circular .inner {
top: 50%;
left: 50%;
height: 80px;
width: 80px;
margin: -40px 0 0 -40px;
background-color: #dde6f0;
border-radius: 100%;
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
}
.circular .circle {
z-index: 1;
box-shadow: none;
}
.circular .numb {
position: absolute;
top: 5%;
left: 40%;
transform: translate(-50%, -50%);
z-index: 10;
font-size: 18px;
font-weight: 500;
color: #4158d0;
}
.numb-center {
top:50%!important;
left:50%!important;
}
.circular .bar {
position: absolute;
height: 100%;
width: 100%;
background: #fff;
-webkit-border-radius: 100%;
clip: rect(0px, 100px, 100px, 50px);
}
.circle .bar .progress {
position: absolute;
height: 100%;
width: 100%;
-webkit-border-radius: 100%;
clip: rect(0px, 50px, 100px, 0px);
}
.circle .bar .progress,
.dot span {
background: #4158d0;
}
.circle .left .progress {
z-index: 1;
animation: left 4s linear both;
}
#keyframes left {
100% {
transform: rotate(180deg);
}
}
.circle .right {
z-index: 3;
transform: rotate(180deg);
}
.circle .right .progress {
animation: right 4s linear both;
animation-delay: 4s;
}
#keyframes right {
100% {
transform: rotate(180deg);
}
}
.circle .dot {
z-index: 2;
position: absolute;
left: 50%;
top: 50%;
width: 50%;
height: 10px;
margin-top: -5px;
animation: dot 8s linear both;
transform-origin: 0% 50%;
}
.circle .dot span {
position: absolute;
right: 0;
width: 10px;
height: 10px;
border-radius: 100%;
}
#keyframes dot {
0% {
transform: rotate(-90deg);
}
50% {
transform: rotate(90deg);
z-index: 4;
}
100% {
transform: rotate(270deg);
z-index: 4;
}
}
<!DOCTYPE html>
<!-- Created By CodingNepal -->
<html lang="en" dir="ltr">
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<!-- Somehow I got an error, so I comment the title, just uncomment to show -->
<!-- <title>Circular Progress Bar | CodingNepal</title> -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="circular">
<div class="inner">
</div>
<div class="outer">
</div>
<div class="numb">
0%</div>
<div class="circle">
<div class="dot">
<span></span>
</div>
<div class="bar left">
<div class="progress">
</div>
</div>
<div class="bar right">
<div class="progress">
</div>
</div>
</div>
</div>
</body>
</html>

Related

How to change the text on certain points

Using the below code it will display the single text with percentage loader but i am trying add multiple text instead of single, basically i am rshiny developer no i started learning html and css code it wil be useful if i get any idea on how to change the text on certain points
i have tried this keyframe anim i dont know y its not working
#keyframes anim{
10%{
content:'Stage 1';
}
25%{
content:'Stage 2';
}
50%{
content:'Stage 3';
}
75%{
content:'Stage 4';
}
100%{
content:'Completed';
}
}
const analyse=document.getElementById('analyse');
const numb = document.querySelector(".number");
let counter = 0;
let id1;
let cnt = 0;
id1 = setInterval(() => {
if (counter == 100) {
fetch.style.display='inline-block';
clearInterval(id1);
} else {
counter += 1;
numb.innerHTML = counter + "%";
fetch.style.display='none';
}
}, 120);
html, body{
display:inline-block;
height:100%;
text-align: left;
place-items: left;
background: #dde6f0;
}
.circular{
height:100px;
width: 100px;
margin-left: 43%;
margin-top:10%;
position: absolute;
display: inline-block;
/* transform:scale(2); */
}
.circular .inner{
position: absolute;
z-index: 6;
top: 50%;
left: 50%;
height: 80px;
width: 80px;
margin: -40px 0 0 -40px;
background: #dde6f0;
border-radius: 100%;
}
.circular .number{
position: absolute;
top:50%;
left:50%;
transform: translate(-50%, -50%);
z-index:10;
font-size:18px;
font-weight:500;
color:#4158d0;
}
.circular .bar{
position: absolute;
height: 100%;
width: 100%;
background: #fff;
border-radius: 100%;
clip: rect(0px, 100px, 100px, 50px);
}
.circle .bar .progress{
position: absolute;
height: 100%;
width: 100%;
border-radius: 100%;
clip: rect(0px, 50px, 100px, 0px);
background: #4158d0;
}
.circle .left .progress{
z-index:1;
animation: left 6s linear both;
}
#keyframes left{
100%{
transform: rotate(180deg);
}
}
.circle .right {
transform: rotate(180deg);
z-index:3;
}
.circle .right .progress{
animation: right 6s linear both;
animation-delay:6s;
}
#keyframes right{
100%{
transform: rotate(180deg);
}
}
.text::after{
animation:anim 10s linear both;
}
<html>
<head>
<link rel="stylesheet" href="TestTwoCss.css">
</head>
<body>
<div class="container">
<div id="analyse">
<div class="text">Analysing...</div>
<div class="circular">
<div class="inner"></div>
<div class="number">0%</div>
<div class="circle">
<div class="bar left">
<div class="progress"></div>
</div>
<div class="bar right">
<div class="progress"></div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
you can use switch and change analyze text base on counter .
const analyzeText = document.querySelector("#analyse .text");
const numb = document.querySelector(".number");
let counter = 0;
let id1;
let cnt = 0;
id1 = setInterval(() => {
if (counter == 100) {
// fetch.style.display='inline-block';
clearInterval(id1);
} else {
counter += 1;
numb.innerHTML = counter + "%";
// fetch.style.display='none';
changeText(counter); // change analyze text base on counter value.
}
}, 110);
function changeText() {
switch (counter) {
case 1:
analyzeText.innerHTML = "Stage 1";
break;
case 25:
analyzeText.innerHTML = "Stage 2";
break;
case 50:
analyzeText.innerHTML = "Stage 3";
break;
case 75:
analyzeText.innerHTML = "Stage 4";
break;
case 100:
analyzeText.innerHTML = "Completed";
break;
}
}
html, body{
display:inline-block;
height:100%;
text-align: left;
place-items: left;
background: #dde6f0;
}
.circular{
height:100px;
width: 100px;
margin-left: 43%;
margin-top:10%;
position: absolute;
display: inline-block;
/* transform:scale(2); */
}
.circular .inner{
position: absolute;
z-index: 6;
top: 50%;
left: 50%;
height: 80px;
width: 80px;
margin: -40px 0 0 -40px;
background: #dde6f0;
border-radius: 100%;
}
.circular .number{
position: absolute;
top:50%;
left:50%;
transform: translate(-50%, -50%);
z-index:10;
font-size:18px;
font-weight:500;
color:#4158d0;
}
.circular .bar{
position: absolute;
height: 100%;
width: 100%;
background: #fff;
border-radius: 100%;
clip: rect(0px, 100px, 100px, 50px);
}
.circle .bar .progress{
position: absolute;
height: 100%;
width: 100%;
border-radius: 100%;
clip: rect(0px, 50px, 100px, 0px);
background: #4158d0;
}
.circle .left .progress{
z-index:1;
animation: left 6s linear both;
}
#keyframes left{
100%{
transform: rotate(180deg);
}
}
.circle .right {
transform: rotate(180deg);
z-index:3;
}
.circle .right .progress{
animation: right 6s linear both;
animation-delay:6s;
}
#keyframes right{
100%{
transform: rotate(180deg);
}
}
<html>
<head>
<!-- <link rel="stylesheet" href="TestTwoCss.css"> -->
</head>
<body>
<div class="container">
<div id="analyse">
<div class="text">Analysing...</div>
<div class="circular">
<div class="inner"></div>
<div class="number">0%</div>
<div class="circle">
<div class="bar left">
<div class="progress"></div>
</div>
<div class="bar right">
<div class="progress"></div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

How can i create a dynamic progress bar

I am trying to create a progress bar which looks like the first image above but end up getting the second image as a result.
I am using html, CSS and JavaScript. where did I get it wrong? Or is there something I am missing out?
the black dots are not really that important to me as I am interested in the shape of the progress bar
const numb = document.querySelector(".number");
let counter = 0;
setInterval(() => {
if(counter == 65 ){
clearInterval();
}else{
counter+=1;
numb.textContent = counter + "%";
}
}, 80);
*{
margin: 0;
padding: 0;
font-family: 'Arial', sans-serif;
}
html, body{
display:grid;
height:100%;
text-align: center;
place-items: center;
background: #dde6f0;
}
.circular{
height:120px;
width: 120px;
position: relative;
transform:scale(2);
}
.circular .inner{
position: absolute;
z-index: 6;
top: 50%;
left: 50%;
height: 80px;
width: 80px;
margin: -40px 0 0 -40px;
background: #dde6f0;
border-radius: 100%;
}
.circular .number{
position: absolute;
top:50%;
left:50%;
transform: translate(-50%, -50%);
z-index:10;
font-size:18px;
font-weight:500;
color:#4158d0;
}
.circular .bar{
position: absolute;
height: 100%;
width: 100%;
background: #fff;
-webkit-border-radius: 100%;
clip: rect(0px, 120px, 120px, 70px);
}
.circle .bar .progress{
position: absolute;
height: 100%;
width: 100%;
-webkit-border-radius: 100%;
clip: rect(0px, 70px, 120px, 0px);
background: #FF6600;
}
.circle .left .progress{
z-index:1;
animation: left 4s linear both;
}
#keyframes left{
100%{
transform: rotate(180deg);
}
}
.circle .right {
transform: rotate(180deg);
z-index:3;
}
.circle .right .progress{
animation: right 4s linear both;
animation-delay:4s;
}
#keyframes right{
100%{
transform: rotate(180deg);
}
}
<div class="circular">
<div class="inner"></div>
<div class="number">100%</div>
<div class="circle">
<div class="bar left">
<div class="progress"></div>
</div>
<div class="bar right">
<div class="progress"></div>
</div>
</div>
</div>
I fiddled with it until it worked.
Changed the clip on .circular .bar and .circle .bar .progress to
clip: rect(0px, 120px, 120px, 60px); and respectively clip: rect(0px, 60px, 120px, 0);
const numb = document.querySelector(".number");
let counter = 0;
setInterval(() => {
if(counter == 65 ){
clearInterval();
}else{
counter+=1;
numb.textContent = counter + "%";
}
}, 80);
*{
margin: 0;
padding: 0;
font-family: 'Arial', sans-serif;
}
html, body{
display:grid;
height:100%;
text-align: center;
place-items: center;
background: #dde6f0;
}
.circular{
height:120px;
width: 120px;
position: relative;
transform:scale(2);
}
.circular .inner{
position: absolute;
z-index: 6;
top: 50%;
left: 50%;
height: 80px;
width: 80px;
margin: -40px 0 0 -40px;
background: #dde6f0;
border-radius: 100%;
}
.circular .number{
position: absolute;
top:50%;
left:50%;
transform: translate(-50%, -50%);
z-index:10;
font-size:18px;
font-weight:500;
color:#4158d0;
}
.circular .bar{
position: absolute;
height: 100%;
width: 100%;
background: #fff;
-webkit-border-radius: 100%;
clip: rect(0px, 120px, 120px, 60px);
}
.circle .bar .progress{
position: absolute;
height: 100%;
width: 100%;
-webkit-border-radius: 100%;
clip: rect(0px, 60px, 120px, 0);
background: #FF6600;
}
.circle .left .progress{
z-index:1;
animation: left 4s linear both;
}
#keyframes left{
100%{
transform: rotate(180deg);
}
}
.circle .right {
transform: rotate(180deg);
z-index:3;
}
.circle .right .progress{
animation: right 4s linear both;
animation-delay:4s;
}
#keyframes right{
100%{
transform: rotate(180deg);
}
}
<div class="circular">
<div class="inner"></div>
<div class="number">100%</div>
<div class="circle">
<div class="bar left">
<div class="progress"></div>
</div>
<div class="bar right">
<div class="progress"></div>
</div>
</div>
</div>

Responsive menu in JavaScript

I have an issue with js. I want to make an responsive menu. I mean when I am on start page the start page is on first place on the list. If I am on contact page the contact is first in the list. var planet = ["Start","Contact", "First","Second", "Third", "Fourth", "Fifth", "Sixth"]; <div class="name_container"><p class="pn">Start</p><p class="more">READ MORE</p></div> The menu is a circle with icons that are moving on it. First element in list is on bottom of the circle. On conclusion I need change the list dinamicly in js script depends on subpage i am on. I know i can create several js files and it will work, but i wonna try it by js or HTML or u have some ideas.
Thanks from any help
var element = document.getElementById('mobile_control');
var hammertime = new Hammer(element);
hammertime.get('swipe').set({ direction: Hammer.DIRECTION_ALL });
hammertime.on('swipeleft', function(ev) {
cmove("prev");
});
hammertime.on('swiperight', function(ev) {
cmove("next");
});
$(".action").on("click", function(){
cmove($(this).attr('id'));
});
$('.title').each(function(){
$(this).html("Earth".replace("<span class='letter'>$&</span>"));
});
var angle = 0;
var planet_id = 0;
function cmove(dir){
var n_planet = 8, next_id;
var prev, next;
var top = $("#pl"+ planet_id);
var orbit = $(".planet_container");
top.removeClass("pt");
if(planet_id == 0){
prev = $("#pl"+ (n_planet-1));
next = $("#pl"+ (planet_id+1)%n_planet);
}else{
prev = $("#pl"+ (planet_id-1));
next = $("#pl"+ (planet_id+1)%n_planet);
}
if(dir == "prev"){
next_id = (planet_id + 1) % n_planet;
angle -= 45;
next.addClass("pt");
planet_id++;
}else{
if(planet_id == 0){
next_id = 7;
planet_id = 7;
}else{
next_id = planet_id-1;
--planet_id;
}
angle += 45;
prev.addClass("pt");
}
$('.pn').each(function(){
$(this).html(planet[next_id].replace( "<span class='letter'>$&</span>"));
});
anime.timeline({})
.add({
targets: '.pn .letter',
translateX: [40,0],
translateZ: 0,
opacity: [0,1],
easing: "easeOutExpo",
duration: 1200,
delay: function(el, i) {
return 500 + 30 * i;
}
});
orbit.css("transform", "rotateZ(" + angle + "deg)");
}
var planet = ["Start","Contact", "First","Second", "Third", "Fourth", "Fifth", "Sixth"];
let loocation_path = location.pathname.split('/');
var path = loocation_path[loocation_path.length - 1];
switch(path){
case 'index.html':
while(planet[0] != 'Start'){
let head = planet.shift();
planet.push(head);
};
var nazwa = document.getElementById('show_pathname');
nazwa.innerHTML = "Start";
break;
case 'contact.html':
while(planet[0] != 'Contact'){
let head = planet.shift();
planet.push(head);
};
var nazwa = document.getElementById('show_pathname');
nazwa.innerHTML = "Contact";
break;
}
const planets = document.querySelectorAll('.moon');
var moon_id = 0;
function moon(direction){
var n_planet = 8, moon_next;
if(direction == "prev"){
moon_next = (moon_id + 1) % n_planet;
moon_id++;
} else {
if(moon_id == 0){
moon_next = 7;
moon_id = 7;
} else {
moon_next = moon_id - 1;
--moon_id;
}
};
planets.forEach( ( planet, i ) => {
if ( i === moon_next ) {
planet.style.visibility = 'visible';
} else {
planet.style.visibility = 'hidden';
}
} );
};
body {
color: #444444;
font-size: 1rem;
margin: 0;
padding: 0;
}
.t-site-header {
padding-top: 20px;
height: 30vh;
}
.full_container {
position: relative;
display: block;
width: 100vmin;
height: 100%;
margin: auto;
z-index: 100;
}
.full_container .bottom {
position: absolute;
transform: rotate(180deg);
top: 0;
width: 100%;
height: 28vh;
}
.full_container .bottom .nav {
width: 100%;
height: 40px;
padding-top: 15px;
display: block !important;
}
.full_container .bottom .nav span {
color: #999;
cursor: pointer;
}
.full_container .bottom .nav span i {
font-size: 40px;
font-weight: 200;
}
.full_container .bottom .nav span:nth-child(1) {
padding-left: 10vmin;
}
.full_container .bottom .nav span:nth-child(2) {
padding-right: 10vmin;
float: right;
}
.full_container .bottom .orbit {
position: absolute;
top: 5vh;
width: 100%;
height: 100vmin;
border-radius: 50%;
border: 3px solid #eee;
margin: auto;
left: 0;
right: 0;
}
.full_container .bottom .orbit .planet_container {
width: 100%;
height: 100%;
border-radius: 50%;
transition: transform 0.7s ease-in;
}
.full_container .bottom .orbit .planet_container .planet {
position: absolute;
border-radius: 50%;
width: 5vmin;
height: 5vmin;
transition: transform 0.4s linear;
will-change: transform;
}
.full_container .bottom .orbit .planet_container .pt {
transition: transform 0.4s ease-in;
transform: scale(1.7);
will-change: transform;
-webkit-animation: spin 0.4s;
animation: spin 0.4s;
}
/* */
.full_container .bottom .orbit .planet_container .earth {
background: url(https://cdn3.iconfinder.com/data/icons/other-icons/48/app_window-512.png) no-repeat center center / contain;
top: -2.5vmin;
left: 0;
right: 0;
margin: auto;
/* transform: rotate(180deg)*/
}
.full_container .bottom .orbit .planet_container .earth .mars .jupiter .saturn .uranus .neptune .mercury .venus .moon span {
top: -1vmin;
left: -1vmin;
}
.full_container .bottom .orbit .planet_container .mars {
background: url(https://cdn3.iconfinder.com/data/icons/other-icons/48/app_window-512.png) no-repeat center center / contain;
right: 12vmin;
top: 12vmin;
/* transform: rotate(-135deg)*/
}
.full_container .bottom .orbit .planet_container .jupiter {
background: url(https://cdn3.iconfinder.com/data/icons/other-icons/48/app_window-512.png) no-repeat center center / contain;
right: -2.5vmin;
bottom: 46.5vmin;
/* transform: rotate(-90deg) scale(1.7);*/
}
.full_container .bottom .orbit .planet_container .saturn {
background: url(https://cdn3.iconfinder.com/data/icons/other-icons/48/app_window-512.png) no-repeat center center / contain;
right: 12vmin;
bottom: 12vmin;
/* transform: rotate(-45deg) scale(1.7);*/
}
.full_container .bottom .orbit .planet_container .uranus {
background: url(https://cdn3.iconfinder.com/data/icons/other-icons/48/app_window-512.png) no-repeat center center / contain;
right: 0;
left: 0;
margin: auto;
bottom: -2.5vmin;
/* transform: rotate(0deg) scale(1.7);*/
}
.full_container .bottom .orbit .planet_container .neptune {
background: url(https://cdn3.iconfinder.com/data/icons/other-icons/48/app_window-512.png) no-repeat center center / contain;
left: 12vmin;
bottom: 12vmin;
/* transform: rotate(45deg) scale(1.7);*/
}
.full_container .bottom .orbit .planet_container .mercury {
background: url(https://cdn3.iconfinder.com/data/icons/other-icons/48/app_window-512.png) no-repeat center center / contain;
left: -2.5vmin;
bottom: 46.5vmin;
/* transform: rotate(90deg) scale(1.7);*/
}
.full_container .bottom .orbit .planet_container .venus {
background: url(https://cdn3.iconfinder.com/data/icons/other-icons/48/app_window-512.png) no-repeat center center / contain;
left: 12vmin;
top: 12vmin;
/* transform: rotate(135deg) scale(1.7);*/
}
.full_container .bottom .orbit .name_container {
position: absolute;
display: flex;
width: auto;
margin: auto;
left: 0;
right: 0;
top: 8vh;
text-align: center;
align-items: center;
justify-content: center;
flex-wrap: wrap;
transform: rotate(180deg);
}
.full_container .bottom .orbit .name_container .more {
width: 100%;
padding: 8px 0;
color: #bbb;
font-weight: 500;
cursor: pointer;
transition: color 0.2s;
}
.full_container .bottom .orbit .name_container .more:hover {
color: #888;
transition: color 0.3s;
}
.full_container .bottom .orbit .name_container .pn {
font-size: 25px;
color: #666;
text-transform: uppercase;
padding-bottom: 4px;
letter-spacing: 4px;
padding-left: 8px;
border-bottom: 3px solid #bbb;
}
.full_container .bottom .orbit .name_container .pn .letter {
display: inline-block;
line-height: 1em;
opacity: 0;
}
.moon {
width: 100%;
height: 100%;
-webkit-animation: planet_rotation 2s infinite linear;
animation: planet_rotation 2s infinite linear;
visibility: hidden;
}
.moon span {
width: 0.8vmin;
height: 0.8vmin;
background: black;
border-radius: 50%;
position: absolute;
}
#-webkit-keyframes planet_rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#keyframes planet_rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#-webkit-keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#pl0{
transform: rotate(180deg);
}
#pl1{
transform: rotate(225deg);
}
#pl2{
transform: rotate(270deg);
}
#pl3{
transform: rotate(315deg);
}
#pl4{
transform: rotate(360deg);
}
#pl5{
transform: rotate(405deg);
}
#pl6{
transform: rotate(450deg);
}
#pl7{
transform: rotate(495deg);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel='stylesheet' href='https://fonts.googleapis.com/icon?family=Material+Icons'/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="style/style.css" />
</head>
<body>
<header class="t-site-header">
<div class="full_container" id="mobile_control">
<div class="bottom">
<div class="nav">
<span id="next" onclick="moon('next')" class="action"><i class="material-icons">keyboard_arrow_left</i></span>
<span id="prev" onclick="moon('prev')" class="action"><i class="material-icons">keyboard_arrow_right</i></span>
</div>
<div class="orbit">
<div class="planet_container">
<div class="planet pt earth" id="pl0">
<div class="moon">
<span></span>
</div>
</div>
<div class="planet mars" id="pl1">
<div class="moon">
<span></span>
</div>
</div>
<div class="planet jupiter" id="pl2">
<div class="moon">
<span></span>
</div>
</div>
<div class="planet saturn" id="pl3">
<div class="moon">
<span></span>
</div>
</div>
<div class="planet uranus" id="pl4">
<div class="moon">
<span></span>
</div>
</div>
<div class="planet neptune" id="pl5">
<div class="moon">
<span></span>
</div>
</div>
<div class="planet mercury" id="pl6">
<div class="moon">
<span></span>
</div>
</div>
<div class="planet venus" id="pl7">
<div class="moon">
<span></span>
</div>
</div>
</div>
<div class="name_container">
<p class="pn" id="show_pathname"></p>
<p class="more">READ MORE</p>
</div>
</div>
</div>
</div>
</header>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.min.js'></script><script src="./js/script.js"></script>
</body>
</html>

How can I implement this loader for my project?

Basically, I am trying to implement a loader for my clock project. However, for some reason, it does not work. I have tried moving my code around to see what's wrong, but I have not figured it out. However, if I remove the div that my clock is in, the loader appears and fades out which is what I want it to do. How can I produce my loader so it appears, fades out, and shows the clock? Any help is appreciated. Here is my code below.
setInterval(setClock, 1000)
const hourHand = document.querySelector('[data-hour-hand]')
const minuteHand = document.querySelector('[data-minute-hand]')
const secondHand = document.querySelector('[data-second-hand]')
function setClock() {
const currentDate = new Date()
const secondsRatio = currentDate.getSeconds() / 60
const minutesRatio = (secondsRatio + currentDate.getMinutes()) / 60
const hoursRatio = (minutesRatio + currentDate.getHours()) / 12
setRotation(secondHand, secondsRatio)
setRotation(minuteHand, minutesRatio)
setRotation(hourHand, hoursRatio)
}
function setRotation(element, rotationRatio){
element.style.setProperty('--rotation', rotationRatio * 360)
}
setClock()
.loader-wrap{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background-color: #292929;
overflow: hidden;
}
.loader-circles{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
transform: rotate(45deg);
width: 200px;
height: 200px;
}
.loader-circles .circle{
box-sizing: border-box;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background-color: transparent;
border: 4px solid #fff;
border-radius: 50%;
border-bottom-color: transparent;
border-right-color: transparent;
text-align: center;
}
.loader-circles .circle:nth-child(even){
border-color: #42CAFD;
border-bottom-color: transparent;
border-right-color: transparent;
}
.loader-circles .circle:nth-child(odd){
border-color: #EFD2CB;
border-bottom-color: transparent;
border-right-color: transparent;
}
.loader-circles .circle:nth-child(1){
width: 20px;
height: 20px;
animation: rotate-circle linear infinite;
animation-duration: 12s;
}
.loader-circles .circle:nth-child(2) {
width: 40px;
height: 40px;
animation: rotate-circle linear infinite;
animation-duration: 6s;
}
.loader-circles .circle:nth-child(3) {
width: 60px;
height: 60px;
animation: rotate-circle linear infinite;
animation-duration: 4s;
}
.loader-circles .circle:nth-child(4) {
width: 80px;
height: 80px;
animation: rotate-circle linear infinite;
animation-duration: 3s;
}
.loader-circles .circle:nth-child(5) {
width: 100px;
height: 100px;
animation: rotate-circle linear infinite;
animation-duration: 2.4s;
}
.loader-circles .circle:nth-child(6) {
width: 120px;
height: 120px;
animation: rotate-circle linear infinite;
animation-duration: 2s;
}
.loader-circles .circle:nth-child(7) {
width: 140px;
height: 140px;
animation: rotate-circle linear infinite;
animation-duration: 1.7142857143s;
}
.loader-circles .circle:nth-child(8) {
width: 160px;
height: 160px;
animation: rotate-circle linear infinite;
animation-duration: 1.5s;
}
.loader-circles .circle:nth-child(9) {
width: 180px;
height: 180px;
animation: rotate-circle linear infinite;
animation-duration: 1.3333333333s;
}
.loader-circles .circle:nth-child(10) {
width: 200px;
height: 200px;
animation: rotate-circle linear infinite;
animation-duration: 1.2s;
}
#keyframes rotate-circle {
100% {
transform: rotate(360deg);
}
}
#keyframes rotate-circle {
100% {
transform: rotate(360deg);
}
}
#keyframes rotate-circle {
100% {
transform: rotate(360deg);
}
}
#keyframes rotate-circle {
100% {
transform: rotate(360deg);
}
}
#keyframes rotate-circle {
100% {
transform: rotate(360deg);
}
}
#keyframes rotate-circle {
100% {
transform: rotate(360deg);
}
}
#keyframes rotate-circle {
100% {
transform: rotate(360deg);
}
}
#keyframes rotate-circle {
100% {
transform: rotate(360deg);
}
}
#keyframes rotate-circle {
100% {
transform: rotate(360deg);
}
}
#keyframes rotate-circle {
100% {
transform: rotate(360deg);
}
}
* {
margin: 0;
padding: 0;
}
.clock {
width: 300px;
height: 300px;
background-color: rgba(255, 255, 255, .8);
border-radius: 50%;
border: 2px solid black;
position: relative;
}
.clock .number{
--rotation: 0;
position: absolute;
width: 100%;
height: 100%;
text-align: center;
transform: rotate(var(--rotation));
font-size: 1.5rem;
}
.clock .number1 { --rotation: 30deg;}
.clock .number2 { --rotation: 60deg;}
.clock .number3 { --rotation: 90deg;}
.clock .number4 { --rotation: 120deg;}
.clock .number5 { --rotation: 150deg;}
.clock .number6 { --rotation: 180deg;}
.clock .number7 { --rotation: 210deg;}
.clock .number8 { --rotation: 240deg;}
.clock .number9 { --rotation: 270deg;}
.clock .number10 { --rotation: 300deg;}
.clock .number11 { --rotation: 330deg;}
.clock .hand{
--rotation: 0;
position: absolute;
bottom: 50%;
left: 50%;
background-color: black;
border: 1px solid white;
border-top-right-radius: 10px;
border-top-left-radius: 10px;
transform-origin: bottom;
z-index: 10;
transform: translate(-50%) rotate(calc(var(--rotation) * 1deg));
}
.clock::after{
content: " ";
position: absolute;
background-color: black;
z-index: 11;
width: 15px;
height: 15px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
}
.clock .hand.second{
width: 3px;
height: 45%;
background-color: red;
}
.clock .hand.minute{
width: 7px;
height: 40%;
background-color: black;
}
.clock .hand.hour{
width: 10px;
height: 35%;
background-color: black;
}
body {
background-color: cornflowerblue;
text-align: center;
overflow-x: hidden;
}
.section {
min-height: 820px;
position: relative;
text-align: center;
font-family: sans-serif, arial;
margin: 0;
}
h1, p {
margin: 0;
font-family: sans-serif, arial;
font-weight: bold;
}
.title-top {
font-size: 60px;
padding-bottom: 30px;
}
.title-bottom {
font-size: 30px;
}
.title-tx {
font-size: 20px;
opacity: 0.8;
}
/* Navbar */
.nav {
position: fixed;
width: 100%;
top: 20px;
z-index: 9;
padding-left: 10px;
}
.nav a {
padding: 7px 20px;
border-radius: 50px;
margin-right: 10px;
float: left;
border-style: ridge;
background: rgba(255, 255, 255, 0.5);
-webkit-transition: all 0.2s ease-out;
-moz-transition: all 0.2s ease-out;
-ms-transition: all 0.2s ease-out;
-o-transition: all 0.2s ease-out;
transition: all 0.2s ease-out;
text-decoration: none;
color: black;
font-family: sans-serif, arial;
font-weight: 100;
}
.nav a.active {
background: rgba(0, 0, 0, 0.5);
color: white;
}
.nav a:hover {
background: rgba(250, 164, 84, 0.795);
color: white;
}
/* Sections */
#section1{
background: linear-gradient(to right, #1e5799 0%, #2ce0bf 20%, #76dd2c 40%, #dba62b 60%, #e02cbf 80%, #1e5799 100%);
background-size: 10000px 100%;
animation: bg 15s linear infinite;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
overflow: hidden;
font-family: 'Audiowide', cursive;
}
#keyframes bg {
0% {
background-position-x: 0;
}
100% {
background-position-x: 10000px;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<!--Animations Page HTML-->
<!DOCTYPE html>
<html lang="en">
<head>
<!--Links and Fonts-->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="jquery-3.4.1.min.js"></script>
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>JavaScript Clock</title>
<script defer src="script.js"></script>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Audiowide&display=swap" rel="stylesheet">
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="loader-wrap">
<div class="loader-circles">
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
</div>
</div>
<!--Navbar-->
<div class="nav">
<nav>
<a class="active" href="#section1">Section 1</a>
</nav>
</div>
<!--Lesson 1-->
<div class="section" id="section1">
<div class = "clock">
<div class = "hand hour" data-hour-hand></div>
<div class = "hand minute" data-minute-hand></div>
<div class = "hand second" data-second-hand></div>
<div class="number number1">1</div>
<div class="number number2">2</div>
<div class="number number3">3</div>
<div class="number number4">4</div>
<div class="number number5">5</div>
<div class="number number6">6</div>
<div class="number number7">7</div>
<div class="number number8">8</div>
<div class="number number9">9</div>
<div class="number number10">10</div>
<div class="number number11">11</div>
<div class="number number12">12</div>
</div>
</div>
<script>
setTimeout(function(){
$('.loader-wrap').fadeToggle();
}, 2500);
</script>
</body>
</html>
You only need to add Z-index to the parent container of either the Clock or the loader:
Here I add a z-index on the container of the clock:
#section1{
z-index: -1;
}
So the loader and your clock are overlapping on one another and the clock has higher priority in terms of your HTML which is below the loader HTML-markup and that is why the clock shows on top of the Loader.
setInterval(setClock, 1000)
const hourHand = document.querySelector('[data-hour-hand]')
const minuteHand = document.querySelector('[data-minute-hand]')
const secondHand = document.querySelector('[data-second-hand]')
function setClock() {
const currentDate = new Date()
const secondsRatio = currentDate.getSeconds() / 60
const minutesRatio = (secondsRatio + currentDate.getMinutes()) / 60
const hoursRatio = (minutesRatio + currentDate.getHours()) / 12
setRotation(secondHand, secondsRatio)
setRotation(minuteHand, minutesRatio)
setRotation(hourHand, hoursRatio)
}
function setRotation(element, rotationRatio){
element.style.setProperty('--rotation', rotationRatio * 360)
}
setClock()
.loader-wrap{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background-color: #292929;
overflow: hidden;
}
.loader-circles{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
transform: rotate(45deg);
width: 200px;
height: 200px;
}
.loader-circles .circle{
box-sizing: border-box;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background-color: transparent;
border: 4px solid #fff;
border-radius: 50%;
border-bottom-color: transparent;
border-right-color: transparent;
text-align: center;
}
.loader-circles .circle:nth-child(even){
border-color: #42CAFD;
border-bottom-color: transparent;
border-right-color: transparent;
}
.loader-circles .circle:nth-child(odd){
border-color: #EFD2CB;
border-bottom-color: transparent;
border-right-color: transparent;
}
.loader-circles .circle:nth-child(1){
width: 20px;
height: 20px;
animation: rotate-circle linear infinite;
animation-duration: 12s;
}
.loader-circles .circle:nth-child(2) {
width: 40px;
height: 40px;
animation: rotate-circle linear infinite;
animation-duration: 6s;
}
.loader-circles .circle:nth-child(3) {
width: 60px;
height: 60px;
animation: rotate-circle linear infinite;
animation-duration: 4s;
}
.loader-circles .circle:nth-child(4) {
width: 80px;
height: 80px;
animation: rotate-circle linear infinite;
animation-duration: 3s;
}
.loader-circles .circle:nth-child(5) {
width: 100px;
height: 100px;
animation: rotate-circle linear infinite;
animation-duration: 2.4s;
}
.loader-circles .circle:nth-child(6) {
width: 120px;
height: 120px;
animation: rotate-circle linear infinite;
animation-duration: 2s;
}
.loader-circles .circle:nth-child(7) {
width: 140px;
height: 140px;
animation: rotate-circle linear infinite;
animation-duration: 1.7142857143s;
}
.loader-circles .circle:nth-child(8) {
width: 160px;
height: 160px;
animation: rotate-circle linear infinite;
animation-duration: 1.5s;
}
.loader-circles .circle:nth-child(9) {
width: 180px;
height: 180px;
animation: rotate-circle linear infinite;
animation-duration: 1.3333333333s;
}
.loader-circles .circle:nth-child(10) {
width: 200px;
height: 200px;
animation: rotate-circle linear infinite;
animation-duration: 1.2s;
}
#keyframes rotate-circle {
100% {
transform: rotate(360deg);
}
}
#keyframes rotate-circle {
100% {
transform: rotate(360deg);
}
}
#keyframes rotate-circle {
100% {
transform: rotate(360deg);
}
}
#keyframes rotate-circle {
100% {
transform: rotate(360deg);
}
}
#keyframes rotate-circle {
100% {
transform: rotate(360deg);
}
}
#keyframes rotate-circle {
100% {
transform: rotate(360deg);
}
}
#keyframes rotate-circle {
100% {
transform: rotate(360deg);
}
}
#keyframes rotate-circle {
100% {
transform: rotate(360deg);
}
}
#keyframes rotate-circle {
100% {
transform: rotate(360deg);
}
}
#keyframes rotate-circle {
100% {
transform: rotate(360deg);
}
}
* {
margin: 0;
padding: 0;
}
.clock {
width: 300px;
height: 300px;
background-color: rgba(255, 255, 255, .8);
border-radius: 50%;
border: 2px solid black;
position: relative;
}
.clock .number{
--rotation: 0;
position: absolute;
width: 100%;
height: 100%;
text-align: center;
transform: rotate(var(--rotation));
font-size: 1.5rem;
}
.clock .number1 { --rotation: 30deg;}
.clock .number2 { --rotation: 60deg;}
.clock .number3 { --rotation: 90deg;}
.clock .number4 { --rotation: 120deg;}
.clock .number5 { --rotation: 150deg;}
.clock .number6 { --rotation: 180deg;}
.clock .number7 { --rotation: 210deg;}
.clock .number8 { --rotation: 240deg;}
.clock .number9 { --rotation: 270deg;}
.clock .number10 { --rotation: 300deg;}
.clock .number11 { --rotation: 330deg;}
.clock .hand{
--rotation: 0;
position: absolute;
bottom: 50%;
left: 50%;
background-color: black;
border: 1px solid white;
border-top-right-radius: 10px;
border-top-left-radius: 10px;
transform-origin: bottom;
z-index: 10;
transform: translate(-50%) rotate(calc(var(--rotation) * 1deg));
}
.clock::after{
content: " ";
position: absolute;
background-color: black;
z-index: 11;
width: 15px;
height: 15px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
}
.clock .hand.second{
width: 3px;
height: 45%;
background-color: red;
}
.clock .hand.minute{
width: 7px;
height: 40%;
background-color: black;
}
.clock .hand.hour{
width: 10px;
height: 35%;
background-color: black;
}
body {
background-color: cornflowerblue;
text-align: center;
overflow-x: hidden;
}
.section {
min-height: 820px;
position: relative;
text-align: center;
font-family: sans-serif, arial;
margin: 0;
}
h1, p {
margin: 0;
font-family: sans-serif, arial;
font-weight: bold;
}
.title-top {
font-size: 60px;
padding-bottom: 30px;
}
.title-bottom {
font-size: 30px;
}
.title-tx {
font-size: 20px;
opacity: 0.8;
}
/* Navbar */
.nav {
position: fixed;
width: 100%;
top: 20px;
z-index: 9;
padding-left: 10px;
}
.nav a {
padding: 7px 20px;
border-radius: 50px;
margin-right: 10px;
float: left;
border-style: ridge;
background: rgba(255, 255, 255, 0.5);
-webkit-transition: all 0.2s ease-out;
-moz-transition: all 0.2s ease-out;
-ms-transition: all 0.2s ease-out;
-o-transition: all 0.2s ease-out;
transition: all 0.2s ease-out;
text-decoration: none;
color: black;
font-family: sans-serif, arial;
font-weight: 100;
}
.nav a.active {
background: rgba(0, 0, 0, 0.5);
color: white;
}
.nav a:hover {
background: rgba(250, 164, 84, 0.795);
color: white;
}
/* Sections */
#section1{
background: linear-gradient(to right, #1e5799 0%, #2ce0bf 20%, #76dd2c 40%, #dba62b 60%, #e02cbf 80%, #1e5799 100%);
background-size: 10000px 100%;
animation: bg 15s linear infinite;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
overflow: hidden;
font-family: 'Audiowide', cursive;
z-index: -1; /* ADDED THIS LINE OF CSS */
}
#keyframes bg {
0% {
background-position-x: 0;
}
100% {
background-position-x: 10000px;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<!--Animations Page HTML-->
<!DOCTYPE html>
<html lang="en">
<head>
<!--Links and Fonts-->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="jquery-3.4.1.min.js"></script>
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>JavaScript Clock</title>
<script defer src="script.js"></script>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Audiowide&display=swap" rel="stylesheet">
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="loader-wrap">
<div class="loader-circles">
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
</div>
</div>
<!--Navbar-->
<div class="nav">
<nav>
<a class="active" href="#section1">Section 1</a>
</nav>
</div>
<!--Lesson 1-->
<div class="section" id="section1">
<div class = "clock">
<div class = "hand hour" data-hour-hand></div>
<div class = "hand minute" data-minute-hand></div>
<div class = "hand second" data-second-hand></div>
<div class="number number1">1</div>
<div class="number number2">2</div>
<div class="number number3">3</div>
<div class="number number4">4</div>
<div class="number number5">5</div>
<div class="number number6">6</div>
<div class="number number7">7</div>
<div class="number number8">8</div>
<div class="number number9">9</div>
<div class="number number10">10</div>
<div class="number number11">11</div>
<div class="number number12">12</div>
</div>
</div>
<script>
setTimeout(function(){
$('.loader-wrap').fadeToggle();
}, 2500);
</script>
</body>
</html>

Reverse animation on hamburger button

I'm trying to animate a hamburger button. The problem is that the animation works great only for the first click, and I do not know how to make the second click do the reverse animation. I'm not sure if this can be done without using keyframes. Ps. brackets in css are not formatted because its compiled from scss.
var hamburger = document.getElementById("hamburger");
var nav_items = document.getElementsByClassName("nav-items")[0];
var line1 = document.getElementsByClassName("line1")[0];
var line2 = document.getElementsByClassName("line2")[0];
var line3 = document.getElementsByClassName("line3")[0];
hamburger.addEventListener("click", function() {
nav_items.classList.toggle("nav-open");
line1.classList.toggle("first-line");
line2.classList.toggle("middle-line-hidden");
line3.classList.toggle("last-line");
});
body {
background-color: white;
margin: 0;
padding: 0;
}
#navbar {
position: fixed;
top: 0;
width: 100%;
height: 100px;
color: white;
z-index: 100;
background-color: blue;
}
#logo {
position: absolute;
top: 50%;
left: 25px;
transform: translateY(-50%);
font-size: 25px; }
#logo a {
text-decoration: none;
color: white; }
#logo a::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
height: 5px;
width: 100%;
background-color: yellow;
z-index: -1; }
.nav-items {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
visibility: hidden;
justify-content: center;
font-size: 2rem;
background-color: black; }
.nav-items a {
text-decoration: none;
color: white;
margin: 15px 0; }
.nav-items a:first-child {
margin-top: 0; }
.nav-items a:hover {
color: yellow; }
#hamburger {
height: 40px;
width: 40px;
background-color: transparent;
border: 0px solid transparent;
padding: 0;
position: absolute;
right: 80px;
top: 50%;
transform: translateY(-50%);
z-index: 100;
}
#hamburger .line1,
#hamburger .line2,
#hamburger .line3 {
position: absolute;
left: 0;
height: 5px;
width: 100%;
background-color: white;
border-radius: 25px;
transition: 0.5s linear; }
#hamburger .line1 {
top: 3px; }
#hamburger .line2 {
top: 50%;
transform: translateY(-50%); }
#hamburger .line3 {
bottom: 3px; }
.nav-open {
visibility: visible; }
.middle-line-hidden {
animation: hamburger-mid-line 0s linear;
animation-fill-mode: forwards;
animation-delay: 0.3s; }
.first-line {
animation: hamburger-first-line 0.5s;
animation-fill-mode: forwards; }
.last-line {
animation: hamburger-last-line 0.5s;
animation-fill-mode: forwards; }
#keyframes hamburger-mid-line {
from {
visibility: visible; }
to {
visibility: hidden; } }
#keyframes hamburger-first-line {
0% { }
50% {
top: 50%;
transform: translateY(-50%); }
100% {
top: 42%;
transform: rotate(45deg); } }
#keyframes hamburger-last-line {
0% { }
50% {
bottom: 50%;
transform: translateY(50%); }
100% {
bottom: 45%;
transform: rotate(-45deg); } }
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<link rel="stylesheet" href="./css/main.css" />
</head>
<body>
<header id="navbar">
<div class="nav-items">
link1
link2
link3
</div>
<button id="hamburger">
<div class="line1"></div>
<div class="line2"></div>
<div class="line3"></div>
</button>
</header>
</body>
</html>
The most easy way is to assign in the css the animation to a class, for example .openedhamburger with the opening animation.
Now create other animation assigned to other class, for example .closedhamburger, with the closing animation.
Finally switch the class asigned to the element with javascript and there it is, whenever a different class is assigned, the proper animation will be triggered.
Edit: also, albeit in your case use a two step animation, so this is not applicable, know that using this class-approach, if you enable smooth transitions, then sometimes you can even do it without any animation: simply associate the positions and rotations for the elements on the two states and then because smooth transformations are enabled, animation will ocur.

Categories

Resources