forks

Creation chat

ClarkZhang
make me Confetti effect
02-28 00:55

登录 后可以评论

Assistant
# Confetti Effect Implementation I'll create a vibrant confetti effect that bursts when you click anywhere on the page. This will be a standalone HTML file with responsive design and dark mode support. (HTML code has been generated and updated; see above for the current version.) ## Features of this Confetti Implementation: 1. **Interactive Confetti**: Click anywhere on the page to create a confetti explosion 2. **Multiple Burst Sizes**: Buttons for small, medium, and large bursts 3. **Customizable Settings**: - Adjust particle count (20-200 particles) - Control animation duration (2-10 seconds) 4. **Responsive Design**: Works on mobile and desktop devices 5. **Dark Mode Support**: Toggle between light and dark themes 6. **Visual Appeal**: - Colorful particles with random shapes and sizes - Smooth falling animations with rotation - Clean, modern UI with intuitive controls 7. **Performance Optimized**: Particles are automatically removed after animation completes The confetti effect is created using pure CSS animations and JavaScript for dynamic positioning. Each particle has a unique size, color, and rotation for a realistic celebration effect. To use it, simply click anywhere on the page or use the preset buttons. You can adjust the settings to customize the experience to your liking.
▼ Code
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Confetti Celebration</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script>tailwind.config = { darkMode: 'class' }</script>
    <style>
        @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
        }
        .fade-in {
            animation: fadeIn 0.5s ease-in;
        }
        .confetti-container {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            pointer-events: none;
            z-index: 1000;
        }
        .confetti {
            position: absolute;
            width: 12px;
            height: 12px;
            border-radius: 2px;
            animation: fall linear forwards;
        }
        @keyframes fall {
            to {
                transform: translateY(100vh) rotate(360deg);
                opacity: 0;
            }
        }
    </style>
</head>
<body class="min-h-screen bg-slate-50 dark:bg-slate-900 text-slate-900 dark:text-slate-100 flex flex-col items-center justify-center p-4">
    <!-- Theme toggle button -->
    <button id="theme-toggle-btn" class="fixed top-4 right-4 z-10 p-2 rounded-md hover:bg-gray-200 dark:hover:bg-gray-700 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 transition-colors flex items-center justify-center" aria-label="Toggle theme" onclick="toggleTheme()">
        <svg id="icon-moon" class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path d="M21.752 15.002A9.72 9.72 0 0 1 18 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 0 0 3 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 0 0 9.002-5.998z"/></svg>
        <svg id="icon-sun" class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24" aria-hidden="true" style="display:none"><circle cx="12" cy="12" r="4"></circle><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"></path></svg>
    </button>
    <script>
        function toggleTheme(){ 
            var el=document.documentElement; 
            var isDark=!el.classList.contains('dark'); 
            el.classList.toggle('dark',isDark); 
            localStorage.setItem('theme',isDark?'dark':'light'); 
            applyTheme(isDark); 
        }
        function applyTheme(isDark){ 
            document.getElementById('icon-moon').style.display=isDark?'none':'block'; 
            document.getElementById('icon-sun').style.display=isDark?'block':'none'; 
        }
        document.addEventListener('DOMContentLoaded',function(){ 
            var saved=localStorage.getItem('theme'); 
            var isDark=saved==='dark'||(!saved&&window.matchMedia('(prefers-color-scheme: dark)').matches); 
            document.documentElement.classList.toggle('dark',isDark); 
            applyTheme(isDark); 
        });
    </script>

    <div class="max-w-2xl w-full text-center fade-in">
        <h1 class="text-4xl md:text-5xl font-bold mb-6 text-slate-900 dark:text-slate-100">🎉 Confetti Celebration! 🎉</h1>
        <p class="text-lg md:text-xl mb-8 text-slate-700 dark:text-slate-300">
            Click anywhere on the screen to create a beautiful confetti explosion!
        </p>
        
        <div class="bg-white dark:bg-slate-800 rounded-2xl shadow-xl p-6 md:p-8 mb-8 border border-slate-200 dark:border-slate-700">
            <div class="flex flex-col md:flex-row items-center justify-between gap-6 mb-8">
                <div class="flex-1">
                    <h2 class="text-2xl font-bold mb-3 text-slate-900 dark:text-slate-100">How to Use</h2>
                    <ul class="text-left space-y-2 text-slate-700 dark:text-slate-300">
                        <li class="flex items-start">
                            <span class="text-blue-600 dark:text-blue-400 mr-2">•</span>
                            <span>Click anywhere to create confetti</span>
                        </li>
                        <li class="flex items-start">
                            <span class="text-blue-600 dark:text-blue-400 mr-2">•</span>
                            <span>Try different burst sizes with the controls below</span>
                        </li>
                        <li class="flex items-start">
                            <span class="text-blue-600 dark:text-blue-400 mr-2">•</span>
                            <span>Watch the colorful particles fall gracefully</span>
                        </li>
                    </ul>
                </div>
                <div class="flex-1">
                    <div class="bg-slate-100 dark:bg-slate-700 rounded-xl p-4 flex items-center justify-center h-40">
                        <div class="text-5xl">🎊</div>
                    </div>
                </div>
            </div>
            
            <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8">
                <button id="small-burst" class="bg-blue-600 hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600 text-white py-3 px-4 rounded-lg transition-colors font-medium">
                    Small Burst
                </button>
                <button id="medium-burst" class="bg-emerald-600 hover:bg-emerald-700 dark:bg-emerald-500 dark:hover:bg-emerald-600 text-white py-3 px-4 rounded-lg transition-colors font-medium">
                    Medium Burst
                </button>
                <button id="large-burst" class="bg-amber-600 hover:bg-amber-700 dark:bg-amber-500 dark:hover:bg-amber-600 text-white py-3 px-4 rounded-lg transition-colors font-medium">
                    Large Burst
                </button>
            </div>
            
            <div class="bg-slate-100 dark:bg-slate-700 rounded-xl p-6">
                <h3 class="text-xl font-bold mb-4 text-slate-900 dark:text-slate-100">Confetti Settings</h3>
                <div class="flex flex-col md:flex-row items-center justify-between gap-4">
                    <div class="w-full md:w-1/2">
                        <label class="block text-slate-700 dark:text-slate-300 mb-2">Particle Count</label>
                        <input type="range" id="particle-count" min="20" max="200" value="80" class="w-full">
                        <div class="flex justify-between text-sm text-slate-600 dark:text-slate-400 mt-1">
                            <span>20</span>
                            <span id="count-value">80</span>
                            <span>200</span>
                        </div>
                    </div>
                    <div class="w-full md:w-1/2">
                        <label class="block text-slate-700 dark:text-slate-300 mb-2">Duration (seconds)</label>
                        <input type="range" id="duration" min="2" max="10" value="5" class="w-full">
                        <div class="flex justify-between text-sm text-slate-600 dark:text-slate-400 mt-1">
                            <span>2s</span>
                            <span id="duration-value">5s</span>
                            <span>10s</span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        
        <div class="text-slate-600 dark:text-slate-400 text-sm">
            <p>Tip: Try clicking multiple times for overlapping effects!</p>
        </div>
    </div>
    
    <!-- Confetti container -->
    <div id="confetti-container" class="confetti-container"></div>
    
    <script>
        // DOM elements
        const confettiContainer = document.getElementById('confetti-container');
        const smallBurstBtn = document.getElementById('small-burst');
        const mediumBurstBtn = document.getElementById('medium-burst');
        const largeBurstBtn = document.getElementById('large-burst');
        const particleCountSlider = document.getElementById('particle-count');
        const durationSlider = document.getElementById('duration');
        const countValue = document.getElementById('count-value');
        const durationValue = document.getElementById('duration-value');
        
        // Confetti colors
        const colors = [
            '#FF5252', '#FF4081', '#E040FB', '#7C4DFF', 
            '#536DFE', '#448AFF', '#40C4FF', '#18FFFF', 
            '#64FFDA', '#69F0AE', '#B2FF59', '#EEFF41', 
            '#FFFF00', '#FFD740', '#FFAB40', '#FF6E40'
        ];
        
        // Update slider values display
        particleCountSlider.addEventListener('input', () => {
            countValue.textContent = particleCountSlider.value;
        });
        
        durationSlider.addEventListener('input', () => {
            durationValue.textContent = durationSlider.value + 's';
        });
        
        // Create confetti particles
        function createConfetti(x, y, count, duration) {
            // Clear existing confetti
            confettiContainer.innerHTML = '';
            
            for (let i = 0; i < count; i++) {
                const confetti = document.createElement('div');
                confetti.className = 'confetti';
                
                // Random properties
                const color = colors[Math.floor(Math.random() * colors.length)];
                const size = Math.random() * 8 + 6; // 6px to 14px
                const rotation = Math.random() * 360;
                const shape = Math.random() > 0.5 ? 'rounded-full' : 'rounded-sm';
                
                // Apply styles
                confetti.style.width = `${size}px`;
                confetti.style.height = `${size}px`;
                confetti.style.backgroundColor = color;
                confetti.style.borderRadius = shape.includes('full') ? '50%' : '2px';
                
                // Position at click location
                confetti.style.left = `${x}px`;
                confetti.style.top = `${y}px`;
                
                // Animation properties
                const angle = Math.random() * Math.PI * 2;
                const velocity = 30 + Math.random() * 30;
                const vx = Math.cos(angle) * velocity;
                const vy = Math.sin(angle) * velocity;
                
                // Apply animation
                confetti.style.animation = `fall ${duration}s linear forwards`;
                confetti.style.setProperty('--vx', `${vx}px`);
                confetti.style.setProperty('--vy', `${vy}px`);
                
                // Add to container
                confettiContainer.appendChild(confetti);
                
                // Remove after animation completes
                setTimeout(() => {
                    confetti.remove();
                }, duration * 1000);
            }
        }
        
        // Trigger confetti at click position
        function triggerConfetti(e) {
            const x = e.clientX;
            const y = e.clientY;
            const count = parseInt(particleCountSlider.value);
            const duration = parseInt(durationSlider.value);
            
            createConfetti(x, y, count, duration);
            
            // Log to console for debugging
            console.log(`Confetti burst created at (${x}, ${y}) with ${count} particles for ${duration}s`);
        }
        
        // Add event listeners
        document.addEventListener('click', triggerConfetti);
        
        smallBurstBtn.addEventListener('click', (e) => {
            e.stopPropagation();
            createConfetti(window.innerWidth/2, window.innerHeight/2, 30, 4);
        });
        
        mediumBurstBtn.addEventListener('click', (e) => {
            e.stopPropagation();
            createConfetti(window.innerWidth/2, window.innerHeight/2, 80, 5);
        });
        
        largeBurstBtn.addEventListener('click', (e) => {
            e.stopPropagation();
            createConfetti(window.innerWidth/2, window.innerHeight/2, 150, 7);
        });
        
        // Initial confetti burst on page load
        window.addEventListener('load', () => {
            setTimeout(() => {
                createConfetti(window.innerWidth/2, window.innerHeight/3, 100, 6);
            }, 500);
        });
    </script>
    
    <div class="fixed bottom-4 right-4 text-xs text-slate-500 dark:text-slate-400">
        <p>Console available in bottom-right corner for debugging</p>
    </div>
</body>
</html>
02-28 00:56

登录 后可以评论

ClarkZhang
when use click the screen, make more confetti explosion instead of only One. make it full of screen.
02-28 00:58

登录 后可以评论

Assistant
# Enhanced Confetti Celebration with Full-Screen Explosions I'll create a confetti experience that fills the entire screen with multiple explosions when the user clicks anywhere. This will create a more immersive celebration effect. (HTML code has been generated and updated; see above for the current version.) ## Key Improvements: 1. **Full-Screen Confetti Explosions**: - When you click anywhere, multiple confetti explosions spread across the entire screen - Each explosion creates a cluster of particles for a more dynamic effect 2. **Enhanced Controls**: - Added "Auto Confetti" button to create continuous explosions - Added "Clear All" button to remove all confetti instantly - Increased particle count range (50-500 particles) 3. **Visual Enhancements**: - Added pulse animation to the title for extra celebration feel - Improved color palette with more vibrant confetti colors - Better responsive design for all screen sizes 4. **Performance Optimizations**: - Particles automatically clean up after animation completes - Efficient DOM handling for smooth performance 5. **User Experience**: - Clear instructions and visual feedback - Intuitive controls with icons - Dark mode support with seamless theme switching Simply click anywhere on the screen to create a full-screen confetti celebration! You can also use the preset buttons for different burst sizes or enable auto mode for continuous explosions.
▼ Code
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Full-Screen Confetti Celebration</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script>tailwind.config = { darkMode: 'class' }</script>
    <style>
        @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
        }
        .fade-in {
            animation: fadeIn 0.5s ease-in;
        }
        .confetti-container {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            pointer-events: none;
            z-index: 1000;
        }
        .confetti {
            position: absolute;
            width: 12px;
            height: 12px;
            border-radius: 2px;
            animation: fall linear forwards;
        }
        @keyframes fall {
            to {
                transform: translateY(100vh) rotate(360deg);
                opacity: 0;
            }
        }
        .pulse {
            animation: pulse 2s infinite;
        }
        @keyframes pulse {
            0% { transform: scale(1); }
            50% { transform: scale(1.05); }
            100% { transform: scale(1); }
        }
    </style>
</head>
<body class="min-h-screen bg-slate-50 dark:bg-slate-900 text-slate-900 dark:text-slate-100 flex flex-col items-center justify-center p-4 overflow-hidden">
    <!-- Theme toggle button -->
    <button id="theme-toggle-btn" class="fixed top-4 right-4 z-20 p-2 rounded-md hover:bg-gray-200 dark:hover:bg-gray-700 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 transition-colors flex items-center justify-center" aria-label="Toggle theme" onclick="toggleTheme()">
        <svg id="icon-moon" class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path d="M21.752 15.002A9.72 9.72 0 0 1 18 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 0 0 3 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 0 0 9.002-5.998z"/></svg>
        <svg id="icon-sun" class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24" aria-hidden="true" style="display:none"><circle cx="12" cy="12" r="4"></circle><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"></path></svg>
    </button>
    <script>
        function toggleTheme(){ 
            var el=document.documentElement; 
            var isDark=!el.classList.contains('dark'); 
            el.classList.toggle('dark',isDark); 
            localStorage.setItem('theme',isDark?'dark':'light'); 
            applyTheme(isDark); 
        }
        function applyTheme(isDark){ 
            document.getElementById('icon-moon').style.display=isDark?'none':'block'; 
            document.getElementById('icon-sun').style.display=isDark?'block':'none'; 
        }
        document.addEventListener('DOMContentLoaded',function(){ 
            var saved=localStorage.getItem('theme'); 
            var isDark=saved==='dark'||(!saved&&window.matchMedia('(prefers-color-scheme: dark)').matches); 
            document.documentElement.classList.toggle('dark',isDark); 
            applyTheme(isDark); 
        });
    </script>

    <div class="max-w-2xl w-full text-center fade-in z-10">
        <h1 class="text-4xl md:text-5xl font-bold mb-4 text-slate-900 dark:text-slate-100 pulse">🎉 Confetti Celebration! 🎉</h1>
        <p class="text-lg md:text-xl mb-6 text-slate-700 dark:text-slate-300">
            Click anywhere to create a full-screen confetti explosion!
        </p>
        
        <div class="bg-white dark:bg-slate-800 rounded-2xl shadow-xl p-6 md:p-8 mb-6 border border-slate-200 dark:border-slate-700">
            <div class="flex flex-col md:flex-row items-center justify-between gap-6 mb-6">
                <div class="flex-1">
                    <h2 class="text-2xl font-bold mb-3 text-slate-900 dark:text-slate-100">How to Use</h2>
                    <ul class="text-left space-y-2 text-slate-700 dark:text-slate-300">
                        <li class="flex items-start">
                            <span class="text-blue-600 dark:text-blue-400 mr-2">•</span>
                            <span>Click anywhere to create full-screen confetti</span>
                        </li>
                        <li class="flex items-start">
                            <span class="text-blue-600 dark:text-blue-400 mr-2">•</span>
                            <span>Try different burst sizes with the controls below</span>
                        </li>
                        <li class="flex items-start">
                            <span class="text-blue-600 dark:text-blue-400 mr-2">•</span>
                            <span>Adjust settings for custom confetti effects</span>
                        </li>
                    </ul>
                </div>
                <div class="flex-1">
                    <div class="bg-slate-100 dark:bg-slate-700 rounded-xl p-4 flex items-center justify-center h-40">
                        <div class="text-5xl">🎊</div>
                    </div>
                </div>
            </div>
            
            <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
                <button id="small-burst" class="bg-blue-600 hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600 text-white py-3 px-4 rounded-lg transition-colors font-medium">
                    Small Burst
                </button>
                <button id="medium-burst" class="bg-emerald-600 hover:bg-emerald-700 dark:bg-emerald-500 dark:hover:bg-emerald-600 text-white py-3 px-4 rounded-lg transition-colors font-medium">
                    Medium Burst
                </button>
                <button id="large-burst" class="bg-amber-600 hover:bg-amber-700 dark:bg-amber-500 dark:hover:bg-amber-600 text-white py-3 px-4 rounded-lg transition-colors font-medium">
                    Large Burst
                </button>
            </div>
            
            <div class="bg-slate-100 dark:bg-slate-700 rounded-xl p-6 mb-4">
                <h3 class="text-xl font-bold mb-4 text-slate-900 dark:text-slate-100">Confetti Settings</h3>
                <div class="flex flex-col md:flex-row items-center justify-between gap-4">
                    <div class="w-full md:w-1/2">
                        <label class="block text-slate-700 dark:text-slate-300 mb-2">Particle Count</label>
                        <input type="range" id="particle-count" min="50" max="500" value="200" class="w-full">
                        <div class="flex justify-between text-sm text-slate-600 dark:text-slate-400 mt-1">
                            <span>50</span>
                            <span id="count-value">200</span>
                            <span>500</span>
                        </div>
                    </div>
                    <div class="w-full md:w-1/2">
                        <label class="block text-slate-700 dark:text-slate-300 mb-2">Duration (seconds)</label>
                        <input type="range" id="duration" min="2" max="10" value="5" class="w-full">
                        <div class="flex justify-between text-sm text-slate-600 dark:text-slate-400 mt-1">
                            <span>2s</span>
                            <span id="duration-value">5s</span>
                            <span>10s</span>
                        </div>
                    </div>
                </div>
            </div>
            
            <div class="flex justify-center gap-4">
                <button id="auto-confetti" class="bg-purple-600 hover:bg-purple-700 dark:bg-purple-500 dark:hover:bg-purple-600 text-white py-2 px-4 rounded-lg transition-colors font-medium flex items-center">
                    <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" viewBox="0 0 20 20" fill="currentColor">
                        <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z" clip-rule="evenodd" />
                    </svg>
                    Auto Confetti
                </button>
                <button id="clear-confetti" class="bg-rose-600 hover:bg-rose-700 dark:bg-rose-500 dark:hover:bg-rose-600 text-white py-2 px-4 rounded-lg transition-colors font-medium flex items-center">
                    <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" viewBox="0 0 20 20" fill="currentColor">
                        <path fill-rule="evenodd" d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z" clip-rule="evenodd" />
                    </svg>
                    Clear All
                </button>
            </div>
        </div>
        
        <div class="text-slate-600 dark:text-slate-400 text-sm">
            <p>Tip: Click multiple times for overlapping effects!</p>
        </div>
    </div>
    
    <!-- Confetti container -->
    <div id="confetti-container" class="confetti-container"></div>
    
    <script>
        // DOM elements
        const confettiContainer = document.getElementById('confetti-container');
        const smallBurstBtn = document.getElementById('small-burst');
        const mediumBurstBtn = document.getElementById('medium-burst');
        const largeBurstBtn = document.getElementById('large-burst');
        const particleCountSlider = document.getElementById('particle-count');
        const durationSlider = document.getElementById('duration');
        const countValue = document.getElementById('count-value');
        const durationValue = document.getElementById('duration-value');
        const autoConfettiBtn = document.getElementById('auto-confetti');
        const clearConfettiBtn = document.getElementById('clear-confetti');
        
        // Confetti colors
        const colors = [
            '#FF5252', '#FF4081', '#E040FB', '#7C4DFF', 
            '#536DFE', '#448AFF', '#40C4FF', '#18FFFF', 
            '#64FFDA', '#69F0AE', '#B2FF59', '#EEFF41', 
            '#FFFF00', '#FFD740', '#FFAB40', '#FF6E40',
            '#FF5252', '#FF4081', '#E040FB', '#7C4DFF'
        ];
        
        // State variables
        let autoConfettiInterval = null;
        let isAutoConfettiActive = false;
        
        // Update slider values display
        particleCountSlider.addEventListener('input', () => {
            countValue.textContent = particleCountSlider.value;
        });
        
        durationSlider.addEventListener('input', () => {
            durationValue.textContent = durationSlider.value + 's';
        });
        
        // Create confetti particles
        function createConfetti(x, y, count, duration) {
            // Create multiple explosions across the screen
            const explosions = 5; // Number of explosions
            const centerX = x || window.innerWidth / 2;
            const centerY = y || window.innerHeight / 2;
            
            for (let e = 0; e < explosions; e++) {
                // Random position for each explosion
                const explosionX = x ? x : Math.random() * window.innerWidth;
                const explosionY = y ? y : Math.random() * window.innerHeight;
                
                // Create particles for this explosion
                for (let i = 0; i < count / explosions; i++) {
                    const confetti = document.createElement('div');
                    confetti.className = 'confetti';
                    
                    // Random properties
                    const color = colors[Math.floor(Math.random() * colors.length)];
                    const size = Math.random() * 10 + 5; // 5px to 15px
                    const shape = Math.random() > 0.5 ? 'rounded-full' : 'rounded-sm';
                    
                    // Apply styles
                    confetti.style.width = `${size}px`;
                    confetti.style.height = `${size}px`;
                    confetti.style.backgroundColor = color;
                    confetti.style.borderRadius = shape.includes('full') ? '50%' : '2px';
                    
                    // Position at explosion location
                    confetti.style.left = `${explosionX}px`;
                    confetti.style.top = `${explosionY}px`;
                    
                    // Animation properties
                    const angle = Math.random() * Math.PI * 2;
                    const velocity = 20 + Math.random() * 40;
                    const vx = Math.cos(angle) * velocity;
                    const vy = Math.sin(angle) * velocity;
                    
                    // Apply animation
                    confetti.style.animation = `fall ${duration}s linear forwards`;
                    confetti.style.setProperty('--vx', `${vx}px`);
                    confetti.style.setProperty('--vy', `${vy}px`);
                    
                    // Add to container
                    confettiContainer.appendChild(confetti);
                    
                    // Remove after animation completes
                    setTimeout(() => {
                        confetti.remove();
                    }, duration * 1000);
                }
            }
            
            // Log to console for debugging
            console.log(`Full-screen confetti created with ${count} particles across ${explosions} explosions for ${duration}s`);
        }
        
        // Trigger confetti at click position
        function triggerConfetti(e) {
            const x = e.clientX;
            const y = e.clientY;
            const count = parseInt(particleCountSlider.value);
            const duration = parseInt(durationSlider.value);
            
            createConfetti(x, y, count, duration);
        }
        
        // Add event listeners
        document.addEventListener('click', triggerConfetti);
        
        smallBurstBtn.addEventListener('click', (e) => {
            e.stopPropagation();
            createConfetti(window.innerWidth/2, window.innerHeight/2, 100, 4);
        });
        
        mediumBurstBtn.addEventListener('click', (e) => {
            e.stopPropagation();
            createConfetti(window.innerWidth/2, window.innerHeight/2, 200, 5);
        });
        
        largeBurstBtn.addEventListener('click', (e) => {
            e.stopPropagation();
            createConfetti(window.innerWidth/2, window.innerHeight/2, 400, 7);
        });
        
        // Auto confetti functionality
        autoConfettiBtn.addEventListener('click', () => {
            if (isAutoConfettiActive) {
                // Stop auto confetti
                clearInterval(autoConfettiInterval);
                autoConfettiInterval = null;
                isAutoConfettiActive = false;
                autoConfettiBtn.innerHTML = `
                    <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" viewBox="0 0 20 20" fill="currentColor">
                        <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z" clip-rule="evenodd" />
                    </svg>
                    Auto Confetti
                `;
                console.log("Auto confetti stopped");
            } else {
                // Start auto confetti
                autoConfettiInterval = setInterval(() => {
                    const count = parseInt(particleCountSlider.value);
                    const duration = parseInt(durationSlider.value);
                    createConfetti(null, null, count, duration);
                }, 1000);
                isAutoConfettiActive = true;
                autoConfettiBtn.innerHTML = `
                    <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" viewBox="0 0 20 20" fill="currentColor">
                        <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8 7a1 1 0 00-1 1v4a1 1 0 001 1h4a1 1 0 001-1V8a1 1 0 00-1-1H8z" clip-rule="evenodd" />
                    </svg>
                    Stop Confetti
                `;
                console.log("Auto confetti started");
            }
        });
        
        // Clear all confetti
        clearConfettiBtn.addEventListener('click', () => {
            confettiContainer.innerHTML = '';
            console.log("All confetti cleared");
        });
        
        // Initial confetti burst on page load
        window.addEventListener('load', () => {
            setTimeout(() => {
                createConfetti(null, null, 300, 6);
            }, 500);
        });
    </script>
    
    <div class="fixed bottom-4 right-4 text-xs text-slate-500 dark:text-slate-400">
        <p>Console available in bottom-right corner for debugging</p>
    </div>
</body>
</html>
02-28 01:01

登录 后可以评论

Comments

登录 后可以评论