My goal is to create a menu button that transitions from 3 horizontal lines into an 'X'.
I have managed to achieve this but the minor issue I am having is that the animation is perfect only AFTER the first click. If I refresh the browser and click the button, it will not execute correctly.
It's hard to notice if I leave the animation at 0.1 seconds as I intend so I have slowed it down to 1 second.
Here is all the relevant code, you can just copy and paste it to test it out. Keep in mind that this is ideally created for iPhone 6/7/8 Plus using the browser.
const menuButton = document.querySelector('.menu-button')
const menuButtonLines = document.querySelectorAll('.line')
let menuIsOpen = false;
// functions for MenuButton
let changeOpacity = x => {
if (menuIsOpen === false) {
menuButtonLines[x].style.transition = 'opacity 1s linear'
menuButtonLines[x].style.opacity = '0%'
} else if (menuIsOpen === true) {
menuButtonLines[x].style.transition = 'opacity 1s linear'
menuButtonLines[x].style.opacity = '100%'
}
}
let rotateAndAdjustMenuButtonXLines = (x, y) => {
if (menuIsOpen === false) {
menuButtonLines[x].style.transition = 'all 1s linear'
menuButtonLines[y].style.transition = 'all 1s linear'
menuButtonLines[x].style.transform = 'rotate(45deg)'
menuButtonLines[y].style.transform = 'rotate(-45deg)'
menuButtonLines[x].style.top = '42.5%'
menuButtonLines[y].style.bottom = '42.5%'
} else if (menuIsOpen === true) {
menuButtonLines[x].style.transition = 'all 1s linear'
menuButtonLines[y].style.transition = 'all 1s linear'
menuButtonLines[x].style.transform = 'rotate(0deg)'
menuButtonLines[y].style.transform = 'rotate(0deg)'
menuButtonLines[x].style.top = '0%'
menuButtonLines[y].style.bottom = '0%'
}
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
font-family: 'Inter', sans-serif;
}
/* button styling removal code */
button {
background: transparent;
box-shadow: 0px 0px 0px transparent;
border: 0px solid transparent;
text-shadow: 0px 0px 0px transparent;
}
button:hover {
background: transparent;
box-shadow: 0px 0px 0px transparent;
text-shadow: 0px 0px 0px transparent;
}
button:active {
outline: none;
border: none;
}
button:focus {
outline: 0;
}
/* ---------------------------------------- */
body {
height: 100%;
width: 100%;
}
.logo-and-menu-buttom {
background-color: white;
height: 17.5vh;
width: 100%;
display: flex;
align-items: center;
justify-content: space-evenly;
}
.menu-button {
border: 0.3vh solid black;
border-radius: 0.25vh;
width: 20%;
height: 30%;
display: flex;
align-items: center;
justify-content: space-evenly;
}
.line-container {
height: 40%;
width: 20%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
}
.line {
position: relative;
border: 0.1vh solid black;
border-radius: 100vh;
width: 100%;
}
.menu-button p {
font-weight: bold;
letter-spacing: 0.1vh;
}
<section class="logo-and-menu-buttom">
<button class="menu-button">
<div class="line-container">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
</div>
<p>Menu</p>
</button>
</section>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
The problem is your "correct" animation is relying on styles youre giving to your elements via js, and not html and css, therefore they dont exist before js is triggered, hence the first time it looks different.
To fix your problem all you need to do is to add those styles, so change your html from :
<div class="line-container">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
</div>
to:
<div class="line-container">
<div class="line" style="top: 0"></div>
<div class="line"></div>
<div class="line" style="bottom: 0"></div>
</div>
Even tho I strongly suggesting switching from js based animations to css based animations with css-animation syntax and 2 different classes with different closing and opening animations.