|
<!DOCTYPE html> |
|
<html lang="zh"> |
|
<head> |
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>春节拜年 - LINUX DO</title> |
|
<script src="https://cdn.tailwindcss.com"></script> |
|
<style> |
|
body { |
|
margin: 0; |
|
padding: 0; |
|
overflow: hidden; |
|
background-color: #ff4d4d; |
|
display: flex; |
|
justify-content: center; |
|
align-items: center; |
|
height: 100vh; |
|
position: relative; |
|
} |
|
|
|
canvas { |
|
position: absolute; |
|
top: 0; |
|
left: 0; |
|
width: 100%; |
|
height: 100%; |
|
pointer-events: none; |
|
z-index: 0; |
|
} |
|
|
|
.red-envelope { |
|
width: 200px; |
|
height: 300px; |
|
background-color: #d9534f; |
|
border-radius: 15px; |
|
position: absolute; |
|
top: 50%; |
|
left: 50%; |
|
transform: translate(-50%, -50%); |
|
overflow: hidden; |
|
z-index: 2; |
|
} |
|
|
|
.red-envelope .top { |
|
position: absolute; |
|
top: 0; |
|
left: 0; |
|
width: 100%; |
|
height: 0; |
|
background-color: #a92b29; |
|
animation: openTop 2s ease-out forwards; |
|
z-index: 1; |
|
} |
|
|
|
.red-envelope .top-text { |
|
position: absolute; |
|
top: 15%; |
|
left: 50%; |
|
transform: translateX(-50%); |
|
font-size: 16px; |
|
color: #fff; |
|
font-weight: bold; |
|
opacity: 0; |
|
animation: showText 2s 1.5s forwards; |
|
text-align: center; |
|
} |
|
|
|
.red-envelope .content { |
|
position: absolute; |
|
top: 50%; |
|
left: 50%; |
|
transform: translate(-50%, -50%); |
|
color: #fff; |
|
font-size: 24px; |
|
font-weight: bold; |
|
z-index: 0; |
|
opacity: 0; |
|
animation: showContent 2s 1.5s forwards; |
|
} |
|
|
|
@keyframes openTop { |
|
0% { |
|
height: 0; |
|
} |
|
100% { |
|
height: 33%; |
|
} |
|
} |
|
|
|
@keyframes showText { |
|
0% { |
|
opacity: 0; |
|
} |
|
100% { |
|
opacity: 1; |
|
} |
|
} |
|
|
|
@keyframes showContent { |
|
0% { |
|
opacity: 0; |
|
} |
|
100% { |
|
opacity: 1; |
|
} |
|
} |
|
|
|
.countdown { |
|
position: absolute; |
|
top: 10px; |
|
left: 10px; |
|
padding: 10px; |
|
background-color: rgba(0, 0, 0, 0.5); |
|
border-radius: 10px; |
|
color: white; |
|
font-size: 18px; |
|
font-weight: bold; |
|
backdrop-filter: blur(5px); |
|
z-index: 4; |
|
} |
|
|
|
.logo-container { |
|
position: absolute; |
|
bottom: 5%; |
|
text-align: center; |
|
z-index: 3; |
|
left: 50%; |
|
transform: translateX(-50%); |
|
} |
|
|
|
.logo-container img { |
|
width: 150px; |
|
height: auto; |
|
margin-bottom: 20px; |
|
} |
|
|
|
.logo-container .text { |
|
font-size: 24px; |
|
color: white; |
|
font-weight: bold; |
|
} |
|
|
|
.emoji { |
|
position: absolute; |
|
font-size: 2rem; |
|
pointer-events: none; |
|
animation: floatUp 2s ease-out forwards; |
|
} |
|
|
|
@keyframes floatUp { |
|
0% { |
|
opacity: 1; |
|
transform: translateY(0); |
|
} |
|
100% { |
|
opacity: 0; |
|
transform: translateY(-100px); |
|
} |
|
} |
|
|
|
.spark { |
|
width: 5px; |
|
height: 5px; |
|
border-radius: 50%; |
|
position: absolute; |
|
animation: explode 1s ease-out forwards; |
|
} |
|
|
|
@keyframes explode { |
|
0% { |
|
opacity: 1; |
|
transform: translate(0, 0); |
|
} |
|
100% { |
|
opacity: 0; |
|
transform: translate(var(--dx), var(--dy)); |
|
} |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<canvas id="fireworksCanvas"></canvas> |
|
<div class="red-envelope"> |
|
<div class="top"></div> |
|
<div class="top-text">富强民主文明和谐</div> |
|
<div class="content">LINUX DO</div> |
|
</div> |
|
<div class="logo-container"> |
|
<img src="https://linux.do/uploads/default/original/3X/a/8/a8168bb80c93075aad7aa1f598eee063adef1cb0.png" alt="LINUX DO Logo"> |
|
<div class="text">LINUX DO</div> |
|
</div> |
|
<div class="countdown" id="countdown"></div> |
|
|
|
<div id="fireworks-container" class="fixed top-0 left-0 w-full h-full pointer-events-none"></div> |
|
|
|
<script> |
|
|
|
const canvas = document.getElementById('fireworksCanvas'); |
|
const ctx = canvas.getContext('2d'); |
|
canvas.width = window.innerWidth; |
|
canvas.height = window.innerHeight; |
|
|
|
|
|
class Firework { |
|
constructor(x, y) { |
|
this.x = x; |
|
this.y = y; |
|
this.alpha = 1; |
|
this.particles = []; |
|
this.createParticles(); |
|
} |
|
|
|
createParticles() { |
|
const colors = ['#ffdf00', '#ff6347', '#32cd32', '#ff4500', '#00bfff', '#ff1493']; |
|
for (let i = 0; i < 500; i++) { |
|
this.particles.push(new Particle(this.x, this.y, colors[Math.floor(Math.random() * colors.length)])); |
|
} |
|
} |
|
|
|
update() { |
|
this.particles.forEach(particle => particle.update()); |
|
this.alpha -= 0.02; |
|
} |
|
|
|
draw() { |
|
this.particles.forEach(particle => particle.draw()); |
|
} |
|
|
|
isDead() { |
|
return this.alpha <= 0; |
|
} |
|
} |
|
|
|
class Particle { |
|
constructor(x, y, color) { |
|
this.x = x; |
|
this.y = y; |
|
this.color = color; |
|
this.size = Math.random() * 6 + 3; |
|
this.speedX = Math.random() * 12 - 6; |
|
this.speedY = Math.random() * 12 - 6; |
|
this.alpha = 1; |
|
this.lifeTime = Math.random() * 2 + 1; |
|
} |
|
|
|
update() { |
|
this.x += this.speedX; |
|
this.y += this.speedY; |
|
this.alpha -= 0.02; |
|
this.size *= 0.98; |
|
this.lifeTime -= 0.02; |
|
} |
|
|
|
draw() { |
|
ctx.beginPath(); |
|
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); |
|
ctx.fillStyle = this.color; |
|
ctx.globalAlpha = this.alpha; |
|
ctx.fill(); |
|
} |
|
} |
|
|
|
const fireworks = []; |
|
function createFirework(x, y) { |
|
fireworks.push(new Firework(x, y)); |
|
} |
|
|
|
function animate() { |
|
ctx.clearRect(0, 0, canvas.width, canvas.height); |
|
fireworks.forEach((firework, index) => { |
|
firework.update(); |
|
firework.draw(); |
|
if (firework.isDead()) { |
|
fireworks.splice(index, 1); |
|
} |
|
}); |
|
requestAnimationFrame(animate); |
|
} |
|
|
|
setInterval(() => { |
|
const randomX = Math.random() * canvas.width; |
|
const randomY = Math.random() * canvas.height; |
|
createFirework(randomX, randomY); |
|
}, Math.random() * 300 + 200); |
|
animate(); |
|
|
|
|
|
const emojis = ['🎉', '✨', '🎆', '🎇', '💥', '❤️', '🌟', '😊', '🥳', '🎊', '🎈', '🌸', '🌠', '🌈', '🔥']; |
|
|
|
|
|
function getRandomEmoji() { |
|
return emojis[Math.floor(Math.random() * emojis.length)]; |
|
} |
|
|
|
|
|
function createEmoji(x, y) { |
|
const emoji = document.createElement('div'); |
|
emoji.classList.add('emoji'); |
|
emoji.textContent = getRandomEmoji(); |
|
emoji.style.left = `${x}px`; |
|
emoji.style.top = `${y}px`; |
|
document.body.appendChild(emoji); |
|
|
|
|
|
setTimeout(() => { |
|
document.body.removeChild(emoji); |
|
}, 2000); |
|
} |
|
|
|
|
|
document.addEventListener('keydown', (event) => { |
|
const x = Math.random() * window.innerWidth; |
|
const y = Math.random() * window.innerHeight; |
|
createEmoji(x, y); |
|
}); |
|
|
|
document.addEventListener('click', (event) => { |
|
createEmoji(event.clientX, event.clientY); |
|
createFirework(event.clientX, event.clientY); |
|
}); |
|
|
|
|
|
function getChineseNewYearDate() { |
|
return new Date('2025-01-29T00:00:00'); |
|
} |
|
|
|
|
|
function updateCountdown() { |
|
const now = new Date(); |
|
const newYearDate = getChineseNewYearDate(); |
|
const timeDiff = newYearDate - now; |
|
|
|
if (timeDiff > 0) { |
|
const days = Math.floor(timeDiff / (1000 * 60 * 60 * 24)); |
|
const hours = Math.floor((timeDiff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); |
|
const minutes = Math.floor((timeDiff % (1000 * 60 * 60)) / (1000 * 60)); |
|
const seconds = Math.floor((timeDiff % (1000 * 60)) / 1000); |
|
document.getElementById('countdown').textContent = `距离新年还有 ${days}天 ${hours}时 ${minutes}分 ${seconds}秒`; |
|
} else { |
|
const daysSince = Math.floor(-timeDiff / (1000 * 60 * 60 * 24)); |
|
const hoursSince = Math.floor((-timeDiff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); |
|
const minutesSince = Math.floor((-timeDiff % (1000 * 60 * 60)) / (1000 * 60)); |
|
const secondsSince = Math.floor((-timeDiff % (1000 * 60)) / 1000); |
|
document.getElementById('countdown').textContent = `新的一年已经开始了 ${daysSince}天 ${hoursSince}时 ${minutesSince}分 ${secondsSince}秒`; |
|
} |
|
} |
|
|
|
setInterval(updateCountdown, 1000); |
|
updateCountdown(); |
|
</script> |
|
</body> |
|
</html> |