モーダル
Anime.js

Morph Shape Notification

通知がSVGのモーフィングシェイプで出現する有機的なアニメーション。

HTML
<button class="msn-trigger" id="msn-trigger">Show Notification</button>
<div class="msn-toast" id="msn-toast">
  <svg class="msn-svg" viewBox="0 0 320 80" preserveAspectRatio="none">
    <path id="msn-bg" fill="#312e81" d="M0,40 Q0,0 40,0 L280,0 Q320,0 320,40 Q320,80 280,80 L40,80 Q0,80 0,40Z"></path>
  </svg>
  <span class="msn-text">Notification sent!</span>
</div>
CSS
.msn-trigger {
  padding: 12px 28px;
  background: #6366f1;
  color: #fff;
  border: none;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
}
.msn-toast {
  position: fixed;
  bottom: 30px;
  left: 50%;
  transform: translateX(-50%) translateY(120px);
  width: 320px;
  height: 80px;
  z-index: 100;
}
.msn-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.msn-text {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #e2e8f0;
  font-size: 14px;
  font-weight: 600;
}
JavaScript
const toast = document.getElementById('msn-toast');
const bgPath = document.getElementById('msn-bg');
document.getElementById('msn-trigger').addEventListener('click', function() {
  anime({
    targets: toast,
    translateX: '-50%',
    translateY: [120, 0],
    duration: 600,
    easing: 'easeOutElastic(1, 0.6)'
  });
  anime({
    targets: bgPath,
    d: [
      { value: 'M0,40 Q0,0 40,0 L280,0 Q320,0 320,40 Q320,80 280,80 L40,80 Q0,80 0,40Z' },
      { value: 'M0,40 Q10,5 50,2 L270,2 Q310,5 320,40 Q310,75 270,78 L50,78 Q10,75 0,40Z' },
      { value: 'M0,40 Q0,0 40,0 L280,0 Q320,0 320,40 Q320,80 280,80 L40,80 Q0,80 0,40Z' }
    ],
    duration: 800,
    easing: 'easeInOutQuad'
  });
  setTimeout(function() {
    anime({
      targets: toast,
      translateY: 120,
      duration: 400,
      easing: 'easeInCubic'
    });
  }, 2500);
});