Issue
Whenever the top and bottom bars rotate, it isn't centered on the middle. How can I fix this? I want the 3 bars to form an X shape from the hamburger shape, but when the animation starts, the bottom and top bars get offset from the center when they rotate.
What I have currently:
function toggleState(target) {
target.classList.toggle("animate");
}
:root {
--btn-size: min(8vh, 8vw);
--bar-height: calc(var(--btn-size) / 5);
--margin-top: calc(var(--bar-height)*2);
--margin-bottom: calc(var(--bar-height)*-2);
--animation: 1s;
--anim-half: calc(var(--animation)/2);
--anim-func: ease-in-out;
--btn-color: #929292;
}
body {
height: max-content;
width: max-content;
margin: 5%;
}
#menu-btn {
height: var(--btn-size);
width: var(--btn-size);
display: flex;
align-items: center;
cursor: pointer;
}
#menu-icon,
#menu-icon::before,
#menu-icon::after {
height: var(--bar-height);
width: var(--btn-size);
background-color: var(--btn-color);
position: absolute;
transform-origin: center;
}
#menu-icon {
transition: rotate var(--animation) var(--anim-func) 0.00s;
}
#menu-icon::before {
transition: translate var(--anim-half) var(--anim-func) var(--anim-half), rotate var(--anim-half) var(--anim-func) 0.00s;
content: "";
transform: translateY(var(--margin-top));
}
#menu-icon::after {
transition: translate var(--anim-half) var(--anim-func) var(--anim-half), rotate var(--anim-half) var(--anim-func) 0.00s;
content: "";
transform: translateY(var(--margin-bottom));
}
.animate #menu-icon {
transition: rotate var(--animation) var(--anim-func) 0.00s;
rotate: 360deg;
}
.animate #menu-icon::before {
transition: translate var(--anim-half) var(--anim-func) 0.00s, rotate var(--anim-half) var(--anim-func) var(--anim-half);
translate: 0px var(--margin-bottom);
rotate: 45deg;
}
.animate #menu-icon::after {
transition: translate var(--anim-half) var(--anim-func) 0.00s, rotate var(--anim-half) var(--anim-func) var(--anim-half);
translate: 0px var(--margin-top);
rotate: -45deg;
}
<body>
<div id="menu-btn" onclick="toggleState(this)">
<div id="menu-icon" class=""></div>
</div>
</body>
<html>
I tried transform-origin: center on every line but it didn't work. I expected it to rotate centered about the middle of the original.
Solution
I would consider a slightly different idea and simplify your code like below:
function toggleState(target) {
target.classList.toggle("animate");
}
:root {
--btn-size: 20vmin; /* no need to use min between vh and vw, vmin will do it for you */
--animation: 1s;
--anim-half: calc(var(--animation)/2);
--anim-func: ease-in-out;
--btn-color: #929292;
}
#menu-btn {
height: var(--btn-size);
aspect-ratio: 1;
border: none;
cursor: pointer;
background: /* the background will create the middle bar */
linear-gradient(var(--btn-color) 0 0)
50%/100% 20% no-repeat;
position: relative;
transition:
rotate var(--animation) var(--anim-func),
background-size 0s var(--anim-half);
}
#menu-btn::before,
#menu-btn::after {
content:"";
position: absolute;
inset-inline: 0;
height: 20%;
background-color: var(--btn-color);
transition:
translate var(--anim-half) var(--anim-func) var(--anim-half),
rotate var(--anim-half) var(--anim-func);
}
#menu-btn::before { top: 0}
#menu-btn::after { bottom: 0}
#menu-btn.animate{
rotate: 360deg;
background-size: 0% 20%;
}
#menu-btn.animate::before,
#menu-btn.animate::after {
transition:
translate var(--anim-half) var(--anim-func),
rotate var(--anim-half) var(--anim-func) var(--anim-half);
}
#menu-btn.animate::before {
rotate: 45deg;
translate: 0 calc(2*var(--btn-size)/5);
}
#menu-btn.animate::after {
rotate: -45deg;
translate: 0 calc(-2*var(--btn-size)/5);
}
body {
margin: 50px;
}
<button id="menu-btn" onclick="toggleState(this)"></button>
Answered By - Temani Afif
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.