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);