| <!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="linux.do.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> |