首页:恢复星空层,门户区块背景透明以透出星云

Made-with: Cursor
This commit is contained in:
whm
2026-03-24 15:28:03 +08:00
parent 5ea23ba657
commit 65d5e425d7

View File

@@ -1,10 +1,7 @@
<template>
<div class="landing">
<div class="space-bg"></div>
<div class="stars" ref="starsEl"></div>
<div class="planet planet-1"></div>
<div class="planet planet-2"></div>
<div class="planet planet-3"></div>
<div ref="starsEl" class="stars" aria-hidden="true"></div>
<nav class="navbar" :style="navbarStyle">
<a href="#intro" class="logo-space" @click.prevent="scrollToSel('#intro')">
@@ -366,9 +363,32 @@ function socialListImgSrc(item) {
return list[i]
}
const starsEl = ref(null)
let cometTimer = null
const scrollY = ref(0)
const starsEl = ref(null)
function addStars() {
const host = starsEl.value
if (!host) return
host.innerHTML = ''
const w = window.innerWidth
const h = window.innerHeight
const n = Math.min(220, Math.max(80, Math.floor((w * h) / 10000)))
const frag = document.createDocumentFragment()
for (let i = 0; i < n; i++) {
const star = document.createElement('span')
star.className = 'star'
const r = Math.random()
const size = r < 0.82 ? 1 : r < 0.97 ? 2 : 3
star.style.width = `${size}px`
star.style.height = `${size}px`
star.style.left = `${Math.random() * 100}%`
star.style.top = `${Math.random() * 100}%`
star.style.animationDuration = `${2.2 + Math.random() * 4}s`
star.style.animationDelay = `${Math.random() * 5}s`
frag.appendChild(star)
}
host.appendChild(frag)
}
const openFaq = ref(0)
/** 官网 site_idbootstrap 已拉路由时此处已有值;产品视频:静态优先,否则 promotion-media API */
const webSiteId = ref(getCachedWebSiteId() || '')
@@ -648,43 +668,6 @@ function onScroll() {
scrollY.value = window.pageYOffset || 0
}
function addStars() {
if (!starsEl.value) return
for (let i = 0; i < 200; i++) {
const star = document.createElement('div')
star.className = 'star'
star.style.left = Math.random() * 100 + '%'
star.style.top = Math.random() * 100 + '%'
const size = Math.random() * 2 + 1
star.style.width = size + 'px'
star.style.height = size + 'px'
star.style.setProperty('--duration', (Math.random() * 3 + 2) + 's')
star.style.setProperty('--min-opacity', Math.random() * 0.3 + 0.1)
star.style.animationDelay = Math.random() * 5 + 's'
starsEl.value.appendChild(star)
}
}
function createComet() {
const root = document.getElementById('app') || document.body
const comet = document.createElement('div')
comet.className = 'comet'
comet.style.top = Math.random() * 60 + '%'
comet.style.left = '-100px'
comet.style.transform = 'rotate(' + (Math.random() * 30 - 15) + 'deg)'
root.appendChild(comet)
let position = -100
const speed = Math.random() * 3 + 2
function move() {
position += speed
comet.style.left = position + 'px'
comet.style.opacity = (position > window.innerWidth * 0.3 && position < window.innerWidth * 0.7) ? 1 : 0
if (position < window.innerWidth + 100) requestAnimationFrame(move)
else comet.remove()
}
move()
}
async function fetchHomepage() {
try {
const url = apiBase ? `${apiBase}/api/web/homepage` : '/api/web/homepage'
@@ -720,7 +703,6 @@ onMounted(() => {
document.addEventListener('keydown', onDocKeydown)
nextTick(() => {
addStars()
cometTimer = setInterval(createComet, 3000)
const hash = window.location.hash
if (hash) {
setTimeout(() => {
@@ -731,7 +713,6 @@ onMounted(() => {
})
onUnmounted(() => {
if (cometTimer) clearInterval(cometTimer)
window.removeEventListener('scroll', onScroll)
document.removeEventListener('keydown', onDocKeydown)
})
@@ -775,41 +756,26 @@ onUnmounted(() => {
radial-gradient(ellipse at 50% 50%, rgba(0,0,0,0) 0%, var(--space-dark) 100%);
}
.stars { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 1; pointer-events: none; }
.landing .stars .star {
position: absolute; background: #fff; border-radius: 50%;
animation: landing-twinkle var(--duration, 2.5s) ease-in-out infinite;
will-change: opacity, transform;
.stars {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
pointer-events: none;
overflow: hidden;
}
.stars .star {
position: absolute;
border-radius: 50%;
background: rgba(255, 255, 255, 0.95);
box-shadow: 0 0 3px rgba(255, 255, 255, 0.7);
animation: landing-twinkle ease-in-out infinite;
}
@keyframes landing-twinkle {
0%, 100% { opacity: var(--min-opacity, 0.3); transform: scale(1); }
50% { opacity: 1; transform: scale(1.2); }
}
.comet {
position: fixed; width: 120px; height: 3px; z-index: 1; pointer-events: none;
background: linear-gradient(90deg, rgba(255,255,255,0.9) 0%, transparent 100%);
border-radius: 2px; box-shadow: 0 0 10px rgba(255,255,255,0.6);
}
.planet { position: fixed; border-radius: 50%; z-index: 2; pointer-events: none; }
.planet-1 {
width: 300px; height: 300px; top: 10%; right: -100px;
background: linear-gradient(135deg, var(--nebula-purple), #1a0a2e);
box-shadow: inset -30px -30px 60px rgba(0,0,0,0.5), 0 0 60px rgba(74,26,107,0.4);
opacity: 0.6;
}
.planet-2 {
width: 150px; height: 150px; bottom: 20%; left: -50px;
background: linear-gradient(135deg, var(--space-blue), #0a1520);
box-shadow: inset -20px -20px 40px rgba(0,0,0,0.5), 0 0 40px rgba(30,58,95,0.4);
opacity: 0.5;
}
.planet-3 {
width: 80px; height: 80px; top: 60%; right: 15%;
background: linear-gradient(135deg, #ff6b35, #8b3a00);
box-shadow: inset -10px -10px 20px rgba(0,0,0,0.5), 0 0 30px rgba(255, 107, 53, 0.4);
opacity: 0.4;
0%, 100% { opacity: 0.35; transform: scale(1); }
50% { opacity: 1; transform: scale(1.05); }
}
.navbar {
@@ -949,7 +915,7 @@ onUnmounted(() => {
.portal-shell {
position: relative;
z-index: 10;
background: linear-gradient(180deg, rgba(10, 12, 22, 0.4) 0%, rgba(18, 22, 38, 0.92) 8%, rgba(20, 24, 40, 0.98) 100%);
background: transparent;
padding: 24px 0 4px;
}
.home-portal-shell {
@@ -1564,7 +1530,6 @@ onUnmounted(() => {
}
@media (max-width: 768px) {
.navbar { padding: 15px 20px; }
.planet { display: none; }
.stats-container { grid-template-columns: 1fr; }
.testimonials-grid { grid-template-columns: 1fr; }
}