feat: 晟算科技官网 V6 太空世界观

- 首页: Three.js破碎月亮太空之旅(warp入场/碎片悬浮/代码泄漏/腐化标题)
- 关于: 地面控制中心
- 产品: 碎片修复舱(加密悬念)
- 联系: 通讯链路
- 纯静态: HTML+CSS+原生JS+Three.js本地化
This commit is contained in:
leefer
2026-08-01 11:03:38 +08:00
commit 40dd2fffff
10 changed files with 5112 additions and 0 deletions
+18
View File
@@ -0,0 +1,18 @@
# 系统文件
.DS_Store
Thumbs.db
desktop.ini
# 编辑器
.vscode/
.idea/
*.swp
*.swo
# 日志与临时文件
*.log
*.tmp
~$*
# 空目录占位(如不需要可删除)
images/.gitkeep
+259
View File
@@ -0,0 +1,259 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="地面控制中心档案 — 一群受够了糟糕软件的人,决定把碎掉的月亮修回去。">
<title>地面控制中心 | 晟算科技</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/space.css">
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect width='100' height='100' rx='20' fill='%2300e676'/%3E%3Ctext x='50' y='68' font-size='56' font-weight='bold' fill='%23020309' text-anchor='middle' font-family='sans-serif'%3E晟%3C/text%3E%3C/svg%3E">
</head>
<body data-space="orbit">
<div id="spaceCanvas"></div>
<div class="nebula nebula-1"></div>
<div class="nebula nebula-2"></div>
<div class="scanlines"></div>
<!-- ===== 导航栏 ===== -->
<header class="header">
<div class="header-inner">
<a href="index.html" class="logo">
<div class="logo-icon"></div>
<div class="logo-text">
晟算科技
<small>SHENGSUAN TECH</small>
</div>
</a>
<nav class="nav">
<a href="index.html" class="nav-link">首页</a>
<a href="about.html" class="nav-link">关于</a>
<a href="products.html" class="nav-link">产品</a>
<a href="contact.html" class="nav-link">聊聊</a>
<a href="contact.html" class="nav-cta">Say Hi</a>
</nav>
<div class="menu-toggle">
<span></span>
<span></span>
<span></span>
</div>
</div>
</header>
<!-- ===== 页面 Hero ===== -->
<section class="page-hero" style="min-height:auto">
<div class="geo-deco" style="position:absolute;top:100px;left:40px">FILE: ground_control.log</div>
<div class="geo-deco" style="position:absolute;top:100px;right:40px">ACCESS: PUBLIC</div>
<div class="page-hero-content">
<h1 class="fade-in-up">地面控制中心</h1>
<p class="fade-in-up delay-1">一群受够了糟糕软件的人,决定把碎掉的月亮修回去</p>
<div class="breadcrumb fade-in-up delay-2">
<a href="index.html">首页</a>
<span>/</span>
<span class="current">控制中心</span>
</div>
</div>
</section>
<!-- ===== 起源 ===== -->
<section class="section">
<div class="container">
<div class="chapter-marker reveal">
<span class="chapter-num">01</span>
<span class="chapter-line"></span>
<span class="chapter-tag">ORIGIN.log</span>
</div>
<div class="about-story">
<div class="about-story-text reveal">
<h2>一切始于第N次崩溃</h2>
<p>那天下午,一个团队想导出一份数据报表。这个简单的操作花了四十分钟——三次卡顿、两次"意外错误"、一次强制更新,以及一句灵魂拷问:"确定要离开吗?您的更改将不会保存。"</p>
<p>他们看了看彼此。这群人写了十几年代码,给别人修过无数系统,却突然意识到:<strong style="color:var(--text-primary)">整个行业都在制造这种问题,而大家都在假装正常。</strong></p>
<p>软件本该是工具。但现在的软件,更像是需要被伺候的祖宗——你要学习它、迁就它、忍受它的脾气。月亮就是这么碎的:不是某一天突然崩的,是无数道小裂缝,没人修,越裂越大。</p>
<p>2026年,郑州。几个人凑在一起,成立了晟算科技。目标简单粗暴:<strong style="color:var(--code-green)">写出本来就懂人的软件,把月亮一块一块拼回去。</strong></p>
<div class="terminal-deco" style="margin-top:24px;background:rgba(2,3,10,0.6);border:1px solid var(--border-subtle);border-radius:8px;padding:16px 20px">
<div><span class="log-time">[init]</span> <span class="log-info">></span> ground_control.founded(location="郑州", year=2026)</div>
<div><span class="log-time">[init]</span> <span class="log-ok">></span> mission: "repair_the_moon" <span class="log-ok">[LOCKED]</span></div>
</div>
</div>
<div class="about-story-visual reveal">
<div class="about-visual-block">
<div class="big-quote">
月亮碎了<br>不是月亮<br><span>的问题</span>
</div>
<div class="author">—— 是写代码的人出了问题。我们从人开始修。</div>
</div>
</div>
</div>
</div>
</section>
<!-- ===== 名字 ===== -->
<section class="section" style="padding-top:0">
<div class="container">
<div class="reveal" style="background:var(--bg-card);backdrop-filter:blur(18px);border:1px solid var(--border-subtle);border-radius:var(--radius-xl);padding:56px;text-align:center;position:relative;overflow:hidden">
<span class="section-label" style="margin-bottom:28px">呼号解码</span>
<h3 style="font-size:32px;font-weight:800;color:var(--text-primary);margin-bottom:24px;position:relative">晟算 = <span style="color:var(--sun-warm)">光明</span> × <span style="color:var(--code-green)">计算</span></h3>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:32px;max-width:640px;margin:0 auto;position:relative;text-align:left">
<div style="padding:24px;background:rgba(255,243,214,0.04);border:1px solid rgba(255,243,214,0.1);border-radius:12px">
<div style="font-size:36px;font-weight:900;color:var(--sun-warm);margin-bottom:10px"></div>
<p style="font-size:14px;color:var(--text-muted);line-height:1.9">光明、旺盛。像远处那颗太阳——软件应该照亮工作,而不是制造阴影。每一次修复,都是把光打回裂缝里。</p>
</div>
<div style="padding:24px;background:rgba(77,255,166,0.04);border:1px solid rgba(77,255,166,0.1);border-radius:12px">
<div style="font-size:36px;font-weight:900;color:var(--code-green);margin-bottom:10px"></div>
<p style="font-size:14px;color:var(--text-muted);line-height:1.9">计算、算法。月亮由代码组成,修复月亮也得靠代码。用计算的力量,把失控的世界拉回正轨。</p>
</div>
</div>
</div>
</div>
</section>
<!-- ===== 修复守则 ===== -->
<section class="section" style="padding-top:0">
<div class="container">
<div class="chapter-marker reveal">
<span class="chapter-num">02</span>
<span class="chapter-line"></span>
<span class="chapter-tag">THE_RULES</span>
</div>
<div class="section-header reveal" style="margin-bottom:56px">
<h2 class="section-title" data-scramble>修复守则</h2>
<p class="section-subtitle">写进任务手册的规矩,没有例外</p>
</div>
<div class="grid-2" style="gap:24px">
<div class="card reveal" style="padding:36px">
<div class="terminal-deco" style="margin-bottom:16px"><span class="log-ok">RULE_01</span> <span class="log-info">// 永远生效</span></div>
<h3 style="font-size:20px;font-weight:700;color:var(--text-primary);margin-bottom:12px">不为功能而功能</h3>
<p style="font-size:15px;color:var(--text-muted);line-height:1.9">每加一个功能,先回答:"谁,在什么场景下,解决什么具体痛苦?"答不上来,就不写。竞对有?那不是理由。</p>
</div>
<div class="card reveal" style="padding:36px">
<div class="terminal-deco" style="margin-bottom:16px"><span class="log-ok">RULE_02</span> <span class="log-info">// 永远生效</span></div>
<h3 style="font-size:20px;font-weight:700;color:var(--text-primary);margin-bottom:12px">慢发布,快迭代</h3>
<p style="font-size:15px;color:var(--text-muted);line-height:1.9">没打磨好就不发布,这是底线。但只要用户在手,反馈就是命令——小步快跑,持续修复,每周都有变化。</p>
</div>
<div class="card reveal" style="padding:36px">
<div class="terminal-deco" style="margin-bottom:16px"><span class="log-ok">RULE_03</span> <span class="log-info">// 永远生效</span></div>
<h3 style="font-size:20px;font-weight:700;color:var(--text-primary);margin-bottom:12px">代码要过得了自己这关</h3>
<p style="font-size:15px;color:var(--text-muted);line-height:1.9">用户看不见代码,但烂代码会变成用户看得见的卡顿、崩溃和bug。写每一行都当作明天要自己来维护。</p>
</div>
<div class="card reveal" style="padding:36px">
<div class="terminal-deco" style="margin-bottom:16px"><span class="log-ok">RULE_04</span> <span class="log-info">// 永远生效</span></div>
<h3 style="font-size:20px;font-weight:700;color:var(--text-primary);margin-bottom:12px">说人话</h3>
<p style="font-size:15px;color:var(--text-muted);line-height:1.9">错误提示不说"Exception 0x80004005",说"网络好像断了,检查一下?"。更新日志不写"优化了若干体验",写清楚改了什么、为什么。</p>
</div>
</div>
</div>
</section>
<!-- ===== 修复小组 ===== -->
<section class="section" style="padding-top:0">
<div class="container">
<div class="chapter-marker reveal">
<span class="chapter-num">03</span>
<span class="chapter-line"></span>
<span class="chapter-tag">THE_SQUAD</span>
</div>
<div class="section-header reveal" style="margin-bottom:56px">
<h2 class="section-title" data-scramble>修复小组编制</h2>
<p class="section-subtitle">三个单元,一个目标。人不多,但每个人都顶用</p>
</div>
<div class="structure-block reveal">
<h3>
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="var(--code-green)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
地面编制架构
</h3>
<div class="structure-grid">
<div class="structure-item">
<div class="num">UNIT_A</div>
<h4>观测与定位</h4>
<p>潜入真实工作场景,找到那些让人崩溃的瞬间。定义"哪道裂缝最该先修",而不是"哪个最好修"</p>
</div>
<div class="structure-item">
<div class="num">UNIT_B</div>
<h4>工程与焊接</h4>
<p>把修复方案写成可靠的代码。性能优先,架构干净。每一行都要经得起 review 和时间</p>
</div>
<div class="structure-item">
<div class="num">UNIT_C</div>
<h4>验证与回收</h4>
<p>把修复件放到真实用户手里接受检验。收集崩溃报告、倾听吐槽,然后回去继续焊</p>
</div>
</div>
</div>
<div class="terminal-deco reveal" style="margin-top:40px;text-align:center;opacity:0.6">
<span class="log-info">></span> squad_size: &lt;10 &nbsp;|&nbsp; <span class="log-info">></span> output_per_capita: MAX &nbsp;|&nbsp; <span class="log-ok">></span> hiring: maybe, if you're as obsessed as us
</div>
</div>
</section>
<!-- ===== CTA ===== -->
<section class="cta-section">
<div class="cta-content">
<h2 class="reveal">想跟地面控制中心通话?</h2>
<p class="reveal">不管你是想吐槽糟糕软件、想参与内测、还是单纯想聊聊,通讯频道一直开着</p>
<div class="reveal" style="display:flex;gap:16px;justify-content:center;flex-wrap:wrap">
<a href="contact.html" class="btn btn-primary btn-lg">建立通讯链路</a>
<a href="products.html" class="btn btn-outline btn-lg">查看碎片修复舱</a>
</div>
</div>
</section>
<!-- ===== 页脚 ===== -->
<footer class="footer">
<div class="container">
<div class="footer-grid">
<div class="footer-brand">
<div class="logo">
<div class="logo-icon"></div>
<div class="logo-text">
晟算科技
<small style="color:var(--text-muted)">SHENGSUAN TECH</small>
</div>
</div>
<p>月亮碎了,我们在修。修复内容保密,修复进度公开。</p>
</div>
<div class="footer-col">
<h4>导航</h4>
<ul>
<li><a href="index.html">首页</a></li>
<li><a href="about.html">关于我们</a></li>
<li><a href="products.html">产品矩阵</a></li>
<li><a href="contact.html">来聊聊</a></li>
</ul>
</div>
<div class="footer-col">
<h4>碎片清单</h4>
<ul>
<li><a href="products.html">FRAGMENT_α</a></li>
<li><a href="products.html">FRAGMENT_β</a></li>
<li><a href="products.html">FRAGMENT_γ</a></li>
<li><a href="products.html">???</a></li>
</ul>
</div>
<div class="footer-col">
<h4>信号源</h4>
<ul class="footer-contact">
<li><span class="contact-icon"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg></span><span>河南省 · 郑州市 · 金水区</span></li>
<li><span class="contact-icon"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/></svg></span><span>0371-8888-6666</span></li>
<li><span class="contact-icon"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg></span><span>hello@shengsuan.tech</span></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<span>&copy; 2026 郑州晟算科技有限公司</span>
<span>ground_control@shengsuan:~$ repairing_moon --progress 85%</span>
</div>
</div>
</footer>
<script src="js/lib/three.min.js"></script>
<script src="js/space.js"></script>
<script src="js/main.js"></script>
</body>
</html>
+252
View File
@@ -0,0 +1,252 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="建立通讯链路 — 报告裂缝现场、申请观测权限、或与地面控制中心通话。">
<title>建立通讯链路 | 晟算科技</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/space.css">
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect width='100' height='100' rx='20' fill='%2300e676'/%3E%3Ctext x='50' y='68' font-size='56' font-weight='bold' fill='%23020309' text-anchor='middle' font-family='sans-serif'%3E晟%3C/text%3E%3C/svg%3E">
</head>
<body data-space="orbit">
<div id="spaceCanvas"></div>
<div class="nebula nebula-1"></div>
<div class="nebula nebula-2"></div>
<div class="scanlines"></div>
<!-- ===== 导航栏 ===== -->
<header class="header">
<div class="header-inner">
<a href="index.html" class="logo">
<div class="logo-icon"></div>
<div class="logo-text">
晟算科技
<small>SHENGSUAN TECH</small>
</div>
</a>
<nav class="nav">
<a href="index.html" class="nav-link">首页</a>
<a href="about.html" class="nav-link">关于</a>
<a href="products.html" class="nav-link">产品</a>
<a href="contact.html" class="nav-link">聊聊</a>
<a href="contact.html" class="nav-cta">Say Hi</a>
</nav>
<div class="menu-toggle">
<span></span>
<span></span>
<span></span>
</div>
</div>
</header>
<!-- ===== 页面 Hero ===== -->
<section class="page-hero" style="min-height:auto">
<div class="geo-deco" style="position:absolute;top:100px;left:40px">CHANNEL: OPEN</div>
<div class="geo-deco" style="position:absolute;top:100px;right:40px">LATENCY: &lt;24h</div>
<div class="page-hero-content">
<h1 class="fade-in-up">建立通讯链路</h1>
<p class="fade-in-up delay-1">报告裂缝现场、申请观测权限、或者只是向地面打个信号</p>
<div class="breadcrumb fade-in-up delay-2">
<a href="index.html">首页</a>
<span>/</span>
<span class="current">通讯</span>
</div>
</div>
</section>
<!-- ===== 通讯区 ===== -->
<section class="section">
<div class="container">
<div class="contact-layout">
<!-- 左侧: 地面站信息 -->
<div class="contact-card-dark reveal">
<h3>地面站</h3>
<p>频道常开,回复通常不超过24小时。</p>
<div class="contact-info-row">
<div class="contact-info-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>
</div>
<div class="contact-info-text">
<div class="ci-label">GROUND_STATION</div>
<div class="ci-value">河南省 · 郑州市 · 金水区</div>
</div>
</div>
<div class="contact-info-row">
<div class="contact-info-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/></svg>
</div>
<div class="contact-info-text">
<div class="ci-label">VOICE_CHANNEL</div>
<div class="ci-value">0371-8888-6666</div>
</div>
</div>
<div class="contact-info-row">
<div class="contact-info-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>
</div>
<div class="contact-info-text">
<div class="ci-label">MAIL_PROTOCOL</div>
<div class="ci-value">hello@shengsuan.tech</div>
</div>
</div>
<div class="contact-info-row">
<div class="contact-info-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
</div>
<div class="contact-info-text">
<div class="ci-label">ONLINE_WINDOW</div>
<div class="ci-value">工作日 9:00 - 18:00<br>深夜也在观测,但不一定回</div>
</div>
</div>
<div class="terminal-deco" style="margin-top:32px;padding-top:24px;border-top:1px solid var(--border-subtle)">
<div><span class="log-ok">></span> encryption: TLS 1.3</div>
<div><span class="log-ok">></span> spam_filter: MAXIMUM</div>
<div><span class="log-info">></span> response_sla: &lt; 24 hours</div>
</div>
</div>
<!-- 右侧: 传输表单 -->
<div class="contact-form-dark reveal">
<h3>发送深空信号</h3>
<p>不用太正式,就当在通讯终端里敲几行字。</p>
<div class="form-success">
✓ 信号已抵达地面站!通常24小时内会有回音。
</div>
<form id="contactForm">
<div class="form-row">
<div class="form-group">
<label class="form-label" for="name">呼号 / 姓名 <span class="required">*</span></label>
<input type="text" id="name" name="name" class="form-input" placeholder="怎么称呼你?" required>
</div>
<div class="form-group">
<label class="form-label" for="phone">回传频道 <span class="required">*</span></label>
<input type="tel" id="phone" name="phone" class="form-input" placeholder="手机号或微信" required>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label class="form-label" for="email">备用频道</label>
<input type="email" id="email" name="email" class="form-input" placeholder="邮箱(选填)">
</div>
<div class="form-group">
<label class="form-label" for="interest">信号类型</label>
<select id="interest" name="interest" class="form-select">
<option value="">选择你的来意</option>
<option value="beta">申请观测权限(内测)</option>
<option value="chaos">报告裂缝现场(吐槽软件)</option>
<option value="collab">谈合作</option>
<option value="join">想加入修复小组</option>
<option value="chat">纯粹聊聊</option>
</select>
</div>
</div>
<div class="form-group">
<label class="form-label" for="message">信号内容 <span class="required">*</span></label>
<textarea id="message" name="message" class="form-textarea" placeholder="说说你想说的。吐槽糟糕软件尤其欢迎,我们会认真记进裂缝档案..." required></textarea>
</div>
<button type="submit" class="form-submit">传输信号 →</button>
</form>
<div class="terminal-deco" style="margin-top:24px;text-align:center;opacity:0.5">
<span class="log-info">></span> your_message will be read by real humans, not bots
</div>
</div>
</div>
</div>
</section>
<!-- ===== 地面站坐标 ===== -->
<section class="section map-section">
<div class="container">
<div class="chapter-marker reveal">
<span class="chapter-num">LOC</span>
<span class="chapter-line"></span>
<span class="chapter-tag">STATION_COORDINATES</span>
</div>
<div class="map-wrapper reveal" style="height:360px">
<div style="width:100%;height:100%;background:rgba(2,3,10,0.7);display:flex;align-items:center;justify-content:center;position:relative;overflow:hidden">
<div style="position:absolute;inset:0;background-image:linear-gradient(rgba(160,180,255,0.04) 1px,transparent 1px),linear-gradient(90deg,rgba(160,180,255,0.04) 1px,transparent 1px);background-size:50px 50px"></div>
<!-- 雷达圈 -->
<div style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:220px;height:220px;border:1px solid rgba(77,255,166,0.15);border-radius:50%;animation:dotPulse 3s ease-in-out infinite"></div>
<div style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:130px;height:130px;border:1px dashed rgba(77,255,166,0.25);border-radius:50%"></div>
<div style="position:absolute;top:50%;left:50%;width:130px;height:1px;background:linear-gradient(90deg,rgba(77,255,166,0.5),transparent);transform-origin:left center;animation:radarSweep 3s linear infinite"></div>
<div style="position:relative;z-index:2;text-align:center">
<div style="margin-bottom:16px;display:flex;justify-content:center">
<svg width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="var(--code-green)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>
</div>
<h3 style="font-size:22px;font-weight:700;color:var(--text-primary);margin-bottom:8px">晟算地面站</h3>
<p style="font-size:15px;color:var(--text-muted)">河南省 · 郑州市 · 金水区</p>
<div class="geo-deco" style="margin-top:10px;opacity:0.8">N 34°44.52 &nbsp;·&nbsp; E 113°37.48</div>
<p style="font-size:13px;color:var(--text-muted);opacity:0.5;margin-top:12px">到访前请先建立通讯预约</p>
</div>
</div>
</div>
</div>
</section>
<!-- ===== 页脚 ===== -->
<footer class="footer">
<div class="container">
<div class="footer-grid">
<div class="footer-brand">
<div class="logo">
<div class="logo-icon"></div>
<div class="logo-text">
晟算科技
<small style="color:var(--text-muted)">SHENGSUAN TECH</small>
</div>
</div>
<p>月亮碎了,我们在修。修复内容保密,修复进度公开。</p>
</div>
<div class="footer-col">
<h4>导航</h4>
<ul>
<li><a href="index.html">首页</a></li>
<li><a href="about.html">关于我们</a></li>
<li><a href="products.html">产品矩阵</a></li>
<li><a href="contact.html">来聊聊</a></li>
</ul>
</div>
<div class="footer-col">
<h4>碎片清单</h4>
<ul>
<li><a href="products.html">FRAGMENT_α</a></li>
<li><a href="products.html">FRAGMENT_β</a></li>
<li><a href="products.html">FRAGMENT_γ</a></li>
<li><a href="products.html">???</a></li>
</ul>
</div>
<div class="footer-col">
<h4>信号源</h4>
<ul class="footer-contact">
<li><span class="contact-icon"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg></span><span>河南省 · 郑州市 · 金水区</span></li>
<li><span class="contact-icon"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/></svg></span><span>0371-8888-6666</span></li>
<li><span class="contact-icon"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg></span><span>hello@shengsuan.tech</span></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<span>&copy; 2026 郑州晟算科技有限公司</span>
<span>ground_control@shengsuan:~$ repairing_moon --progress 85%</span>
</div>
</div>
</footer>
<style>
@keyframes radarSweep { to { transform: rotate(360deg); } }
</style>
<script src="js/lib/three.min.js"></script>
<script src="js/space.js"></script>
<script src="js/main.js"></script>
</body>
</html>
+395
View File
@@ -0,0 +1,395 @@
/* ============================================================
晟算科技 · 太空主题层
深空沉浸 + 玻璃面板 + 腐化标题特效
在 style.css 之后加载,覆盖太空世界观样式
============================================================ */
/* === 太空配色覆盖 === */
:root {
--bg-deep: #02030a;
--bg-dark: #05060f;
--bg-card: rgba(13, 17, 30, 0.62);
--bg-card-hover: rgba(18, 24, 40, 0.7);
--border-subtle: rgba(160, 180, 255, 0.09);
--border-glow: rgba(77, 255, 166, 0.3);
--text-primary: #eef1fa;
--text-secondary: #96a0bc;
--text-muted: #5b6480;
--code-green: #4dffa6;
--code-dim: #1fbf7a;
--sun-warm: #fff3d6;
--nebula-indigo: rgba(88, 70, 220, 0.1);
--nebula-blue: rgba(40, 90, 220, 0.1);
--blue: #4dffa6;
--blue-glow: #8affc9;
--cyan: #7dd8ff;
--cyan-dark: #3a9bc9;
--purple: #a78bff;
--purple-glow: #c9b3ff;
--green: #4dffa6;
--red: #ff4455;
--orange: #ffb020;
--shadow-glow: 0 0 40px rgba(77, 255, 166, 0.12);
--shadow-glow-strong: 0 0 80px rgba(77, 255, 166, 0.18);
}
html, body {
background: var(--bg-deep);
}
/* === 太空画布层 === */
#spaceCanvas {
position: fixed;
inset: 0;
z-index: 0;
pointer-events: none;
}
#spaceCanvas canvas { display: block; }
/* WebGL兜底: CSS星空 */
.space-fallback #spaceCanvas {
background:
radial-gradient(1.5px 1.5px at 20% 30%, rgba(255,255,255,0.9), transparent),
radial-gradient(1px 1px at 40% 70%, rgba(255,255,255,0.7), transparent),
radial-gradient(2px 2px at 60% 20%, rgba(200,220,255,0.8), transparent),
radial-gradient(1px 1px at 80% 50%, rgba(255,255,255,0.6), transparent),
radial-gradient(1.5px 1.5px at 90% 80%, rgba(255,240,200,0.7), transparent),
radial-gradient(1px 1px at 10% 60%, rgba(255,255,255,0.5), transparent),
radial-gradient(2.5px 2.5px at 70% 85%, rgba(255,255,255,0.6), transparent),
radial-gradient(1px 1px at 30% 90%, rgba(200,220,255,0.5), transparent);
background-color: var(--bg-deep);
background-size: 100% 100%;
}
/* === 星云环境光 === */
.nebula {
position: fixed;
border-radius: 50%;
filter: blur(140px);
pointer-events: none;
z-index: 0;
}
.nebula-1 { width: 700px; height: 700px; background: var(--nebula-indigo); top: -15%; left: -10%; }
.nebula-2 { width: 600px; height: 600px; background: var(--nebula-blue); bottom: -20%; right: -8%; }
/* === BOOT 加载屏 === */
#spaceBoot {
position: fixed;
inset: 0;
background: #02030a;
z-index: 100000;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
transition: opacity 0.9s ease, visibility 0.9s;
}
#spaceBoot.hide { opacity: 0; visibility: hidden; pointer-events: none; }
#spaceBoot .boot-scope {
width: 120px; height: 120px;
border: 1px solid rgba(77, 255, 166, 0.35);
border-radius: 50%;
margin-bottom: 40px;
position: relative;
animation: scopeSpin 3s linear infinite;
}
#spaceBoot .boot-scope::before {
content: "";
position: absolute;
inset: 18px;
border: 1px dashed rgba(77, 255, 166, 0.25);
border-radius: 50%;
}
#spaceBoot .boot-scope::after {
content: "";
position: absolute;
top: 50%; left: 50%;
width: 6px; height: 6px;
background: var(--code-green);
border-radius: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 0 14px var(--code-green);
}
#spaceBoot .boot-cross {
position: absolute;
top: 50%; left: -30%;
width: 160%; height: 1px;
background: rgba(77, 255, 166, 0.2);
}
#spaceBoot .boot-cross.v { transform: rotate(90deg); }
@keyframes scopeSpin { to { transform: rotate(360deg); } }
#spaceBoot .boot-terminal {
width: 480px;
max-width: 88vw;
font-family: var(--font-mono);
font-size: 14px;
line-height: 2.1;
color: var(--text-muted);
min-height: 190px;
}
#spaceBoot .terminal-prompt { color: var(--text-secondary); }
#spaceBoot .terminal-text.ok { color: var(--code-green); }
#spaceBoot .terminal-text.log-error { color: var(--red); }
#spaceBoot .terminal-line { animation: fadeIn 0.25s ease; }
#spaceBoot .boot-progress {
width: 480px;
max-width: 88vw;
height: 2px;
background: rgba(255, 255, 255, 0.08);
margin-top: 28px;
position: relative;
overflow: hidden;
}
#spaceBootBar {
height: 100%;
width: 0%;
background: linear-gradient(90deg, var(--code-dim), var(--code-green));
box-shadow: 0 0 12px rgba(77, 255, 166, 0.6);
transition: width 0.3s ease;
}
#spaceBoot .boot-tag {
margin-top: 20px;
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 3px;
color: var(--text-muted);
opacity: 0.7;
}
/* === 玻璃面板(内容浮在太空上) === */
.card, .teaser-card, .feature-card, .belief-card, .philosophy-item,
.structure-block, .contact-card-dark, .contact-form-dark,
.chaos-card, .teaser-main, .teaser-side-item, .about-visual-block {
background: var(--bg-card);
backdrop-filter: blur(18px) saturate(140%);
-webkit-backdrop-filter: blur(18px) saturate(140%);
border: 1px solid var(--border-subtle);
}
.card:hover, .teaser-card:hover, .feature-card:hover,
.belief-card:hover, .philosophy-item:hover, .chaos-card:hover {
border-color: rgba(77, 255, 166, 0.22);
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55), var(--shadow-glow);
}
/* === 区块在太空中的层级 === */
.section, .page-hero, .cta-section, .footer { position: relative; z-index: 2; }
.footer { background: rgba(3, 4, 10, 0.85); backdrop-filter: blur(20px); }
/* === Hero(太空版) === */
.space-hero {
position: relative;
min-height: 100vh;
display: flex;
align-items: center;
z-index: 2;
pointer-events: none;
}
.space-hero .container, .space-hero a, .space-hero button { pointer-events: auto; }
.space-hero-content {
max-width: 640px;
padding: 120px 24px 0;
}
/* === FATAL ERROR 徽章 === */
.fatal-badge {
display: inline-flex;
align-items: center;
gap: 10px;
padding: 8px 20px;
background: rgba(255, 68, 85, 0.1);
border: 1px solid rgba(255, 68, 85, 0.35);
border-radius: 4px;
color: var(--red);
font-family: var(--font-mono);
font-size: 13px;
font-weight: 700;
letter-spacing: 2px;
margin-bottom: 28px;
animation: fatalBlink 1.6s steps(2) infinite;
}
.fatal-badge .fatal-dot {
width: 8px; height: 8px;
background: var(--red);
border-radius: 50%;
box-shadow: 0 0 12px var(--red);
}
@keyframes fatalBlink {
0%, 100% { opacity: 1; box-shadow: 0 0 0 rgba(255, 68, 85, 0); }
50% { opacity: 0.75; box-shadow: 0 0 30px rgba(255, 68, 85, 0.25); }
}
/* ============================================================
腐化标题特效 —— 标题本身就是一个正在发生的bug
============================================================ */
.corrupt-wrap {
position: relative;
display: inline-block;
}
.corrupt-title {
font-size: clamp(44px, 8vw, 84px);
font-weight: 900;
color: var(--text-primary);
line-height: 1.15;
letter-spacing: -1px;
position: relative;
font-family: var(--font-sans);
}
/* 色差重影层 */
.corrupt-title::before,
.corrupt-title::after {
content: attr(data-text);
position: absolute;
inset: 0;
opacity: 0;
pointer-events: none;
}
.corrupt-title::before {
color: #ff2255;
animation: chromaA 3.7s steps(1) infinite;
}
.corrupt-title::after {
color: #22ddff;
animation: chromaB 3.7s steps(1) infinite;
}
@keyframes chromaA {
0%, 91%, 100% { opacity: 0; transform: translate(0, 0); }
92% { opacity: 0.75; transform: translate(-5px, 2px); }
94% { opacity: 0.5; transform: translate(4px, -2px); clip-path: inset(20% 0 40% 0); }
96% { opacity: 0.8; transform: translate(-3px, 0); clip-path: inset(60% 0 10% 0); }
98% { opacity: 0.4; transform: translate(5px, 1px); }
}
@keyframes chromaB {
0%, 91%, 100% { opacity: 0; transform: translate(0, 0); }
92% { opacity: 0.75; transform: translate(5px, -2px); }
94% { opacity: 0.5; transform: translate(-4px, 2px); clip-path: inset(30% 0 30% 0); }
96% { opacity: 0.8; transform: translate(3px, 0); clip-path: inset(10% 0 60% 0); }
98% { opacity: 0.4; transform: translate(-5px, -1px); }
}
/* 屏幕震颤(偶发) */
.corrupt-wrap.shake {
animation: screenShake 0.22s linear;
}
@keyframes screenShake {
0% { transform: translate(0, 0); }
20% { transform: translate(-4px, 2px) skewX(-1deg); }
40% { transform: translate(4px, -2px) skewX(1deg); }
60% { transform: translate(-3px, -1px); }
80% { transform: translate(3px, 1px); }
100% { transform: translate(0, 0); }
}
/* 腐化字符样式 */
.corrupt-char {
display: inline-block;
position: relative;
transition: color 0.05s;
}
.corrupt-char.glitching {
color: var(--red);
text-shadow: 0 0 20px rgba(255, 68, 85, 0.7);
}
/* === 错误代码副标题 === */
.error-code-line {
font-family: var(--font-mono);
font-size: 14px;
color: var(--text-muted);
letter-spacing: 1px;
margin-top: 26px;
line-height: 2;
}
.error-code-line .ec-key { color: var(--text-secondary); }
.error-code-line .ec-val { color: var(--code-green); }
.error-code-line .ec-err { color: var(--red); }
/* === Hero 右侧留白给月亮 === */
@media (min-width: 900px) {
.space-hero-content { margin-left: 6vw; }
}
/* === 滚动场景在太空中的适配 === */
.scroll-scene .scene-sticky {
background: transparent;
}
.scene-line .line-big { text-shadow: 0 4px 40px rgba(0, 0, 0, 0.8); }
/* === 诊断报告面板 === */
.chaos-card { border-color: rgba(255, 68, 85, 0.14); }
.chaos-card::before { background: linear-gradient(90deg, transparent, var(--red), transparent); }
/* === 碎片修复舱卡片 === */
.frag-card .sys-status.debug { color: var(--code-green); }
.frag-card .sys-status.debug::before { background: var(--code-green); box-shadow: 0 0 10px var(--code-green); }
/* === 按钮太空化 === */
.btn-primary {
background: linear-gradient(135deg, #1fbf7a, #0d8f5a);
box-shadow: 0 0 30px rgba(77, 255, 166, 0.25);
}
.btn-primary:hover { box-shadow: 0 0 50px rgba(77, 255, 166, 0.45); }
.btn-outline {
border-color: rgba(160, 180, 255, 0.2);
color: var(--text-primary);
}
.btn-outline:hover {
border-color: var(--code-green);
background: rgba(77, 255, 166, 0.06);
box-shadow: 0 0 30px rgba(77, 255, 166, 0.15);
}
/* === 标签/徽章色 === */
.section-label { color: var(--code-green); }
.status-vision { background: rgba(125, 216, 255, 0.1); color: var(--cyan); border-color: rgba(125, 216, 255, 0.2); }
.status-coming { background: rgba(167, 139, 255, 0.1); color: var(--purple); border-color: rgba(167, 139, 255, 0.2); }
.indicator-purple { background: var(--purple); box-shadow: 0 0 12px var(--purple); }
.indicator-cyan { background: var(--code-green); box-shadow: 0 0 12px var(--code-green); }
/* === 进度条(修复能量) === */
.build-progress-fill {
background: linear-gradient(90deg, var(--code-dim), var(--code-green));
box-shadow: 0 0 15px rgba(77, 255, 166, 0.5);
}
/* === 加密块 === */
.encrypted-block { border-color: rgba(77, 255, 166, 0.2); }
.encrypted-line { color: var(--code-green); }
.encrypted-block::after { color: var(--orange); }
/* === 导航栏太空化 === */
.header { background: rgba(2, 3, 10, 0.72); }
.nav-link.active { color: var(--code-green); background: rgba(77, 255, 166, 0.08); }
.nav-cta { background: linear-gradient(135deg, #1fbf7a, #0d8f5a); box-shadow: 0 0 20px rgba(77, 255, 166, 0.2); }
.logo-icon { background: linear-gradient(135deg, #1fbf7a, #0a6e46); box-shadow: 0 0 20px rgba(77, 255, 166, 0.25); }
/* === 滚动进度条 === */
.scroll-progress { background: linear-gradient(90deg, var(--code-dim), var(--code-green), var(--cyan)); }
/* === 滚动场景角标配色 === */
.chapter-marker .chapter-num { -webkit-text-stroke-color: rgba(77, 255, 166, 0.3); }
.chapter-marker .chapter-line { background: linear-gradient(90deg, rgba(77, 255, 166, 0.3), transparent); }
.scene-frame::before, .scene-frame::after,
.scene-frame .frame-corner-b, .scene-frame .frame-corner-c { border-color: rgba(77, 255, 166, 0.22); }
.scene-corner .big-pct { color: rgba(77, 255, 166, 0.5); }
.bg-giant-text { -webkit-text-stroke-color: rgba(160, 180, 255, 0.05); }
/* === 宣言高亮色 === */
.manifesto .highlight { color: var(--code-green); text-shadow: 0 0 30px rgba(77, 255, 166, 0.4); }
.scene-line .line-big .accent { color: var(--code-green); text-shadow: 0 0 40px rgba(77, 255, 166, 0.4); }
/* === CTA区 === */
.cta-section::before { background: transparent; }
/* === 自定义光标太空色 === */
.cursor-dot { background: var(--code-green); }
.cursor-ring { border-color: rgba(77, 255, 166, 0.4); }
.cursor-ring.hovering { border-color: rgba(77, 255, 166, 0.8); background: rgba(77, 255, 166, 0.05); }
/* === 入场初始状态(配合boot) === */
body:not(.space-ready) .space-hero-content,
body:not(.space-ready) .scroll-hint {
opacity: 0;
}
.space-hero-content { transition: opacity 1s ease 0.2s; }
+2256
View File
File diff suppressed because it is too large Load Diff
+423
View File
@@ -0,0 +1,423 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="月亮碎了,代码正在从裂缝里漏出来。晟算科技——修复软件世界的人。">
<title>晟算科技 | MOON.SYS 已崩溃</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/space.css">
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect width='100' height='100' rx='20' fill='%2300e676'/%3E%3Ctext x='50' y='68' font-size='56' font-weight='bold' fill='%23020309' text-anchor='middle' font-family='sans-serif'%3E晟%3C/text%3E%3C/svg%3E">
</head>
<body data-space="journey">
<!-- BOOT 加载屏 -->
<div id="spaceBoot">
<div class="boot-scope">
<div class="boot-cross"></div>
<div class="boot-cross v"></div>
</div>
<div class="boot-terminal" id="spaceBootBody"></div>
<div class="boot-progress"><div id="spaceBootBar"></div></div>
<div class="boot-tag">SHENGSUAN // DEEP_SPACE_OBSERVATORY</div>
</div>
<!-- 3D太空画布 -->
<div id="spaceCanvas"></div>
<!-- 星云 -->
<div class="nebula nebula-1"></div>
<div class="nebula nebula-2"></div>
<!-- CRT 扫描线 -->
<div class="scanlines"></div>
<!-- ===== 导航栏 ===== -->
<header class="header">
<div class="header-inner">
<a href="index.html" class="logo">
<div class="logo-icon"></div>
<div class="logo-text">
晟算科技
<small>SHENGSUAN TECH</small>
</div>
</a>
<nav class="nav">
<a href="index.html" class="nav-link">首页</a>
<a href="about.html" class="nav-link">关于</a>
<a href="products.html" class="nav-link">产品</a>
<a href="contact.html" class="nav-link">聊聊</a>
<a href="contact.html" class="nav-cta">Say Hi</a>
</nav>
<div class="menu-toggle">
<span></span>
<span></span>
<span></span>
</div>
</div>
</header>
<!-- ===== Hero: 世界已崩溃 ===== -->
<section class="space-hero">
<div class="space-hero-content">
<div class="fatal-badge">
<span class="fatal-dot"></span>
FATAL_ERROR // MOON.SYS
</div>
<div class="corrupt-wrap">
<h1 class="corrupt-title" data-text="世界已崩溃">世界已崩溃</h1>
</div>
<div class="error-code-line">
<div><span class="ec-key">> error_code:</span> <span class="ec-err">0xM00N_CRACKED</span></div>
<div><span class="ec-key">> detail:</span> 月亮碎裂为3块,代码正从裂缝泄漏</div>
<div><span class="ec-key">> assigned_to:</span> <span class="ec-val">晟算科技 · 修复小组</span></div>
<div><span class="ec-key">> status:</span> <span class="ec-val">PATCHING… 修复进行中</span></div>
</div>
<div class="hero-actions" style="margin-top:44px;justify-content:flex-start">
<a href="#diagnosis" class="btn btn-primary btn-lg">查看崩溃报告</a>
<a href="about.html" class="btn btn-outline btn-lg">谁在修复</a>
</div>
</div>
<div class="scroll-hint">
<span>SCROLL // 接近月球</span>
<div class="scroll-hint-line"></div>
</div>
</section>
<!-- ===== 滚动场景 A: 发现 (接近月亮) ===== -->
<section class="scroll-scene" style="height:340vh">
<div class="scene-sticky">
<div class="bg-giant-text">CRACKED</div>
<div class="scene-frame">
<div class="frame-corner-b"></div>
<div class="frame-corner-c"></div>
</div>
<div class="scene-corner tl">
LOG_01
<span style="display:block;opacity:0.5;margin-top:4px">DISCOVERY</span>
</div>
<div class="scene-corner br">
DISTANCE
<span class="big-pct" data-scene-pct>00%</span>
</div>
<div class="scene-line">
<div class="line-big">这个世界,由代码组成</div>
<div class="line-sub">// this_world_runs_on_code</div>
</div>
<div class="scene-line">
<div class="line-big">而月亮——<span class="danger">碎了</span></div>
<div class="line-sub">// moon.exe_has_stopped_responding</div>
</div>
<div class="scene-line">
<div class="line-big">代码正从裂缝里<span class="accent">漏出来</span></div>
<div class="line-sub">// memory_leak · 持续扩散中</div>
</div>
<div class="scene-line">
<div class="line-big">就像你每天在用的软件<br><span class="danger">一样</span></div>
<div class="line-sub">// sound_familiar?</div>
</div>
</div>
</section>
<!-- ===== 崩溃诊断报告 ===== -->
<section class="section" id="diagnosis">
<div class="container">
<div class="chapter-marker reveal">
<span class="chapter-num">01</span>
<span class="chapter-line"></span>
<span class="chapter-tag">CRASH_REPORT</span>
</div>
<div class="section-header reveal" style="margin-bottom:56px">
<h2 class="section-title" data-scramble>崩溃诊断报告</h2>
<p class="section-subtitle">月亮不是一夜之间碎的。地面上的软件,也早已满是裂缝</p>
</div>
<div class="grid-4">
<div class="chaos-card reveal">
<div class="chaos-num"><span data-chaos-count="76">0</span><span class="chaos-unit">%</span></div>
<h3>功能从未被使用</h3>
<p>软件越来越臃肿,但你真正需要的功能,淹没在几百个永远不会点的按钮里</p>
</div>
<div class="chaos-card reveal">
<div class="chaos-num"><span data-chaos-count="2.5" data-decimals="1">0</span><span class="chaos-unit">h</span></div>
<h3>每天浪费在界面上</h3>
<p>寻找按钮、等待加载、确认弹窗——本该5分钟完成的事,硬生生拖成半小时</p>
</div>
<div class="chaos-card reveal">
<div class="chaos-num"><span data-chaos-count="17">0</span><span class="chaos-unit"></span></div>
<h3>完成简单任务的点击数</h3>
<p>导出一份报表:文件→导出→选格式→确认→再确认→选路径→完成→关闭提示……</p>
</div>
<div class="chaos-card reveal">
<div class="chaos-num"><span data-chaos-count="99">0</span><span class="chaos-unit">+</span></div>
<h3>永远读不完的更新日志</h3>
<p>"我们优化了一些体验"——翻译:你自己猜我们改了什么,顺便重新学一遍</p>
</div>
</div>
<div class="terminal-deco reveal" style="margin-top:48px;text-align:center;opacity:0.6">
<span class="log-error">diagnosis:</span> 病因相同——没人把用户当回事
</div>
</div>
</section>
<!-- ===== 滚动场景 B: 修复宣言 ===== -->
<section class="scroll-scene" style="height:300vh">
<div class="scene-sticky">
<div class="bg-giant-text">REPAIR</div>
<div class="scene-frame">
<div class="frame-corner-b"></div>
<div class="frame-corner-c"></div>
</div>
<div class="scene-corner tl">
LOG_02
<span style="display:block;opacity:0.5;margin-top:4px">PROTOCOL</span>
</div>
<div class="scene-corner br">
PROGRESS
<span class="big-pct" data-scene-pct>00%</span>
</div>
<div class="scene-line">
<div class="line-big">总得有人,<span class="accent">把月亮修回去</span></div>
<div class="line-sub">// someone_has_to_fix_the_moon</div>
</div>
<div class="scene-line">
<div class="line-big">我们不写让人<span style="color:var(--text-muted);text-decoration:line-through;text-decoration-color:var(--red);text-decoration-thickness:4px">学着用</span>的软件</div>
<div class="line-sub">// no_manuals_required</div>
</div>
<div class="scene-line">
<div class="line-big">我们写<span class="accent">本来就懂人</span>的软件</div>
<div class="line-sub">// software_that_understands_humans</div>
</div>
</div>
</section>
<!-- ===== 修复守则 ===== -->
<section class="section" style="position:relative">
<div class="container">
<div class="chapter-marker reveal">
<span class="chapter-num">02</span>
<span class="chapter-line"></span>
<span class="chapter-tag">REPAIR_PROTOCOL</span>
</div>
<div class="grid-3">
<div class="belief-card reveal">
<div class="belief-number" style="color:var(--code-green)">RULE_01</div>
<h3>砍掉,而不是堆叠</h3>
<p>每个功能存在的唯一理由:有人真的需要它。没有"万一用到",没有"竞对也有"。砍掉90%的噪音,把10%打磨到上瘾。</p>
</div>
<div class="belief-card reveal">
<div class="belief-number" style="color:var(--cyan)">RULE_02</div>
<h3>快,是一种尊重</h3>
<p>加载每多一秒,就是对用户时间的一次盗窃。我们把性能当成核心功能来写,而不是上线前的补救项。</p>
</div>
<div class="belief-card reveal">
<div class="belief-number" style="color:var(--purple)">RULE_03</div>
<h3>界面应该消失</h3>
<p>最好的界面是你感觉不到它存在的界面。用户要的是完成任务,不是欣赏你的设计系统有多庞大。</p>
</div>
</div>
</div>
</section>
<!-- ===== 碎片修复进度 ===== -->
<section class="section" style="position:relative">
<div class="container">
<div class="chapter-marker reveal">
<span class="chapter-num">03</span>
<span class="chapter-line"></span>
<span class="chapter-tag">FRAGMENT_RECOVERY</span>
</div>
<div class="section-header reveal" style="margin-bottom:40px">
<h2 class="section-title" data-scramble>碎片修复进度</h2>
<p class="section-subtitle">每块碎片里封装着什么?解密时间——当它足够好的时候</p>
</div>
<div class="reveal" style="text-align:center;margin-bottom:48px">
<span class="classified-stamp">CLASSIFIED</span>
</div>
<div class="grid-3">
<div class="card frag-card reveal" style="padding:36px">
<div class="terminal-deco" style="margin-bottom:20px">
<span class="log-info">FRAGMENT_α</span>
<span class="sys-status debug" style="margin-left:12px">DEBUGGING</span>
</div>
<h3 style="font-size:22px;font-weight:800;color:var(--text-primary);margin-bottom:18px;font-family:var(--font-mono)">
<span data-scramble-loop data-length="12">████████████</span>
</h3>
<div class="encrypted-block" style="margin-bottom:24px">
<div class="encrypted-line"><span data-scramble-loop data-length="38">██████████████████████████████████████</span></div>
<div class="encrypted-line"><span data-scramble-loop data-length="30">██████████████████████████████</span></div>
</div>
<div class="build-progress" style="margin:0">
<div class="build-progress-header">
<span class="bp-label">RECOVERY</span>
<span class="bp-value">85%</span>
</div>
<div class="build-progress-track">
<div class="build-progress-fill" data-progress="85"></div>
</div>
</div>
<div class="terminal-deco" style="margin-top:16px;opacity:0.6;font-size:11px">
<span class="log-warn">></span> payload: <span class="redacted">██████</span>
</div>
</div>
<div class="card frag-card reveal" style="padding:36px">
<div class="terminal-deco" style="margin-bottom:20px">
<span class="log-info">FRAGMENT_β</span>
<span class="sys-status compile" style="margin-left:12px">COMPILING</span>
</div>
<h3 style="font-size:22px;font-weight:800;color:var(--text-primary);margin-bottom:18px;font-family:var(--font-mono)">
<span data-scramble-loop data-length="12">████████████</span>
</h3>
<div class="encrypted-block" style="margin-bottom:24px">
<div class="encrypted-line"><span data-scramble-loop data-length="38">██████████████████████████████████████</span></div>
<div class="encrypted-line"><span data-scramble-loop data-length="30">██████████████████████████████</span></div>
</div>
<div class="build-progress" style="margin:0">
<div class="build-progress-header">
<span class="bp-label">RECOVERY</span>
<span class="bp-value">32%</span>
</div>
<div class="build-progress-track">
<div class="build-progress-fill" data-progress="32" style="background:linear-gradient(90deg,#7c5cd6,#a78bff);box-shadow:0 0 15px rgba(167,139,255,0.4)"></div>
</div>
</div>
<div class="terminal-deco" style="margin-top:16px;opacity:0.6;font-size:11px">
<span class="log-warn">></span> payload: <span class="redacted">██████</span>
</div>
</div>
<div class="card frag-card reveal" style="padding:36px">
<div class="terminal-deco" style="margin-bottom:20px">
<span class="log-info">FRAGMENT_γ</span>
<span class="sys-status queue" style="margin-left:12px">QUEUED</span>
</div>
<h3 style="font-size:22px;font-weight:800;color:var(--text-primary);margin-bottom:18px;font-family:var(--font-mono)">
<span data-scramble-loop data-length="12">████████████</span>
</h3>
<div class="encrypted-block" style="margin-bottom:24px">
<div class="encrypted-line"><span data-scramble-loop data-length="38">██████████████████████████████████████</span></div>
<div class="encrypted-line"><span data-scramble-loop data-length="30">██████████████████████████████</span></div>
</div>
<div class="build-progress" style="margin:0">
<div class="build-progress-header">
<span class="bp-label">QUEUE</span>
<span class="bp-value">#3</span>
</div>
<div class="build-progress-track">
<div class="build-progress-fill" data-progress="8" style="background:linear-gradient(90deg,#3a9bc9,#7dd8ff);box-shadow:0 0 15px rgba(125,216,255,0.3)"></div>
</div>
</div>
<div class="terminal-deco" style="margin-top:16px;opacity:0.6;font-size:11px">
<span class="log-warn">></span> payload: <span class="redacted">██████</span>
</div>
</div>
</div>
<div class="terminal-deco reveal" style="margin-top:48px;text-align:center;opacity:0.6">
<span class="log-info">></span> 抬头看——碎片正在归位 &nbsp;|&nbsp; <span class="log-warn">></span> 修复上限: 85%(剩下的,等见面那天)
</div>
</div>
</section>
<!-- ===== CTA: 月亮重圆那天 ===== -->
<section class="cta-section">
<div class="cta-content">
<div class="chapter-marker reveal" style="justify-content:center;margin-bottom:32px">
<span class="chapter-num" style="font-size:56px">04</span>
<span class="chapter-tag">GROUND_CONTROL</span>
</div>
<h2 class="reveal">当月亮重新完整那天</h2>
<p class="reveal">你会是第一个收到信号的人。加入地面控制中心,见证修复完成——没有垃圾邮件,我们也很烦那种。</p>
<div class="reveal" style="display:flex;gap:16px;justify-content:center;flex-wrap:wrap">
<a href="contact.html" class="btn btn-primary btn-lg">加入地面控制中心</a>
<a href="about.html" class="btn btn-outline btn-lg">认识修复小组</a>
</div>
<div class="terminal-deco reveal" style="margin-top:40px;opacity:0.5">
<span class="log-ok">></span> uplink_established ... awaiting your signal
</div>
</div>
</section>
<!-- ===== 页脚 ===== -->
<footer class="footer">
<div class="container">
<div class="footer-grid">
<div class="footer-brand">
<div class="logo">
<div class="logo-icon"></div>
<div class="logo-text">
晟算科技
<small style="color:var(--text-muted)">SHENGSUAN TECH</small>
</div>
</div>
<p>月亮碎了,我们在修。修复内容保密,修复进度公开。</p>
</div>
<div class="footer-col">
<h4>导航</h4>
<ul>
<li><a href="index.html">首页</a></li>
<li><a href="about.html">关于我们</a></li>
<li><a href="products.html">产品矩阵</a></li>
<li><a href="contact.html">来聊聊</a></li>
</ul>
</div>
<div class="footer-col">
<h4>碎片清单</h4>
<ul>
<li><a href="products.html">FRAGMENT_α</a></li>
<li><a href="products.html">FRAGMENT_β</a></li>
<li><a href="products.html">FRAGMENT_γ</a></li>
<li><a href="products.html">???</a></li>
</ul>
</div>
<div class="footer-col">
<h4>信号源</h4>
<ul class="footer-contact">
<li>
<span class="contact-icon">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>
</span>
<span>河南省 · 郑州市 · 金水区</span>
</li>
<li>
<span class="contact-icon">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/></svg>
</span>
<span>0371-8888-6666</span>
</li>
<li>
<span class="contact-icon">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>
</span>
<span>hello@shengsuan.tech</span>
</li>
</ul>
</div>
</div>
<div class="footer-bottom">
<span>&copy; 2026 郑州晟算科技有限公司</span>
<span>ground_control@shengsuan:~$ repairing_moon --progress 85%</span>
</div>
</div>
</footer>
<script src="js/lib/three.min.js"></script>
<script src="js/space.js"></script>
<script src="js/main.js"></script>
</body>
</html>
+7
View File
File diff suppressed because one or more lines are too long
+732
View File
@@ -0,0 +1,732 @@
/* ============================
郑州晟算科技有限公司 - 交互脚本 v3
自定义光标 · 启动加载屏 · 3D倾斜 · 磁性按钮 · 乱序解码
============================ */
(function () {
"use strict";
/* ========================================
1. 自定义光标
======================================== */
const isTouchDevice = "ontouchstart" in window || navigator.maxTouchPoints > 0;
if (!isTouchDevice) {
const dot = document.createElement("div");
dot.className = "cursor-dot";
const ring = document.createElement("div");
ring.className = "cursor-ring";
document.body.appendChild(dot);
document.body.appendChild(ring);
let dotX = 0, dotY = 0;
let ringX = 0, ringY = 0;
let mouseX = 0, mouseY = 0;
let isVisible = false;
let cursorActivated = false;
document.addEventListener("mousemove", function (e) {
mouseX = e.clientX;
mouseY = e.clientY;
if (!isVisible) {
isVisible = true;
dot.style.opacity = "1";
ring.style.opacity = "1";
// 确认自定义光标工作后才隐藏系统光标
if (!cursorActivated) {
cursorActivated = true;
document.body.classList.add("custom-cursor-active");
}
}
});
document.addEventListener("mouseleave", function () {
isVisible = false;
dot.style.opacity = "0";
ring.style.opacity = "0";
});
document.addEventListener("mousedown", function () {
ring.classList.add("clicking");
});
document.addEventListener("mouseup", function () {
ring.classList.remove("clicking");
});
// 检测可交互元素
const hoverables = document.querySelectorAll("a, button, .card, .teaser-card, .feature-card, .belief-card, .philosophy-item, input, textarea, select, .nav-cta, .structure-item, .vision-item");
hoverables.forEach(function (el) {
el.addEventListener("mouseenter", function () { ring.classList.add("hovering"); });
el.addEventListener("mouseleave", function () { ring.classList.remove("hovering"); });
});
function animateCursor() {
// 点:即时跟随
dotX += (mouseX - dotX) * 0.35;
dotY += (mouseY - dotY) * 0.35;
dot.style.left = dotX + "px";
dot.style.top = dotY + "px";
// 环:延迟跟随
ringX += (mouseX - ringX) * 0.12;
ringY += (mouseY - ringY) * 0.12;
ring.style.left = ringX + "px";
ring.style.top = ringY + "px";
requestAnimationFrame(animateCursor);
}
animateCursor();
}
/* ========================================
2. 启动加载屏(太空模式下由space.js接管)
======================================== */
const isFirstVisit = !sessionStorage.getItem("visited");
if (!window.SPACE_MODE && isFirstVisit) {
const loadingScreen = document.createElement("div");
loadingScreen.className = "loading-screen";
loadingScreen.innerHTML =
'<div class="loading-logo">SHENG<span>SUAN</span></div>' +
'<div class="loading-terminal">' +
'<div class="terminal-header">' +
'<div class="terminal-dot"></div>' +
'<div class="terminal-dot"></div>' +
'<div class="terminal-dot"></div>' +
'<div class="terminal-title">shengsuan@tech ~ boot</div>' +
'</div>' +
'<div class="terminal-body">' +
'<div class="terminal-line" style="animation-delay:0.1s"><span class="terminal-prompt">></span><span class="terminal-text">Detecting software chaos... </span><span class="terminal-text ok">[76%]</span></div>' +
'<div class="terminal-line" style="animation-delay:0.4s"><span class="terminal-prompt">></span><span class="terminal-text">Loading fix modules... </span><span class="terminal-text ok">[OK]</span></div>' +
'<div class="terminal-line" style="animation-delay:0.7s"><span class="terminal-prompt">></span><span class="terminal-text">Mounting patches... </span><span class="terminal-text ok">[3 loaded]</span></div>' +
'<div class="terminal-line" style="animation-delay:1.0s"><span class="terminal-prompt">></span><span class="terminal-text">Rendering scene... </span><span class="terminal-text ok">[OK]</span></div>' +
'<div class="terminal-line" style="animation-delay:1.3s"><span class="terminal-prompt">></span><span class="terminal-text typing" style="color:var(--cyan)">Welcome, fixer. Let\'s repair some software.</span></div>' +
'</div>' +
'</div>';
document.body.appendChild(loadingScreen);
setTimeout(function () {
loadingScreen.classList.add("hide");
sessionStorage.setItem("visited", "true");
setTimeout(function () {
if (loadingScreen.parentNode) loadingScreen.parentNode.removeChild(loadingScreen);
}, 700);
}, 2000);
} else {
sessionStorage.setItem("visited", "true");
}
/* ========================================
3. 滚动进度条
======================================== */
const progressBar = document.createElement("div");
progressBar.className = "scroll-progress";
progressBar.style.width = "0%";
document.body.appendChild(progressBar);
window.addEventListener("scroll", function () {
const scrollTop = window.scrollY;
const docHeight = document.documentElement.scrollHeight - window.innerHeight;
const scrollPercent = docHeight > 0 ? (scrollTop / docHeight) * 100 : 0;
progressBar.style.width = scrollPercent + "%";
}, { passive: true });
/* ========================================
4. 粒子背景(太空模式下禁用,由space.js接管)
======================================== */
let canvas = document.getElementById("particlesCanvas");
if (window.SPACE_MODE) {
if (canvas) canvas.remove();
} else {
if (!canvas) {
canvas = document.createElement("canvas");
canvas.id = "particlesCanvas";
document.body.prepend(canvas);
}
const ctx = canvas.getContext("2d");
let particles = [];
const PARTICLE_COUNT = 50;
let pmouseX = 0, pmouseY = 0;
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
resizeCanvas();
window.addEventListener("resize", resizeCanvas);
for (let i = 0; i < PARTICLE_COUNT; i++) {
particles.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
vx: (Math.random() - 0.5) * 0.4,
vy: (Math.random() - 0.5) * 0.4,
size: Math.random() * 1.5 + 0.5,
opacity: Math.random() * 0.35 + 0.08
});
}
document.addEventListener("mousemove", function (e) {
pmouseX = e.clientX;
pmouseY = e.clientY;
});
function drawParticles() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i < particles.length; i++) {
const p = particles[i];
p.x += p.vx;
p.y += p.vy;
if (p.x < 0) p.x = canvas.width;
if (p.x > canvas.width) p.x = 0;
if (p.y < 0) p.y = canvas.height;
if (p.y > canvas.height) p.y = 0;
const dx = pmouseX - p.x;
const dy = pmouseY - p.y;
const dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 180 && dist > 0) {
const force = (180 - dist) / 180 * 0.5;
p.vx += (dx / dist) * force * 0.03;
p.vy += (dy / dist) * force * 0.03;
}
p.vx *= 0.999;
p.vy *= 0.999;
ctx.beginPath();
ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
ctx.fillStyle = "rgba(0, 230, 118, " + p.opacity + ")";
ctx.fill();
}
for (let j = 0; j < particles.length; j++) {
for (let k = j + 1; k < particles.length; k++) {
const a = particles[j], b = particles[k];
const d = Math.sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
if (d < 120) {
ctx.beginPath();
ctx.moveTo(a.x, a.y);
ctx.lineTo(b.x, b.y);
ctx.strokeStyle = "rgba(0, 230, 118, " + (0.06 * (1 - d / 120)) + ")";
ctx.lineWidth = 0.5;
ctx.stroke();
}
}
}
requestAnimationFrame(drawParticles);
}
drawParticles();
} /* end else (非太空模式才运行粒子) */
/* ========================================
5. 导航栏
======================================== */
const header = document.querySelector(".header");
window.addEventListener("scroll", function () {
if (window.scrollY > 10) {
header.classList.add("scrolled");
} else {
header.classList.remove("scrolled");
}
}, { passive: true });
const menuToggle = document.querySelector(".menu-toggle");
const nav = document.querySelector(".nav");
if (menuToggle && nav) {
menuToggle.addEventListener("click", function () {
menuToggle.classList.toggle("active");
nav.classList.toggle("active");
});
nav.querySelectorAll("a").forEach(function (link) {
link.addEventListener("click", function () {
menuToggle.classList.remove("active");
nav.classList.remove("active");
});
});
}
/* ========================================
6. 滚动显现
======================================== */
const revealElements = document.querySelectorAll(".reveal");
if ("IntersectionObserver" in window && revealElements.length > 0) {
const observer = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
entry.target.classList.add("visible");
observer.unobserve(entry.target);
}
});
}, { threshold: 0.1, rootMargin: "0px 0px -30px 0px" });
revealElements.forEach(function (el) { observer.observe(el); });
} else {
revealElements.forEach(function (el) { el.classList.add("visible"); });
}
/* ========================================
7. 打字机效果
======================================== */
const typewriterEl = document.querySelector("#typewriter");
if (typewriterEl) {
let words;
try {
words = typewriterEl.getAttribute("data-words")
? JSON.parse(typewriterEl.getAttribute("data-words"))
: [typewriterEl.textContent.trim()];
} catch (e) {
words = [typewriterEl.textContent.trim()];
}
let wordIndex = 0;
let charIndex = 0;
let isDeleting = false;
const typeSpeed = 80;
const deleteSpeed = 40;
const pauseTime = 2000;
function type() {
const currentWord = words[wordIndex];
if (isDeleting) {
typewriterEl.textContent = currentWord.substring(0, charIndex - 1);
charIndex--;
if (charIndex === 0) {
isDeleting = false;
wordIndex = (wordIndex + 1) % words.length;
setTimeout(type, 300);
return;
}
setTimeout(type, deleteSpeed);
} else {
typewriterEl.textContent = currentWord.substring(0, charIndex + 1);
charIndex++;
if (charIndex === currentWord.length) {
setTimeout(function () {
isDeleting = true;
type();
}, pauseTime);
return;
}
setTimeout(type, typeSpeed);
}
}
const cursor = document.createElement("span");
cursor.className = "typewriter-cursor";
cursor.textContent = "_";
typewriterEl.parentNode.insertBefore(cursor, typewriterEl.nextSibling);
setTimeout(type, 500);
}
/* ========================================
8. 3D 倾斜卡片
======================================== */
const tiltCards = document.querySelectorAll(".card, .teaser-card, .feature-card, .belief-card, .philosophy-item, .teaser-main, .teaser-side-item, .about-visual-block");
tiltCards.forEach(function (card) {
card.addEventListener("mousemove", function (e) {
const rect = card.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const centerX = rect.width / 2;
const centerY = rect.height / 2;
const rotateX = (y - centerY) / centerY * -8;
const rotateY = (x - centerX) / centerX * 8;
card.style.transform = "perspective(800px) rotateX(" + rotateX + "deg) rotateY(" + rotateY + "deg) translateZ(10px)";
// 更新光斑位置
let glow = card.querySelector(".card-glow");
if (!glow) {
glow = document.createElement("div");
glow.className = "card-glow";
card.appendChild(glow);
}
glow.style.left = (x - 100) + "px";
glow.style.top = (y - 100) + "px";
});
card.addEventListener("mouseleave", function () {
card.style.transform = "perspective(800px) rotateX(0) rotateY(0) translateZ(0)";
card.style.transition = "transform 0.6s ease";
setTimeout(function () {
card.style.transition = "";
}, 600);
});
});
/* ========================================
9. 磁性按钮
======================================== */
const magneticBtns = document.querySelectorAll(".btn, .nav-cta");
magneticBtns.forEach(function (btn) {
btn.classList.add("magnetic");
btn.addEventListener("mousemove", function (e) {
const rect = btn.getBoundingClientRect();
const x = e.clientX - rect.left - rect.width / 2;
const y = e.clientY - rect.top - rect.height / 2;
const strength = 0.3;
btn.style.transform = "translate(" + x * strength + "px, " + y * strength + "px)";
});
btn.addEventListener("mouseleave", function () {
btn.style.transform = "translate(0, 0)";
btn.style.transition = "transform 0.4s cubic-bezier(0.22, 1, 0.36, 1)";
setTimeout(function () {
btn.style.transition = "";
}, 400);
});
});
/* ========================================
10. 文字乱序解码 (Scramble)
======================================== */
const CHARS = "!<>-_\\/[]{}—=+*^?#________";
const scrambleElements = document.querySelectorAll("[data-scramble]");
if (scrambleElements.length > 0 && "IntersectionObserver" in window) {
const scrambleObserver = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting && !entry.target.classList.contains("scrambled")) {
entry.target.classList.add("scrambled");
scrambleText(entry.target);
scrambleObserver.unobserve(entry.target);
}
});
}, { threshold: 0.5 });
scrambleElements.forEach(function (el) {
scrambleObserver.observe(el);
});
}
function scrambleText(el) {
const originalText = el.textContent;
const length = originalText.length;
let frame = 0;
const totalFrames = length * 3;
const revealed = new Array(length).fill(false);
function update() {
let output = "";
let done = true;
for (let i = 0; i < length; i++) {
if (revealed[i]) {
output += originalText[i];
continue;
}
if (frame > i * 2 + Math.random() * 10) {
revealed[i] = true;
output += originalText[i];
} else {
done = false;
output += CHARS[Math.floor(Math.random() * CHARS.length)];
}
}
el.textContent = output;
frame++;
if (!done) {
requestAnimationFrame(update);
} else {
el.textContent = originalText;
}
}
requestAnimationFrame(update);
}
/* ========================================
11. 视差滚动 (Orbs - 排除hero-orb避免与CSS动画冲突)
======================================== */
const orbs = document.querySelectorAll(".cta-orb, .page-hero-orb");
if (orbs.length > 0) {
window.addEventListener("scroll", function () {
const scrollY = window.scrollY;
orbs.forEach(function (orb, index) {
const speed = 0.05 + (index % 3) * 0.03;
orb.style.transform = "translateY(" + scrollY * speed + "px)";
});
}, { passive: true });
}
/* ========================================
11.5 编译进度条动画
======================================== */
const progressFills = document.querySelectorAll(".build-progress-fill[data-progress]");
if (progressFills.length > 0 && "IntersectionObserver" in window) {
const progressObserver = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
const fill = entry.target;
const target = fill.getAttribute("data-progress");
setTimeout(function () {
fill.style.width = target + "%";
}, 200);
progressObserver.unobserve(fill);
}
});
}, { threshold: 0.5 });
progressFills.forEach(function (fill) {
fill.style.width = "0%";
progressObserver.observe(fill);
});
}
/* ========================================
11.6 失控数字滚动
======================================== */
const chaosNums = document.querySelectorAll("[data-chaos-count]");
if (chaosNums.length > 0 && "IntersectionObserver" in window) {
const chaosObserver = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
animateChaosNum(entry.target);
chaosObserver.unobserve(entry.target);
}
});
}, { threshold: 0.5 });
chaosNums.forEach(function (el) { chaosObserver.observe(el); });
}
function animateChaosNum(el) {
const target = parseFloat(el.getAttribute("data-chaos-count"));
const decimals = el.getAttribute("data-decimals") ? parseInt(el.getAttribute("data-decimals")) : 0;
const duration = 1600;
let startTime = null;
function step(timestamp) {
if (!startTime) startTime = timestamp;
const progress = Math.min((timestamp - startTime) / duration, 1);
const eased = progress === 1 ? 1 : 1 - Math.pow(2, -10 * progress);
const current = eased * target;
el.textContent = decimals > 0 ? current.toFixed(decimals) : Math.floor(current).toLocaleString();
if (progress < 1) {
requestAnimationFrame(step);
} else {
el.textContent = decimals > 0 ? target.toFixed(decimals) : target.toLocaleString();
}
}
requestAnimationFrame(step);
}
/* ========================================
12.5 KPR风格滚动场景引擎
======================================== */
const scrollScenes = document.querySelectorAll(".scroll-scene");
if (scrollScenes.length > 0) {
const sceneData = [];
scrollScenes.forEach(function (scene) {
sceneData.push({
el: scene,
lines: scene.querySelectorAll(".scene-line"),
pctEls: scene.querySelectorAll("[data-scene-pct]"),
giantTexts: scene.querySelectorAll(".bg-giant-text")
});
});
let sceneTicking = false;
function updateScenes() {
const vh = window.innerHeight;
sceneData.forEach(function (data) {
const rect = data.el.getBoundingClientRect();
const scrollable = rect.height - vh;
if (scrollable <= 0) return;
const progress = Math.min(Math.max(-rect.top / scrollable, 0), 1);
// 进度百分比
const pct = Math.floor(progress * 100);
data.pctEls.forEach(function (el) {
el.textContent = (pct < 10 ? "0" : "") + pct + "%";
});
// 大字背景视差
data.giantTexts.forEach(function (gt) {
const shift = (progress - 0.5) * 120;
gt.style.transform = "translate(-50%, -50%) translateX(" + shift + "px)";
});
// 逐行揭示
const n = data.lines.length;
data.lines.forEach(function (line, i) {
const lineStart = (i / n) * 0.9;
const lineEnd = ((i + 1) / n) * 0.9 + 0.05;
if (progress >= lineStart && progress < lineEnd) {
line.classList.add("active");
line.classList.remove("exit");
} else if (progress >= lineEnd) {
line.classList.remove("active");
line.classList.add("exit");
} else {
line.classList.remove("active", "exit");
}
});
});
sceneTicking = false;
}
window.addEventListener("scroll", function () {
if (!sceneTicking) {
requestAnimationFrame(updateScenes);
sceneTicking = true;
}
}, { passive: true });
updateScenes();
}
/* ========================================
12.6 持续加密乱码(永不解码)
======================================== */
const SCRAMBLE_CHARS = "01!<>-_/[]{}=+*^?#@%&$ABCDEF";
const loopEncrypted = document.querySelectorAll("[data-scramble-loop]");
if (loopEncrypted.length > 0) {
const encStates = [];
loopEncrypted.forEach(function (el) {
const len = parseInt(el.getAttribute("data-length") || el.textContent.length, 10);
encStates.push({ el: el, len: len });
});
let encFrame = 0;
function loopScramble() {
encFrame++;
// 每3帧更新一次,降低频率更有"电流感"
if (encFrame % 3 === 0) {
encStates.forEach(function (s) {
let out = "";
for (let i = 0; i < s.len; i++) {
out += SCRAMBLE_CHARS[Math.floor(Math.random() * SCRAMBLE_CHARS.length)];
}
s.el.textContent = out;
});
}
requestAnimationFrame(loopScramble);
}
// 仅在视口内时运行
const encObserver = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting && !entry.target.dataset.looping) {
entry.target.dataset.looping = "1";
}
});
});
loopEncrypted.forEach(function (el) { encObserver.observe(el); });
loopScramble();
}
/* ========================================
12.7 数据流下落线条生成(带裁剪层,防页面弹跳)
======================================== */
const streamContainers = document.querySelectorAll("[data-streams]");
streamContainers.forEach(function (container) {
// 裁剪层:防止线条溢出改变文档高度导致底部弹跳
const layer = document.createElement("div");
layer.style.cssText = "position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:0";
const count = parseInt(container.getAttribute("data-streams"), 10) || 5;
for (let i = 0; i < count; i++) {
const stream = document.createElement("div");
stream.className = "data-stream";
stream.style.left = (10 + Math.random() * 80) + "%";
stream.style.height = (60 + Math.random() * 120) + "px";
stream.style.animationDelay = (Math.random() * 3) + "s";
stream.style.animationDuration = (2.5 + Math.random() * 2) + "s";
layer.appendChild(stream);
}
container.insertBefore(layer, container.firstChild);
});
/* ========================================
12. 联系表单
======================================== */
const contactForm = document.querySelector("#contactForm");
if (contactForm) {
contactForm.addEventListener("submit", function (e) {
e.preventDefault();
const successMsg = document.querySelector(".form-success");
if (successMsg) {
successMsg.classList.add("show");
successMsg.scrollIntoView({ behavior: "smooth", block: "center" });
}
contactForm.reset();
setTimeout(function () {
if (successMsg) successMsg.classList.remove("show");
}, 6000);
});
}
/* ========================================
13. 当前页面高亮导航
======================================== */
const currentPage = window.location.pathname.split("/").pop() || "index.html";
const navLinks = document.querySelectorAll(".nav-link");
navLinks.forEach(function (link) {
const href = link.getAttribute("href");
if (href === currentPage || (currentPage === "" && href === "index.html")) {
link.classList.add("active");
}
});
/* ========================================
14. 腐化标题特效 —— 标题本身就是bug
======================================== */
const corruptEl = document.querySelector(".corrupt-title[data-text]");
if (corruptEl) {
const original = corruptEl.getAttribute("data-text");
const GLITCH_CHARS = "▓█◆#@$%&!?◢◤╳╱╲─│┌┐└┘01";
// 拆分字符
corruptEl.innerHTML = "";
const charSpans = [];
for (let ci = 0; ci < original.length; ci++) {
const span = document.createElement("span");
span.className = "corrupt-char";
span.textContent = original[ci];
span.setAttribute("data-orig", original[ci]);
corruptEl.appendChild(span);
charSpans.push(span);
}
const wrap = corruptEl.closest(".corrupt-wrap");
// 持续轻微腐化: 随机字符短暂变为乱码
setInterval(function () {
if (Math.random() > 0.45) {
const idx = Math.floor(Math.random() * charSpans.length);
const span = charSpans[idx];
span.textContent = GLITCH_CHARS[Math.floor(Math.random() * GLITCH_CHARS.length)];
span.classList.add("glitching");
setTimeout(function () {
span.textContent = span.getAttribute("data-orig");
span.classList.remove("glitching");
}, 60 + Math.random() * 120);
}
}, 140);
// 偶发重度腐化: 多个字符同时崩溃 + 屏幕震颤
setInterval(function () {
if (Math.random() > 0.6) {
const burst = 2 + Math.floor(Math.random() * 3);
for (let b = 0; b < burst; b++) {
const span = charSpans[Math.floor(Math.random() * charSpans.length)];
span.textContent = GLITCH_CHARS[Math.floor(Math.random() * GLITCH_CHARS.length)];
span.classList.add("glitching");
(function (s) {
setTimeout(function () {
s.textContent = s.getAttribute("data-orig");
s.classList.remove("glitching");
}, 120 + Math.random() * 200);
})(span);
}
if (wrap) {
wrap.classList.remove("shake");
void wrap.offsetWidth; // 重置动画
wrap.classList.add("shake");
}
}
}, 4200);
}
})();
+487
View File
@@ -0,0 +1,487 @@
/* ============================================================
晟算科技 · 太空场景引擎
破碎的月亮 = 失控的软件世界 | 修复进度 85% 停住
模式: journey(首页滚动驱动) / orbit(子页面轨道展示)
============================================================ */
window.SPACE_MODE = document.body.getAttribute("data-space") || "journey";
(function () {
"use strict";
var isMobile = window.innerWidth < 768 || "ontouchstart" in window;
var reducedMotion = window.matchMedia("(prefers-reduced-motion: reduced)").matches;
var bootEl = document.getElementById("spaceBoot");
var canvasHost = document.getElementById("spaceCanvas");
/* ---------- WebGL 不可用时的兜底 ---------- */
function fallback() {
if (bootEl) bootEl.remove();
document.body.classList.add("space-fallback");
// 退化为2D星空(CSS实现,见space.css)
}
if (!window.THREE) { fallback(); return; }
var testCanvas = document.createElement("canvas");
var gl = testCanvas.getContext("webgl") || testCanvas.getContext("experimental-webgl");
if (!gl) { fallback(); return; }
/* ============================================================
程序化纹理生成
============================================================ */
// 径向光晕纹理(太阳辉光/镜头光斑)
function makeGlowTexture(inner, outer, size) {
var c = document.createElement("canvas");
c.width = c.height = size;
var ctx = c.getContext("2d");
var g = ctx.createRadialGradient(size / 2, size / 2, 0, size / 2, size / 2, size / 2);
g.addColorStop(0, inner);
g.addColorStop(0.35, inner.replace(/[\d.]+\)$/, "0.35)"));
g.addColorStop(1, outer);
ctx.fillStyle = g;
ctx.fillRect(0, 0, size, size);
var t = new THREE.CanvasTexture(c);
return t;
}
// 月球纹理: 写实环形山 + 代码字符混合
var crackPath = []; // 裂缝路径点(供粒子泄漏/光缝定位)
function makeMoonTexture() {
var W = 1024, H = 512;
var c = document.createElement("canvas");
c.width = W; c.height = H;
var ctx = c.getContext("2d");
// 基底灰
var base = ctx.createLinearGradient(0, 0, W, H);
base.addColorStop(0, "#8d8d8f");
base.addColorStop(0.5, "#7c7c80");
base.addColorStop(1, "#6e6e73");
ctx.fillStyle = base;
ctx.fillRect(0, 0, W, H);
// 月海(大块暗斑)
for (var m = 0; m < 7; m++) {
var mx = Math.random() * W, my = Math.random() * H, mr = 60 + Math.random() * 130;
var mg = ctx.createRadialGradient(mx, my, 0, mx, my, mr);
mg.addColorStop(0, "rgba(70,70,76,0.5)");
mg.addColorStop(1, "rgba(70,70,76,0)");
ctx.fillStyle = mg;
ctx.beginPath(); ctx.arc(mx, my, mr, 0, Math.PI * 2); ctx.fill();
}
// 环形山
for (var i = 0; i < 220; i++) {
var x = Math.random() * W, y = Math.random() * H;
var r = 2 + Math.random() * 18;
ctx.fillStyle = "rgba(50,50,56," + (0.15 + Math.random() * 0.25) + ")";
ctx.beginPath(); ctx.arc(x, y, r, 0, Math.PI * 2); ctx.fill();
// 亮缘
ctx.strokeStyle = "rgba(200,200,205," + (0.1 + Math.random() * 0.2) + ")";
ctx.lineWidth = 1;
ctx.beginPath(); ctx.arc(x, y, r, -0.6, 1.8); ctx.stroke();
}
// 表面噪点
for (var n = 0; n < 2600; n++) {
var nx = Math.random() * W, ny = Math.random() * H;
ctx.fillStyle = Math.random() > 0.5
? "rgba(255,255,255," + Math.random() * 0.06 + ")"
: "rgba(0,0,0," + Math.random() * 0.08 + ")";
ctx.fillRect(nx, ny, 1.5, 1.5);
}
// 代码字符纹理(远看是月面,近看全是代码)
var glyphs = "01{}[]<>/=;+*#$&%@!?~:fnrax";
ctx.textBaseline = "top";
for (var g2 = 0; g2 < 520; g2++) {
var gx = Math.random() * W, gy = Math.random() * H;
var fs = 6 + Math.random() * 8;
ctx.font = fs + "px monospace";
var greenish = Math.random() > 0.72;
ctx.fillStyle = greenish
? "rgba(90,220,150," + (0.06 + Math.random() * 0.1) + ")"
: "rgba(230,230,235," + (0.04 + Math.random() * 0.08) + ")";
ctx.fillText(glyphs[Math.floor(Math.random() * glyphs.length)], gx, gy);
}
// 裂缝(锯齿状,贯穿一侧) —— 同时记录路径
ctx.strokeStyle = "rgba(18,18,22,0.9)";
ctx.lineCap = "round";
var cx = W * 0.62, cy = H * 0.16;
ctx.lineWidth = 7;
ctx.beginPath(); ctx.moveTo(cx, cy);
crackPath.push([cx, cy]);
while (cy < H * 0.9) {
cx += (Math.random() - 0.42) * 90;
cy += 26 + Math.random() * 30;
ctx.lineTo(cx, cy);
crackPath.push([cx, cy]);
ctx.lineWidth = Math.max(2, ctx.lineWidth * 0.94);
}
ctx.stroke();
// 裂缝两侧的次级裂纹
for (var b = 0; b < 8; b++) {
var bp = crackPath[Math.floor(Math.random() * crackPath.length)];
ctx.lineWidth = 1.5;
ctx.beginPath(); ctx.moveTo(bp[0], bp[1]);
var bx = bp[0], by = bp[1];
for (var s = 0; s < 4; s++) {
bx += (Math.random() - 0.5) * 60;
by += Math.random() * 26;
ctx.lineTo(bx, by);
}
ctx.stroke();
}
var tex = new THREE.CanvasTexture(c);
tex.colorSpace = THREE.SRGBColorSpace;
return tex;
}
// 代码字符精灵纹理
function makeCharSprite(ch, color) {
var s = 48;
var c = document.createElement("canvas");
c.width = c.height = s;
var ctx = c.getContext("2d");
ctx.font = "bold 30px monospace";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.shadowColor = color;
ctx.shadowBlur = 8;
ctx.fillStyle = color;
ctx.fillText(ch, s / 2, s / 2);
return new THREE.CanvasTexture(c);
}
/* ============================================================
场景搭建
============================================================ */
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 0.1, 2000);
var rig = new THREE.Group(); // 相机吊舱(负责呼吸式漂移)
rig.add(camera);
scene.add(rig);
var renderer;
try {
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, powerPreference: "high-performance" });
} catch (e) { fallback(); return; }
renderer.setPixelRatio(Math.min(window.devicePixelRatio, isMobile ? 1.2 : 1.6));
renderer.setSize(window.innerWidth, window.innerHeight);
canvasHost.appendChild(renderer.domElement);
/* ---------- 星空(两层) ---------- */
function makeStars(count, spread, size, opacity) {
var geo = new THREE.BufferGeometry();
var pos = new Float32Array(count * 3);
var col = new Float32Array(count * 3);
for (var i = 0; i < count; i++) {
pos[i * 3] = (Math.random() - 0.5) * spread;
pos[i * 3 + 1] = (Math.random() - 0.5) * spread;
pos[i * 3 + 2] = (Math.random() - 0.5) * spread;
var r = Math.random();
if (r > 0.85) { col[i * 3] = 1.0; col[i * 3 + 1] = 0.9; col[i * 3 + 2] = 0.75; } // 暖星
else if (r > 0.7) { col[i * 3] = 0.75; col[i * 3 + 1] = 0.85; col[i * 3 + 2] = 1.0; } // 蓝星
else { col[i * 3] = 1; col[i * 3 + 1] = 1; col[i * 3 + 2] = 1; }
}
geo.setAttribute("position", new THREE.BufferAttribute(pos, 3));
geo.setAttribute("color", new THREE.BufferAttribute(col, 3));
var mat = new THREE.PointsMaterial({
size: size, vertexColors: true, transparent: true, opacity: opacity,
sizeAttenuation: true, depthWrite: false
});
return new THREE.Points(geo, mat);
}
var starsFar = makeStars(isMobile ? 1500 : 3200, 900, 1.6, 0.85);
var starsNear = makeStars(isMobile ? 120 : 260, 220, 2.4, 0.6); // 近处星尘(景深)
scene.add(starsFar);
rig.add(starsNear);
/* ---------- 太阳(远景) ---------- */
var sunGroup = new THREE.Group();
var sunCore = new THREE.Mesh(
new THREE.SphereGeometry(14, 24, 24),
new THREE.MeshBasicMaterial({ color: 0xfff8e7 })
);
sunGroup.add(sunCore);
var glowTex = makeGlowTexture("rgba(255,244,214,1)", "rgba(255,244,214,0)", 256);
var sunGlow1 = new THREE.Sprite(new THREE.SpriteMaterial({ map: glowTex, transparent: true, blending: THREE.AdditiveBlending, depthWrite: false }));
sunGlow1.scale.set(110, 110, 1);
sunGroup.add(sunGlow1);
var sunGlow2 = new THREE.Sprite(new THREE.SpriteMaterial({ map: glowTex, transparent: true, opacity: 0.5, blending: THREE.AdditiveBlending, depthWrite: false }));
sunGlow2.scale.set(220, 220, 1);
sunGroup.add(sunGlow2);
// 镜头光斑链
var flareTex = makeGlowTexture("rgba(255,236,190,0.8)", "rgba(255,236,190,0)", 128);
for (var f = 0; f < 3; f++) {
var flare = new THREE.Sprite(new THREE.SpriteMaterial({ map: flareTex, transparent: true, opacity: 0.25 - f * 0.06, blending: THREE.AdditiveBlending, depthWrite: false }));
var fs2 = [22, 10, 6][f];
flare.scale.set(fs2, fs2, 1);
flare.position.set(18 + f * 14, -6 - f * 4, 0);
sunGroup.add(flare);
}
sunGroup.position.set(-150, 70, -260);
scene.add(sunGroup);
/* ---------- 月亮(破碎) ---------- */
var moonGroup = new THREE.Group();
var MOON_R = 10;
var moonTex = makeMoonTexture();
var moonMat = new THREE.MeshStandardMaterial({
map: moonTex, bumpMap: moonTex, bumpScale: 0.35,
roughness: 0.95, metalness: 0.02
});
var moon = new THREE.Mesh(new THREE.SphereGeometry(MOON_R, 64, 64), moonMat);
moonGroup.add(moon);
// 月亮轮廓微光(大气感)
var moonHalo = new THREE.Sprite(new THREE.SpriteMaterial({
map: makeGlowTexture("rgba(190,200,220,0.5)", "rgba(190,200,220,0)", 256),
transparent: true, opacity: 0.5, blending: THREE.AdditiveBlending, depthWrite: false
}));
moonHalo.scale.set(34, 34, 1);
moonGroup.add(moonHalo);
// 碎片(3块, 不规则形状)
var fragments = [];
var fragSpecs = [
{ size: 2.6, scatter: new THREE.Vector3(9, 4.5, 3), home: new THREE.Vector3(7.6, 3.4, 2.2), spin: 0.16 },
{ size: 1.8, scatter: new THREE.Vector3(-7, -5, 4.5), home: new THREE.Vector3(-5.4, -3.9, 3.4), spin: -0.22 },
{ size: 1.3, scatter: new THREE.Vector3(4, -8, -4), home: new THREE.Vector3(3.2, -6.2, -3.1), spin: 0.3 }
];
fragSpecs.forEach(function (spec) {
var geo = new THREE.IcosahedronGeometry(spec.size, 1);
var posAttr = geo.getAttribute("position");
for (var i = 0; i < posAttr.count; i++) {
var jitter = 0.75 + Math.random() * 0.45;
posAttr.setXYZ(i, posAttr.getX(i) * jitter, posAttr.getY(i) * jitter, posAttr.getZ(i) * jitter);
}
geo.computeVertexNormals();
var mesh = new THREE.Mesh(geo, moonMat);
mesh.position.copy(spec.scatter);
mesh.rotation.set(Math.random() * 3, Math.random() * 3, Math.random() * 3);
moonGroup.add(mesh);
fragments.push({ mesh: mesh, spec: spec, phase: Math.random() * Math.PI * 2 });
});
// 修复光缝(绿色能量缝,随修复进度亮起)
var seams = [];
var seamTex = makeGlowTexture("rgba(77,255,166,1)", "rgba(77,255,166,0)", 64);
fragSpecs.forEach(function (spec) {
var seam = new THREE.Sprite(new THREE.SpriteMaterial({
map: seamTex, color: 0x4dffa6, transparent: true, opacity: 0,
blending: THREE.AdditiveBlending, depthWrite: false
}));
seam.scale.set(spec.size * 3.2, spec.size * 1.2, 1);
seam.position.copy(spec.home).multiplyScalar(0.92);
moonGroup.add(seam);
seams.push(seam);
});
moonGroup.position.set(6, 1, -26);
scene.add(moonGroup);
/* ---------- 代码泄漏粒子 ---------- */
var codeChars = "01{}<>/=;#*$fx";
var leakSprites = [];
var LEAK_COUNT = isMobile ? 22 : 46;
var charTexCache = {};
function charTex(ch) {
if (!charTexCache[ch]) charTexCache[ch] = makeCharSprite(ch, "#4dffa6");
return charTexCache[ch];
}
for (var li = 0; li < LEAK_COUNT; li++) {
var sp = new THREE.Sprite(new THREE.SpriteMaterial({
map: charTex(codeChars[Math.floor(Math.random() * codeChars.length)]),
transparent: true, opacity: 0, depthWrite: false, blending: THREE.AdditiveBlending
}));
var sc = 0.5 + Math.random() * 0.7;
sp.scale.set(sc, sc, 1);
// 从裂缝附近发射
var emit = new THREE.Vector3(
moonGroup.position.x + 3 + Math.random() * 6,
moonGroup.position.y - 4 + Math.random() * 8,
moonGroup.position.z + 2 + Math.random() * 4
);
sp.position.copy(emit);
scene.add(sp);
leakSprites.push({
sp: sp, life: Math.random(), speed: 0.06 + Math.random() * 0.1,
drift: new THREE.Vector3((Math.random() - 0.5) * 0.5, (Math.random() - 0.5) * 0.5, (Math.random() - 0.5) * 0.3),
origin: emit
});
}
/* ---------- 灯光 ---------- */
var sunLight = new THREE.DirectionalLight(0xfff3dd, 2.2);
sunLight.position.set(-150, 70, -200);
scene.add(sunLight);
scene.add(new THREE.AmbientLight(0x334455, 0.5));
var rimLight = new THREE.DirectionalLight(0x8899ff, 0.4); // 背面冷光勾勒
rimLight.position.set(80, -40, 60);
scene.add(rimLight);
/* ============================================================
相机编排: 呼吸漂移 + 鼠标惯性 + 滚动驱动
============================================================ */
var mouseX = 0, mouseY = 0;
if (!isMobile) {
document.addEventListener("mousemove", function (e) {
mouseX = (e.clientX / window.innerWidth - 0.5) * 2;
mouseY = (e.clientY / window.innerHeight - 0.5) * 2;
});
}
function scrollProgress() {
var h = document.documentElement.scrollHeight - window.innerHeight;
return h > 0 ? Math.min(Math.max(window.scrollY / h, 0), 1) : 0;
}
function easeInOut(t) { return t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2; }
function lerp(a, b, t) { return a + (b - a) * t; }
var isJourney = window.SPACE_MODE === "journey";
var warpT = reducedMotion ? 1 : 0; // 0→1 warp入场
var clock = new THREE.Clock();
var bootDone = false;
/* ============================================================
BOOT 加载序列 → warp 穿越入场
============================================================ */
var bootLines = [
{ t: "> 接入深空观测网络 ………… ", ok: "[OK]" },
{ t: "> 望远镜阵列对焦 …………… ", ok: "[OK]" },
{ t: "> 扫描目标: MOON.SYS ……… ", ok: "[FATAL]" },
{ t: "> 检测到结构性碎裂 ………… ", ok: "[3 FRAGS]" },
{ t: "> 启动修复协议 ……………… ", ok: "[GO]" }
];
var bootBody = document.getElementById("spaceBootBody");
var bootBar = document.getElementById("spaceBootBar");
function runBoot() {
if (!bootEl || reducedMotion) { finishBoot(); return; }
var i = 0;
var total = bootLines.length;
function next() {
if (i < total) {
var line = document.createElement("div");
line.className = "terminal-line";
var isFatal = bootLines[i].ok.indexOf("FATAL") >= 0 || bootLines[i].ok.indexOf("FRAG") >= 0;
line.innerHTML = '<span class="terminal-prompt">' + bootLines[i].t + '</span><span class="terminal-text ' + (isFatal ? "log-error" : "ok") + '">' + bootLines[i].ok + "</span>";
if (bootBody) bootBody.appendChild(line);
if (bootBar) bootBar.style.width = ((i + 1) / total * 100) + "%";
i++;
setTimeout(next, 340);
} else {
setTimeout(finishBoot, 420);
}
}
next();
}
function finishBoot() {
if (bootEl) {
bootEl.classList.add("hide");
setTimeout(function () { if (bootEl.parentNode) bootEl.parentNode.removeChild(bootEl); }, 900);
}
bootDone = true;
document.body.classList.add("space-ready");
}
runBoot();
// 保险: 4.5s内必须入场
setTimeout(finishBoot, 4500);
/* ============================================================
主循环
============================================================ */
function animate() {
requestAnimationFrame(animate);
var t = clock.getElapsedTime();
var p = isJourney ? scrollProgress() : 0;
var ep = easeInOut(p);
// warp入场: 相机从远处冲刺到工位
if (warpT < 1) {
warpT = Math.min(1, warpT + 0.008);
var w = 1 - Math.pow(1 - warpT, 3);
camera.position.z = lerp(220, isJourney ? 46 : 42, w);
starsFar.rotation.z += 0.002 * (1 - warpT);
} else if (isJourney) {
// 滚动驱动: 接近月亮
camera.position.z = lerp(46, 24, ep);
camera.position.y = lerp(0, 3, ep);
} else {
camera.position.z = 42;
}
// 呼吸式失重漂移
rig.position.x = Math.sin(t * 0.24) * 0.55;
rig.position.y = Math.cos(t * 0.19) * 0.45;
rig.rotation.z = Math.sin(t * 0.1) * 0.008;
// 鼠标惯性跟随(像在太空里转头)
camera.rotation.y += ((-mouseX * 0.09) - camera.rotation.y) * 0.045;
camera.rotation.x += ((-mouseY * 0.06) - camera.rotation.x) * 0.045;
// 月亮自转 + 月组轻微摆动
moon.rotation.y += 0.0009;
moonGroup.position.y = 1 + Math.sin(t * 0.35) * 0.35;
moonGroup.rotation.z = Math.sin(t * 0.12) * 0.02;
// 修复进度: journey模式随滚动到85%停住 / orbit模式固定0.3
var repair = isJourney ? Math.min(Math.max((p - 0.42) / 0.46, 0), 1) * 0.85 : 0.3;
var rt = repair / 0.85; // 0→1
fragments.forEach(function (f) {
var target = f.spec.scatter.clone().lerp(f.spec.home, rt * rt);
// 悬浮: 在目标点附近小幅浮动
f.mesh.position.set(
target.x + Math.sin(t * 0.5 + f.phase) * 0.35 * (1 - rt),
target.y + Math.cos(t * 0.42 + f.phase) * 0.3 * (1 - rt),
target.z + Math.sin(t * 0.31 + f.phase * 2) * 0.3 * (1 - rt)
);
f.mesh.rotation.x += 0.0016 * f.spec.spin * (1 - rt * 0.8);
f.mesh.rotation.y += 0.0022 * f.spec.spin * (1 - rt * 0.8);
});
// 光缝亮起
seams.forEach(function (s, i) {
s.material.opacity = rt * 0.85 + Math.sin(t * 2 + i) * 0.06 * rt;
});
// 代码泄漏(修复越少漏得越多)
var leakRate = 1 - rt * 0.7;
leakSprites.forEach(function (L) {
L.life += L.speed * 0.016 * 60 * 0.016;
if (L.life > 1) {
L.life = 0;
L.sp.position.copy(L.origin);
L.sp.material.map = charTex(codeChars[Math.floor(Math.random() * codeChars.length)]);
}
L.sp.position.x += L.drift.x * 0.016;
L.sp.position.y += L.drift.y * 0.016;
L.sp.position.z += L.drift.z * 0.016;
L.sp.material.opacity = Math.sin(L.life * Math.PI) * 0.75 * leakRate;
});
// 太阳呼吸
sunGlow1.material.opacity = 0.85 + Math.sin(t * 0.8) * 0.1;
// 星尘缓流
starsNear.rotation.y += 0.0002;
starsFar.rotation.y += 0.00004;
renderer.render(scene, camera);
}
animate();
/* ---------- 自适应 ---------- */
window.addEventListener("resize", function () {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
})();
+283
View File
@@ -0,0 +1,283 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="碎片修复舱 — 三块月亮碎片正在修复中。内容已加密,解密时间待定。">
<title>碎片修复舱 [CLASSIFIED] | 晟算科技</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/space.css">
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect width='100' height='100' rx='20' fill='%2300e676'/%3E%3Ctext x='50' y='68' font-size='56' font-weight='bold' fill='%23020309' text-anchor='middle' font-family='sans-serif'%3E晟%3C/text%3E%3C/svg%3E">
</head>
<body data-space="orbit">
<div id="spaceCanvas"></div>
<div class="nebula nebula-1"></div>
<div class="nebula nebula-2"></div>
<div class="scanlines"></div>
<!-- ===== 导航栏 ===== -->
<header class="header">
<div class="header-inner">
<a href="index.html" class="logo">
<div class="logo-icon"></div>
<div class="logo-text">
晟算科技
<small>SHENGSUAN TECH</small>
</div>
</a>
<nav class="nav">
<a href="index.html" class="nav-link">首页</a>
<a href="about.html" class="nav-link">关于</a>
<a href="products.html" class="nav-link">产品</a>
<a href="contact.html" class="nav-link">聊聊</a>
<a href="contact.html" class="nav-cta">Say Hi</a>
</nav>
<div class="menu-toggle">
<span></span>
<span></span>
<span></span>
</div>
</div>
</header>
<!-- ===== 页面 Hero ===== -->
<section class="page-hero" style="min-height:auto">
<div class="geo-deco" style="position:absolute;top:100px;left:40px">DIR: /recovery_bay/</div>
<div class="geo-deco" style="position:absolute;top:100px;right:40px">ACCESS: RESTRICTED</div>
<div class="page-hero-content">
<div class="reveal" style="margin-bottom:28px">
<span class="classified-stamp">CLASSIFIED</span>
</div>
<h1 class="fade-in-up">碎片修复舱</h1>
<p class="fade-in-up delay-1">三块碎片正在修复。至于每块里封装着什么——暂时保密</p>
<div class="breadcrumb fade-in-up delay-2">
<a href="index.html">首页</a>
<span>/</span>
<span class="current">修复舱</span>
</div>
</div>
</section>
<!-- ===== 加密碎片档案 ===== -->
<section class="section">
<div class="container">
<div class="chapter-marker reveal">
<span class="chapter-num">R.1</span>
<span class="chapter-line"></span>
<span class="chapter-tag">ENCRYPTED_FRAGMENTS</span>
</div>
<!-- FRAGMENT_α 主档案 -->
<div class="card reveal" style="padding:52px 44px;margin-bottom:32px">
<div style="display:flex;justify-content:space-between;align-items:flex-start;flex-wrap:wrap;gap:20px;margin-bottom:24px">
<div style="flex:1;min-width:280px">
<div class="terminal-deco" style="margin-bottom:16px">
<span class="log-info">FILE: fragment_alpha.pkg</span>
<span class="sys-status debug" style="margin-left:16px">DEBUGGING</span>
</div>
<h3 style="font-size:32px;font-weight:800;color:var(--text-primary);font-family:var(--font-mono);letter-spacing:2px">
<span data-scramble-loop data-length="16">████████████████</span>
</h3>
<p style="font-size:15px;color:var(--text-muted);line-height:2;margin-top:16px;max-width:560px">
最大的一块碎片,裂缝最深。问题已锁定,方案已成型,焊接已完成大半。剩下的,是让每一行代码都对得起"修复"这两个字。
</p>
</div>
<div class="geo-deco" style="text-align:right;line-height:2.2">
MASS: <span class="redacted">████</span><br>
ORBIT: <span class="redacted">████████</span><br>
RECOVERY: 85%<br>
SEALED_UNTIL: <span class="redacted">████</span>
</div>
</div>
<div class="encrypted-block" style="margin-bottom:28px">
<div class="encrypted-line"><span data-scramble-loop data-length="52">████████████████████████████████████████████████████</span></div>
<div class="encrypted-line"><span data-scramble-loop data-length="44">████████████████████████████████████████████</span></div>
<div class="encrypted-line"><span data-scramble-loop data-length="36">████████████████████████████████████</span></div>
</div>
<div class="build-progress" style="margin-bottom:0">
<div class="build-progress-header">
<span class="bp-label">RECOVERY_PROGRESS</span>
<span class="bp-value">85%</span>
</div>
<div class="build-progress-track">
<div class="build-progress-fill" data-progress="85"></div>
</div>
<div class="build-progress-log">> surface_welding ✓ &nbsp;|&nbsp; > core_calibration ✓ &nbsp;|&nbsp; > final stress tests... &nbsp;|&nbsp; > decryption scheduled</div>
</div>
</div>
<div class="grid-2">
<!-- FRAGMENT_β -->
<div class="card reveal" style="padding:44px">
<div class="terminal-deco" style="margin-bottom:16px">
<span class="log-info">FILE: fragment_beta.pkg</span>
<span class="sys-status compile" style="margin-left:16px">COMPILING</span>
</div>
<h3 style="font-size:26px;font-weight:800;color:var(--text-primary);font-family:var(--font-mono);letter-spacing:2px;margin-bottom:20px">
<span data-scramble-loop data-length="14">██████████████</span>
</h3>
<div class="encrypted-block" style="margin-bottom:24px">
<div class="encrypted-line"><span data-scramble-loop data-length="40">████████████████████████████████████████</span></div>
<div class="encrypted-line"><span data-scramble-loop data-length="32">████████████████████████████████</span></div>
</div>
<div class="build-progress" style="margin:0">
<div class="build-progress-header">
<span class="bp-label">RECOVERY_PROGRESS</span>
<span class="bp-value">32%</span>
</div>
<div class="build-progress-track">
<div class="build-progress-fill" data-progress="32" style="background:linear-gradient(90deg,#7c5cd6,#a78bff);box-shadow:0 0 15px rgba(167,139,255,0.4)"></div>
</div>
<div class="build-progress-log">> assembling modules... &nbsp;|&nbsp; > training <span class="redacted">████</span>...</div>
</div>
</div>
<!-- FRAGMENT_γ -->
<div class="card reveal" style="padding:44px">
<div class="terminal-deco" style="margin-bottom:16px">
<span class="log-info">FILE: fragment_gamma.pkg</span>
<span class="sys-status queue" style="margin-left:16px">QUEUED</span>
</div>
<h3 style="font-size:26px;font-weight:800;color:var(--text-primary);font-family:var(--font-mono);letter-spacing:2px;margin-bottom:20px">
<span data-scramble-loop data-length="14">██████████████</span>
</h3>
<div class="encrypted-block" style="margin-bottom:24px">
<div class="encrypted-line"><span data-scramble-loop data-length="40">████████████████████████████████████████</span></div>
<div class="encrypted-line"><span data-scramble-loop data-length="32">████████████████████████████████</span></div>
</div>
<div class="build-progress" style="margin:0">
<div class="build-progress-header">
<span class="bp-label">QUEUE_POSITION</span>
<span class="bp-value">#3</span>
</div>
<div class="build-progress-track">
<div class="build-progress-fill" data-progress="8" style="background:linear-gradient(90deg,#3a9bc9,#7dd8ff);box-shadow:0 0 15px rgba(125,216,255,0.3)"></div>
</div>
<div class="build-progress-log">> crack_analysis ✓ &nbsp;|&nbsp; > solution sketching...</div>
</div>
</div>
</div>
<!-- 舱内清单 -->
<div class="reveal" style="margin-top:48px;background:rgba(2,3,10,0.6);border:1px solid var(--border-subtle);border-radius:12px;padding:28px 32px">
<div class="terminal-deco" style="margin-bottom:16px"><span class="log-ok">ground_control:~$</span> ls -la /recovery_bay/ --sort=priority</div>
<div class="file-list">
<div class="file-item"><span class="file-icon"></span><span class="file-name">fragment_alpha.pkg</span><span class="file-locked">[LOCKED]</span><span class="file-size">85% recovered</span></div>
<div class="file-item"><span class="file-icon"></span><span class="file-name">fragment_beta.pkg</span><span class="file-locked">[LOCKED]</span><span class="file-size">32% recovered</span></div>
<div class="file-item"><span class="file-icon"></span><span class="file-name">fragment_gamma.pkg</span><span class="file-locked">[LOCKED]</span><span class="file-size">queued</span></div>
<div class="file-item"><span class="file-icon"></span><span class="file-name">fragment_<span data-scramble-loop data-length="1"></span>.pkg</span><span class="file-locked">[?????]</span><span class="file-size">--</span></div>
</div>
</div>
</div>
</section>
<!-- ===== 修复流水线 ===== -->
<section class="section">
<div class="container">
<div class="chapter-marker reveal">
<span class="chapter-num">R.2</span>
<span class="chapter-line"></span>
<span class="chapter-tag">REPAIR_PIPELINE</span>
</div>
<div class="section-header reveal" style="margin-bottom:56px">
<h2 class="section-title" data-scramble>修复流水线</h2>
<p class="section-subtitle">碎片保密,但过程公开。每一步都不凑合</p>
</div>
<div class="grid-4">
<div class="feature-card reveal">
<div class="terminal-deco" style="margin-bottom:16px"><span class="log-info">STEP_01</span></div>
<h3 style="font-size:18px">捕获裂缝现场</h3>
<p>蹲在真实用户旁边看他们工作,记录每一次皱眉、叹气、和砸键盘的冲动</p>
</div>
<div class="feature-card reveal">
<div class="terminal-deco" style="margin-bottom:16px"><span class="log-info">STEP_02</span></div>
<h3 style="font-size:18px">定位裂缝根源</h3>
<p>不停留在"不好用",追问五层为什么。表面是交互,根源可能是架构错了</p>
</div>
<div class="feature-card reveal">
<div class="terminal-deco" style="margin-bottom:16px"><span class="log-info">STEP_03</span></div>
<h3 style="font-size:18px">最小化焊接</h3>
<p>能用一个功能解决的,绝不用三个。原型先行,一周内做出可交互的东西验证</p>
</div>
<div class="feature-card reveal">
<div class="terminal-deco" style="margin-bottom:16px"><span class="log-info">STEP_04</span></div>
<h3 style="font-size:18px">真实环境压测</h3>
<p>交给最挑剔的内测用户折腾。他们骂得越狠,月亮拼回去那天笑得越稳</p>
</div>
</div>
</div>
</section>
<!-- ===== CTA ===== -->
<section class="cta-section">
<div class="cta-content">
<h2 class="reveal">想在解密那天第一个知道?</h2>
<p class="reveal">留下通讯频道。碎片解密时,你会收到第一条深空传输</p>
<div class="reveal" style="display:flex;gap:16px;justify-content:center;flex-wrap:wrap">
<a href="contact.html" class="btn btn-primary btn-lg">接收解密信号</a>
<a href="about.html" class="btn btn-outline btn-lg">认识修复小组</a>
</div>
<div class="terminal-deco reveal" style="margin-top:40px;opacity:0.5">
<span class="log-ok">></span> observer_slots: LIMITED &nbsp;|&nbsp; <span class="log-info">></span> requirement: willing_to_complain
</div>
</div>
</section>
<!-- ===== 页脚 ===== -->
<footer class="footer">
<div class="container">
<div class="footer-grid">
<div class="footer-brand">
<div class="logo">
<div class="logo-icon"></div>
<div class="logo-text">
晟算科技
<small style="color:var(--text-muted)">SHENGSUAN TECH</small>
</div>
</div>
<p>月亮碎了,我们在修。修复内容保密,修复进度公开。</p>
</div>
<div class="footer-col">
<h4>导航</h4>
<ul>
<li><a href="index.html">首页</a></li>
<li><a href="about.html">关于我们</a></li>
<li><a href="products.html">产品矩阵</a></li>
<li><a href="contact.html">来聊聊</a></li>
</ul>
</div>
<div class="footer-col">
<h4>碎片清单</h4>
<ul>
<li><a href="products.html">FRAGMENT_α</a></li>
<li><a href="products.html">FRAGMENT_β</a></li>
<li><a href="products.html">FRAGMENT_γ</a></li>
<li><a href="products.html">???</a></li>
</ul>
</div>
<div class="footer-col">
<h4>信号源</h4>
<ul class="footer-contact">
<li><span class="contact-icon"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg></span><span>河南省 · 郑州市 · 金水区</span></li>
<li><span class="contact-icon"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/></svg></span><span>0371-8888-6666</span></li>
<li><span class="contact-icon"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg></span><span>hello@shengsuan.tech</span></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<span>&copy; 2026 郑州晟算科技有限公司</span>
<span>ground_control@shengsuan:~$ repairing_moon --progress 85%</span>
</div>
</div>
</footer>
<script src="js/lib/three.min.js"></script>
<script src="js/space.js"></script>
<script src="js/main.js"></script>
</body>
</html>