JSFiddle - React, Tailwind, and code Playground
by gweax
HTML
<svg class="morph-icon" width="200" height="200" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<path id="line" d="M 0,0 l 18,0 a 1,1 0 0 1 0,2 l -18,0 a 1,1 0 0 1 0,-2" />
</defs>
<use class="top" xlink:href="#line" x="3" y="11" />
<use class="middle" xlink:href="#line" x="3" y="11" />
<use class="bottom" xlink:href="#line" x="3" y="11" />
</svg>
<div class="morph-buttons">
<button type="button" data-class="">Menu</button>
<button type="button" data-class="close">Close</button>
<button type="button" data-class="plus">Plus</button>
<button type="button" data-class="minus">Minus</button>
<button type="button" data-class="arrow">Arrow</button>
</div>
CSS
.top,
.middle,
.bottom {
transition: transform 0.5s ease;
transform-origin: 12px 12px;
}
.top {
transform: translate(0, -6px);
}
.bottom {
transform: translate(0, 6px);
}
/* Close */
.morph-icon.close .top {
transform: rotate(135deg);
}
.morph-icon.close .middle {
transform: rotate(135deg);
}
.morph-icon.close .bottom {
transform: rotate(45deg);
}
/* Plus */
.morph-icon.plus .top {
transform: rotate(90deg);
}
.morph-icon.plus .middle {
transform: rotate(90deg);
}
.morph-icon.plus .bottom {
transform: rotate(180deg);
}
/* Minus */
.morph-icon.minus .top {
transform: rotate(180deg);
}
.morph-icon.minus .middle {
transform: rotate(180deg);
}
.morph-icon.minus .bottom {
transform: rotate(180deg);
}
/* Arrow */
.morph-icon.arrow .top {
transform: rotate(-45deg) translate(-1.1px, -6.35px) scale(0.6, 1);
}
.morph-icon.arrow .bottom {
transform: rotate(45deg) translate(-1.1px, 6.35px) scale(0.6, 1);
}
JavaScript
document.querySelector('.morph-buttons').addEventListener('click', function(event) {
if (event.target.hasAttribute('data-class')) {
document.querySelector('.morph-icon').setAttribute('class', 'morph-icon ' + event.target.getAttribute('data-class'));
}
}, false);