cmsn
2 hours ago in Plain Text
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<title>Chúc mừng sinh nhật 🎂</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background: radial-gradient(circle at center, #000010, #000);
color: #fff;
font-family: "Comic Sans MS", sans-serif;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.message {
position: relative;
font-size: 2em;
white-space: nowrap;
animation: moveText 10s linear infinite;
z-index: 2;
text-shadow: 0 0 10px #ff9, 0 0 20px #f39;
}
@keyframes moveText {
0% { left: 100%; }
100% { left: -100%; }
}
canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 1;
}
</style>
</head>
<body>
<div class="message">
🎉 Chúc em Nguyễn Thế Đạt tuổi mới bớt ăn hại, có được nhiều tiền, đạt được HSG năm nay và được điểm cao tất cả các môn thi 💖💖💖🎆
</div>
<canvas id="fireworksCanvas"></canvas>
<script>
const canvas = document.getElementById('fireworksCanvas');
const ctx = canvas.getContext('2d');
let cw = canvas.width = window.innerWidth;
let ch = canvas.height = window.innerHeight;
window.addEventListener('resize', () => {
cw = canvas.width = window.innerWidth;
ch = canvas.height = window.innerHeight;
});
class Firework {
constructor() {
this.x = Math.random()*cw;
this.y = ch;
this.targetY = Math.random()*ch/2;
this.speedY = (this.y - this.targetY)/30;
this.exploded = false;
this.particles = [];
}
update() {
if (!this.exploded) {
this.y -= this.speedY;
if (this.y <= this.targetY) {
this.exploded = true;
for (let i=0; i<60; i++) {
this.particles.push(new Particle(this.x, this.y));
}
}
}
this.particles.forEach(p => p.update());
}
draw() {
if (!this.exploded) {
ctx.beginPath();
ctx.arc(this.x, this.y, 3, 0, Math.PI*2);
ctx.fillStyle = 'white';
ctx.fill();
}
this.particles.forEach(p => p.draw());
}
}
class Particle {
constructor(x,y) {
this.x = x;
this.y = y;
this.vx = (Math.random()-0.5)*6;
this.vy = (Math.random()-0.5)*6;
this.alpha = 1;
this.color = `hsl(${Math.random()*360},100%,60%)`;
}
update() {
this.x += this.vx;
this.y += this.vy;
this.vy += 0.03; // trọng lực nhẹ
this.alpha -= 0.02;
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, 2, 0, Math.PI*2);
ctx.fillStyle = this.color.replace(')', `,${this.alpha})`).replace('hsl', 'hsla');
ctx.fill();
}
}
const fireworks = [];
function animate() {
requestAnimationFrame(animate);
ctx.fillStyle = 'rgba(0,0,0,0.2)';
ctx.fillRect(0,0,cw,ch);
if (Math.random() < 0.03) fireworks.push(new Firework());
fireworks.forEach((f,i) => {
f.update();
f.draw();
if (f.exploded && f.particles.every(p => p.alpha <= 0)) fireworks.splice(i,1);
});
}
animate();
</script>
</body>
</html>