Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>ClickMaster Pro - Interactive Buttons</title> | |
| <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <script src="https://unpkg.com/feather-icons"></script> | |
| <style> | |
| .btn-effect { | |
| transition: all 0.3s ease; | |
| } | |
| .btn-effect:hover { | |
| transform: translateY(-3px); | |
| box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); | |
| } | |
| .btn-effect:active { | |
| transform: translateY(1px); | |
| } | |
| .click-counter { | |
| transition: all 0.2s ease; | |
| } | |
| .click-animation { | |
| animation: clickPop 0.4s ease-out; | |
| } | |
| @keyframes clickPop { | |
| 0% { transform: scale(1); } | |
| 50% { transform: scale(1.2); } | |
| 100% { transform: scale(1); } | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gradient-to-br from-indigo-100 to-purple-100 min-h-screen"> | |
| <div class="container mx-auto px-4 py-16"> | |
| <header class="text-center mb-12"> | |
| <h1 class="text-5xl font-bold text-indigo-800 mb-4">ClickMaster Pro 🎯</h1> | |
| <p class="text-xl text-purple-600">The ultimate button clicking experience</p> | |
| </header> | |
| <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8"> | |
| <!-- Primary Button --> | |
| <div class="bg-white rounded-xl shadow-lg p-6 flex flex-col items-center"> | |
| <button id="primary-btn" class="btn-effect bg-indigo-600 hover:bg-indigo-700 text-white font-bold py-4 px-8 rounded-full text-lg mb-4 flex items-center"> | |
| <i data-feather="zap" class="mr-2"></i> Primary Click | |
| </button> | |
| <p class="text-gray-600 mb-2">Clicks: <span id="primary-count" class="font-bold text-indigo-600">0</span></p> | |
| <p class="text-sm text-gray-500 text-center">A smooth primary button with hover and click effects</p> | |
| </div> | |
| <!-- Danger Button --> | |
| <div class="bg-white rounded-xl shadow-lg p-6 flex flex-col items-center"> | |
| <button id="danger-btn" class="btn-effect bg-red-500 hover:bg-red-600 text-white font-bold py-4 px-8 rounded-full text-lg mb-4 flex items-center"> | |
| <i data-feather="alert-triangle" class="mr-2"></i> Danger Zone | |
| </button> | |
| <p class="text-gray-600 mb-2">Clicks: <span id="danger-count" class="font-bold text-red-600">0</span></p> | |
| <p class="text-sm text-gray-500 text-center">Handle with care! This button means business</p> | |
| </div> | |
| <!-- Success Button --> | |
| <div class="bg-white rounded-xl shadow-lg p-6 flex flex-col items-center"> | |
| <button id="success-btn" class="btn-effect bg-emerald-500 hover:bg-emerald-600 text-white font-bold py-4 px-8 rounded-full text-lg mb-4 flex items-center"> | |
| <i data-feather="check-circle" class="mr-2"></i> Success Click | |
| </button> | |
| <p class="text-gray-600 mb-2">Clicks: <span id="success-count" class="font-bold text-emerald-600">0</span></p> | |
| <p class="text-sm text-gray-500 text-center">Celebrate every click with this cheerful button</p> | |
| </div> | |
| <!-- Ghost Button --> | |
| <div class="bg-white rounded-xl shadow-lg p-6 flex flex-col items-center"> | |
| <button id="ghost-btn" class="btn-effect border-2 border-purple-500 text-purple-600 hover:bg-purple-50 font-bold py-4 px-8 rounded-full text-lg mb-4 flex items-center"> | |
| <i data-feather="ghost" class="mr-2"></i> Ghost Mode | |
| </button> | |
| <p class="text-gray-600 mb-2">Clicks: <span id="ghost-count" class="font-bold text-purple-600">0</span></p> | |
| <p class="text-sm text-gray-500 text-center">A subtle yet powerful ghost button</p> | |
| </div> | |
| <!-- Animated Button --> | |
| <div class="bg-white rounded-xl shadow-lg p-6 flex flex-col items-center"> | |
| <button id="animated-btn" class="btn-effect bg-gradient-to-r from-pink-500 to-orange-500 hover:from-pink-600 hover:to-orange-600 text-white font-bold py-4 px-8 rounded-full text-lg mb-4 flex items-center"> | |
| <i data-feather="activity" class="mr-2"></i> Party Mode! | |
| </button> | |
| <p class="text-gray-600 mb-2">Clicks: <span id="animated-count" class="font-bold text-pink-600">0</span></p> | |
| <p class="text-sm text-gray-500 text-center">Who doesn't love a gradient party?</p> | |
| </div> | |
| <!-- Mega Button --> | |
| <div class="bg-white rounded-xl shadow-lg p-6 flex flex-col items-center"> | |
| <button id="mega-btn" class="btn-effect bg-yellow-400 hover:bg-yellow-500 text-gray-900 font-bold py-4 px-8 rounded-full text-lg mb-4 flex items-center transform hover:scale-105 transition-transform"> | |
| <i data-feather="award" class="mr-2"></i> MEGA CLICK | |
| </button> | |
| <p class="text-gray-600 mb-2">Clicks: <span id="mega-count" class="font-bold text-yellow-600">0</span></p> | |
| <p class="text-sm text-gray-500 text-center">The ultimate clicking experience</p> | |
| </div> | |
| </div> | |
| <div class="mt-16 bg-white rounded-xl shadow-lg p-8 text-center"> | |
| <h2 class="text-2xl font-bold text-indigo-800 mb-4">Total Clicks Mastered</h2> | |
| <div class="text-5xl font-extrabold text-purple-600 mb-6" id="total-count">0</div> | |
| <button id="reset-btn" class="bg-gray-200 hover:bg-gray-300 text-gray-800 font-medium py-2 px-6 rounded-lg"> | |
| Reset All Counters | |
| </button> | |
| </div> | |
| </div> | |
| <script> | |
| document.addEventListener('DOMContentLoaded', function() { | |
| feather.replace(); | |
| // Initialize counters | |
| let counters = { | |
| primary: 0, | |
| danger: 0, | |
| success: 0, | |
| ghost: 0, | |
| animated: 0, | |
| mega: 0 | |
| }; | |
| // Button click handlers | |
| document.getElementById('primary-btn').addEventListener('click', function() { | |
| counters.primary++; | |
| updateCounter('primary-count', counters.primary); | |
| animateClick(this); | |
| }); | |
| document.getElementById('danger-btn').addEventListener('click', function() { | |
| counters.danger++; | |
| updateCounter('danger-count', counters.danger); | |
| animateClick(this); | |
| createRipple(this, 'red'); | |
| }); | |
| document.getElementById('success-btn').addEventListener('click', function() { | |
| counters.success++; | |
| updateCounter('success-count', counters.success); | |
| animateClick(this); | |
| createConfetti(this); | |
| }); | |
| document.getElementById('ghost-btn').addEventListener('click', function() { | |
| counters.ghost++; | |
| updateCounter('ghost-count', counters.ghost); | |
| animateClick(this); | |
| this.classList.toggle('border-purple-500'); | |
| this.classList.toggle('border-indigo-500'); | |
| }); | |
| document.getElementById('animated-btn').addEventListener('click', function() { | |
| counters.animated++; | |
| updateCounter('animated-count', counters.animated); | |
| animateClick(this); | |
| this.classList.toggle('from-pink-500'); | |
| this.classList.toggle('to-orange-500'); | |
| this.classList.toggle('from-blue-500'); | |
| this.classList.toggle('to-teal-500'); | |
| }); | |
| document.getElementById('mega-btn').addEventListener('click', function() { | |
| counters.mega++; | |
| updateCounter('mega-count', counters.mega); | |
| animateClick(this, true); | |
| createRipple(this, 'yellow'); | |
| }); | |
| document.getElementById('reset-btn').addEventListener('click', function() { | |
| for (let key in counters) { | |
| counters[key] = 0; | |
| updateCounter(key + '-count', 0); | |
| } | |
| updateTotalCount(); | |
| }); | |
| // Helper functions | |
| function updateCounter(elementId, value) { | |
| const element = document.getElementById(elementId); | |
| element.textContent = value; | |
| element.classList.add('click-animation'); | |
| setTimeout(() => { | |
| element.classList.remove('click-animation'); | |
| }, 400); | |
| updateTotalCount(); | |
| } | |
| function updateTotalCount() { | |
| const total = Object.values(counters).reduce((a, b) => a + b, 0); | |
| document.getElementById('total-count').textContent = total; | |
| } | |
| function animateClick(element, isMega = false) { | |
| element.classList.add('transform', 'scale-95'); | |
| setTimeout(() => { | |
| element.classList.remove('transform', 'scale-95'); | |
| if (isMega) { | |
| element.classList.add('animate-bounce'); | |
| setTimeout(() => { | |
| element.classList.remove('animate-bounce'); | |
| }, 1000); | |
| } | |
| }, 150); | |
| } | |
| function createRipple(button, color) { | |
| const ripple = document.createElement('span'); | |
| ripple.classList.add('absolute', 'rounded-full', 'pointer-events-none'); | |
| ripple.style.backgroundColor = `rgba(255, 255, 255, 0.7)`; | |
| ripple.style.width = ripple.style.height = '20px'; | |
| ripple.style.left = (event.clientX - button.getBoundingClientRect().left - 10) + 'px'; | |
| ripple.style.top = (event.clientY - button.getBoundingClientRect().top - 10) + 'px'; | |
| ripple.style.transform = 'scale(0)'; | |
| ripple.style.transition = 'transform 0.6s ease-out, opacity 0.6s ease-out'; | |
| button.style.position = 'relative'; | |
| button.style.overflow = 'hidden'; | |
| button.appendChild(ripple); | |
| setTimeout(() => { | |
| ripple.style.transform = 'scale(15)'; | |
| ripple.style.opacity = '0'; | |
| }, 10); | |
| setTimeout(() => { | |
| ripple.remove(); | |
| }, 600); | |
| } | |
| function createConfetti(button) { | |
| const confettiCount = 15; | |
| for (let i = 0; i < confettiCount; i++) { | |
| const confetti = document.createElement('div'); | |
| confetti.classList.add('absolute', 'w-2', 'h-2', 'rounded-full', 'pointer-events-none'); | |
| confetti.style.backgroundColor = `hsl(${Math.random() * 360}, 100%, 50%)`; | |
| confetti.style.left = (event.clientX - button.getBoundingClientRect().left - 1) + 'px'; | |
| confetti.style.top = (event.clientY - button.getBoundingClientRect().top - 1) + 'px'; | |
| const angle = Math.random() * Math.PI * 2; | |
| const velocity = 2 + Math.random() * 3; | |
| const x = Math.cos(angle) * velocity; | |
| const y = Math.sin(angle) * velocity; | |
| button.appendChild(confetti); | |
| let posX = 0, posY = 0; | |
| let opacity = 1; | |
| const duration = 1000 + Math.random() * 500; | |
| const start = Date.now(); | |
| function animate() { | |
| const elapsed = Date.now() - start; | |
| const progress = elapsed / duration; | |
| if (progress >= 1) { | |
| confetti.remove(); | |
| return; | |
| } | |
| posX += x; | |
| posY += y + progress * 0.5; // Add gravity | |
| opacity = 1 - progress; | |
| confetti.style.transform = `translate(${posX}px, ${posY}px)`; | |
| confetti.style.opacity = opacity; | |
| requestAnimationFrame(animate); | |
| } | |
| requestAnimationFrame(animate); | |
| } | |
| } | |
| }); | |
| </script> | |
| </body> | |
| </html> | |