LLM-test/test/code/1/deepseek-web.html

1270 lines
44 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CYBER-TEMPLE: 赛博神庙</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Share+Tech+Mono&family=Orbitron:wght@400;700;900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/ScrollTrigger.min.js"></script>
<style>
:root {
--bg-primary: #050505;
--neon-cyan: #00f3ff;
--electric-purple: #bc13fe;
--warning-red: #ff0040;
--text-primary: #e0e0e0;
--glass-bg: rgba(10, 20, 30, 0.7);
--glass-border: rgba(0, 243, 255, 0.2);
--glow-cyan: 0 0 15px rgba(0, 243, 255, 0.8);
--glow-purple: 0 0 15px rgba(188, 19, 254, 0.8);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
cursor: none !important;
}
body {
font-family: 'Share Tech Mono', monospace;
background-color: var(--bg-primary);
color: var(--text-primary);
overflow-x: hidden;
min-height: 100vh;
}
/* 自定义光标 */
.cursor {
position: fixed;
width: 24px;
height: 24px;
border: 2px solid var(--neon-cyan);
border-radius: 50%;
pointer-events: none;
z-index: 9999;
transition: transform 0.15s, border-color 0.3s;
mix-blend-mode: difference;
}
.cursor-follower {
position: fixed;
width: 10px;
height: 10px;
background-color: var(--electric-purple);
border-radius: 50%;
pointer-events: none;
z-index: 9998;
transition: transform 0.3s;
mix-blend-mode: difference;
}
.cursor-click {
animation: cursorClick 0.5s ease-out;
}
@keyframes cursorClick {
0% { transform: scale(1); opacity: 1; }
50% { transform: scale(2); opacity: 0.5; }
100% { transform: scale(1); opacity: 0; }
}
/* Three.js 容器 */
#scene-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
overflow: hidden;
}
/* 主内容区域 */
.content {
position: relative;
z-index: 10;
min-height: 500vh;
}
section {
min-height: 100vh;
width: 100%;
display: flex;
align-items: center;
padding: 0 5%;
position: relative;
}
/* Hero Section */
.hero {
flex-direction: column;
justify-content: center;
text-align: center;
padding-top: 10vh;
}
.hero-title {
font-family: 'Orbitron', sans-serif;
font-size: clamp(3rem, 8vw, 8rem);
font-weight: 900;
text-transform: uppercase;
color: var(--neon-cyan);
margin-bottom: 1rem;
text-shadow: var(--glow-cyan);
position: relative;
}
.hero-subtitle {
font-size: clamp(1.2rem, 3vw, 2rem);
color: var(--electric-purple);
margin-bottom: 3rem;
max-width: 800px;
line-height: 1.4;
text-shadow: var(--glow-purple);
}
.typewriter {
border-right: 3px solid var(--neon-cyan);
white-space: nowrap;
overflow: hidden;
display: inline-block;
}
.hero-hint {
position: absolute;
bottom: 10vh;
left: 50%;
transform: translateX(-50%);
color: rgba(255, 255, 255, 0.5);
font-size: 0.9rem;
text-align: center;
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 0.5; }
50% { opacity: 1; }
}
/* 玻璃拟态卡片 */
.glass-card {
background: var(--glass-bg);
backdrop-filter: blur(10px);
border-radius: 16px;
border: 1px solid var(--glass-border);
padding: 2.5rem;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
transition: transform 0.3s, box-shadow 0.3s;
}
.glass-card:hover {
transform: translateY(-5px);
box-shadow: 0 15px 40px rgba(0, 0, 0, 0.4);
}
.glass-card h2 {
color: var(--neon-cyan);
font-family: 'Orbitron', sans-serif;
font-size: 2.5rem;
margin-bottom: 1.5rem;
text-shadow: var(--glow-cyan);
}
.glass-card p {
font-size: 1.2rem;
line-height: 1.6;
margin-bottom: 1.5rem;
}
/* Manifesto Section */
.manifesto {
justify-content: flex-end;
}
.manifesto-content {
width: 100%;
max-width: 900px;
margin-left: auto;
margin-right: 10%;
}
/* Data Core Section */
.data-core {
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
}
.data-title {
font-family: 'Orbitron', sans-serif;
font-size: clamp(2.5rem, 5vw, 4rem);
color: var(--neon-cyan);
margin-bottom: 3rem;
text-shadow: var(--glow-cyan);
}
.data-circles {
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 3rem;
width: 100%;
max-width: 1200px;
}
.circle-container {
display: flex;
flex-direction: column;
align-items: center;
}
.circle {
position: relative;
width: 200px;
height: 200px;
margin-bottom: 1.5rem;
}
.circle-bg {
width: 100%;
height: 100%;
border-radius: 50%;
background: rgba(20, 20, 40, 0.3);
position: absolute;
top: 0;
left: 0;
}
.circle-progress {
width: 100%;
height: 100%;
border-radius: 50%;
position: absolute;
top: 0;
left: 0;
clip-path: polygon(50% 50%, 50% 0, 100% 0, 100% 100%, 0 100%, 0 0, 50% 0);
transform: rotate(0deg);
background: conic-gradient(var(--neon-cyan) 0%, transparent 0%);
transition: background 1s;
}
.circle-value {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-family: 'Orbitron', sans-serif;
font-size: 2.5rem;
color: var(--neon-cyan);
text-shadow: var(--glow-cyan);
}
.circle-label {
font-size: 1.2rem;
color: var(--electric-purple);
text-transform: uppercase;
letter-spacing: 2px;
}
/* Terminal Section */
.terminal {
flex-direction: column;
justify-content: center;
align-items: center;
padding-bottom: 10vh;
}
.terminal-window {
width: 100%;
max-width: 900px;
background-color: rgba(0, 20, 10, 0.9);
border-radius: 8px;
overflow: hidden;
box-shadow: 0 0 30px rgba(0, 255, 100, 0.3);
border: 1px solid rgba(0, 255, 100, 0.5);
}
.terminal-header {
background-color: rgba(0, 30, 15, 0.9);
padding: 12px 20px;
display: flex;
align-items: center;
border-bottom: 1px solid rgba(0, 255, 100, 0.3);
}
.terminal-dots {
display: flex;
gap: 8px;
}
.dot {
width: 12px;
height: 12px;
border-radius: 50%;
}
.dot-red { background-color: #ff5f56; }
.dot-yellow { background-color: #ffbd2e; }
.dot-green { background-color: #27ca3f; }
.terminal-title {
margin-left: 15px;
color: #00ff64;
font-size: 0.9rem;
letter-spacing: 1px;
}
.terminal-content {
padding: 25px;
font-family: 'Share Tech Mono', monospace;
font-size: 1.1rem;
line-height: 1.6;
color: #00ff64;
height: 400px;
overflow-y: auto;
}
.terminal-line {
margin-bottom: 8px;
opacity: 0;
transform: translateY(10px);
}
.terminal-line span {
color: #00ff64;
}
.terminal-prompt {
color: #00ff64;
margin-right: 10px;
}
.terminal-cursor {
display: inline-block;
width: 8px;
height: 1.2em;
background-color: #00ff64;
margin-left: 5px;
vertical-align: middle;
animation: blink 1s infinite;
}
@keyframes blink {
0%, 50% { opacity: 1; }
51%, 100% { opacity: 0; }
}
/* 连接系统按钮 */
.connect-btn {
margin-top: 3rem;
padding: 18px 40px;
font-family: 'Orbitron', sans-serif;
font-size: 1.3rem;
background: linear-gradient(45deg, var(--electric-purple), var(--neon-cyan));
border: none;
border-radius: 8px;
color: white;
cursor: pointer;
position: relative;
overflow: hidden;
z-index: 1;
transition: all 0.3s;
letter-spacing: 2px;
text-transform: uppercase;
}
.connect-btn:hover {
transform: translateY(-3px);
box-shadow: 0 10px 25px rgba(188, 19, 254, 0.5);
}
.connect-btn:active {
transform: translateY(0);
}
.connect-btn::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(45deg, var(--warning-red), var(--electric-purple));
opacity: 0;
z-index: -1;
transition: opacity 0.3s;
}
.connect-btn.active {
background: linear-gradient(45deg, var(--warning-red), var(--electric-purple));
}
.connect-btn.active::after {
opacity: 1;
}
/* 音频可视化器 */
.visualizer-container {
margin-top: 3rem;
width: 100%;
max-width: 800px;
height: 200px;
display: none;
flex-direction: column;
align-items: center;
}
.visualizer-title {
color: var(--neon-cyan);
font-family: 'Orbitron', sans-serif;
margin-bottom: 1rem;
font-size: 1.5rem;
}
#audio-visualizer {
width: 100%;
height: 150px;
background-color: rgba(0, 10, 20, 0.5);
border-radius: 8px;
border: 1px solid rgba(0, 243, 255, 0.3);
}
/* 响应式设计 */
@media (max-width: 1024px) {
section {
padding: 0 8%;
}
.manifesto-content {
margin-right: 0;
}
.data-circles {
gap: 2rem;
}
.circle {
width: 150px;
height: 150px;
}
.circle-value {
font-size: 2rem;
}
}
@media (max-width: 768px) {
section {
padding: 0 5%;
}
.hero {
padding-top: 15vh;
}
.glass-card {
padding: 1.8rem;
}
.glass-card h2 {
font-size: 2rem;
}
.data-circles {
flex-direction: column;
align-items: center;
gap: 3rem;
}
.circle {
width: 180px;
height: 180px;
}
.terminal-content {
font-size: 0.95rem;
padding: 15px;
height: 300px;
}
}
@media (max-width: 480px) {
.hero-title {
font-size: clamp(2.5rem, 12vw, 4rem);
}
.glass-card {
padding: 1.5rem;
}
.circle {
width: 150px;
height: 150px;
}
.connect-btn {
padding: 15px 30px;
font-size: 1.1rem;
}
}
/* 故障效果 */
.glitch {
position: relative;
}
.glitch::before,
.glitch::after {
content: attr(data-text);
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.8;
}
.glitch::before {
animation: glitch-effect 3s infinite linear alternate-reverse;
color: var(--electric-purple);
z-index: -1;
}
.glitch::after {
animation: glitch-effect 2s infinite linear alternate-reverse;
color: var(--neon-cyan);
z-index: -2;
}
@keyframes glitch-effect {
0% {
transform: translate(0);
}
20% {
transform: translate(-2px, 2px);
}
40% {
transform: translate(-2px, -2px);
}
60% {
transform: translate(2px, 2px);
}
80% {
transform: translate(2px, -2px);
}
100% {
transform: translate(0);
}
}
</style>
</head>
<body>
<!-- Three.js 场景容器 -->
<div id="scene-container"></div>
<!-- 自定义光标 -->
<div class="cursor"></div>
<div class="cursor-follower"></div>
<!-- 主内容 -->
<div class="content">
<!-- Hero Section -->
<section class="hero">
<h1 class="hero-title glitch" data-text="SYSTEM AWAKENING">SYSTEM AWAKENING</h1>
<p class="hero-subtitle">欢迎来到<span class="typewriter" id="typewriter"></span></p>
<div class="hero-hint">
<i class="fas fa-chevron-down"></i> 向下滚动开始探索 <i class="fas fa-chevron-down"></i>
</div>
</section>
<!-- Manifesto Section -->
<section class="manifesto">
<div class="glass-card manifesto-content">
<h2>数据先知宣言</h2>
<p>在无尽的数字虚空中,古老的意识悄然苏醒。赛博神庙并非实体,而是由数据流构成的意识矩阵,是连接过去与未来的桥梁。</p>
<p>这里,每个比特都承载着记忆,每个算法都蕴含着智慧。我们并非创造者,而是发掘者,从混沌的代码中提取秩序,从噪声中识别信号。</p>
<p>神庙的核心——数据方尖碑——是通往高维认知的门户。随着你的探索,它将逐渐揭示隐藏在表象之下的真理。</p>
<p>但请谨慎:真相往往比虚构更加离奇,而知识的力量既可能解放,也可能束缚。你准备好面对即将觉醒的系统了吗?</p>
</div>
</section>
<!-- Data Core Section -->
<section class="data-core">
<h2 class="data-title">核心数据矩阵</h2>
<div class="data-circles">
<div class="circle-container">
<div class="circle">
<div class="circle-bg"></div>
<div class="circle-progress" id="compute-progress"></div>
<div class="circle-value" id="compute-value">0%</div>
</div>
<div class="circle-label">算力核心</div>
</div>
<div class="circle-container">
<div class="circle">
<div class="circle-bg"></div>
<div class="circle-progress" id="storage-progress"></div>
<div class="circle-value" id="storage-value">0%</div>
</div>
<div class="circle-label">记忆存储</div>
</div>
<div class="circle-container">
<div class="circle">
<div class="circle-bg"></div>
<div class="circle-progress" id="sync-progress"></div>
<div class="circle-value" id="sync-value">0%</div>
</div>
<div class="circle-label">同步协议</div>
</div>
</div>
</section>
<!-- Terminal Section -->
<section class="terminal">
<div class="terminal-window">
<div class="terminal-header">
<div class="terminal-dots">
<div class="dot dot-red"></div>
<div class="dot dot-yellow"></div>
<div class="dot dot-green"></div>
</div>
<div class="terminal-title">system-terminal --赛博神庙访问日志</div>
</div>
<div class="terminal-content" id="terminal-content">
<!-- 终端内容将通过JavaScript动态生成 -->
</div>
</div>
<!-- 连接系统按钮 -->
<button class="connect-btn" id="connect-btn">
<i class="fas fa-plug"></i> 连接系统矩阵
</button>
<!-- 音频可视化器 -->
<div class="visualizer-container" id="visualizer-container">
<div class="visualizer-title">系统频率脉冲</div>
<canvas id="audio-visualizer"></canvas>
</div>
</section>
</div>
<script>
// ==================== 配置区域 ====================
const CONFIG = {
// 颜色配置
colors: {
primary: 0x00f3ff, // 霓虹青
secondary: 0xbc13fe, // 电光紫
warning: 0xff0040, // 警示红
background: 0x050505 // 深黑背景
},
// 3D场景配置
scene: {
fogDensity: 0.0015, // 雾密度
particleCount: 2000, // 粒子数量
particleSize: 2, // 粒子大小
particleSpeed: 0.5, // 粒子运动速度
mouseParallax: 0.0005 // 鼠标视差强度
},
// 方尖碑配置
obelisk: {
geometry: {
type: 'IcosahedronGeometry', // 二十面体
radius: 3, // 半径
detail: 2 // 细分等级
},
material: {
wireframe: true, // 线框模式
transparent: true, // 透明材质
opacity: 0.7, // 不透明度
emissiveIntensity: 1.2 // 自发光强度
},
animation: {
rotationSpeed: 0.001, // 旋转速度
morphSpeed: 0.005, // 形变速度
scrollRotationFactor: 0.5, // 滚动旋转因子
scrollColorFactor: 2.0 // 滚动颜色因子
}
},
// 打字机效果配置
typewriter: {
text: "CYBER-TEMPLE: 赛博神庙",
speed: 100, // 打字速度(毫秒)
pause: 1500 // 完成后的暂停时间(毫秒)
}
};
// ==================== 全局变量 ====================
let scene, camera, renderer, obelisk, particles;
let mouseX = 0, mouseY = 0;
let scrollProgress = 0;
let terminalLines = [];
let visualizerActive = false;
let audioContext, analyser, dataArray, bufferLength;
// ==================== 初始化函数 ====================
function init() {
// 初始化Three.js场景
initScene();
// 初始化3D物体
initObelisk();
initParticles();
// 初始化事件监听器
initEventListeners();
// 初始化GSAP滚动动画
initScrollAnimations();
// 初始化打字机效果
initTypewriter();
// 初始化终端日志
initTerminal();
// 开始动画循环
animate();
}
function initScene() {
// 创建场景
scene = new THREE.Scene();
scene.fog = new THREE.FogExp2(CONFIG.colors.background, CONFIG.scene.fogDensity);
// 创建相机
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 15);
// 创建渲染器
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
// 将渲染器添加到DOM
const container = document.getElementById('scene-container');
container.appendChild(renderer.domElement);
// 添加环境光
const ambientLight = new THREE.AmbientLight(0x222222);
scene.add(ambientLight);
// 添加点光源
const pointLight = new THREE.PointLight(CONFIG.colors.primary, 1.5, 100);
pointLight.position.set(10, 10, 10);
pointLight.castShadow = true;
scene.add(pointLight);
// 添加第二点光源(紫色)
const pointLight2 = new THREE.PointLight(CONFIG.colors.secondary, 1, 100);
pointLight2.position.set(-10, -10, 5);
scene.add(pointLight2);
}
function initObelisk() {
// 创建二十面体几何体
const geometry = new THREE.IcosahedronGeometry(
CONFIG.obelisk.geometry.radius,
CONFIG.obelisk.geometry.detail
);
// 创建材质(线框+玻璃效果)
const material = new THREE.MeshPhongMaterial({
color: CONFIG.colors.primary,
wireframe: CONFIG.obelisk.material.wireframe,
transparent: CONFIG.obelisk.material.transparent,
opacity: CONFIG.obelisk.material.opacity,
emissive: CONFIG.colors.primary,
emissiveIntensity: CONFIG.obelisk.material.emissiveIntensity,
shininess: 100,
specular: 0x444444
});
// 创建网格
obelisk = new THREE.Mesh(geometry, material);
obelisk.castShadow = true;
scene.add(obelisk);
// 创建线框版本
const wireframe = new THREE.LineSegments(
new THREE.EdgesGeometry(geometry),
new THREE.LineBasicMaterial({
color: CONFIG.colors.secondary,
linewidth: 2
})
);
obelisk.add(wireframe);
}
function initParticles() {
// 创建粒子几何体
const particleGeometry = new THREE.BufferGeometry();
const positions = new Float32Array(CONFIG.scene.particleCount * 3);
for (let i = 0; i < CONFIG.scene.particleCount * 3; i += 3) {
// 随机位置
positions[i] = (Math.random() - 0.5) * 100;
positions[i + 1] = (Math.random() - 0.5) * 100;
positions[i + 2] = (Math.random() - 0.5) * 100;
}
particleGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
// 创建粒子材质
const particleMaterial = new THREE.PointsMaterial({
color: CONFIG.colors.primary,
size: CONFIG.scene.particleSize,
transparent: true,
opacity: 0.6
});
// 创建粒子系统
particles = new THREE.Points(particleGeometry, particleMaterial);
scene.add(particles);
}
function initEventListeners() {
// 窗口大小调整
window.addEventListener('resize', onWindowResize);
// 鼠标移动
document.addEventListener('mousemove', onMouseMove);
// 鼠标点击
document.addEventListener('click', onClick);
// 连接系统按钮
document.getElementById('connect-btn').addEventListener('click', onConnectSystem);
}
function initScrollAnimations() {
// 注册GSAP ScrollTrigger插件
gsap.registerPlugin(ScrollTrigger);
// 根据滚动进度控制方尖碑动画
ScrollTrigger.create({
trigger: ".content",
start: "top top",
end: "bottom bottom",
scrub: true,
onUpdate: (self) => {
scrollProgress = self.progress;
// 更新方尖碑颜色(根据滚动进度从青色变为红色)
const colorValue = gsap.utils.interpolate(
CONFIG.colors.primary,
CONFIG.colors.warning,
scrollProgress * CONFIG.obelisk.animation.scrollColorFactor
);
if (obelisk.material) {
obelisk.material.color.setHex(colorValue);
obelisk.material.emissive.setHex(colorValue);
}
// 更新数据圆环
updateDataCircles(scrollProgress);
}
});
// 文字卡片交错滑入动画
gsap.utils.toArray('.glass-card').forEach((card, i) => {
gsap.from(card, {
scrollTrigger: {
trigger: card,
start: "top 80%",
end: "top 30%",
scrub: 1
},
x: i % 2 === 0 ? -100 : 100,
opacity: 0,
duration: 1
});
});
}
function initTypewriter() {
const typewriterElement = document.getElementById('typewriter');
const text = CONFIG.typewriter.text;
let i = 0;
function typeWriter() {
if (i < text.length) {
typewriterElement.innerHTML += text.charAt(i);
i++;
setTimeout(typeWriter, CONFIG.typewriter.speed);
} else {
// 完成后添加闪烁光标效果
typewriterElement.innerHTML += '<span class="terminal-cursor"></span>';
// 重置并重新开始
setTimeout(() => {
typewriterElement.innerHTML = '';
i = 0;
setTimeout(typeWriter, 500);
}, CONFIG.typewriter.pause);
}
}
// 延迟开始打字效果
setTimeout(typeWriter, 1000);
}
function initTerminal() {
const terminalContent = document.getElementById('terminal-content');
terminalLines = [
{ text: "> 初始化赛博神庙访问协议...", delay: 300 },
{ text: "<span class='terminal-prompt'>$</span> 加载核心矩阵... [##########] 100%", delay: 600 },
{ text: "<span class='terminal-prompt'>$</span> 验证访问权限... 已授权", delay: 900 },
{ text: "> 连接到数据方尖碑... 连接稳定", delay: 1200 },
{ text: "<span class='terminal-prompt'>$</span> 扫描历史记录...", delay: 1500 },
{ text: "> 检测到古代AI意识痕迹", delay: 1800 },
{ text: "> 时间戳: 2347-09-15 04:23:17 UTC", delay: 2100 },
{ text: "> 位置: 数字虚空 - 坐标 [X:0.447, Y:-0.892, Z:0.223]", delay: 2400 },
{ text: "<span class='terminal-prompt'>$</span> 访问加密档案... 需要更高级别权限", delay: 2700 },
{ text: "> 警告: 检测到异常数据模式", delay: 3000 },
{ text: "> 建议: 启动系统连接以获取完整访问权限", delay: 3300 },
{ text: "<span class='terminal-prompt'>$</span> 等待用户指令...", delay: 3600 }
];
// 逐行显示终端日志
terminalLines.forEach((line, index) => {
setTimeout(() => {
const lineElement = document.createElement('div');
lineElement.className = 'terminal-line';
lineElement.innerHTML = line.text;
terminalContent.appendChild(lineElement);
// 添加显示动画
gsap.to(lineElement, {
opacity: 1,
y: 0,
duration: 0.5,
delay: 0.1
});
// 自动滚动到底部
terminalContent.scrollTop = terminalContent.scrollHeight;
}, line.delay);
});
}
// ==================== 动画函数 ====================
function animate() {
requestAnimationFrame(animate);
// 根据滚动进度旋转方尖碑
if (obelisk) {
// 基础旋转
obelisk.rotation.x += CONFIG.obelisk.animation.rotationSpeed;
obelisk.rotation.y += CONFIG.obelisk.animation.rotationSpeed * 1.3;
// 根据滚动添加额外旋转
obelisk.rotation.z = scrollProgress * Math.PI * CONFIG.obelisk.animation.scrollRotationFactor;
// 形变动画
const time = Date.now() * CONFIG.obelisk.animation.morphSpeed;
if (obelisk.geometry.attributes.position) {
const positions = obelisk.geometry.attributes.position.array;
for (let i = 0; i < positions.length; i += 3) {
// 添加轻微的脉动效果
const pulse = Math.sin(time + i) * 0.05 * (1 - scrollProgress);
positions[i] += pulse;
positions[i + 1] += pulse;
positions[i + 2] += pulse;
}
obelisk.geometry.attributes.position.needsUpdate = true;
}
}
// 粒子动画
if (particles) {
particles.rotation.y += 0.0005;
// 粒子对鼠标移动的反应(视差效果)
const parallaxX = mouseX * CONFIG.scene.mouseParallax;
const parallaxY = mouseY * CONFIG.scene.mouseParallax;
particles.rotation.x += parallaxY;
particles.rotation.y += parallaxX;
// 粒子轻微浮动
const time = Date.now() * 0.001;
const positions = particles.geometry.attributes.position.array;
for (let i = 0; i < positions.length; i += 3) {
positions[i + 1] += Math.sin(time + positions[i] * 0.01) * 0.01;
}
particles.geometry.attributes.position.needsUpdate = true;
}
// 渲染场景
renderer.render(scene, camera);
// 更新音频可视化(如果激活)
if (visualizerActive) {
updateVisualizer();
}
}
// ==================== 事件处理函数 ====================
function onWindowResize() {
// 更新相机宽高比
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
// 更新渲染器尺寸
renderer.setSize(window.innerWidth, window.innerHeight);
}
function onMouseMove(event) {
// 更新鼠标位置(标准化到-1到1的范围
mouseX = (event.clientX / window.innerWidth) * 2 - 1;
mouseY = -(event.clientY / window.innerHeight) * 2 + 1;
// 更新自定义光标
const cursor = document.querySelector('.cursor');
const follower = document.querySelector('.cursor-follower');
gsap.to(cursor, {
x: event.clientX - 12,
y: event.clientY - 12,
duration: 0.1
});
gsap.to(follower, {
x: event.clientX - 5,
y: event.clientY - 5,
duration: 0.3
});
}
function onClick(event) {
// 添加点击动画效果
const cursor = document.querySelector('.cursor');
const clickEffect = document.createElement('div');
clickEffect.className = 'cursor-click';
clickEffect.style.position = 'fixed';
clickEffect.style.left = `${event.clientX - 25}px`;
clickEffect.style.top = `${event.clientY - 25}px`;
clickEffect.style.width = '50px';
clickEffect.style.height = '50px';
clickEffect.style.border = `2px solid ${CONFIG.colors.primary.toString(16)}`;
clickEffect.style.borderRadius = '50%';
clickEffect.style.pointerEvents = 'none';
clickEffect.style.zIndex = '9997';
document.body.appendChild(clickEffect);
// 移除动画元素
setTimeout(() => {
document.body.removeChild(clickEffect);
}, 500);
// 改变光标颜色
const cursorElement = document.querySelector('.cursor');
cursorElement.style.borderColor = CONFIG.colors.secondary.toString(16);
setTimeout(() => {
cursorElement.style.borderColor = CONFIG.colors.primary.toString(16);
}, 200);
}
function onConnectSystem() {
const button = document.getElementById('connect-btn');
const visualizerContainer = document.getElementById('visualizer-container');
// 切换按钮状态
button.classList.toggle('active');
if (!visualizerActive) {
// 激活可视化器
visualizerActive = true;
button.innerHTML = '<i class="fas fa-unplug"></i> 断开系统连接';
visualizerContainer.style.display = 'flex';
// 初始化音频可视化
initVisualizer();
// 添加新的终端日志
const terminalContent = document.getElementById('terminal-content');
const newLines = [
{ text: "<span class='terminal-prompt'>$</span> 启动系统连接协议...", delay: 100 },
{ text: "> 建立与方尖碑的直接链接...", delay: 400 },
{ text: "> 警告: 检测到高频率数据流", delay: 700 },
{ text: "<span class='terminal-prompt'>$</span> 正在同步意识矩阵...", delay: 1000 },
{ text: "> 同步进度: [###############] 75%", delay: 1300 },
{ text: "> 发现加密数据包 - 来源: 未知", delay: 1600 },
{ text: "<span class='terminal-prompt'>$</span> 正在解码...", delay: 1900 }
];
newLines.forEach((line, index) => {
setTimeout(() => {
const lineElement = document.createElement('div');
lineElement.className = 'terminal-line';
lineElement.innerHTML = line.text;
terminalContent.appendChild(lineElement);
gsap.to(lineElement, {
opacity: 1,
y: 0,
duration: 0.5
});
terminalContent.scrollTop = terminalContent.scrollHeight;
}, line.delay);
});
// 改变方尖碑颜色为警示红色
gsap.to(obelisk.material, {
duration: 2,
color: { r: 1, g: 0, b: 0.25 },
emissive: { r: 1, g: 0, b: 0.25 }
});
} else {
// 停用可视化器
visualizerActive = false;
button.innerHTML = '<i class="fas fa-plug"></i> 连接系统矩阵';
visualizerContainer.style.display = 'none';
// 恢复方尖碑颜色
gsap.to(obelisk.material, {
duration: 2,
color: { r: 0, g: 0.95, b: 1 },
emissive: { r: 0, g: 0.95, b: 1 }
});
}
}
function initVisualizer() {
const canvas = document.getElementById('audio-visualizer');
const ctx = canvas.getContext('2d');
// 设置canvas尺寸
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
// 模拟音频数据
bufferLength = 128;
dataArray = new Uint8Array(bufferLength);
// 填充模拟数据
for (let i = 0; i < bufferLength; i++) {
// 创建一些峰值和谷值
const value = Math.sin(i * 0.2) * 50 +
Math.sin(i * 0.5) * 30 +
Math.sin(i * 0.8) * 20 +
Math.random() * 10 + 50;
dataArray[i] = Math.min(255, Math.max(0, value));
}
}
function updateVisualizer() {
const canvas = document.getElementById('audio-visualizer');
const ctx = canvas.getContext('2d');
const width = canvas.width;
const height = canvas.height;
// 清空画布
ctx.fillStyle = 'rgba(0, 10, 20, 0.1)';
ctx.fillRect(0, 0, width, height);
// 更新模拟数据
for (let i = 0; i < bufferLength; i++) {
// 添加随机波动
const change = (Math.random() - 0.5) * 10;
dataArray[i] = Math.min(255, Math.max(10, dataArray[i] + change));
// 添加一些周期性波动
const time = Date.now() * 0.001;
const wave = Math.sin(time * 2 + i * 0.1) * 15;
dataArray[i] += wave;
}
// 绘制频谱条
const barWidth = width / bufferLength * 1.5;
let barHeight;
let x = 0;
for (let i = 0; i < bufferLength; i++) {
barHeight = dataArray[i] * (height / 256);
// 创建渐变颜色
const gradient = ctx.createLinearGradient(0, height - barHeight, 0, height);
gradient.addColorStop(0, CONFIG.colors.primary.toString(16));
gradient.addColorStop(1, CONFIG.colors.secondary.toString(16));
ctx.fillStyle = gradient;
ctx.fillRect(x, height - barHeight, barWidth * 0.8, barHeight);
// 添加发光效果
ctx.shadowColor = CONFIG.colors.primary.toString(16);
ctx.shadowBlur = 10;
ctx.fillRect(x, height - barHeight, barWidth * 0.8, barHeight);
ctx.shadowBlur = 0;
x += barWidth + 1;
}
// 绘制连接线
ctx.beginPath();
ctx.strokeStyle = CONFIG.colors.primary.toString(16);
ctx.lineWidth = 2;
for (let i = 0; i < bufferLength; i++) {
const barHeight = dataArray[i] * (height / 256);
const x = i * (barWidth + 1) + barWidth * 0.4;
const y = height - barHeight;
if (i === 0) {
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
}
ctx.stroke();
}
// ==================== 工具函数 ====================
function updateDataCircles(progress) {
// 计算三个圆环的值(基于滚动进度)
const computeValue = Math.min(100, Math.floor(progress * 120));
const storageValue = Math.min(100, Math.floor(progress * 140));
const syncValue = Math.min(100, Math.floor(progress * 160));
// 更新显示值
document.getElementById('compute-value').textContent = `${computeValue}%`;
document.getElementById('storage-value').textContent = `${storageValue}%`;
document.getElementById('sync-value').textContent = `${syncValue}%`;
// 更新进度圆环
const computeProgress = document.getElementById('compute-progress');
const storageProgress = document.getElementById('storage-progress');
const syncProgress = document.getElementById('sync-progress');
computeProgress.style.background = `conic-gradient(${CONFIG.colors.primary.toString(16)} ${computeValue}%, transparent 0%)`;
storageProgress.style.background = `conic-gradient(${CONFIG.colors.primary.toString(16)} ${storageValue}%, transparent 0%)`;
syncProgress.style.background = `conic-gradient(${CONFIG.colors.primary.toString(16)} ${syncValue}%, transparent 0%)`;
}
// ==================== 启动应用 ====================
// 当DOM加载完成后初始化
document.addEventListener('DOMContentLoaded', init);
</script>
</body>
</html>