Follow us on the instagram please
Full code is :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Valentine's Week Surprise</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background: linear-gradient(135deg, #ffccd5, #ffe6f0);
overflow: hidden;
font-family: Arial, sans-serif;
}
.mail-wrapper {
position: relative;
width: 220px;
height: 160px;
background: #fff;
border-radius: 10px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
z-index: 2;
animation: tiltBounce 2s infinite ease-in-out;
transition: opacity 0.5s ease-in-out, transform 0.3s ease-in-out;
}
.mail-wrapper:hover {
animation: none; /* Stop tilting on hover */
transform: scale(1.05); /* Slight zoom on hover */
}
.mail-wrapper.hide {
opacity: 0;
}
@keyframes tiltBounce {
0% { transform: rotate(0deg); }
25% { transform: rotate(-10deg); }
50% { transform: rotate(10deg); }
75% { transform: rotate(-5deg); }
100% { transform: rotate(0deg); }
}
.mail-wrapper::before {
content: "";
position: absolute;
top: 0;
transform: rotate(180deg);
width: 210px;
height: 60px;
background: #e74c3c;
clip-path: polygon(50% 0, 100% 100%, 0 100%);
}
.heart {
font-size: 50px;
transition: transform 0.3s ease-in-out;
}
.mail-wrapper:hover .heart {
transform: scale(1.2);
}
.letter {
position: absolute;
padding: 8px;
bottom: -160px;
width: 200px;
height: 200px;
background: #fff;
border-radius: 10px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
transform: translateY(0);
transition: transform 0.8s ease-in-out, opacity 0.5s ease-in-out;
opacity: 0;
z-index: 1; /* Appear behind the mail wrapper */
}
.letter.show {
position: absolute;
top:400px;
transform: translateY(-180px); /* Move up from behind the mail */
opacity: 1;
z-index: 3; /* Bring above the mail wrapper */
}
.letter h2 {
font-family: 'Brush Script MT', cursive;
color: #e74c3c;
font-size: 24px;
}
.letter p {
font-size: 14px;
color: #444;
text-align: center;
padding: 5px;
}
.letter .small-hearts {
display: flex;
gap: 5px;
margin-top: 5px;
}
.letter .small-hearts span {
font-size: 20px;
}
.heart-rain {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
.heart-rain span {
position: absolute;
bottom: 100%;
font-size: 24px;
opacity: 0.9;
animation: fall linear infinite;
}
@keyframes fall {
0% { transform: translateY(0); opacity: 1; }
100% { transform: translateY(100vh); opacity: 0; }
}
</style>
</head>
<body>
<div class="mail-wrapper" id="mailWrapper" onclick="openLetter()">
<div class="heart">💌</div>
</div>
<div class="letter" id="letter">
<h2>Happy Valentine's Week</h2>
<p>"You're the reason hearts keep falling all around! 💕"</p>
<div class="small-hearts">
<span>❤️</span><span>💖</span><span>💘</span>
</div>
</div>
<div class="heart-rain" id="heartRain"></div>
<script>
const heartEmojis = ['❤️', '💙', '💜', '💛', '💚', '🧡', '🤎', '🖤', '🤍', '💖', '💘', '💝'];
function openLetter() {
document.getElementById("letter").classList.add("show");
document.getElementById("mailWrapper").classList.add("hide");
startContinuousHeartRain();
}
function startContinuousHeartRain() {
setInterval(() => {
createHeart();
}, 200); // Hearts keep falling every 200ms
}
function createHeart() {
const heartContainer = document.getElementById("heartRain");
const heart = document.createElement("span");
heart.innerHTML = heartEmojis[Math.floor(Math.random() * heartEmojis.length)];
heart.style.left = Math.random() * window.innerWidth + "px";
heart.style.animationDuration = (Math.random() * 3 + 2) + "s"; // Random fall speed
heartContainer.appendChild(heart);
// Remove heart after it falls
setTimeout(() => heart.remove(), 5000);
}
</script>
</body>
</html>
Top comments (1)
<!DOCTYPE html>
<br> * {<br> margin: 0;<br> padding: 0;<br> box-sizing: border-box;<br> user-select: none;<br> }<br> html, body {<br> width: 100%;<br> height: 100%;<br> overflow: hidden;<br> background: #000;<br> font-family: Arial, sans-serif;<br> }<br> canvas {<br> display: block;<br> width: 100vw;<br> height: 100vh;<br> }<br>
<br> const canvas = document.getElementById("c");<br> const ctx = canvas.getContext("2d");<br> let W, H, CX, CY, SCALE;<br> const DPR = Math.min(window.devicePixelRatio || 1, 2);<br> const text = "I love you";<br> const points = [];<br> const TOTAL = 95; // menos puntos = menos amontonado, más limpio</p> <div class="highlight"><pre class="highlight plaintext"><code>function resize() { W = window.innerWidth; H = window.innerHeight; canvas.width = W * DPR; canvas.height = H * DPR; canvas.style.width = W + "px"; canvas.style.height = H + "px"; ctx.setTransform(1, 0, 0, 1, 0, 0); ctx.scale(DPR, DPR); CX = W / 2; CY = H / 2 + 20; // tamaño adaptado a celular SCALE = Math.min(W, H) * 0.014; buildPoints(); } // Ecuación clásica del corazón function heart(t) { const x = 16 * Math.pow(Math.sin(t), 3); const y = 13 * Math.cos(t) - 5 * Math.cos(2*t) - 2 * Math.cos(3*t) - Math.cos(4*t); return { x: x * SCALE, y: -y * SCALE }; } function buildPoints() { points.length = 0; for (let i = 0; i < TOTAL; i++) { const t = (i / TOTAL) * Math.PI * 2; points.push({ baseT: t, phase: Math.random() * Math.PI * 2 }); } } // Completed your glowing text drawing logic function glowText(txt, x, y, angle, size, alpha = 1) { ctx.save(); ctx.translate(x, y); ctx.rotate(angle); ctx.font = `bold ${size}px Arial, sans-serif`; ctx.textAlign = "center"; ctx.textBaseline = "middle"; // Glow fuerte tipo neón ctx.shadowColor = "rgba(255, 120, 190, 0.95)"; ctx.shadowBlur = 15; // Multiple fills layer the glow intensity ctx.fillStyle = `rgba(255, 180, 210, ${alpha})`; ctx.fillText(txt, 0, 0); ctx.shadowBlur = 4; ctx.fillStyle = `rgba(255, 255, 255, ${alpha})`; ctx.fillText(txt, 0, 0); ctx.restore(); } // New animation loop function to make it pulse dynamically function loop(now) { ctx.fillStyle = "rgba(0, 0, 0, 0.15)"; // Soft trailing effect ctx.fillRect(0, 0, W, H); const time = now * 0.002; points.forEach((p) => { // Calculate tangent angle for text alignment along the heart border const delta = 0.01; const pos = heart(p.baseT); const posNext = heart(p.baseT + delta); const angle = Math.atan2(posNext.y - pos.y, posNext.x - pos.x); // Gentle individual pulse movement offset const pulse = Math.sin(time + p.phase) * 3; const finalX = CX + pos.x + Math.cos(angle + Math.PI/2) * pulse; const finalY = CY + pos.y + Math.sin(angle + Math.PI/2) * pulse; // Dynamic sizing for fluid neon look const size = Math.max(10, SCALE * 0.9 + Math.sin(time + p.phase) * 2); glowText(text, finalX, finalY, angle, size, 0.85); }); requestAnimationFrame(loop); } // Event listeners and initial startup window.addEventListener("resize", resize); resize(); requestAnimationFrame(loop); </code></pre></div> <p>