document.addEventListener("DOMContentLoaded", (event) => {
const hamburgerButtons = document.querySelectorAll('.hm-button');
const hamburgerLines = [
{
closed: {
x1: 13,
x2: 37,
y1: 13,
y2: 13,
},
open: {
x1: 13,
x2: 37,
y1: 37,
y2: 13,
}
}, {
closed: {
x1: 13,
x2: 37,
y1: 25,
y2: 25,
},
open: null,
}, {
closed: {
x1: 13,
x2: 37,
y1: 37,
y2: 37,
},
open: {
x1: 13,
x2: 37,
y1: 13,
y2: 37,
}
}
]
const handleHamburgerClick = (event) => {
const button = event.target.closest('.hm-button');
const lines = button.querySelectorAll('line');
if (!button.classList.contains('open')) {
lines.forEach((line, idx) => {
if (hamburgerLines[idx].open) {
line.setAttribute('x1', hamburgerLines[idx].open.x1)
line.setAttribute('y1', hamburgerLines[idx].open.y1)
line.setAttribute('x2', hamburgerLines[idx].open.x2)
line.setAttribute('y2', hamburgerLines[idx].open.y2)
}
});
button.classList.add('open');
} else {
if (button.classList.contains('open')) {
lines.forEach((line, idx) => {
if (hamburgerLines[idx].closed) {
line.setAttribute('x1', hamburgerLines[idx].closed.x1)
line.setAttribute('y1', hamburgerLines[idx].closed.y1)
line.setAttribute('x2', hamburgerLines[idx].closed.x2)
line.setAttribute('y2', hamburgerLines[idx].closed.y2)
}
});
button.classList.remove('open');
}
}
};
hamburgerButtons.forEach((button) => {
button.addEventListener("click", handleHamburgerClick);
});
});
.hm-button {
width: 50px;
height: 50px;
cursor: pointer;
}
.hm-button.open .hm-line2 {
stroke: none;
}
.hm-outline {
x: 2px;
y: 2px;
width: 46px;
height: 46px;
rx: 4px;
fill: none;
}
.hm-outline,
[class^="hm-line"] {
stroke-width: 4px;
stroke: black;
}
[class^="hm-line"] {
stroke-linecap: round;
transition: all 0.25s ease;
}
<svg class="hm-button" role="button">
<rect class="hm-outline" />
<line class="hm-line1" x1="13" x2="37" y1="13" y2="13" />
<line class="hm-line2" x1="13" x2="37" y1="25" y2="25" />
<line class="hm-line3" x1="13" x2="37" y1="37" y2="37" />
</svg>
I’m attempting to create a hamburger menu icon using SVG and its child elements as a way to teach myself, but I’m having trouble transitioning the line positions. The change in position is instant, rather than gradual.
What I’m trying to achieve is, the middle line disappearing, and the left point of the first and third lines swap to form an X when the svg is clicked. When it is clicked again, the lines move back and the middle one reappears. Transition doesn’t seem to work when changing the position of the lines, however.