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