| class ConfettiEffect extends HTMLElement { |
| connectedCallback() { |
| this.attachShadow({ mode: 'open' }); |
| this.shadowRoot.innerHTML = ` |
| <style> |
| .confetti { |
| position: absolute; |
| width: 10px; |
| height: 10px; |
| background-color: #f00; |
| opacity: 0; |
| } |
| |
| @keyframes confetti-fall { |
| 0% { |
| transform: translateY(0) rotate(0deg); |
| opacity: 1; |
| } |
| 100% { |
| transform: translateY(100vh) rotate(360deg); |
| opacity: 0; |
| } |
| } |
| </style> |
| <div id="confetti-container"></div> |
| `; |
| |
| this.container = this.shadowRoot.getElementById('confetti-container'); |
| } |
| |
| trigger() { |
| |
| this.container.innerHTML = ''; |
| |
| |
| const colors = ['#f00', '#0f0', '#00f', '#ff0', '#f0f', '#0ff']; |
| |
| for (let i = 0; i < 50; i++) { |
| const confetti = document.createElement('div'); |
| confetti.className = 'confetti'; |
| confetti.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)]; |
| confetti.style.left = `${Math.random() * 100}%`; |
| confetti.style.top = '0'; |
| confetti.style.animation = `confetti-fall ${2 + Math.random() * 3}s linear forwards`; |
| confetti.style.animationDelay = `${Math.random() * 0.5}s`; |
| confetti.style.width = `${5 + Math.random() * 10}px`; |
| confetti.style.height = `${5 + Math.random() * 10}px`; |
| |
| this.container.appendChild(confetti); |
| } |
| } |
| } |
|
|
| customElements.define('confetti-effect', ConfettiEffect); |