:root {
–pink: #ff6b9d;
–purple: #6c5ce7;
–gold: #ffd700;
–white: #f8f5ff;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 100vw;
height: 100vh;
height: 100dvh;
overflow: hidden;
font-family: -apple-system, BlinkMacSystemFont, “PingFang SC”, “Microsoft YaHei”, sans-serif;
background: #0a0015;
touch-action: manipulation;
-webkit-tap-highlight-color: transparent;
user-select: none;
-webkit-user-select: none;
}
/* ========== 星空画布 ========== */
#starCanvas {
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
z-index: 1;
}
/* ========== 月亮 ========== */
.moon {
position: fixed;
top: 8%;
right: 12%;
width: 80px;
height: 80px;
z-index: 2;
animation: moonGlow 3s ease-in-out infinite;
}
.moon-body {
width: 100%; height: 100%;
border-radius: 50%;
background: radial-gradient(circle at 35% 35%, #fffde7, #ffe082, #ffcc02);
box-shadow: 0 0 40px rgba(255,215,0,0.5), 0 0 80px rgba(255,215,0,0.25), 0 0 120px rgba(255,215,0,0.1);
}
.moon-crater {
position: absolute;
border-radius: 50%;
background: rgba(255,183,0,0.3);
}
.moon-crater:nth-child(2) { width: 14px; height: 14px; top: 25%; left: 55%; }
.moon-crater:nth-child(3) { width: 8px; height: 8px; top: 50%; left: 40%; }
.moon-crater:nth-child(4) { width: 10px; height: 10px; top: 60%; left: 60%; }
@keyframes moonGlow {
0%, 100% { filter: brightness(1); }
50% { filter: brightness(1.15); }
}
/* ========== 云朵装饰 ========== */
.clouds {
position: fixed;
inset: 0;
z-index: 2;
pointer-events: none;
}
.cloud {
position: absolute;
background: rgba(255,255,255,0.04);
border-radius: 50%;
filter: blur(30px);
}
.cloud:nth-child(1) { width: 200px; height: 60px; top: 15%; left: -50px; animation: drift 25s linear infinite; }
.cloud:nth-child(2) { width: 160px; height: 50px; top: 30%; right: -60px; animation: drift 30s linear infinite reverse; }
.cloud:nth-child(3) { width: 240px; height: 70px; top: 55%; left: -80px; animation: drift 35s linear infinite; }
.cloud:nth-child(4) { width: 180px; height: 55px; top: 70%; right: -40px; animation: drift 28s linear infinite reverse; }
@keyframes drift {
from { transform: translateX(0); }
to { transform: translateX(calc(100vw + 400px)); }
}
/* ========== 主内容层 ========== */
.main-content {
position: fixed;
inset: 0;
z-index: 10;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
pointer-events: none;
}
/* ========== 标题区域 ========== */
.title-area {
text-align: center;
pointer-events: auto;
}
.greeting {
font-size: clamp(1.2rem, 3vw, 1.6rem);
color: rgba(255,255,255,0.8);
font-weight: 300;
letter-spacing: 0.2em;
margin-bottom: 8px;
animation: fadeInDown 1.2s ease-out;
}
.title {
font-size: clamp(3rem, 8vw, 5rem);
font-weight: 700;
background: linear-gradient(135deg, #ff6b9d, #ffd700, #ff6b9d);
background-size: 200% 200%;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
animation: gradientShift 3s ease-in-out infinite, fadeInUp 1s ease-out;
line-height: 1.2;
}
.subtitle {
font-size: clamp(0.9rem, 2vw, 1.1rem);
color: rgba(255,255,255,0.5);
margin-top: 12px;
letter-spacing: 0.15em;
animation: fadeInUp 1.4s ease-out;
}
@keyframes fadeInDown {
from { opacity: 0; transform: translateY(-30px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(30px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes gradientShift {
0%, 100% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
}
/* ========== 消息卡片 ========== */
.message-card {
margin-top: 32px;
padding: 24px 32px;
background: rgba(255,255,255,0.06);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(255,255,255,0.12);
border-radius: 20px;
max-width: 360px;
width: 85%;
text-align: center;
pointer-events: auto;
animation: fadeInUp 1.6s ease-out;
transition: all 0.5s ease;
}
.message-card:hover {
background: rgba(255,255,255,0.1);
border-color: rgba(255,107,157,0.3);
box-shadow: 0 8px 40px rgba(255,107,157,0.1);
}
.message-text {
font-size: clamp(0.95rem, 2.2vw, 1.1rem);
color: rgba(255,255,255,0.85);
line-height: 2;
letter-spacing: 0.05em;
}
.message-text .highlight {
color: #ffd700;
font-weight: 600;
}
.message-text .pink {
color: #ff6b9d;
font-weight: 600;
}
/* ========== 点击提示 ========== */
.hint {
margin-top: 28px;
display: flex;
align-items: center;
gap: 8px;
color: rgba(255,255,255,0.4);
font-size: 0.85rem;
animation: fadeInUp 2s ease-out, pulse 2s ease-in-out infinite;
pointer-events: auto;
}
.hint-dot {
width: 6px; height: 6px;
border-radius: 50%;
background: #ffd700;
animation: hintDot 1.5s ease-in-out infinite;
}
.hint-dot:nth-child(2) { animation-delay: 0.3s; }
.hint-dot:nth-child(3) { animation-delay: 0.6s; }
@keyframes hintDot {
0%, 100% { opacity: 0.3; transform: scale(0.8); }
50% { opacity: 1; transform: scale(1.2); }
}
@keyframes pulse {
0%, 100% { opacity: 0.4; }
50% { opacity: 0.7; }
}
/* ========== 页脚 ========== */
.footer {
position: fixed;
bottom: 24px;
z-index: 10;
color: rgba(255,255,255,0.25);
font-size: 0.75rem;
letter-spacing: 0.1em;
pointer-events: auto;
animation: fadeInUp 2.2s ease-out;
}
/* ========== 响应式 ========== */
@media (max-width: 480px) {
.moon { width: 60px; height: 60px; top: 6%; right: 10%; }
.message-card { padding: 20px 24px; margin-top: 24px; }
}
/* ========== 粒子爆发的CSS爱心(用于点击特效) ========== */
.float-heart {
position: fixed;
pointer-events: none;
z-index: 5;
font-size: 24px;
animation: floatUp 3s ease-out forwards;
opacity: 0;
}
@keyframes floatUp {
0% { opacity: 1; transform: translateY(0) scale(0.5) rotate(0deg); }
20% { opacity: 1; transform: translateY(-20px) scale(1.1) rotate(10deg); }
100% { opacity: 0; transform: translateY(-280px) scale(0.3) rotate(-20deg); }
}
很高兴认识你
520
✦ 认识你的一周,每一天都很特别 ✦
七天前,我们第一次见面
三次约会,一次比一次期待
昨天一起看的电影
是我这周最开心的时刻
希望在未来的日子里
能有更多机会
和你一起看更多的风景 🌙
点一点屏幕
// ========== 星空画布 ==========
const canvas = document.getElementById(‘starCanvas’);
const ctx = canvas.getContext(‘2d’);
let stars = [];
let dpr = window.devicePixelRatio || 1;
function resizeCanvas() {
canvas.width = window.innerWidth * dpr;
canvas.height = window.innerHeight * dpr;
canvas.style.width = window.innerWidth + ‘px’;
canvas.style.height = window.innerHeight + ‘px’;
ctx.scale(dpr, dpr);
}
function createStars(count) {
stars = [];
const w = window.innerWidth;
const h = window.innerHeight;
for (let i = 0; i < count; i++) {
stars.push({
x: Math.random() * w,
y: Math.random() * h,
r: Math.random() * 1.8 + 0.4,
t: Math.random() * Math.PI * 2,
speed: Math.random() * 0.008 + 0.003,
opacity: Math.random(),
opacitySpeed: Math.random() * 0.015 + 0.005,
hue: Math.random() 1 || s.opacity 1.2 && s.opacity > 0.7) {
ctx.strokeStyle = `rgba(255,255,255,${alpha * 0.3})`;
ctx.lineWidth = 0.5;
ctx.beginPath();
ctx.moveTo(s.x – s.r * 3, s.y);
ctx.lineTo(s.x + s.r * 3, s.y);
ctx.moveTo(s.x, s.y – s.r * 3);
ctx.lineTo(s.x, s.y + s.r * 3);
ctx.stroke();
}
}
}
function animateStars() {
drawStars();
requestAnimationFrame(animateStars);
}
// ========== 点击爱心特效 ==========
const heartEmojis = [‘💕’, ‘💖’, ‘💗’, ‘💝’, ‘✨’, ‘💫’, ‘🌟’, ‘💛’, ‘🧡’, ‘❤️’, ‘🩷’, ‘💘’];
function spawnHeart(x, y) {
const el = document.createElement(‘span’);
el.className = ‘float-heart’;
el.textContent = heartEmojis[Math.floor(Math.random() * heartEmojis.length)];
el.style.left = x + ‘px’;
el.style.top = y + ‘px’;
el.style.fontSize = (Math.random() * 20 + 18) + ‘px’;
el.style.animationDuration = (Math.random() * 1.5 + 2.5) + ‘s’;
document.body.appendChild(el);
el.addEventListener(‘animationend’, () => el.remove());
}
// 批量爱心爆发
function burstHearts(x, y, count) {
for (let i = 0; i {
const ox = (Math.random() – 0.5) * 80;
const oy = (Math.random() – 0.5) * 40;
spawnHeart(x + ox, y + oy);
}, i * 60);
}
}
// ========== 事件监听 ==========
let heartCount = 0;
const hintEl = document.getElementById(‘hint’);
const messageCard = document.getElementById(‘messageCard’);
function handleInteraction(e) {
const x = e.touches ? e.touches[0].clientX : e.clientX;
const y = e.touches ? e.touches[0].clientY : e.clientY;
spawnHeart(x, y);
heartCount++;
// 点够5次后隐藏提示
if (heartCount >= 5 && hintEl.style.opacity !== ‘0’) {
hintEl.style.transition = ‘opacity 0.8s’;
hintEl.style.opacity = ‘0’;
setTimeout(() => { hintEl.style.display = ‘none’; }, 800);
}
// 每10次来一波爆发
if (heartCount % 10 === 0) {
burstHearts(x, y, 8);
}
}
document.addEventListener(‘click’, handleInteraction);
document.addEventListener(‘touchstart’, handleInteraction, { passive: true });
// ========== 初始化 ==========
resizeCanvas();
createStars(180);
animateStars();
window.addEventListener(‘resize’, () => {
resizeCanvas();
createStars(180);
});
// ========== 卡片微动效:随陀螺仪倾斜 ==========
if (window.DeviceOrientationEvent && ‘ontouchstart’ in window) {
window.addEventListener(‘deviceorientation’, (e) => {
const x = e.gamma / 45; // -1 to 1
const y = e.beta / 45;
messageCard.style.transform = `perspective(500px) rotateY(${x * 3}deg) rotateX(${-y * 3}deg)`;
});
}
// ========== 定时流星 ==========
function shootingStar() {
const w = window.innerWidth;
const h = window.innerHeight;
const sx = Math.random() * w * 0.6;
const sy = Math.random() * h * 0.3;
const ex = sx + 100 + Math.random() * 150;
const ey = sy + 80 + Math.random() * 120;
const trail = ctx.createLinearGradient(sx, sy, ex, ey);
trail.addColorStop(0, ‘rgba(255,255,255,0)’);
trail.addColorStop(1, ‘rgba(255,255,255,0.8)’);
// 在canvas上画流星(需要一个特殊处理)
// 用DOM元素实现更简单
const meteor = document.createElement(‘div’);
meteor.style.cssText = `
position: fixed; pointer-events: none; z-index: 3;
width: 2px; height: 80px;
background: linear-gradient(to bottom, transparent, rgba(255,255,255,0.9), rgba(255,215,0,0.7));
border-radius: 50%;
left: ${sx}px; top: ${sy}px;
transform: rotate(-30deg);
animation: meteorFall 0.8s ease-in forwards;
opacity: 0;
`;
document.body.appendChild(meteor);
// 动态添加动画
const style = document.createElement(‘style’);
style.textContent = `
@keyframes meteorFall {
0% { opacity: 0; transform: rotate(-30deg) translateX(0) translateY(0); }
10% { opacity: 1; }
100% { opacity: 0; transform: rotate(-30deg) translateX(160px) translateY(100px); }
}
`;
document.head.appendChild(style);
meteor.addEventListener(‘animationend’, () => {
meteor.remove();
style.remove();
});
// 随机间隔再触发
const nextDelay = 8000 + Math.random() * 15000;
setTimeout(shootingStar, nextDelay);
}
setTimeout(() => shootingStar(), 5000);
// ========== 星空画布 ==========
const canvas = document.getElementById(‘starCanvas’);
const ctx = canvas.getContext(‘2d’);
let stars = [];
let dpr = window.devicePixelRatio || 1;
function resizeCanvas() {
canvas.width = window.innerWidth * dpr;
canvas.height = window.innerHeight * dpr;
canvas.style.width = window.innerWidth + ‘px’;
canvas.style.height = window.innerHeight + ‘px’;
ctx.scale(dpr, dpr);
}
function createStars(count) {
stars = [];
const w = window.innerWidth;
const h = window.innerHeight;
for (let i = 0; i < count; i++) {
stars.push({
x: Math.random() * w,
y: Math.random() * h,
r: Math.random() * 1.8 + 0.4,
t: Math.random() * Math.PI * 2,
speed: Math.random() * 0.008 + 0.003,
opacity: Math.random(),
opacitySpeed: Math.random() * 0.015 + 0.005,
hue: Math.random() 1 || s.opacity 1.2 && s.opacity > 0.7) {
ctx.strokeStyle = `rgba(255,255,255,${alpha * 0.3})`;
ctx.lineWidth = 0.5;
ctx.beginPath();
ctx.moveTo(s.x – s.r * 3, s.y);
ctx.lineTo(s.x + s.r * 3, s.y);
ctx.moveTo(s.x, s.y – s.r * 3);
ctx.lineTo(s.x, s.y + s.r * 3);
ctx.stroke();
}
}
}
function animateStars() {
drawStars();
requestAnimationFrame(animateStars);
}
// ========== 点击爱心特效 ==========
const heartEmojis = [‘💕’, ‘💖’, ‘💗’, ‘💝’, ‘✨’, ‘💫’, ‘🌟’, ‘💛’, ‘🧡’, ‘❤️’, ‘🩷’, ‘💘’];
function spawnHeart(x, y) {
const el = document.createElement(‘span’);
el.className = ‘float-heart’;
el.textContent = heartEmojis[Math.floor(Math.random() * heartEmojis.length)];
el.style.left = x + ‘px’;
el.style.top = y + ‘px’;
el.style.fontSize = (Math.random() * 20 + 18) + ‘px’;
el.style.animationDuration = (Math.random() * 1.5 + 2.5) + ‘s’;
document.body.appendChild(el);
el.addEventListener(‘animationend’, () => el.remove());
}
// 批量爱心爆发
function burstHearts(x, y, count) {
for (let i = 0; i {
const ox = (Math.random() – 0.5) * 80;
const oy = (Math.random() – 0.5) * 40;
spawnHeart(x + ox, y + oy);
}, i * 60);
}
}
// ========== 事件监听 ==========
let heartCount = 0;
const hintEl = document.getElementById(‘hint’);
const messageCard = document.getElementById(‘messageCard’);
function handleInteraction(e) {
const x = e.touches ? e.touches[0].clientX : e.clientX;
const y = e.touches ? e.touches[0].clientY : e.clientY;
spawnHeart(x, y);
heartCount++;
// 点够5次后隐藏提示
if (heartCount >= 5 && hintEl.style.opacity !== ‘0’) {
hintEl.style.transition = ‘opacity 0.8s’;
hintEl.style.opacity = ‘0’;
setTimeout(() => { hintEl.style.display = ‘none’; }, 800);
}
// 每10次来一波爆发
if (heartCount % 10 === 0) {
burstHearts(x, y, 8);
}
}
document.addEventListener(‘click’, handleInteraction);
document.addEventListener(‘touchstart’, handleInteraction, { passive: true });
// ========== 初始化 ==========
resizeCanvas();
createStars(180);
animateStars();
window.addEventListener(‘resize’, () => {
resizeCanvas();
createStars(180);
});
// ========== 卡片微动效:随陀螺仪倾斜 ==========
if (window.DeviceOrientationEvent && ‘ontouchstart’ in window) {
window.addEventListener(‘deviceorientation’, (e) => {
const x = e.gamma / 45; // -1 to 1
const y = e.beta / 45;
messageCard.style.transform = `perspective(500px) rotateY(${x * 3}deg) rotateX(${-y * 3}deg)`;
});
}
// ========== 定时流星 ==========
function shootingStar() {
const w = window.innerWidth;
const h = window.innerHeight;
const sx = Math.random() * w * 0.6;
const sy = Math.random() * h * 0.3;
const ex = sx + 100 + Math.random() * 150;
const ey = sy + 80 + Math.random() * 120;
const trail = ctx.createLinearGradient(sx, sy, ex, ey);
trail.addColorStop(0, ‘rgba(255,255,255,0)’);
trail.addColorStop(1, ‘rgba(255,255,255,0.8)’);
// 在canvas上画流星(需要一个特殊处理)
// 用DOM元素实现更简单
const meteor = document.createElement(‘div’);
meteor.style.cssText = `
position: fixed; pointer-events: none; z-index: 3;
width: 2px; height: 80px;
background: linear-gradient(to bottom, transparent, rgba(255,255,255,0.9), rgba(255,215,0,0.7));
border-radius: 50%;
left: ${sx}px; top: ${sy}px;
transform: rotate(-30deg);
animation: meteorFall 0.8s ease-in forwards;
opacity: 0;
`;
document.body.appendChild(meteor);
// 动态添加动画
const style = document.createElement(‘style’);
style.textContent = `
@keyframes meteorFall {
0% { opacity: 0; transform: rotate(-30deg) translateX(0) translateY(0); }
10% { opacity: 1; }
100% { opacity: 0; transform: rotate(-30deg) translateX(160px) translateY(100px); }
}
`;
document.head.appendChild(style);
meteor.addEventListener(‘animationend’, () => {
meteor.remove();
style.remove();
});
// 随机间隔再触发
const nextDelay = 8000 + Math.random() * 15000;
setTimeout(shootingStar, nextDelay);
}
setTimeout(() => shootingStar(), 5000);
声明:本站所有文章,如无特殊说明或标注,均来自于互联网,下载的软件和资源请在24小时之内删除,本站提供的资源只可作为下载、学习交流使用,其版权归原作者所有,其产生的任何后果均自己承担,本站不作任何责任承担,具体可查看本站
免责声明。如已声明或标注原创,任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理,客服链接:
点此前往,投诉邮箱:
nc08wlkj@163.com。