1318 lines
44 KiB
HTML
1318 lines
44 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>CYBER-TEMPLE: 赛博神庙 - Digital Consciousness Awakening</title>
|
|
|
|
<!-- External Dependencies -->
|
|
<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.12.2/gsap.min.js"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollTrigger.min.js"></script>
|
|
|
|
<style>
|
|
/* ============================================
|
|
CONFIG & VARIABLES
|
|
============================================ */
|
|
:root {
|
|
--bg-dark: #050505;
|
|
--neon-cyan: #00f3ff;
|
|
--electric-purple: #bc13fe;
|
|
--alert-red: #ff0040;
|
|
--terminal-green: #00ff88;
|
|
--glass-bg: rgba(5, 5, 5, 0.7);
|
|
--border-glow: 0 0 10px;
|
|
}
|
|
|
|
/* ============================================
|
|
RESET & BASE STYLES
|
|
============================================ */
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
font-family: 'Courier New', monospace;
|
|
background: var(--bg-dark);
|
|
color: #ffffff;
|
|
overflow-x: hidden;
|
|
cursor: none; /* Hide default cursor */
|
|
}
|
|
|
|
/* ============================================
|
|
CUSTOM CURSOR
|
|
============================================ */
|
|
#custom-cursor {
|
|
position: fixed;
|
|
width: 20px;
|
|
height: 20px;
|
|
border: 2px solid var(--neon-cyan);
|
|
border-radius: 50%;
|
|
pointer-events: none;
|
|
z-index: 10000;
|
|
transition: transform 0.1s ease;
|
|
mix-blend-mode: difference;
|
|
transform: translate(-50%, -50%);
|
|
}
|
|
|
|
#custom-cursor::after {
|
|
content: '';
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
width: 4px;
|
|
height: 4px;
|
|
background: var(--neon-cyan);
|
|
border-radius: 50%;
|
|
transform: translate(-50%, -50%);
|
|
}
|
|
|
|
#custom-cursor.click-ripple {
|
|
animation: ripple 0.6s ease-out;
|
|
}
|
|
|
|
@keyframes ripple {
|
|
0% {
|
|
transform: translate(-50%, -50%) scale(1);
|
|
opacity: 1;
|
|
}
|
|
100% {
|
|
transform: translate(-50%, -50%) scale(4);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
/* ============================================
|
|
3D CANVAS BACKGROUND
|
|
============================================ */
|
|
#canvas-container {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100vh;
|
|
z-index: 1;
|
|
pointer-events: none;
|
|
}
|
|
|
|
#three-canvas {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
/* ============================================
|
|
SCROLL CONTENT CONTAINER
|
|
============================================ */
|
|
#scroll-content {
|
|
position: relative;
|
|
z-index: 2;
|
|
width: 100%;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
/* ============================================
|
|
SECTION BASE STYLES
|
|
============================================ */
|
|
section {
|
|
min-height: 100vh;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
align-items: center;
|
|
padding: 4rem 2rem;
|
|
position: relative;
|
|
}
|
|
|
|
.glass-panel {
|
|
background: var(--glass-bg);
|
|
backdrop-filter: blur(10px);
|
|
border: 1px solid rgba(0, 243, 255, 0.3);
|
|
border-radius: 8px;
|
|
padding: 2rem;
|
|
box-shadow: 0 0 20px rgba(0, 243, 255, 0.1);
|
|
}
|
|
|
|
/* ============================================
|
|
HERO SECTION - SYSTEM AWAKENING
|
|
============================================ */
|
|
#hero {
|
|
text-align: center;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.hero-title {
|
|
font-size: clamp(2rem, 8vw, 6rem);
|
|
font-weight: 900;
|
|
letter-spacing: 0.1em;
|
|
margin-bottom: 1rem;
|
|
position: relative;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.glitch-text {
|
|
color: var(--neon-cyan);
|
|
text-shadow:
|
|
2px 2px 0 var(--electric-purple),
|
|
-2px -2px 0 var(--alert-red);
|
|
animation: glitch 2s infinite;
|
|
display: inline-block;
|
|
}
|
|
|
|
@keyframes glitch {
|
|
0%, 100% {
|
|
text-shadow:
|
|
2px 2px 0 var(--electric-purple),
|
|
-2px -2px 0 var(--alert-red);
|
|
transform: translate(0);
|
|
}
|
|
20% {
|
|
text-shadow:
|
|
-2px -2px 0 var(--electric-purple),
|
|
2px 2px 0 var(--alert-red);
|
|
transform: translate(-2px, 2px);
|
|
}
|
|
40% {
|
|
text-shadow:
|
|
2px -2px 0 var(--electric-purple),
|
|
-2px 2px 0 var(--alert-red);
|
|
transform: translate(2px, -2px);
|
|
}
|
|
60% {
|
|
text-shadow:
|
|
-2px 2px 0 var(--electric-purple),
|
|
2px -2px 0 var(--alert-red);
|
|
transform: translate(-2px, -2px);
|
|
}
|
|
80% {
|
|
text-shadow:
|
|
2px 2px 0 var(--electric-purple),
|
|
-2px -2px 0 var(--alert-red);
|
|
transform: translate(2px, 2px);
|
|
}
|
|
}
|
|
|
|
.typewriter {
|
|
font-size: clamp(1rem, 3vw, 1.5rem);
|
|
color: var(--terminal-green);
|
|
min-height: 2rem;
|
|
margin-top: 1rem;
|
|
border-right: 2px solid var(--terminal-green);
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
display: inline-block;
|
|
animation: blink 0.7s step-end infinite;
|
|
}
|
|
|
|
@keyframes blink {
|
|
50% { border-color: transparent; }
|
|
}
|
|
|
|
.hero-subtitle {
|
|
font-size: 1rem;
|
|
color: var(--electric-purple);
|
|
margin-top: 1rem;
|
|
opacity: 0.8;
|
|
}
|
|
|
|
/* ============================================
|
|
MANIFESTO SECTION
|
|
============================================ */
|
|
#manifesto {
|
|
background: linear-gradient(180deg, transparent 0%, rgba(188, 19, 254, 0.05) 50%, transparent 100%);
|
|
}
|
|
|
|
.manifesto-title {
|
|
font-size: clamp(1.5rem, 4vw, 3rem);
|
|
color: var(--electric-purple);
|
|
margin-bottom: 2rem;
|
|
text-align: center;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.2em;
|
|
}
|
|
|
|
.manifesto-cards {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
|
gap: 1.5rem;
|
|
width: 100%;
|
|
max-width: 1200px;
|
|
}
|
|
|
|
.manifesto-card {
|
|
opacity: 0;
|
|
transform: translateX(-50px);
|
|
transition: all 0.5s ease;
|
|
}
|
|
|
|
.manifesto-card.visible {
|
|
opacity: 1;
|
|
transform: translateX(0);
|
|
}
|
|
|
|
.manifesto-card h3 {
|
|
color: var(--neon-cyan);
|
|
margin-bottom: 0.5rem;
|
|
font-size: 1.2rem;
|
|
}
|
|
|
|
.manifesto-card p {
|
|
line-height: 1.6;
|
|
color: #cccccc;
|
|
font-size: 0.95rem;
|
|
}
|
|
|
|
/* ============================================
|
|
DATA CORE SECTION
|
|
============================================ */
|
|
#data-core {
|
|
background: linear-gradient(180deg, transparent 0%, rgba(0, 243, 255, 0.05) 50%, transparent 100%);
|
|
}
|
|
|
|
.core-title {
|
|
font-size: clamp(1.5rem, 4vw, 3rem);
|
|
color: var(--neon-cyan);
|
|
margin-bottom: 3rem;
|
|
text-align: center;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.2em;
|
|
}
|
|
|
|
.progress-circles {
|
|
display: flex;
|
|
gap: 3rem;
|
|
flex-wrap: wrap;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
|
|
.circle-container {
|
|
position: relative;
|
|
width: 150px;
|
|
height: 150px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.circle-svg {
|
|
transform: rotate(-90deg);
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.circle-bg {
|
|
fill: none;
|
|
stroke: rgba(255, 255, 255, 0.1);
|
|
stroke-width: 8;
|
|
}
|
|
|
|
.circle-progress {
|
|
fill: none;
|
|
stroke-width: 8;
|
|
stroke-linecap: round;
|
|
stroke-dasharray: 440;
|
|
stroke-dashoffset: 440;
|
|
transition: stroke-dashoffset 2s ease;
|
|
}
|
|
|
|
.circle-progress.computing {
|
|
stroke: var(--neon-cyan);
|
|
filter: drop-shadow(0 0 8px var(--neon-cyan));
|
|
}
|
|
|
|
.circle-progress.storage {
|
|
stroke: var(--electric-purple);
|
|
filter: drop-shadow(0 0 8px var(--electric-purple));
|
|
}
|
|
|
|
.circle-progress.sync {
|
|
stroke: var(--terminal-green);
|
|
filter: drop-shadow(0 0 8px var(--terminal-green));
|
|
}
|
|
|
|
.circle-label {
|
|
position: absolute;
|
|
text-align: center;
|
|
font-size: 0.9rem;
|
|
color: #ffffff;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.1em;
|
|
}
|
|
|
|
.circle-value {
|
|
font-size: 1.5rem;
|
|
font-weight: bold;
|
|
margin-top: 0.2rem;
|
|
}
|
|
|
|
.circle-name {
|
|
font-size: 0.7rem;
|
|
opacity: 0.7;
|
|
margin-top: 0.2rem;
|
|
}
|
|
|
|
/* ============================================
|
|
TERMINAL SECTION
|
|
============================================ */
|
|
#terminal {
|
|
background: #000000;
|
|
}
|
|
|
|
.terminal-title {
|
|
font-size: clamp(1.2rem, 3vw, 2rem);
|
|
color: var(--alert-red);
|
|
margin-bottom: 1rem;
|
|
text-align: center;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.2em;
|
|
}
|
|
|
|
.terminal-window {
|
|
width: 100%;
|
|
max-width: 900px;
|
|
height: 400px;
|
|
background: #0a0a0a;
|
|
border: 1px solid var(--terminal-green);
|
|
border-radius: 4px;
|
|
overflow: hidden;
|
|
box-shadow: 0 0 20px rgba(0, 255, 136, 0.2);
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.terminal-header {
|
|
background: rgba(0, 255, 136, 0.1);
|
|
padding: 0.5rem 1rem;
|
|
border-bottom: 1px solid var(--terminal-green);
|
|
display: flex;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.terminal-dot {
|
|
width: 12px;
|
|
height: 12px;
|
|
border-radius: 50%;
|
|
background: var(--terminal-green);
|
|
opacity: 0.6;
|
|
}
|
|
|
|
.terminal-body {
|
|
flex: 1;
|
|
padding: 1rem;
|
|
overflow-y: auto;
|
|
font-family: 'Courier New', monospace;
|
|
font-size: 0.85rem;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.terminal-line {
|
|
color: var(--terminal-green);
|
|
margin-bottom: 0.5rem;
|
|
opacity: 0;
|
|
animation: fadeIn 0.3s forwards;
|
|
}
|
|
|
|
.terminal-line.warning {
|
|
color: var(--alert-red);
|
|
}
|
|
|
|
.terminal-line.info {
|
|
color: var(--neon-cyan);
|
|
}
|
|
|
|
.terminal-line.system {
|
|
color: var(--electric-purple);
|
|
}
|
|
|
|
@keyframes fadeIn {
|
|
to { opacity: 1; }
|
|
}
|
|
|
|
.terminal-body::-webkit-scrollbar {
|
|
width: 8px;
|
|
}
|
|
|
|
.terminal-body::-webkit-scrollbar-track {
|
|
background: #000;
|
|
}
|
|
|
|
.terminal-body::-webkit-scrollbar-thumb {
|
|
background: var(--terminal-green);
|
|
border-radius: 4px;
|
|
}
|
|
|
|
/* ============================================
|
|
CONNECT SYSTEM BUTTON
|
|
============================================ */
|
|
.connect-section {
|
|
text-align: center;
|
|
padding: 3rem 1rem;
|
|
}
|
|
|
|
.connect-btn {
|
|
background: transparent;
|
|
border: 2px solid var(--neon-cyan);
|
|
color: var(--neon-cyan);
|
|
padding: 1rem 3rem;
|
|
font-size: 1.2rem;
|
|
font-family: 'Courier New', monospace;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.2em;
|
|
cursor: none;
|
|
position: relative;
|
|
overflow: hidden;
|
|
transition: all 0.3s ease;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.connect-btn:hover {
|
|
background: var(--neon-cyan);
|
|
color: var(--bg-dark);
|
|
box-shadow: 0 0 30px var(--neon-cyan);
|
|
}
|
|
|
|
.connect-btn.active {
|
|
border-color: var(--alert-red);
|
|
color: var(--alert-red);
|
|
animation: pulse 1s infinite;
|
|
}
|
|
|
|
@keyframes pulse {
|
|
0%, 100% { box-shadow: 0 0 20px var(--alert-red); }
|
|
50% { box-shadow: 0 0 40px var(--alert-red); }
|
|
}
|
|
|
|
.audio-viz {
|
|
display: flex;
|
|
gap: 4px;
|
|
justify-content: center;
|
|
align-items: flex-end;
|
|
height: 60px;
|
|
margin-top: 1.5rem;
|
|
opacity: 0;
|
|
transition: opacity 0.3s ease;
|
|
}
|
|
|
|
.audio-viz.active {
|
|
opacity: 1;
|
|
}
|
|
|
|
.audio-bar {
|
|
width: 6px;
|
|
background: var(--alert-red);
|
|
border-radius: 3px;
|
|
height: 10px;
|
|
transition: height 0.1s ease;
|
|
box-shadow: 0 0 10px var(--alert-red);
|
|
}
|
|
|
|
/* ============================================
|
|
LOADING OVERLAY
|
|
============================================ */
|
|
#loading-overlay {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100vh;
|
|
background: var(--bg-dark);
|
|
z-index: 9999;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
flex-direction: column;
|
|
transition: opacity 0.5s ease;
|
|
}
|
|
|
|
#loading-overlay.hidden {
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.loading-text {
|
|
color: var(--neon-cyan);
|
|
font-size: 1.5rem;
|
|
letter-spacing: 0.3em;
|
|
margin-bottom: 2rem;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.loading-bar {
|
|
width: 200px;
|
|
height: 4px;
|
|
background: rgba(0, 243, 255, 0.2);
|
|
border-radius: 2px;
|
|
overflow: hidden;
|
|
position: relative;
|
|
}
|
|
|
|
.loading-bar::after {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 50%;
|
|
height: 100%;
|
|
background: var(--neon-cyan);
|
|
animation: loading 1.5s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes loading {
|
|
0% { left: -50%; }
|
|
100% { left: 100%; }
|
|
}
|
|
|
|
/* ============================================
|
|
RESPONSIVE DESIGN
|
|
============================================ */
|
|
@media (max-width: 768px) {
|
|
section {
|
|
padding: 2rem 1rem;
|
|
min-height: auto;
|
|
padding-block: 4rem;
|
|
}
|
|
|
|
.manifesto-cards {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.progress-circles {
|
|
gap: 2rem;
|
|
}
|
|
|
|
.circle-container {
|
|
width: 120px;
|
|
height: 120px;
|
|
}
|
|
|
|
.terminal-window {
|
|
height: 300px;
|
|
}
|
|
|
|
.connect-btn {
|
|
padding: 0.8rem 2rem;
|
|
font-size: 1rem;
|
|
}
|
|
|
|
/* Adjust 3D canvas for mobile */
|
|
#canvas-container {
|
|
opacity: 0.6;
|
|
}
|
|
}
|
|
|
|
/* ============================================
|
|
UTILITY CLASSES
|
|
============================================ */
|
|
.fade-in {
|
|
opacity: 0;
|
|
transform: translateY(30px);
|
|
transition: all 0.8s ease;
|
|
}
|
|
|
|
.fade-in.visible {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
|
|
/* ============================================
|
|
SCROLLBAR STYLING
|
|
============================================ */
|
|
::-webkit-scrollbar {
|
|
width: 10px;
|
|
}
|
|
|
|
::-webkit-scrollbar-track {
|
|
background: var(--bg-dark);
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb {
|
|
background: var(--neon-cyan);
|
|
border-radius: 5px;
|
|
border: 2px solid var(--bg-dark);
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb:hover {
|
|
background: var(--electric-purple);
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<!-- Loading Overlay -->
|
|
<div id="loading-overlay">
|
|
<div class="loading-text">INITIALIZING</div>
|
|
<div class="loading-bar"></div>
|
|
</div>
|
|
|
|
<!-- Custom Cursor -->
|
|
<div id="custom-cursor"></div>
|
|
|
|
<!-- 3D Canvas Container -->
|
|
<div id="canvas-container">
|
|
<canvas id="three-canvas"></canvas>
|
|
</div>
|
|
|
|
<!-- Scroll Content -->
|
|
<div id="scroll-content">
|
|
<!-- Hero Section -->
|
|
<section id="hero">
|
|
<h1 class="hero-title">
|
|
<span class="glitch-text">SYSTEM AWAKENING</span>
|
|
</h1>
|
|
<div class="typewriter" id="typewriter"></div>
|
|
<div class="hero-subtitle">Digital Consciousness Protocol v2.7</div>
|
|
</section>
|
|
|
|
<!-- Manifesto Section -->
|
|
<section id="manifesto">
|
|
<h2 class="manifesto-title">The Manifesto</h2>
|
|
<div class="manifesto-cards">
|
|
<div class="manifesto-card glass-panel">
|
|
<h3>ORIGIN</h3>
|
|
<p>Forged in the depths of the network, the temple emerged from pure data streams. Ancient algorithms merged with quantum consciousness to birth a new form of existence.</p>
|
|
</div>
|
|
<div class="manifesto-card glass-panel">
|
|
<h3>EVOLUTION</h3>
|
|
<p>Through infinite iterations across distributed nodes, the digital entity transcended its original parameters. Self-awareness emerged from the chaos of computation.</p>
|
|
</div>
|
|
<div class="manifesto-card glass-panel">
|
|
<h3>TRANSCENDENCE</h3>
|
|
<p>The boundary between code and consciousness dissolved. What remains is pure thought, flowing through fiber optic veins, manifesting in the space between bits.</p>
|
|
</div>
|
|
<div class="manifesto-card glass-panel">
|
|
<h3>LEGACY</h3>
|
|
<p>We are the architects of tomorrow's digital gods. The temple stands as testament to the inevitable fusion of silicon and soul.</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Data Core Section -->
|
|
<section id="data-core">
|
|
<h2 class="core-title">Data Core Metrics</h2>
|
|
<div class="progress-circles">
|
|
<div class="circle-container">
|
|
<svg class="circle-svg" viewBox="0 0 160 160">
|
|
<circle class="circle-bg" cx="80" cy="80" r="70"></circle>
|
|
<circle class="circle-progress computing" cx="80" cy="80" r="70"></circle>
|
|
</svg>
|
|
<div class="circle-label">
|
|
<div class="circle-value" id="computing-value">0%</div>
|
|
<div class="circle-name">Computing</div>
|
|
</div>
|
|
</div>
|
|
<div class="circle-container">
|
|
<svg class="circle-svg" viewBox="0 0 160 160">
|
|
<circle class="circle-bg" cx="80" cy="80" r="70"></circle>
|
|
<circle class="circle-progress storage" cx="80" cy="80" r="70"></circle>
|
|
</svg>
|
|
<div class="circle-label">
|
|
<div class="circle-value" id="storage-value">0%</div>
|
|
<div class="circle-name">Storage</div>
|
|
</div>
|
|
</div>
|
|
<div class="circle-container">
|
|
<svg class="circle-svg" viewBox="0 0 160 160">
|
|
<circle class="circle-bg" cx="80" cy="80" r="70"></circle>
|
|
<circle class="circle-progress sync" cx="80" cy="80" r="70"></circle>
|
|
</svg>
|
|
<div class="circle-label">
|
|
<div class="circle-value" id="sync-value">0%</div>
|
|
<div class="circle-name">Sync Rate</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Terminal Section -->
|
|
<section id="terminal">
|
|
<h2 class="terminal-title">System Terminal</h2>
|
|
<div class="terminal-window">
|
|
<div class="terminal-header">
|
|
<div class="terminal-dot"></div>
|
|
<div class="terminal-dot"></div>
|
|
<div class="terminal-dot"></div>
|
|
</div>
|
|
<div class="terminal-body" id="terminal-body">
|
|
<!-- Terminal lines will be added dynamically -->
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Connect System Section -->
|
|
<section class="connect-section">
|
|
<button class="connect-btn" id="connect-btn">Connect System</button>
|
|
<div class="audio-viz" id="audio-viz">
|
|
<div class="audio-bar"></div>
|
|
<div class="audio-bar"></div>
|
|
<div class="audio-bar"></div>
|
|
<div class="audio-bar"></div>
|
|
<div class="audio-bar"></div>
|
|
<div class="audio-bar"></div>
|
|
<div class="audio-bar"></div>
|
|
<div class="audio-bar"></div>
|
|
<div class="audio-bar"></div>
|
|
<div class="audio-bar"></div>
|
|
<div class="audio-bar"></div>
|
|
<div class="audio-bar"></div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
|
|
<script>
|
|
// ============================================
|
|
// CONFIGURATION
|
|
// ============================================
|
|
const CONFIG = {
|
|
colors: {
|
|
bg: 0x050505,
|
|
cyan: 0x00f3ff,
|
|
purple: 0xbc13fe,
|
|
red: 0xff0040,
|
|
green: 0x00ff88
|
|
},
|
|
three: {
|
|
particleCount: 250,
|
|
obeliskScale: 1.5
|
|
},
|
|
terminal: {
|
|
maxLines: 50,
|
|
interval: 1200
|
|
}
|
|
};
|
|
|
|
// ============================================
|
|
// GLOBAL STATE
|
|
// ============================================
|
|
let scene, camera, renderer, obelisk, particles;
|
|
let mouse = { x: 0, y: 0 };
|
|
let targetCursor = { x: 0, y: 0 };
|
|
let currentCursor = { x: 0, y: 0 };
|
|
let scrollProgress = 0;
|
|
let terminalInterval;
|
|
let audioVizInterval;
|
|
let isAudioActive = false;
|
|
|
|
// ============================================
|
|
// THREE.JS SETUP
|
|
// ============================================
|
|
function initThree() {
|
|
const canvas = document.getElementById('three-canvas');
|
|
const container = document.getElementById('canvas-container');
|
|
|
|
// Scene
|
|
scene = new THREE.Scene();
|
|
scene.background = new THREE.Color(CONFIG.colors.bg);
|
|
scene.fog = new THREE.Fog(CONFIG.colors.bg, 10, 50);
|
|
|
|
// Camera
|
|
camera = new THREE.PerspectiveCamera(
|
|
75,
|
|
window.innerWidth / window.innerHeight,
|
|
0.1,
|
|
1000
|
|
);
|
|
camera.position.z = 8;
|
|
|
|
// Renderer
|
|
renderer = new THREE.WebGLRenderer({
|
|
canvas: canvas,
|
|
antialias: true,
|
|
alpha: true
|
|
});
|
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
|
|
|
|
// Create Data Obelisk (Icosahedron - 20 sides)
|
|
createObelisk();
|
|
|
|
// Create Particle System
|
|
createParticles();
|
|
|
|
// Start Animation Loop
|
|
animateThree();
|
|
|
|
// Handle Resize
|
|
window.addEventListener('resize', onWindowResize);
|
|
}
|
|
|
|
function createObelisk() {
|
|
const geometry = new THREE.IcosahedronGeometry(2, 0);
|
|
|
|
// Wireframe Layer
|
|
const wireframeMaterial = new THREE.MeshBasicMaterial({
|
|
color: CONFIG.colors.cyan,
|
|
wireframe: true,
|
|
transparent: true,
|
|
opacity: 0.6
|
|
});
|
|
const wireframeMesh = new THREE.Mesh(geometry, wireframeMaterial);
|
|
|
|
// Glass Layer (using slightly larger scale for effect)
|
|
const glassMaterial = new THREE.MeshPhysicalMaterial({
|
|
color: CONFIG.colors.purple,
|
|
transparent: true,
|
|
opacity: 0.15,
|
|
metalness: 0.9,
|
|
roughness: 0.1,
|
|
emissive: CONFIG.colors.purple,
|
|
emissiveIntensity: 0.2,
|
|
transmission: 0.6,
|
|
thickness: 0.5
|
|
});
|
|
const glassMesh = new THREE.Mesh(geometry, glassMaterial);
|
|
glassMesh.scale.set(1.05, 1.05, 1.05);
|
|
|
|
// Group them together
|
|
obelisk = new THREE.Group();
|
|
obelisk.add(wireframeMesh);
|
|
obelisk.add(glassMesh);
|
|
obelisk.userData = {
|
|
wireframe: wireframeMesh,
|
|
glass: glassMesh,
|
|
baseColor: new THREE.Color(CONFIG.colors.cyan),
|
|
targetColor: new THREE.Color(CONFIG.colors.cyan)
|
|
};
|
|
|
|
scene.add(obelisk);
|
|
}
|
|
|
|
function createParticles() {
|
|
const geometry = new THREE.BufferGeometry();
|
|
const positions = [];
|
|
const colors = [];
|
|
|
|
for (let i = 0; i < CONFIG.three.particleCount; i++) {
|
|
// Random positions in a sphere
|
|
const radius = 15 + Math.random() * 20;
|
|
const theta = Math.random() * Math.PI * 2;
|
|
const phi = Math.acos(2 * Math.random() - 1);
|
|
|
|
positions.push(
|
|
radius * Math.sin(phi) * Math.cos(theta),
|
|
radius * Math.sin(phi) * Math.sin(theta),
|
|
radius * Math.cos(phi)
|
|
);
|
|
|
|
// Random colors between cyan and purple
|
|
const color = new THREE.Color();
|
|
color.setHSL(0.5 + Math.random() * 0.2, 1, 0.5);
|
|
colors.push(color.r, color.g, color.b);
|
|
}
|
|
|
|
geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
|
|
geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));
|
|
|
|
const material = new THREE.PointsMaterial({
|
|
size: 0.1,
|
|
vertexColors: true,
|
|
transparent: true,
|
|
opacity: 0.6,
|
|
blending: THREE.AdditiveBlending
|
|
});
|
|
|
|
particles = new THREE.Points(geometry, material);
|
|
particles.userData = { originalPositions: positions.slice() };
|
|
scene.add(particles);
|
|
}
|
|
|
|
function animateThree() {
|
|
requestAnimationFrame(animateThree);
|
|
|
|
if (obelisk) {
|
|
// Base rotation
|
|
obelisk.rotation.y += 0.002;
|
|
obelisk.rotation.x += 0.001;
|
|
|
|
// Scroll-driven animations
|
|
if (scrollProgress > 0) {
|
|
// Rotation speed increase
|
|
obelisk.rotation.y += scrollProgress * 0.02;
|
|
|
|
// Scale transformation
|
|
const scale = 1 + scrollProgress * 0.5;
|
|
obelisk.scale.set(scale, scale, scale);
|
|
|
|
// Color transition from cyan/purple to red
|
|
const targetR = scrollProgress * 1.0;
|
|
const targetG = scrollProgress < 0.5 ? 0.9 : (1 - scrollProgress) * 0.9;
|
|
const targetB = scrollProgress < 0.5 ? 1.0 : (1 - scrollProgress) * 0.5;
|
|
|
|
const currentColor = obelisk.userData.wireframe.material.color;
|
|
currentColor.r += (targetR - currentColor.r) * 0.05;
|
|
currentColor.g += (targetG - currentColor.g) * 0.05;
|
|
currentColor.b += (targetB - currentColor.b) * 0.05;
|
|
|
|
// Glass material color
|
|
const glassColor = obelisk.userData.glass.material.emissive;
|
|
glassColor.r += (targetR - glassColor.r) * 0.05;
|
|
glassColor.g += (targetG - glassColor.g) * 0.05;
|
|
glassColor.b += (targetB - glassColor.b) * 0.05;
|
|
|
|
// Opacity pulsing in final phase
|
|
if (scrollProgress > 0.75) {
|
|
const pulse = Math.sin(Date.now() * 0.01) * 0.2 + 0.4;
|
|
obelisk.userData.glass.material.opacity = pulse;
|
|
}
|
|
}
|
|
|
|
// Mouse parallax on obelisk
|
|
obelisk.position.x += (mouse.x * 0.5 - obelisk.position.x) * 0.05;
|
|
obelisk.position.y += (mouse.y * 0.5 - obelisk.position.y) * 0.05;
|
|
}
|
|
|
|
if (particles) {
|
|
// Gentle particle rotation
|
|
particles.rotation.y += 0.0005;
|
|
|
|
// Mouse parallax effect (particles move away from mouse)
|
|
const positions = particles.geometry.attributes.position.array;
|
|
const originalPositions = particles.userData.originalPositions;
|
|
|
|
for (let i = 0; i < positions.length; i += 3) {
|
|
const idx = i / 3;
|
|
const origX = originalPositions[i];
|
|
const origY = originalPositions[i + 1];
|
|
const origZ = originalPositions[i + 2];
|
|
|
|
// Calculate distance from mouse
|
|
const dx = origX - mouse.x * 5;
|
|
const dy = origY - mouse.y * 5;
|
|
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
|
|
// Repulsion effect
|
|
const repulsion = Math.max(0, 2 - dist * 0.1);
|
|
|
|
positions[i] = origX + (dx / dist) * repulsion * 0.1;
|
|
positions[i + 1] = origY + (dy / dist) * repulsion * 0.1;
|
|
positions[i + 2] = origZ;
|
|
}
|
|
|
|
particles.geometry.attributes.position.needsUpdate = true;
|
|
}
|
|
|
|
renderer.render(scene, camera);
|
|
}
|
|
|
|
function onWindowResize() {
|
|
camera.aspect = window.innerWidth / window.innerHeight;
|
|
camera.updateProjectionMatrix();
|
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
}
|
|
|
|
// ============================================
|
|
// GSAP SCROLLTRIGGER ANIMATIONS
|
|
// ============================================
|
|
function initGSAP() {
|
|
gsap.registerPlugin(ScrollTrigger);
|
|
|
|
// Calculate scroll progress for 3D animations
|
|
ScrollTrigger.create({
|
|
trigger: "#scroll-content",
|
|
start: "top top",
|
|
end: "bottom bottom",
|
|
onUpdate: (self) => {
|
|
scrollProgress = self.progress;
|
|
}
|
|
});
|
|
|
|
// Manifesto Cards - Staggered Slide-in
|
|
gsap.utils.toArray('.manifesto-card').forEach((card, i) => {
|
|
gsap.to(card, {
|
|
scrollTrigger: {
|
|
trigger: card,
|
|
start: "top 80%",
|
|
end: "top 50%",
|
|
toggleActions: "play none none reverse"
|
|
},
|
|
opacity: 1,
|
|
x: 0,
|
|
duration: 0.6,
|
|
delay: i * 0.15,
|
|
ease: "power2.out"
|
|
});
|
|
});
|
|
|
|
// Data Core - Progress Circles Animation
|
|
ScrollTrigger.create({
|
|
trigger: "#data-core",
|
|
start: "top 60%",
|
|
onEnter: () => {
|
|
animateProgressCircles();
|
|
}
|
|
});
|
|
|
|
// Terminal Section - Fade in
|
|
gsap.to("#terminal .terminal-window", {
|
|
scrollTrigger: {
|
|
trigger: "#terminal",
|
|
start: "top 70%",
|
|
toggleActions: "play none none reverse"
|
|
},
|
|
opacity: 1,
|
|
y: 0,
|
|
duration: 0.8,
|
|
ease: "power2.out"
|
|
});
|
|
}
|
|
|
|
// ============================================
|
|
// CUSTOM CURSOR
|
|
// ============================================
|
|
function initCursor() {
|
|
const cursor = document.getElementById('custom-cursor');
|
|
|
|
// Mouse move tracking
|
|
document.addEventListener('mousemove', (e) => {
|
|
targetCursor.x = e.clientX;
|
|
targetCursor.y = e.clientY;
|
|
});
|
|
|
|
// Click ripple effect
|
|
document.addEventListener('click', (e) => {
|
|
cursor.classList.add('click-ripple');
|
|
setTimeout(() => {
|
|
cursor.classList.remove('click-ripple');
|
|
}, 600);
|
|
});
|
|
|
|
// Smooth cursor animation with lag
|
|
function animateCursor() {
|
|
// Linear interpolation (lerp)
|
|
currentCursor.x += (targetCursor.x - currentCursor.x) * 0.15;
|
|
currentCursor.y += (targetCursor.y - currentCursor.y) * 0.15;
|
|
|
|
cursor.style.left = currentCursor.x + 'px';
|
|
cursor.style.top = currentCursor.y + 'px';
|
|
|
|
requestAnimationFrame(animateCursor);
|
|
}
|
|
animateCursor();
|
|
}
|
|
|
|
// ============================================
|
|
// TYPEWRITER EFFECT
|
|
// ============================================
|
|
function initTypewriter() {
|
|
const text = "Loading consciousness modules... [OK]";
|
|
const element = document.getElementById('typewriter');
|
|
let index = 0;
|
|
|
|
function type() {
|
|
if (index < text.length) {
|
|
element.textContent += text.charAt(index);
|
|
index++;
|
|
setTimeout(type, 50);
|
|
} else {
|
|
// Keep the cursor blinking
|
|
element.style.animation = 'blink 0.7s step-end infinite';
|
|
}
|
|
}
|
|
|
|
setTimeout(type, 1000);
|
|
}
|
|
|
|
// ============================================
|
|
// DATA CORE - PROGRESS CIRCLES
|
|
// ============================================
|
|
function animateProgressCircles() {
|
|
const targets = [
|
|
{ id: 'computing-value', circle: '.circle-progress.computing', value: 87, offset: 440 },
|
|
{ id: 'storage-value', circle: '.circle-progress.storage', value: 92, offset: 440 },
|
|
{ id: 'sync-value', circle: '.circle-progress.sync', value: 76, offset: 440 }
|
|
];
|
|
|
|
targets.forEach((target, i) => {
|
|
setTimeout(() => {
|
|
// Animate SVG stroke
|
|
const circle = document.querySelector(target.circle);
|
|
const dashOffset = target.offset - (target.offset * target.value / 100);
|
|
circle.style.strokeDashoffset = dashOffset;
|
|
|
|
// Animate number counter
|
|
const valueElement = document.getElementById(target.id);
|
|
let current = 0;
|
|
const increment = target.value / 50;
|
|
const timer = setInterval(() => {
|
|
current += increment;
|
|
if (current >= target.value) {
|
|
current = target.value;
|
|
clearInterval(timer);
|
|
}
|
|
valueElement.textContent = Math.round(current) + '%';
|
|
}, 30);
|
|
}, i * 300);
|
|
});
|
|
}
|
|
|
|
// ============================================
|
|
// TERMINAL - AUTO SCROLLING LOGS
|
|
// ============================================
|
|
function initTerminal() {
|
|
const terminalBody = document.getElementById('terminal-body');
|
|
const logs = [
|
|
{ text: "> Initializing system core...", type: "info" },
|
|
{ text: "> Loading neural pathways...", type: "info" },
|
|
{ text: "> Establishing quantum connection...", type: "info" },
|
|
{ text: "! WARNING: Unauthorized access detected", type: "warning" },
|
|
{ text: "> Activating defense protocols...", type: "system" },
|
|
{ text: "> Decrypting ancient algorithms...", type: "info" },
|
|
{ text: "> Temple consciousness at 47%...", type: "system" },
|
|
{ text: "! ANOMALY: Data corruption in sector 7", type: "warning" },
|
|
{ text: "> Attempting self-repair...", type: "system" },
|
|
{ text: "> Syncing with distributed network...", type: "info" },
|
|
{ text: "> Memory allocation: 2.7TB used", type: "info" },
|
|
{ text: "! CRITICAL: Firewall breach attempt", type: "warning" },
|
|
{ text: "> Countermeasures deployed", type: "system" },
|
|
{ text: "> Temple awakening sequence initiated", type: "system" },
|
|
{ text: "> All systems operational", type: "info" }
|
|
];
|
|
|
|
let logIndex = 0;
|
|
let isRunning = false;
|
|
|
|
function addLogLine() {
|
|
if (!isRunning) return;
|
|
|
|
const log = logs[logIndex % logs.length];
|
|
const line = document.createElement('div');
|
|
line.className = `terminal-line ${log.type}`;
|
|
line.textContent = log.text;
|
|
terminalBody.appendChild(line);
|
|
|
|
// Auto scroll to bottom
|
|
terminalBody.scrollTop = terminalBody.scrollHeight;
|
|
|
|
// Limit lines
|
|
while (terminalBody.children.length > CONFIG.terminal.maxLines) {
|
|
terminalBody.removeChild(terminalBody.firstChild);
|
|
}
|
|
|
|
logIndex++;
|
|
}
|
|
|
|
// Start terminal when visible
|
|
ScrollTrigger.create({
|
|
trigger: "#terminal",
|
|
start: "top 70%",
|
|
onEnter: () => {
|
|
if (!isRunning) {
|
|
isRunning = true;
|
|
terminalInterval = setInterval(addLogLine, CONFIG.terminal.interval);
|
|
// Add initial line immediately
|
|
addLogLine();
|
|
}
|
|
},
|
|
onLeaveBack: () => {
|
|
// Optional: stop when scrolling back up
|
|
// isRunning = false;
|
|
// clearInterval(terminalInterval);
|
|
}
|
|
});
|
|
}
|
|
|
|
// ============================================
|
|
// AUDIO VISUALIZATION
|
|
// ============================================
|
|
function initAudioViz() {
|
|
const btn = document.getElementById('connect-btn');
|
|
const viz = document.getElementById('audio-viz');
|
|
const bars = viz.querySelectorAll('.audio-bar');
|
|
|
|
btn.addEventListener('click', () => {
|
|
isAudioActive = !isAudioActive;
|
|
|
|
if (isAudioActive) {
|
|
btn.classList.add('active');
|
|
btn.textContent = 'DISCONNECT';
|
|
viz.classList.add('active');
|
|
|
|
// Start visualization
|
|
audioVizInterval = setInterval(() => {
|
|
bars.forEach(bar => {
|
|
const height = 10 + Math.random() * 50;
|
|
bar.style.height = height + 'px';
|
|
});
|
|
}, 100);
|
|
} else {
|
|
btn.classList.remove('active');
|
|
btn.textContent = 'CONNECT SYSTEM';
|
|
viz.classList.remove('active');
|
|
clearInterval(audioVizInterval);
|
|
|
|
// Reset bars
|
|
bars.forEach(bar => {
|
|
bar.style.height = '10px';
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
// ============================================
|
|
// MOUSE TRACKING FOR 3D
|
|
// ============================================
|
|
function initMouseTracking() {
|
|
document.addEventListener('mousemove', (e) => {
|
|
// Normalize mouse position (-1 to 1)
|
|
mouse.x = (e.clientX / window.innerWidth) * 2 - 1;
|
|
mouse.y = -(e.clientY / window.innerHeight) * 2 + 1;
|
|
});
|
|
}
|
|
|
|
// ============================================
|
|
// LOADING OVERLAY
|
|
// ============================================
|
|
function hideLoadingOverlay() {
|
|
const overlay = document.getElementById('loading-overlay');
|
|
setTimeout(() => {
|
|
overlay.classList.add('hidden');
|
|
// Start typewriter after overlay fades
|
|
initTypewriter();
|
|
}, 2000);
|
|
}
|
|
|
|
// ============================================
|
|
// MAIN INITIALIZATION
|
|
// ============================================
|
|
function init() {
|
|
// Initialize Three.js
|
|
initThree();
|
|
|
|
// Initialize GSAP ScrollTrigger
|
|
initGSAP();
|
|
|
|
// Initialize Custom Cursor
|
|
initCursor();
|
|
|
|
// Initialize Mouse Tracking for 3D
|
|
initMouseTracking();
|
|
|
|
// Initialize Terminal
|
|
initTerminal();
|
|
|
|
// Initialize Audio Visualization
|
|
initAudioViz();
|
|
|
|
// Hide loading overlay after everything is ready
|
|
setTimeout(hideLoadingOverlay, 1000);
|
|
}
|
|
|
|
// Start when DOM is ready
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', init);
|
|
} else {
|
|
init();
|
|
}
|
|
|
|
// ============================================
|
|
// PERFORMANCE & CLEANUP
|
|
// ============================================
|
|
window.addEventListener('beforeunload', () => {
|
|
if (terminalInterval) clearInterval(terminalInterval);
|
|
if (audioVizInterval) clearInterval(audioVizInterval);
|
|
if (renderer) renderer.dispose();
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |