|
|
<!DOCTYPE html> |
|
|
<html lang="zh-TW"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>全螢幕煙火按鈕</title> |
|
|
<script src="https://cdn.tailwindcss.com"></script> |
|
|
<style> |
|
|
|
|
|
.firework-particle { |
|
|
position: absolute; |
|
|
width: 6px; |
|
|
height: 6px; |
|
|
border-radius: 50%; |
|
|
pointer-events: none; |
|
|
animation: fadeOut 1s forwards; |
|
|
} |
|
|
|
|
|
|
|
|
@keyframes fadeOut { |
|
|
0% { |
|
|
opacity: 1; |
|
|
transform: scale(1); |
|
|
} |
|
|
100% { |
|
|
opacity: 0; |
|
|
transform: scale(0.5); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.magic-button:hover { |
|
|
transform: translateY(-3px); |
|
|
box-shadow: 0 10px 20px rgba(255, 215, 0, 0.3); |
|
|
} |
|
|
|
|
|
.magic-button:active { |
|
|
transform: translateY(1px); |
|
|
} |
|
|
|
|
|
|
|
|
@keyframes pulse { |
|
|
0% { |
|
|
box-shadow: 0 0 0 0 rgba(255, 215, 0, 0.7); |
|
|
} |
|
|
70% { |
|
|
box-shadow: 0 0 0 10px rgba(255, 215, 0, 0); |
|
|
} |
|
|
100% { |
|
|
box-shadow: 0 0 0 0 rgba(255, 215, 0, 0); |
|
|
} |
|
|
} |
|
|
|
|
|
.pulse { |
|
|
animation: pulse 2s infinite; |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body class="bg-gray-900 min-h-screen flex items-center justify-center p-4"> |
|
|
<div class="text-center"> |
|
|
<h1 class="text-4xl font-bold text-yellow-400 mb-8">煙火慶典</h1> |
|
|
<p class="text-gray-300 mb-12 max-w-md mx-auto">按下下方按鈕,觸發全螢幕煙火秀!</p> |
|
|
|
|
|
<button id="fireworkButton" class="magic-button pulse relative overflow-hidden bg-gradient-to-r from-yellow-500 to-orange-500 text-white font-bold py-4 px-8 rounded-full text-lg shadow-lg transition-all duration-300 transform hover:scale-105"> |
|
|
<span class="relative z-10">點燃煙火 🎆</span> |
|
|
<span class="absolute inset-0 bg-white opacity-0 group-hover:opacity-10 transition-opacity duration-300"></span> |
|
|
</button> |
|
|
|
|
|
<div class="mt-8 text-gray-400 text-sm"> |
|
|
<p>可以多次點擊按鈕創造更多煙火效果</p> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<script> |
|
|
document.getElementById('fireworkButton').addEventListener('click', function(e) { |
|
|
|
|
|
this.classList.add('animate-ping'); |
|
|
setTimeout(() => { |
|
|
this.classList.remove('animate-ping'); |
|
|
}, 300); |
|
|
|
|
|
|
|
|
const startX = window.innerWidth / 2; |
|
|
const startY = window.innerHeight; |
|
|
const endX = startX + (Math.random() * 400 - 200); |
|
|
const endY = Math.random() * window.innerHeight * 0.3; |
|
|
|
|
|
createLaunchTrail(startX, startY, endX, endY); |
|
|
|
|
|
|
|
|
for(let i = 0; i < 2; i++) { |
|
|
setTimeout(() => { |
|
|
const startX = window.innerWidth / 2 + (Math.random() * 100 - 50); |
|
|
const startY = window.innerHeight; |
|
|
const endX = startX + (Math.random() * 400 - 200); |
|
|
const endY = Math.random() * window.innerHeight * 0.3; |
|
|
createLaunchTrail(startX, startY, endX, endY); |
|
|
}, Math.random() * 500); |
|
|
} |
|
|
}); |
|
|
|
|
|
function createFirework(x, y) { |
|
|
|
|
|
const explosion = document.createElement('div'); |
|
|
explosion.style.left = x + 'px'; |
|
|
explosion.style.top = y + 'px'; |
|
|
explosion.style.position = 'fixed'; |
|
|
explosion.style.width = '10px'; |
|
|
explosion.style.height = '10px'; |
|
|
explosion.style.borderRadius = '50%'; |
|
|
explosion.style.backgroundColor = getRandomColor(); |
|
|
explosion.style.transform = 'scale(0)'; |
|
|
explosion.style.transition = 'transform 0.5s ease-out'; |
|
|
document.body.appendChild(explosion); |
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
explosion.style.transform = 'scale(1)'; |
|
|
explosion.style.opacity = '0'; |
|
|
|
|
|
|
|
|
createParticles(x, y); |
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
explosion.remove(); |
|
|
}, 500); |
|
|
}, 10); |
|
|
} |
|
|
|
|
|
function createLaunchTrail(startX, startY, endX, endY) { |
|
|
const trail = document.createElement('div'); |
|
|
trail.style.position = 'fixed'; |
|
|
trail.style.left = startX + 'px'; |
|
|
trail.style.top = startY + 'px'; |
|
|
trail.style.width = '4px'; |
|
|
trail.style.height = '4px'; |
|
|
trail.style.borderRadius = '50%'; |
|
|
trail.style.backgroundColor = '#FFD700'; |
|
|
trail.style.boxShadow = '0 0 6px 2px rgba(255, 215, 0, 0.7)'; |
|
|
document.body.appendChild(trail); |
|
|
|
|
|
const duration = 1500; |
|
|
const startTime = Date.now(); |
|
|
|
|
|
const animateTrail = () => { |
|
|
const elapsed = Date.now() - startTime; |
|
|
const progress = Math.min(elapsed / duration, 1); |
|
|
|
|
|
const currentX = startX + (endX - startX) * progress; |
|
|
const currentY = startY + (endY - startY) * progress; |
|
|
|
|
|
trail.style.left = currentX + 'px'; |
|
|
trail.style.top = currentY + 'px'; |
|
|
|
|
|
if (progress < 1) { |
|
|
requestAnimationFrame(animateTrail); |
|
|
} else { |
|
|
trail.remove(); |
|
|
createParticles(endX, endY); |
|
|
} |
|
|
}; |
|
|
|
|
|
requestAnimationFrame(animateTrail); |
|
|
} |
|
|
|
|
|
function createParticles(x, y) { |
|
|
const particleCount = 100; |
|
|
|
|
|
for(let i = 0; i < particleCount; i++) { |
|
|
const particle = document.createElement('div'); |
|
|
particle.className = 'firework-particle'; |
|
|
particle.style.backgroundColor = getRandomColor(); |
|
|
|
|
|
|
|
|
particle.style.left = x + 'px'; |
|
|
particle.style.top = y + 'px'; |
|
|
|
|
|
|
|
|
const angle = Math.random() * Math.PI * 2; |
|
|
|
|
|
const radius = Math.sqrt(Math.random()) * (100 + Math.random() * 200); |
|
|
const speed = 0.5 + Math.random() * 2; |
|
|
|
|
|
|
|
|
const initialX = Math.cos(angle) * radius; |
|
|
const initialY = Math.sin(angle) * radius; |
|
|
|
|
|
const velocity = { |
|
|
x: Math.cos(angle) * speed, |
|
|
y: Math.sin(angle) * speed |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const size = 2 + Math.random() * 10; |
|
|
particle.style.width = '0px'; |
|
|
particle.style.height = '0px'; |
|
|
particle.style.left = x + 'px'; |
|
|
particle.style.top = y + 'px'; |
|
|
particle.style.opacity = '0'; |
|
|
particle.style.transition = 'all 0.3s ease-out'; |
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
particle.style.left = (x + initialX) + 'px'; |
|
|
particle.style.top = (y + initialY) + 'px'; |
|
|
particle.style.width = size + 'px'; |
|
|
particle.style.height = size + 'px'; |
|
|
particle.style.opacity = '1'; |
|
|
}, Math.random() * 300); |
|
|
|
|
|
|
|
|
const duration = 1.5 + Math.random() * 1.5; |
|
|
particle.style.animationDuration = duration + 's'; |
|
|
|
|
|
document.body.appendChild(particle); |
|
|
|
|
|
|
|
|
let posX = x + initialX; |
|
|
let posY = y + initialY; |
|
|
let opacity = 1; |
|
|
let scale = 1; |
|
|
|
|
|
const animateParticle = () => { |
|
|
posX += velocity.x; |
|
|
|
|
|
|
|
|
velocity.x *= 0.95; |
|
|
velocity.y *= 0.95; |
|
|
velocity.y += 0.05; |
|
|
opacity -= 0.015; |
|
|
scale -= 0.005; |
|
|
|
|
|
particle.style.left = posX + 'px'; |
|
|
particle.style.top = posY + 'px'; |
|
|
particle.style.opacity = opacity; |
|
|
particle.style.transform = `scale(${scale})`; |
|
|
|
|
|
if(opacity > 0) { |
|
|
requestAnimationFrame(animateParticle); |
|
|
} else { |
|
|
particle.remove(); |
|
|
} |
|
|
}; |
|
|
|
|
|
requestAnimationFrame(animateParticle); |
|
|
} |
|
|
} |
|
|
|
|
|
function getRandomColor() { |
|
|
const colors = [ |
|
|
'#FF5252', '#FF4081', '#E040FB', '#7C4DFF', |
|
|
'#536DFE', '#448AFF', '#40C4FF', '#18FFFF', |
|
|
'#64FFDA', '#69F0AE', '#B2FF59', '#EEFF41', |
|
|
'#FFFF00', '#FFD740', '#FFAB40', '#FF6E40' |
|
|
]; |
|
|
return colors[Math.floor(Math.random() * colors.length)]; |
|
|
} |
|
|
</script> |
|
|
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=BHW/firework" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
|
|
</html> |