Toggle bomb animation

by AntowaKartowa

HTML

<style>
  @property --bomb-angle {
    syntax: "<angle>";
    inherits: false;
    initial-value: 0deg;
  }
  @property --fuse-angle {
    syntax: "<angle>";
    inherits: true;
    initial-value: 0deg;
  }

  .bomb {
    transform: rotate(var(--bomb-angle));
    transform-origin: 9px 15px;
    
    &.is-booped {
      animation: bombRotate var(--bomb-duration) var(--bomb-easing) forwards;
    }
  }
  .fuse {
    transition:
      --fuse-angle var(--child-easing) var(--child-duration);
    transform: rotate(var(--fuse-angle));
    transform-origin: 18px 6px;
  }

  @keyframes bombRotate {
    to { --bomb-angle: 15deg; }
  }
</style>

<button class="wrapper">
  <svg viewBox="0 0 24 24" class="svg">
    <g class="bomb">
      <path
        class="fuse"
        stroke="currentColor"
        stroke-linecap="round"
        stroke-linejoin="round"
        stroke-width="2"
        d="m20.468 1.037-.466 2.96 2.96-.468-2.96.472 1.361 2.671L20 4.003 17 7l2.998-3-2.67-1.36 2.671 1.357z"
      />
      
      <path
        stroke="currentColor"
        stroke-linecap="round"
        stroke-width="2"
        d="M13.444 8.347A8 8 0 1 0 15.93 11"
      />
      <path
        stroke="currentColor"
        stroke-linecap="round"
        stroke-linejoin="round"
        stroke-width="2"
        d="m12.359 7.649 1.06-1.061a2 2 0 0 1 2.829 0l1.414 1.414a2 2 0 0 1 0 2.829l-1.06 1.06"
      />
    </g>
  </svg>
</button>

CSS

html {
  /* Stiffness: 300. Damping: 10  */
    --bomb-easing: linear(0, 0.011, 0.045 1.5%, 0.181 3.2%, 0.896 8.7%, 1.136 11%, 1.17 11.4%, 1.17, 1.16, 1.12 14.4%, 0.96 16.1%, 0.12 21.6%, -0.16 23.9%, -0.33 25.9%, -0.38, -0.41 28.1%, -0.41, -0.41, -0.39, -0.37 31.2%, -0.29 32.9%, -0.06 37.2%, 0.04 39.2%, 0.11 41.5%, 0.13, 0.14 43.9%, 0.14 45.4%, 0.13, 0.1 48.9%, 0.02 53%, -0.01 55.1%, -0.04, -0.05 59.6%, -0.05 61.2%, -0.05 63%, 0 70.9%, 0.01, 0.02 75.1%, 0 86.4%, -0.01 90.3%, 0 94.4%, 0);
    --bomb-duration: 1.317s;

  
  /* Stiffness: 400. Damping: 10  */
  --child-easing: linear(0, 0.012, 0.049 1.1%, 0.2 2.3%, 0.982 6.2%, 1.234, 1.385 9.1%, 1.425, 1.443, 1.442, 1.429 11.7%, 1.363 13%, 1.004 17%, 0.892 18.6%, 0.829 20%, 0.811, 0.803 21.4% 21.9%, 0.809 22.5%, 0.838 23.8%, 0.998 27.9%, 1.048, 1.076, 1.087, 1.085, 1.072 34.6%, 1.001 38.7%, 0.979, 0.966, 0.961 42.9%, 0.962, 0.966 45%, 1.007 50.6%, 1.014, 1.017 53.6%, 1.015 55.8%, 0.997 61.4%, 0.992 64.4%, 1.003, 0.999 85.7%, 1);
  --child-duration: 1.5s;
  /* --child-easing:
  --child-duration: 0.5s; */
}
body {
  height: 100vh;
  height: 100svh;
  display: grid;
  place-content: center;
  border: 1px solid hsl(210deg 15% 25%);
  border-radius: 4px;
  background: hsl(210deg 15% 6%);
  color: white;
  /*
    Don't add scrollbars if the rotation
    forces the element beyond the edge
    of the viewport:
  */
  overflow: hidden;
}
.wrapper {
  position: relative;
  width: 100px;
  height: 100px;
  background: transparent;
  border: none;
  color: white;
  cursor: pointer;
}
svg {
  display: block;
  width: 100%;
  height: 100%;
  fill: none;
  overflow: visible;
}

JavaScript

const wrapper = document.querySelector('button');
const bomb = document.querySelector('.bomb');

wrapper.addEventListener('mouseenter', () => {
  bomb.classList.add('is-booped');

  bomb.addEventListener('animationend', (name) => {
    bomb.classList.remove('is-booped');
  }, { once: true });
  
  // window.setTimeout(() => {
  //   bomb.classList.remove('is-booped');
  // }, 1500);
});