2421 lines
96 KiB
HTML
2421 lines
96 KiB
HTML
|
|
<!DOCTYPE html>
|
|||
|
|
<html lang="zh-CN">
|
|||
|
|
<head>
|
|||
|
|
<meta charset="UTF-8">
|
|||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|||
|
|
<title>赛博朋克未来都市操作系统 | NEO-OS v2.0</title>
|
|||
|
|
<!-- CDN 依赖 -->
|
|||
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|||
|
|
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=Rajdhani:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
|||
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|||
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
|
|||
|
|
<style>
|
|||
|
|
/* CSS 变量 - 赛博朋克主题色 */
|
|||
|
|
:root {
|
|||
|
|
--neon-pink: #ff00ff;
|
|||
|
|
--neon-blue: #00ffff;
|
|||
|
|
--neon-purple: #9d00ff;
|
|||
|
|
--neon-green: #00ff9d;
|
|||
|
|
--dark-bg: #0a0a16;
|
|||
|
|
--darker-bg: #050510;
|
|||
|
|
--glass-bg: rgba(20, 20, 40, 0.7);
|
|||
|
|
--glass-border: rgba(120, 120, 255, 0.2);
|
|||
|
|
--text-primary: #e0e0ff;
|
|||
|
|
--text-secondary: #a0a0ff;
|
|||
|
|
--shadow-glow: 0 0 15px currentColor;
|
|||
|
|
--transition-smooth: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 基础重置 */
|
|||
|
|
* {
|
|||
|
|
margin: 0;
|
|||
|
|
padding: 0;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
body {
|
|||
|
|
font-family: 'Rajdhani', sans-serif;
|
|||
|
|
background-color: var(--dark-bg);
|
|||
|
|
color: var(--text-primary);
|
|||
|
|
overflow: hidden;
|
|||
|
|
height: 100vh;
|
|||
|
|
font-weight: 500;
|
|||
|
|
user-select: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 扫描线效果 */
|
|||
|
|
body::before {
|
|||
|
|
content: "";
|
|||
|
|
position: fixed;
|
|||
|
|
top: 0;
|
|||
|
|
left: 0;
|
|||
|
|
width: 100%;
|
|||
|
|
height: 100%;
|
|||
|
|
background: linear-gradient(
|
|||
|
|
rgba(10, 10, 22, 0) 50%,
|
|||
|
|
rgba(0, 255, 255, 0.02) 50%
|
|||
|
|
);
|
|||
|
|
background-size: 100% 4px;
|
|||
|
|
z-index: 9999;
|
|||
|
|
pointer-events: none;
|
|||
|
|
animation: scanline 8s linear infinite;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@keyframes scanline {
|
|||
|
|
0% { transform: translateY(0); }
|
|||
|
|
100% { transform: translateY(100vh); }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 启动界面 */
|
|||
|
|
#boot-screen {
|
|||
|
|
position: fixed;
|
|||
|
|
top: 0;
|
|||
|
|
left: 0;
|
|||
|
|
width: 100%;
|
|||
|
|
height: 100%;
|
|||
|
|
background-color: var(--darker-bg);
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
justify-content: center;
|
|||
|
|
align-items: center;
|
|||
|
|
z-index: 10000;
|
|||
|
|
font-family: 'Orbitron', monospace;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.boot-logo {
|
|||
|
|
font-size: 4rem;
|
|||
|
|
font-weight: 900;
|
|||
|
|
margin-bottom: 2rem;
|
|||
|
|
color: var(--neon-blue);
|
|||
|
|
text-shadow: var(--shadow-glow);
|
|||
|
|
letter-spacing: 5px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.boot-progress {
|
|||
|
|
width: 300px;
|
|||
|
|
height: 4px;
|
|||
|
|
background-color: rgba(255, 255, 255, 0.1);
|
|||
|
|
border-radius: 2px;
|
|||
|
|
overflow: hidden;
|
|||
|
|
margin-top: 2rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.boot-progress-bar {
|
|||
|
|
height: 100%;
|
|||
|
|
width: 0%;
|
|||
|
|
background: linear-gradient(90deg, var(--neon-pink), var(--neon-blue));
|
|||
|
|
animation: bootProgress 3s ease-in-out forwards;
|
|||
|
|
box-shadow: 0 0 10px var(--neon-blue);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@keyframes bootProgress {
|
|||
|
|
0% { width: 0%; }
|
|||
|
|
100% { width: 100%; }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 锁屏界面 */
|
|||
|
|
#lock-screen {
|
|||
|
|
position: fixed;
|
|||
|
|
top: 0;
|
|||
|
|
left: 0;
|
|||
|
|
width: 100%;
|
|||
|
|
height: 100%;
|
|||
|
|
background: linear-gradient(45deg, #0a0a16 0%, #1a1a2e 100%);
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
justify-content: center;
|
|||
|
|
align-items: center;
|
|||
|
|
z-index: 9999;
|
|||
|
|
font-family: 'Orbitron', monospace;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.lock-time {
|
|||
|
|
font-size: 5rem;
|
|||
|
|
font-weight: 700;
|
|||
|
|
color: var(--neon-blue);
|
|||
|
|
text-shadow: 0 0 20px var(--neon-blue);
|
|||
|
|
margin-bottom: 1rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.lock-date {
|
|||
|
|
font-size: 1.5rem;
|
|||
|
|
color: var(--text-secondary);
|
|||
|
|
margin-bottom: 3rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.unlock-btn {
|
|||
|
|
padding: 15px 40px;
|
|||
|
|
background: rgba(0, 255, 255, 0.1);
|
|||
|
|
border: 2px solid var(--neon-blue);
|
|||
|
|
border-radius: 50px;
|
|||
|
|
color: var(--neon-blue);
|
|||
|
|
font-size: 1.2rem;
|
|||
|
|
font-family: 'Orbitron', monospace;
|
|||
|
|
cursor: pointer;
|
|||
|
|
transition: var(--transition-smooth);
|
|||
|
|
text-transform: uppercase;
|
|||
|
|
letter-spacing: 2px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.unlock-btn:hover {
|
|||
|
|
background: rgba(0, 255, 255, 0.2);
|
|||
|
|
box-shadow: 0 0 20px var(--neon-blue);
|
|||
|
|
transform: translateY(-3px);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 桌面 */
|
|||
|
|
#desktop {
|
|||
|
|
position: fixed;
|
|||
|
|
top: 0;
|
|||
|
|
left: 0;
|
|||
|
|
width: 100%;
|
|||
|
|
height: 100%;
|
|||
|
|
overflow: hidden;
|
|||
|
|
display: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 动态壁纸 */
|
|||
|
|
#wallpaper {
|
|||
|
|
position: absolute;
|
|||
|
|
top: 0;
|
|||
|
|
left: 0;
|
|||
|
|
width: 100%;
|
|||
|
|
height: 100%;
|
|||
|
|
background: linear-gradient(180deg, #050510 0%, #0a0a1a 30%, #151530 100%);
|
|||
|
|
z-index: 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.cyber-grid {
|
|||
|
|
position: absolute;
|
|||
|
|
top: 0;
|
|||
|
|
left: 0;
|
|||
|
|
width: 100%;
|
|||
|
|
height: 100%;
|
|||
|
|
background-image:
|
|||
|
|
linear-gradient(rgba(0, 255, 255, 0.05) 1px, transparent 1px),
|
|||
|
|
linear-gradient(90deg, rgba(0, 255, 255, 0.05) 1px, transparent 1px);
|
|||
|
|
background-size: 50px 50px;
|
|||
|
|
z-index: 2;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.floating-neon {
|
|||
|
|
position: absolute;
|
|||
|
|
border-radius: 50%;
|
|||
|
|
filter: blur(40px);
|
|||
|
|
opacity: 0.3;
|
|||
|
|
z-index: 3;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.neon-1 {
|
|||
|
|
width: 300px;
|
|||
|
|
height: 300px;
|
|||
|
|
background-color: var(--neon-pink);
|
|||
|
|
top: 10%;
|
|||
|
|
left: 10%;
|
|||
|
|
animation: float 15s infinite ease-in-out;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.neon-2 {
|
|||
|
|
width: 200px;
|
|||
|
|
height: 200px;
|
|||
|
|
background-color: var(--neon-blue);
|
|||
|
|
bottom: 15%;
|
|||
|
|
right: 15%;
|
|||
|
|
animation: float 20s infinite ease-in-out reverse;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@keyframes float {
|
|||
|
|
0%, 100% { transform: translate(0, 0) scale(1); }
|
|||
|
|
25% { transform: translate(30px, -30px) scale(1.1); }
|
|||
|
|
50% { transform: translate(-20px, 20px) scale(0.9); }
|
|||
|
|
75% { transform: translate(-30px, -30px) scale(1.05); }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 桌面图标 */
|
|||
|
|
.desktop-icons {
|
|||
|
|
position: absolute;
|
|||
|
|
top: 30px;
|
|||
|
|
left: 30px;
|
|||
|
|
z-index: 10;
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
gap: 25px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.desktop-icon {
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
align-items: center;
|
|||
|
|
width: 80px;
|
|||
|
|
padding: 10px;
|
|||
|
|
border-radius: 8px;
|
|||
|
|
cursor: pointer;
|
|||
|
|
transition: var(--transition-smooth);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.desktop-icon:hover {
|
|||
|
|
background: rgba(0, 255, 255, 0.1);
|
|||
|
|
transform: translateY(-5px);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.desktop-icon i {
|
|||
|
|
font-size: 2.5rem;
|
|||
|
|
color: var(--neon-green);
|
|||
|
|
margin-bottom: 8px;
|
|||
|
|
text-shadow: var(--shadow-glow);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.desktop-icon span {
|
|||
|
|
font-size: 0.9rem;
|
|||
|
|
color: var(--text-primary);
|
|||
|
|
text-align: center;
|
|||
|
|
font-weight: 600;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 窗口系统 */
|
|||
|
|
.window {
|
|||
|
|
position: absolute;
|
|||
|
|
background: var(--glass-bg);
|
|||
|
|
backdrop-filter: blur(10px);
|
|||
|
|
border-radius: 12px;
|
|||
|
|
border: 1px solid var(--glass-border);
|
|||
|
|
box-shadow:
|
|||
|
|
0 10px 30px rgba(0, 0, 0, 0.5),
|
|||
|
|
0 0 0 1px rgba(255, 255, 255, 0.1),
|
|||
|
|
inset 0 0 0 1px rgba(255, 255, 255, 0.05);
|
|||
|
|
overflow: hidden;
|
|||
|
|
min-width: 300px;
|
|||
|
|
min-height: 200px;
|
|||
|
|
z-index: 100;
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.window-header {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
align-items: center;
|
|||
|
|
padding: 12px 15px;
|
|||
|
|
background: rgba(10, 10, 30, 0.8);
|
|||
|
|
border-bottom: 1px solid rgba(0, 255, 255, 0.2);
|
|||
|
|
cursor: move;
|
|||
|
|
user-select: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.window-title {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 10px;
|
|||
|
|
font-weight: 600;
|
|||
|
|
color: var(--neon-blue);
|
|||
|
|
text-shadow: 0 0 5px var(--neon-blue);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.window-title i {
|
|||
|
|
font-size: 1.1rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.window-controls {
|
|||
|
|
display: flex;
|
|||
|
|
gap: 8px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.window-btn {
|
|||
|
|
width: 12px;
|
|||
|
|
height: 12px;
|
|||
|
|
border-radius: 50%;
|
|||
|
|
cursor: pointer;
|
|||
|
|
transition: var(--transition-smooth);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.close-btn { background-color: #ff5f57; }
|
|||
|
|
.minimize-btn { background-color: #ffbd2e; }
|
|||
|
|
.maximize-btn { background-color: #28ca42; }
|
|||
|
|
|
|||
|
|
.window-btn:hover {
|
|||
|
|
transform: scale(1.2);
|
|||
|
|
box-shadow: 0 0 8px currentColor;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.window-content {
|
|||
|
|
flex: 1;
|
|||
|
|
overflow: auto;
|
|||
|
|
padding: 15px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.window.active {
|
|||
|
|
box-shadow:
|
|||
|
|
0 15px 40px rgba(0, 0, 0, 0.7),
|
|||
|
|
0 0 20px rgba(0, 255, 255, 0.3),
|
|||
|
|
inset 0 0 0 1px rgba(255, 255, 255, 0.05);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 任务栏 */
|
|||
|
|
#taskbar {
|
|||
|
|
position: fixed;
|
|||
|
|
bottom: 0;
|
|||
|
|
left: 0;
|
|||
|
|
width: 100%;
|
|||
|
|
height: 50px;
|
|||
|
|
background: rgba(10, 10, 30, 0.8);
|
|||
|
|
backdrop-filter: blur(15px);
|
|||
|
|
border-top: 1px solid rgba(0, 255, 255, 0.2);
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
padding: 0 20px;
|
|||
|
|
z-index: 1000;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.start-btn {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 10px;
|
|||
|
|
padding: 8px 15px;
|
|||
|
|
background: linear-gradient(90deg, rgba(0, 255, 255, 0.1), rgba(255, 0, 255, 0.1));
|
|||
|
|
border-radius: 8px;
|
|||
|
|
cursor: pointer;
|
|||
|
|
transition: var(--transition-smooth);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.start-btn:hover {
|
|||
|
|
background: linear-gradient(90deg, rgba(0, 255, 255, 0.2), rgba(255, 0, 255, 0.2));
|
|||
|
|
box-shadow: 0 0 15px rgba(0, 255, 255, 0.3);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.start-btn i {
|
|||
|
|
font-size: 1.5rem;
|
|||
|
|
color: var(--neon-blue);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.start-btn span {
|
|||
|
|
font-weight: 700;
|
|||
|
|
font-size: 1.1rem;
|
|||
|
|
color: var(--neon-blue);
|
|||
|
|
text-shadow: 0 0 5px var(--neon-blue);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.taskbar-apps {
|
|||
|
|
display: flex;
|
|||
|
|
margin-left: 20px;
|
|||
|
|
gap: 5px;
|
|||
|
|
flex: 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.taskbar-app {
|
|||
|
|
padding: 8px 15px;
|
|||
|
|
border-radius: 6px;
|
|||
|
|
cursor: pointer;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 8px;
|
|||
|
|
transition: var(--transition-smooth);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.taskbar-app:hover {
|
|||
|
|
background: rgba(0, 255, 255, 0.1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.taskbar-app.active {
|
|||
|
|
background: rgba(0, 255, 255, 0.2);
|
|||
|
|
box-shadow: inset 0 0 10px rgba(0, 255, 255, 0.3);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.taskbar-app i {
|
|||
|
|
color: var(--neon-green);
|
|||
|
|
font-size: 1.2rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.taskbar-app span {
|
|||
|
|
font-size: 0.9rem;
|
|||
|
|
color: var(--text-primary);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.system-tray {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 20px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.clock {
|
|||
|
|
font-family: 'Orbitron', monospace;
|
|||
|
|
font-size: 1.2rem;
|
|||
|
|
color: var(--neon-green);
|
|||
|
|
text-shadow: 0 0 5px var(--neon-green);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 开始菜单 */
|
|||
|
|
#start-menu {
|
|||
|
|
position: fixed;
|
|||
|
|
bottom: 60px;
|
|||
|
|
left: 20px;
|
|||
|
|
width: 400px;
|
|||
|
|
height: 500px;
|
|||
|
|
background: rgba(10, 10, 30, 0.9);
|
|||
|
|
backdrop-filter: blur(20px);
|
|||
|
|
border-radius: 15px;
|
|||
|
|
border: 1px solid rgba(0, 255, 255, 0.2);
|
|||
|
|
box-shadow:
|
|||
|
|
0 20px 50px rgba(0, 0, 0, 0.7),
|
|||
|
|
0 0 30px rgba(0, 255, 255, 0.2);
|
|||
|
|
z-index: 999;
|
|||
|
|
display: none;
|
|||
|
|
flex-direction: column;
|
|||
|
|
overflow: hidden;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.start-header {
|
|||
|
|
padding: 20px;
|
|||
|
|
background: linear-gradient(90deg, rgba(0, 255, 255, 0.1), rgba(255, 0, 255, 0.1));
|
|||
|
|
border-bottom: 1px solid rgba(0, 255, 255, 0.2);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.start-user {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 15px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.user-avatar {
|
|||
|
|
width: 60px;
|
|||
|
|
height: 60px;
|
|||
|
|
border-radius: 50%;
|
|||
|
|
background: linear-gradient(45deg, var(--neon-pink), var(--neon-blue));
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
font-size: 1.8rem;
|
|||
|
|
color: white;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.user-info h3 {
|
|||
|
|
font-size: 1.5rem;
|
|||
|
|
color: var(--neon-blue);
|
|||
|
|
margin-bottom: 5px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.user-info p {
|
|||
|
|
color: var(--text-secondary);
|
|||
|
|
font-size: 0.9rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.start-apps {
|
|||
|
|
flex: 1;
|
|||
|
|
padding: 20px;
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: repeat(3, 1fr);
|
|||
|
|
gap: 15px;
|
|||
|
|
overflow-y: auto;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.start-app {
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
padding: 15px 10px;
|
|||
|
|
border-radius: 10px;
|
|||
|
|
cursor: pointer;
|
|||
|
|
transition: var(--transition-smooth);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.start-app:hover {
|
|||
|
|
background: rgba(0, 255, 255, 0.1);
|
|||
|
|
transform: translateY(-3px);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.start-app i {
|
|||
|
|
font-size: 2rem;
|
|||
|
|
color: var(--neon-green);
|
|||
|
|
margin-bottom: 10px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.start-app span {
|
|||
|
|
font-size: 0.9rem;
|
|||
|
|
color: var(--text-primary);
|
|||
|
|
text-align: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.start-footer {
|
|||
|
|
padding: 15px 20px;
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
border-top: 1px solid rgba(0, 255, 255, 0.2);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.power-btn {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 10px;
|
|||
|
|
padding: 8px 15px;
|
|||
|
|
background: rgba(255, 0, 0, 0.2);
|
|||
|
|
border-radius: 8px;
|
|||
|
|
cursor: pointer;
|
|||
|
|
transition: var(--transition-smooth);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.power-btn:hover {
|
|||
|
|
background: rgba(255, 0, 0, 0.3);
|
|||
|
|
box-shadow: 0 0 15px rgba(255, 0, 0, 0.4);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 应用样式 */
|
|||
|
|
.app-content {
|
|||
|
|
height: 100%;
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 文件管理器 */
|
|||
|
|
.file-explorer {
|
|||
|
|
display: flex;
|
|||
|
|
height: 100%;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.file-sidebar {
|
|||
|
|
width: 200px;
|
|||
|
|
border-right: 1px solid rgba(0, 255, 255, 0.2);
|
|||
|
|
padding: 15px 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.file-list {
|
|||
|
|
flex: 1;
|
|||
|
|
padding: 15px;
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
|
|||
|
|
gap: 15px;
|
|||
|
|
overflow-y: auto;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.file-item {
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
align-items: center;
|
|||
|
|
padding: 15px 10px;
|
|||
|
|
border-radius: 8px;
|
|||
|
|
cursor: pointer;
|
|||
|
|
transition: var(--transition-smooth);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.file-item:hover {
|
|||
|
|
background: rgba(0, 255, 255, 0.1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.file-item i {
|
|||
|
|
font-size: 2.5rem;
|
|||
|
|
color: var(--neon-green);
|
|||
|
|
margin-bottom: 10px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 终端 */
|
|||
|
|
.terminal-header {
|
|||
|
|
padding: 10px 15px;
|
|||
|
|
background: rgba(0, 0, 0, 0.5);
|
|||
|
|
border-bottom: 1px solid rgba(0, 255, 255, 0.2);
|
|||
|
|
font-family: 'Orbitron', monospace;
|
|||
|
|
color: var(--neon-green);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.terminal-body {
|
|||
|
|
flex: 1;
|
|||
|
|
background: rgba(0, 0, 0, 0.8);
|
|||
|
|
padding: 15px;
|
|||
|
|
overflow-y: auto;
|
|||
|
|
font-family: 'Courier New', monospace;
|
|||
|
|
color: var(--neon-green);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.terminal-line {
|
|||
|
|
margin-bottom: 10px;
|
|||
|
|
display: flex;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.terminal-prompt {
|
|||
|
|
color: var(--neon-blue);
|
|||
|
|
margin-right: 10px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.terminal-input {
|
|||
|
|
flex: 1;
|
|||
|
|
background: transparent;
|
|||
|
|
border: none;
|
|||
|
|
color: var(--neon-green);
|
|||
|
|
font-family: 'Courier New', monospace;
|
|||
|
|
font-size: 1rem;
|
|||
|
|
outline: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 浏览器 */
|
|||
|
|
.browser-nav {
|
|||
|
|
display: flex;
|
|||
|
|
padding: 10px 15px;
|
|||
|
|
background: rgba(0, 0, 0, 0.5);
|
|||
|
|
border-bottom: 1px solid rgba(0, 255, 255, 0.2);
|
|||
|
|
gap: 10px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.browser-url {
|
|||
|
|
flex: 1;
|
|||
|
|
background: rgba(0, 0, 0, 0.7);
|
|||
|
|
border: 1px solid rgba(0, 255, 255, 0.3);
|
|||
|
|
border-radius: 5px;
|
|||
|
|
padding: 8px 15px;
|
|||
|
|
color: var(--text-primary);
|
|||
|
|
font-family: 'Rajdhani', sans-serif;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.browser-frame {
|
|||
|
|
flex: 1;
|
|||
|
|
border: none;
|
|||
|
|
background: white;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 设置中心 */
|
|||
|
|
.settings-tabs {
|
|||
|
|
display: flex;
|
|||
|
|
border-bottom: 1px solid rgba(0, 255, 255, 0.2);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.settings-tab {
|
|||
|
|
padding: 12px 20px;
|
|||
|
|
cursor: pointer;
|
|||
|
|
transition: var(--transition-smooth);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.settings-tab.active {
|
|||
|
|
border-bottom: 2px solid var(--neon-blue);
|
|||
|
|
color: var(--neon-blue);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.settings-content {
|
|||
|
|
flex: 1;
|
|||
|
|
padding: 20px;
|
|||
|
|
overflow-y: auto;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.setting-item {
|
|||
|
|
margin-bottom: 20px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 音乐播放器 */
|
|||
|
|
.player-controls {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: center;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 20px;
|
|||
|
|
padding: 20px;
|
|||
|
|
border-bottom: 1px solid rgba(0, 255, 255, 0.2);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.player-btn {
|
|||
|
|
width: 50px;
|
|||
|
|
height: 50px;
|
|||
|
|
border-radius: 50%;
|
|||
|
|
background: rgba(0, 255, 255, 0.1);
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
cursor: pointer;
|
|||
|
|
transition: var(--transition-smooth);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.player-btn:hover {
|
|||
|
|
background: rgba(0, 255, 255, 0.2);
|
|||
|
|
transform: scale(1.1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 通知系统 */
|
|||
|
|
.notification-container {
|
|||
|
|
position: fixed;
|
|||
|
|
top: 20px;
|
|||
|
|
right: 20px;
|
|||
|
|
width: 350px;
|
|||
|
|
z-index: 2000;
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
gap: 10px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.notification {
|
|||
|
|
background: rgba(10, 10, 30, 0.9);
|
|||
|
|
backdrop-filter: blur(10px);
|
|||
|
|
border-radius: 10px;
|
|||
|
|
padding: 15px;
|
|||
|
|
border-left: 4px solid var(--neon-blue);
|
|||
|
|
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.5);
|
|||
|
|
transform: translateX(100%);
|
|||
|
|
transition: transform 0.3s ease;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.notification.show {
|
|||
|
|
transform: translateX(0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.notification-title {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
align-items: center;
|
|||
|
|
margin-bottom: 8px;
|
|||
|
|
color: var(--neon-blue);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 右键菜单 */
|
|||
|
|
.context-menu {
|
|||
|
|
position: fixed;
|
|||
|
|
background: rgba(10, 10, 30, 0.95);
|
|||
|
|
backdrop-filter: blur(10px);
|
|||
|
|
border-radius: 8px;
|
|||
|
|
border: 1px solid rgba(0, 255, 255, 0.2);
|
|||
|
|
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.7);
|
|||
|
|
z-index: 3000;
|
|||
|
|
min-width: 200px;
|
|||
|
|
display: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.context-item {
|
|||
|
|
padding: 12px 20px;
|
|||
|
|
cursor: pointer;
|
|||
|
|
transition: var(--transition-smooth);
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 10px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.context-item:hover {
|
|||
|
|
background: rgba(0, 255, 255, 0.1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 响应式设计 */
|
|||
|
|
@media (max-width: 768px) {
|
|||
|
|
.desktop-icons {
|
|||
|
|
top: 20px;
|
|||
|
|
left: 20px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.window {
|
|||
|
|
min-width: 280px;
|
|||
|
|
min-height: 200px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#start-menu {
|
|||
|
|
width: 300px;
|
|||
|
|
height: 400px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.start-apps {
|
|||
|
|
grid-template-columns: repeat(2, 1fr);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.taskbar-app span {
|
|||
|
|
display: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.clock {
|
|||
|
|
font-size: 1rem;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 动画类 */
|
|||
|
|
.fade-in {
|
|||
|
|
animation: fadeIn 0.3s ease forwards;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@keyframes fadeIn {
|
|||
|
|
from { opacity: 0; }
|
|||
|
|
to { opacity: 1; }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.slide-up {
|
|||
|
|
animation: slideUp 0.3s ease forwards;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@keyframes slideUp {
|
|||
|
|
from { transform: translateY(20px); opacity: 0; }
|
|||
|
|
to { transform: translateY(0); opacity: 1; }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.glitch {
|
|||
|
|
position: relative;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.glitch::before, .glitch::after {
|
|||
|
|
content: attr(data-text);
|
|||
|
|
position: absolute;
|
|||
|
|
top: 0;
|
|||
|
|
left: 0;
|
|||
|
|
width: 100%;
|
|||
|
|
height: 100%;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.glitch::before {
|
|||
|
|
left: 2px;
|
|||
|
|
text-shadow: -2px 0 var(--neon-pink);
|
|||
|
|
clip: rect(44px, 450px, 56px, 0);
|
|||
|
|
animation: glitch-anim 5s infinite linear alternate-reverse;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.glitch::after {
|
|||
|
|
left: -2px;
|
|||
|
|
text-shadow: -2px 0 var(--neon-blue);
|
|||
|
|
clip: rect(44px, 450px, 56px, 0);
|
|||
|
|
animation: glitch-anim2 5s infinite linear alternate-reverse;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@keyframes glitch-anim {
|
|||
|
|
0% { clip: rect(42px, 9999px, 44px, 0); }
|
|||
|
|
5% { clip: rect(12px, 9999px, 59px, 0); }
|
|||
|
|
10% { clip: rect(48px, 9999px, 29px, 0); }
|
|||
|
|
15% { clip: rect(42px, 9999px, 73px, 0); }
|
|||
|
|
20% { clip: rect(63px, 9999px, 27px, 0); }
|
|||
|
|
25% { clip: rect(34px, 9999px, 55px, 0); }
|
|||
|
|
30% { clip: rect(86px, 9999px, 73px, 0); }
|
|||
|
|
35% { clip: rect(20px, 9999px, 20px, 0); }
|
|||
|
|
40% { clip: rect(26px, 9999px, 60px, 0); }
|
|||
|
|
45% { clip: rect(25px, 9999px, 66px, 0); }
|
|||
|
|
50% { clip: rect(57px, 9999px, 98px, 0); }
|
|||
|
|
55% { clip: rect(5px, 9999px, 46px, 0); }
|
|||
|
|
60% { clip: rect(82px, 9999px, 31px, 0); }
|
|||
|
|
65% { clip: rect(54px, 9999px, 27px, 0); }
|
|||
|
|
70% { clip: rect(28px, 9999px, 99px, 0); }
|
|||
|
|
75% { clip: rect(45px, 9999px, 69px, 0); }
|
|||
|
|
80% { clip: rect(23px, 9999px, 85px, 0); }
|
|||
|
|
85% { clip: rect(54px, 9999px, 84px, 0); }
|
|||
|
|
90% { clip: rect(45px, 9999px, 47px, 0); }
|
|||
|
|
95% { clip: rect(37px, 9999px, 20px, 0); }
|
|||
|
|
100% { clip: rect(4px, 9999px, 91px, 0); }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@keyframes glitch-anim2 {
|
|||
|
|
0% { clip: rect(65px, 9999px, 100px, 0); }
|
|||
|
|
5% { clip: rect(52px, 9999px, 74px, 0); }
|
|||
|
|
10% { clip: rect(79px, 9999px, 85px, 0); }
|
|||
|
|
15% { clip: rect(75px, 9999px, 5px, 0); }
|
|||
|
|
20% { clip: rect(67px, 9999px, 61px, 0); }
|
|||
|
|
25% { clip: rect(14px, 9999px, 79px, 0); }
|
|||
|
|
30% { clip: rect(1px, 9999px, 66px, 0); }
|
|||
|
|
35% { clip: rect(86px, 9999px, 30px, 0); }
|
|||
|
|
40% { clip: rect(23px, 9999px, 98px, 0); }
|
|||
|
|
45% { clip: rect(85px, 9999px, 72px, 0); }
|
|||
|
|
50% { clip: rect(71px, 9999px, 75px, 0); }
|
|||
|
|
55% { clip: rect(2px, 9999px, 48px, 0); }
|
|||
|
|
60% { clip: rect(30px, 9999px, 16px, 0); }
|
|||
|
|
65% { clip: rect(59px, 9999px, 50px, 0); }
|
|||
|
|
70% { clip: rect(41px, 9999px, 62px, 0); }
|
|||
|
|
75% { clip: rect(2px, 9999px, 82px, 0); }
|
|||
|
|
80% { clip: rect(47px, 9999px, 73px, 0); }
|
|||
|
|
85% { clip: rect(3px, 9999px, 27px, 0); }
|
|||
|
|
90% { clip: rect(40px, 9999px, 86px, 0); }
|
|||
|
|
95% { clip: rect(45px, 9999px, 72px, 0); }
|
|||
|
|
100% { clip: rect(23px, 9999px, 49px, 0); }
|
|||
|
|
}
|
|||
|
|
</style>
|
|||
|
|
</head>
|
|||
|
|
<body>
|
|||
|
|
<!-- 启动界面 -->
|
|||
|
|
<div id="boot-screen">
|
|||
|
|
<div class="boot-logo glitch" data-text="NEO-OS">NEO-OS</div>
|
|||
|
|
<div class="boot-text">初始化赛博朋克未来都市操作系统...</div>
|
|||
|
|
<div class="boot-progress">
|
|||
|
|
<div class="boot-progress-bar"></div>
|
|||
|
|
</div>
|
|||
|
|
<div class="boot-subtext" style="margin-top: 20px; color: var(--text-secondary);">v2.0.7 | © 2077 Neuromancer Corp.</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- 锁屏界面 -->
|
|||
|
|
<div id="lock-screen">
|
|||
|
|
<div class="lock-time" id="lock-time">00:00:00</div>
|
|||
|
|
<div class="lock-date" id="lock-date">2077年1月1日 星期五</div>
|
|||
|
|
<button class="unlock-btn" id="unlock-btn">
|
|||
|
|
<i class="fas fa-fingerprint"></i> 点击解锁系统
|
|||
|
|
</button>
|
|||
|
|
<div style="margin-top: 30px; color: var(--text-secondary); font-size: 0.9rem;">
|
|||
|
|
当前用户: <span style="color: var(--neon-blue);">Admin</span> | 系统状态: <span style="color: var(--neon-green);">在线</span>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- 桌面环境 -->
|
|||
|
|
<div id="desktop">
|
|||
|
|
<!-- 动态壁纸 -->
|
|||
|
|
<div id="wallpaper">
|
|||
|
|
<div class="cyber-grid"></div>
|
|||
|
|
<div class="floating-neon neon-1"></div>
|
|||
|
|
<div class="floating-neon neon-2"></div>
|
|||
|
|
<!-- 桌面小部件 -->
|
|||
|
|
<div style="position: absolute; top: 30px; right: 30px; z-index: 10;">
|
|||
|
|
<div style="background: rgba(10, 10, 30, 0.7); backdrop-filter: blur(10px); border-radius: 10px; padding: 15px; min-width: 200px; border: 1px solid rgba(0, 255, 255, 0.2);">
|
|||
|
|
<div style="font-family: 'Orbitron', monospace; color: var(--neon-blue); margin-bottom: 10px; text-align: center;">系统监控</div>
|
|||
|
|
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
|
|||
|
|
<span>CPU:</span>
|
|||
|
|
<span id="cpu-usage">34%</span>
|
|||
|
|
</div>
|
|||
|
|
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
|
|||
|
|
<span>内存:</span>
|
|||
|
|
<span id="ram-usage">68%</span>
|
|||
|
|
</div>
|
|||
|
|
<div style="display: flex; justify-content: space-between;">
|
|||
|
|
<span>网络:</span>
|
|||
|
|
<span id="network-status">在线</span>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- 桌面图标 -->
|
|||
|
|
<div class="desktop-icons">
|
|||
|
|
<div class="desktop-icon" data-app="files">
|
|||
|
|
<i class="fas fa-folder"></i>
|
|||
|
|
<span>文件管理器</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="desktop-icon" data-app="terminal">
|
|||
|
|
<i class="fas fa-terminal"></i>
|
|||
|
|
<span>终端</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="desktop-icon" data-app="browser">
|
|||
|
|
<i class="fas fa-globe"></i>
|
|||
|
|
<span>浏览器</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="desktop-icon" data-app="settings">
|
|||
|
|
<i class="fas fa-cog"></i>
|
|||
|
|
<span>设置中心</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="desktop-icon" data-app="music">
|
|||
|
|
<i class="fas fa-music"></i>
|
|||
|
|
<span>音乐播放器</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="desktop-icon" data-app="notes">
|
|||
|
|
<i class="fas fa-sticky-note"></i>
|
|||
|
|
<span>便签应用</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="desktop-icon" data-app="monitor">
|
|||
|
|
<i class="fas fa-chart-line"></i>
|
|||
|
|
<span>系统监控</span>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- 窗口容器 -->
|
|||
|
|
<div id="window-container"></div>
|
|||
|
|
|
|||
|
|
<!-- 通知容器 -->
|
|||
|
|
<div class="notification-container" id="notification-container"></div>
|
|||
|
|
|
|||
|
|
<!-- 右键菜单 -->
|
|||
|
|
<div class="context-menu" id="context-menu">
|
|||
|
|
<div class="context-item" id="context-refresh">
|
|||
|
|
<i class="fas fa-sync-alt"></i> 刷新
|
|||
|
|
</div>
|
|||
|
|
<div class="context-item" id="context-settings">
|
|||
|
|
<i class="fas fa-cog"></i> 系统设置
|
|||
|
|
</div>
|
|||
|
|
<div class="context-item" id="context-about">
|
|||
|
|
<i class="fas fa-info-circle"></i> 关于系统
|
|||
|
|
</div>
|
|||
|
|
<div class="context-divider" style="height: 1px; background: rgba(0, 255, 255, 0.2); margin: 5px 0;"></div>
|
|||
|
|
<div class="context-item" id="context-terminal">
|
|||
|
|
<i class="fas fa-terminal"></i> 打开终端
|
|||
|
|
</div>
|
|||
|
|
<div class="context-item" id="context-file-manager">
|
|||
|
|
<i class="fas fa-folder"></i> 文件管理器
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- 任务栏 -->
|
|||
|
|
<div id="taskbar">
|
|||
|
|
<div class="start-btn" id="start-btn">
|
|||
|
|
<i class="fas fa-bolt"></i>
|
|||
|
|
<span>NEO-OS</span>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="taskbar-apps" id="taskbar-apps">
|
|||
|
|
<!-- 动态添加应用 -->
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="system-tray">
|
|||
|
|
<div class="tray-icon">
|
|||
|
|
<i class="fas fa-volume-up"></i>
|
|||
|
|
</div>
|
|||
|
|
<div class="tray-icon">
|
|||
|
|
<i class="fas fa-wifi"></i>
|
|||
|
|
</div>
|
|||
|
|
<div class="tray-icon">
|
|||
|
|
<i class="fas fa-battery-three-quarters"></i>
|
|||
|
|
</div>
|
|||
|
|
<div class="clock" id="system-clock">00:00:00</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- 开始菜单 -->
|
|||
|
|
<div id="start-menu">
|
|||
|
|
<div class="start-header">
|
|||
|
|
<div class="start-user">
|
|||
|
|
<div class="user-avatar">
|
|||
|
|
<i class="fas fa-user"></i>
|
|||
|
|
</div>
|
|||
|
|
<div class="user-info">
|
|||
|
|
<h3>管理员</h3>
|
|||
|
|
<p>最后登录: 今天 08:30</p>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="start-apps" id="start-apps">
|
|||
|
|
<!-- 动态添加开始菜单应用 -->
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="start-footer">
|
|||
|
|
<div class="power-btn" id="power-btn">
|
|||
|
|
<i class="fas fa-power-off"></i>
|
|||
|
|
<span>关机</span>
|
|||
|
|
</div>
|
|||
|
|
<div style="display: flex; gap: 15px;">
|
|||
|
|
<div class="start-footer-item">
|
|||
|
|
<i class="fas fa-user"></i>
|
|||
|
|
</div>
|
|||
|
|
<div class="start-footer-item">
|
|||
|
|
<i class="fas fa-cog"></i>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
// NEO-OS 赛博朋克未来都市操作系统
|
|||
|
|
// 作者:全栈工程师AI
|
|||
|
|
// 版本:2.0.7
|
|||
|
|
// 日期:2077-01-01
|
|||
|
|
|
|||
|
|
// 系统状态变量
|
|||
|
|
const System = {
|
|||
|
|
apps: [],
|
|||
|
|
windows: [],
|
|||
|
|
activeWindow: null,
|
|||
|
|
desktopIcons: [],
|
|||
|
|
settings: {
|
|||
|
|
theme: 'cyberpunk',
|
|||
|
|
wallpaper: 'default',
|
|||
|
|
volume: 75,
|
|||
|
|
notifications: true,
|
|||
|
|
autosave: true
|
|||
|
|
},
|
|||
|
|
user: {
|
|||
|
|
name: 'Admin',
|
|||
|
|
avatar: 'default',
|
|||
|
|
lastLogin: new Date()
|
|||
|
|
},
|
|||
|
|
fs: {
|
|||
|
|
root: {
|
|||
|
|
name: '/',
|
|||
|
|
type: 'dir',
|
|||
|
|
children: [
|
|||
|
|
{ name: '文档', type: 'dir', children: [] },
|
|||
|
|
{ name: '下载', type: 'dir', children: [] },
|
|||
|
|
{ name: '音乐', type: 'dir', children: [] },
|
|||
|
|
{ name: '系统日志.txt', type: 'file', content: '系统启动成功\n用户: Admin\n时间: ' + new Date() },
|
|||
|
|
{ name: 'README.md', type: 'file', content: '# NEO-OS\n赛博朋克未来都市操作系统\n版本 2.0.7' }
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
current: 'root'
|
|||
|
|
},
|
|||
|
|
terminal: {
|
|||
|
|
history: [],
|
|||
|
|
currentDir: '/',
|
|||
|
|
commands: {}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 初始化系统
|
|||
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|||
|
|
// 模拟启动过程
|
|||
|
|
setTimeout(() => {
|
|||
|
|
document.getElementById('boot-screen').style.opacity = '0';
|
|||
|
|
setTimeout(() => {
|
|||
|
|
document.getElementById('boot-screen').style.display = 'none';
|
|||
|
|
document.getElementById('lock-screen').style.display = 'flex';
|
|||
|
|
|
|||
|
|
// 显示欢迎通知
|
|||
|
|
setTimeout(() => {
|
|||
|
|
showNotification('系统启动完成', '欢迎回来,管理员。NEO-OS v2.0.7 已就绪。', 'info');
|
|||
|
|
}, 1000);
|
|||
|
|
}, 500);
|
|||
|
|
}, 3500);
|
|||
|
|
|
|||
|
|
// 初始化时钟
|
|||
|
|
updateClocks();
|
|||
|
|
setInterval(updateClocks, 1000);
|
|||
|
|
|
|||
|
|
// 初始化系统监控数据
|
|||
|
|
updateSystemStats();
|
|||
|
|
setInterval(updateSystemStats, 3000);
|
|||
|
|
|
|||
|
|
// 初始化事件监听器
|
|||
|
|
initEventListeners();
|
|||
|
|
|
|||
|
|
// 初始化应用
|
|||
|
|
initApps();
|
|||
|
|
|
|||
|
|
// 初始化终端命令
|
|||
|
|
initTerminalCommands();
|
|||
|
|
|
|||
|
|
// 加载保存的设置
|
|||
|
|
loadSettings();
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 更新所有时钟
|
|||
|
|
function updateClocks() {
|
|||
|
|
const now = new Date();
|
|||
|
|
const timeStr = now.toLocaleTimeString('zh-CN', { hour12: false });
|
|||
|
|
const dateStr = now.toLocaleDateString('zh-CN', {
|
|||
|
|
year: 'numeric',
|
|||
|
|
month: 'long',
|
|||
|
|
day: 'numeric',
|
|||
|
|
weekday: 'long'
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 锁屏时钟
|
|||
|
|
document.getElementById('lock-time').textContent = timeStr;
|
|||
|
|
document.getElementById('lock-date').textContent = dateStr;
|
|||
|
|
|
|||
|
|
// 系统时钟
|
|||
|
|
document.getElementById('system-clock').textContent = timeStr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新系统监控数据
|
|||
|
|
function updateSystemStats() {
|
|||
|
|
// 模拟动态系统数据
|
|||
|
|
const cpuUsage = Math.floor(Math.random() * 30) + 20;
|
|||
|
|
const ramUsage = Math.floor(Math.random() * 40) + 40;
|
|||
|
|
const networkStatus = ['在线', '不稳定', '离线'][Math.floor(Math.random() * 3)];
|
|||
|
|
|
|||
|
|
document.getElementById('cpu-usage').textContent = cpuUsage + '%';
|
|||
|
|
document.getElementById('ram-usage').textContent = ramUsage + '%';
|
|||
|
|
document.getElementById('network-status').textContent = networkStatus;
|
|||
|
|
document.getElementById('network-status').style.color =
|
|||
|
|
networkStatus === '在线' ? 'var(--neon-green)' :
|
|||
|
|
networkStatus === '不稳定' ? 'var(--neon-blue)' : 'var(--neon-pink)';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 初始化事件监听器
|
|||
|
|
function initEventListeners() {
|
|||
|
|
// 解锁按钮
|
|||
|
|
document.getElementById('unlock-btn').addEventListener('click', unlockSystem);
|
|||
|
|
|
|||
|
|
// 开始菜单按钮
|
|||
|
|
document.getElementById('start-btn').addEventListener('click', toggleStartMenu);
|
|||
|
|
|
|||
|
|
// 关机按钮
|
|||
|
|
document.getElementById('power-btn').addEventListener('click', shutdownSystem);
|
|||
|
|
|
|||
|
|
// 桌面图标点击
|
|||
|
|
document.querySelectorAll('.desktop-icon').forEach(icon => {
|
|||
|
|
icon.addEventListener('click', function() {
|
|||
|
|
const appId = this.getAttribute('data-app');
|
|||
|
|
openApp(appId);
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 右键菜单
|
|||
|
|
document.addEventListener('contextmenu', function(e) {
|
|||
|
|
e.preventDefault();
|
|||
|
|
showContextMenu(e.clientX, e.clientY);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
document.addEventListener('click', function() {
|
|||
|
|
hideContextMenu();
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 右键菜单项
|
|||
|
|
document.getElementById('context-refresh').addEventListener('click', function() {
|
|||
|
|
showNotification('系统刷新', '桌面已刷新', 'info');
|
|||
|
|
hideContextMenu();
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
document.getElementById('context-settings').addEventListener('click', function() {
|
|||
|
|
openApp('settings');
|
|||
|
|
hideContextMenu();
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
document.getElementById('context-terminal').addEventListener('click', function() {
|
|||
|
|
openApp('terminal');
|
|||
|
|
hideContextMenu();
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 解锁系统
|
|||
|
|
function unlockSystem() {
|
|||
|
|
document.getElementById('lock-screen').style.opacity = '0';
|
|||
|
|
setTimeout(() => {
|
|||
|
|
document.getElementById('lock-screen').style.display = 'none';
|
|||
|
|
document.getElementById('desktop').style.display = 'block';
|
|||
|
|
showNotification('欢迎回来', '系统解锁成功,管理员。', 'success');
|
|||
|
|
}, 500);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 切换开始菜单
|
|||
|
|
function toggleStartMenu() {
|
|||
|
|
const startMenu = document.getElementById('start-menu');
|
|||
|
|
if (startMenu.style.display === 'flex') {
|
|||
|
|
startMenu.style.display = 'none';
|
|||
|
|
} else {
|
|||
|
|
startMenu.style.display = 'flex';
|
|||
|
|
startMenu.classList.add('slide-up');
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 关机系统
|
|||
|
|
function shutdownSystem() {
|
|||
|
|
showNotification('系统关机', '正在保存数据并关闭系统...', 'warning');
|
|||
|
|
setTimeout(() => {
|
|||
|
|
document.getElementById('start-menu').style.display = 'none';
|
|||
|
|
document.getElementById('desktop').style.opacity = '0';
|
|||
|
|
setTimeout(() => {
|
|||
|
|
document.getElementById('desktop').style.display = 'none';
|
|||
|
|
document.getElementById('lock-screen').style.display = 'flex';
|
|||
|
|
document.getElementById('lock-screen').style.opacity = '1';
|
|||
|
|
showNotification('系统已锁定', '请重新解锁以继续使用。', 'info');
|
|||
|
|
}, 500);
|
|||
|
|
}, 1500);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 显示右键菜单
|
|||
|
|
function showContextMenu(x, y) {
|
|||
|
|
const menu = document.getElementById('context-menu');
|
|||
|
|
menu.style.display = 'block';
|
|||
|
|
menu.style.left = x + 'px';
|
|||
|
|
menu.style.top = y + 'px';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 隐藏右键菜单
|
|||
|
|
function hideContextMenu() {
|
|||
|
|
document.getElementById('context-menu').style.display = 'none';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 显示通知
|
|||
|
|
function showNotification(title, message, type = 'info') {
|
|||
|
|
const container = document.getElementById('notification-container');
|
|||
|
|
const notification = document.createElement('div');
|
|||
|
|
notification.className = 'notification';
|
|||
|
|
|
|||
|
|
// 设置通知类型颜色
|
|||
|
|
let color = 'var(--neon-blue)';
|
|||
|
|
if (type === 'success') color = 'var(--neon-green)';
|
|||
|
|
if (type === 'warning') color = 'var(--neon-pink)';
|
|||
|
|
if (type === 'error') color = 'var(--neon-pink)';
|
|||
|
|
|
|||
|
|
notification.innerHTML = `
|
|||
|
|
<div class="notification-title">
|
|||
|
|
<span><i class="fas fa-${type === 'info' ? 'info-circle' : type === 'success' ? 'check-circle' : 'exclamation-triangle'}"></i> ${title}</span>
|
|||
|
|
<i class="fas fa-times close-notification" style="cursor: pointer;"></i>
|
|||
|
|
</div>
|
|||
|
|
<div class="notification-message">${message}</div>
|
|||
|
|
`;
|
|||
|
|
|
|||
|
|
notification.style.borderLeftColor = color;
|
|||
|
|
container.appendChild(notification);
|
|||
|
|
|
|||
|
|
// 显示通知
|
|||
|
|
setTimeout(() => {
|
|||
|
|
notification.classList.add('show');
|
|||
|
|
}, 10);
|
|||
|
|
|
|||
|
|
// 关闭通知按钮
|
|||
|
|
notification.querySelector('.close-notification').addEventListener('click', function() {
|
|||
|
|
notification.classList.remove('show');
|
|||
|
|
setTimeout(() => {
|
|||
|
|
container.removeChild(notification);
|
|||
|
|
}, 300);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 自动关闭通知(5秒后)
|
|||
|
|
setTimeout(() => {
|
|||
|
|
if (notification.parentNode) {
|
|||
|
|
notification.classList.remove('show');
|
|||
|
|
setTimeout(() => {
|
|||
|
|
if (notification.parentNode) {
|
|||
|
|
container.removeChild(notification);
|
|||
|
|
}
|
|||
|
|
}, 300);
|
|||
|
|
}
|
|||
|
|
}, 5000);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 初始化应用
|
|||
|
|
function initApps() {
|
|||
|
|
// 定义所有应用
|
|||
|
|
System.apps = [
|
|||
|
|
{
|
|||
|
|
id: 'files',
|
|||
|
|
name: '文件管理器',
|
|||
|
|
icon: 'fa-folder',
|
|||
|
|
component: createFileManager
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'terminal',
|
|||
|
|
name: '终端',
|
|||
|
|
icon: 'fa-terminal',
|
|||
|
|
component: createTerminal
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'browser',
|
|||
|
|
name: '浏览器',
|
|||
|
|
icon: 'fa-globe',
|
|||
|
|
component: createBrowser
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'settings',
|
|||
|
|
name: '设置中心',
|
|||
|
|
icon: 'fa-cog',
|
|||
|
|
component: createSettings
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'music',
|
|||
|
|
name: '音乐播放器',
|
|||
|
|
icon: 'fa-music',
|
|||
|
|
component: createMusicPlayer
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'notes',
|
|||
|
|
name: '便签应用',
|
|||
|
|
icon: 'fa-sticky-note',
|
|||
|
|
component: createNotes
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'monitor',
|
|||
|
|
name: '系统监控',
|
|||
|
|
icon: 'fa-chart-line',
|
|||
|
|
component: createSystemMonitor
|
|||
|
|
}
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
// 填充开始菜单
|
|||
|
|
const startAppsContainer = document.getElementById('start-apps');
|
|||
|
|
System.apps.forEach(app => {
|
|||
|
|
const appElement = document.createElement('div');
|
|||
|
|
appElement.className = 'start-app';
|
|||
|
|
appElement.setAttribute('data-app', app.id);
|
|||
|
|
appElement.innerHTML = `
|
|||
|
|
<i class="fas ${app.icon}"></i>
|
|||
|
|
<span>${app.name}</span>
|
|||
|
|
`;
|
|||
|
|
|
|||
|
|
appElement.addEventListener('click', function() {
|
|||
|
|
openApp(app.id);
|
|||
|
|
document.getElementById('start-menu').style.display = 'none';
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
startAppsContainer.appendChild(appElement);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 打开应用
|
|||
|
|
function openApp(appId, options = {}) {
|
|||
|
|
// 检查应用是否已经打开
|
|||
|
|
const existingWindow = System.windows.find(w => w.appId === appId);
|
|||
|
|
if (existingWindow) {
|
|||
|
|
focusWindow(existingWindow.id);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 查找应用定义
|
|||
|
|
const app = System.apps.find(a => a.id === appId);
|
|||
|
|
if (!app) {
|
|||
|
|
showNotification('错误', `应用 ${appId} 不存在`, 'error');
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 创建窗口ID
|
|||
|
|
const windowId = 'window-' + Date.now();
|
|||
|
|
|
|||
|
|
// 创建窗口
|
|||
|
|
const windowElement = document.createElement('div');
|
|||
|
|
windowElement.className = 'window fade-in';
|
|||
|
|
windowElement.id = windowId;
|
|||
|
|
|
|||
|
|
// 设置窗口位置(稍微偏移避免完全重叠)
|
|||
|
|
const offset = System.windows.length * 30;
|
|||
|
|
windowElement.style.left = 100 + offset + 'px';
|
|||
|
|
windowElement.style.top = 100 + offset + 'px';
|
|||
|
|
windowElement.style.width = '800px';
|
|||
|
|
windowElement.style.height = '500px';
|
|||
|
|
|
|||
|
|
// 创建窗口内容
|
|||
|
|
const appContent = app.component(windowId, app);
|
|||
|
|
windowElement.innerHTML = `
|
|||
|
|
<div class="window-header">
|
|||
|
|
<div class="window-title">
|
|||
|
|
<i class="fas ${app.icon}"></i>
|
|||
|
|
<span>${app.name}</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="window-controls">
|
|||
|
|
<div class="window-btn minimize-btn" data-action="minimize"></div>
|
|||
|
|
<div class="window-btn maximize-btn" data-action="maximize"></div>
|
|||
|
|
<div class="window-btn close-btn" data-action="close"></div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="window-content">
|
|||
|
|
${appContent}
|
|||
|
|
</div>
|
|||
|
|
`;
|
|||
|
|
|
|||
|
|
// 添加到DOM
|
|||
|
|
document.getElementById('window-container').appendChild(windowElement);
|
|||
|
|
|
|||
|
|
// 添加到任务栏
|
|||
|
|
addToTaskbar(windowId, app);
|
|||
|
|
|
|||
|
|
// 保存窗口引用
|
|||
|
|
const windowObj = {
|
|||
|
|
id: windowId,
|
|||
|
|
appId: appId,
|
|||
|
|
element: windowElement,
|
|||
|
|
minimized: false,
|
|||
|
|
maximized: false,
|
|||
|
|
zIndex: System.windows.length + 100
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
System.windows.push(windowObj);
|
|||
|
|
|
|||
|
|
// 聚焦窗口
|
|||
|
|
focusWindow(windowId);
|
|||
|
|
|
|||
|
|
// 初始化窗口交互
|
|||
|
|
initWindowInteractions(windowElement, windowId);
|
|||
|
|
|
|||
|
|
// 显示通知
|
|||
|
|
showNotification('应用已打开', `${app.name} 已启动`, 'success');
|
|||
|
|
|
|||
|
|
return windowId;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 初始化窗口交互
|
|||
|
|
function initWindowInteractions(windowElement, windowId) {
|
|||
|
|
// 窗口拖拽
|
|||
|
|
const header = windowElement.querySelector('.window-header');
|
|||
|
|
let isDragging = false;
|
|||
|
|
let offsetX, offsetY;
|
|||
|
|
|
|||
|
|
header.addEventListener('mousedown', function(e) {
|
|||
|
|
isDragging = true;
|
|||
|
|
offsetX = e.clientX - windowElement.offsetLeft;
|
|||
|
|
offsetY = e.clientY - windowElement.offsetTop;
|
|||
|
|
focusWindow(windowId);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
document.addEventListener('mousemove', function(e) {
|
|||
|
|
if (!isDragging) return;
|
|||
|
|
|
|||
|
|
windowElement.style.left = (e.clientX - offsetX) + 'px';
|
|||
|
|
windowElement.style.top = (e.clientY - offsetY) + 'px';
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
document.addEventListener('mouseup', function() {
|
|||
|
|
isDragging = false;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 窗口控制按钮
|
|||
|
|
windowElement.querySelectorAll('.window-btn').forEach(btn => {
|
|||
|
|
btn.addEventListener('click', function() {
|
|||
|
|
const action = this.getAttribute('data-action');
|
|||
|
|
switch(action) {
|
|||
|
|
case 'minimize':
|
|||
|
|
minimizeWindow(windowId);
|
|||
|
|
break;
|
|||
|
|
case 'maximize':
|
|||
|
|
toggleMaximizeWindow(windowId);
|
|||
|
|
break;
|
|||
|
|
case 'close':
|
|||
|
|
closeWindow(windowId);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 窗口调整大小(简化版本)
|
|||
|
|
windowElement.addEventListener('mousedown', function(e) {
|
|||
|
|
if (e.target !== windowElement) return;
|
|||
|
|
|
|||
|
|
const startX = e.clientX;
|
|||
|
|
const startY = e.clientY;
|
|||
|
|
const startWidth = windowElement.offsetWidth;
|
|||
|
|
const startHeight = windowElement.offsetHeight;
|
|||
|
|
const startLeft = windowElement.offsetLeft;
|
|||
|
|
const startTop = windowElement.offsetTop;
|
|||
|
|
|
|||
|
|
function onMouseMove(e) {
|
|||
|
|
const newWidth = startWidth + (e.clientX - startX);
|
|||
|
|
const newHeight = startHeight + (e.clientY - startY);
|
|||
|
|
|
|||
|
|
if (newWidth > 300) windowElement.style.width = newWidth + 'px';
|
|||
|
|
if (newHeight > 200) windowElement.style.height = newHeight + 'px';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function onMouseUp() {
|
|||
|
|
document.removeEventListener('mousemove', onMouseMove);
|
|||
|
|
document.removeEventListener('mouseup', onMouseUp);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
document.addEventListener('mousemove', onMouseMove);
|
|||
|
|
document.addEventListener('mouseup', onMouseUp);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 聚焦窗口
|
|||
|
|
function focusWindow(windowId) {
|
|||
|
|
// 更新所有窗口的z-index
|
|||
|
|
System.windows.forEach((win, index) => {
|
|||
|
|
win.zIndex = index + 100;
|
|||
|
|
win.element.style.zIndex = win.zIndex;
|
|||
|
|
win.element.classList.remove('active');
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 将目标窗口置顶
|
|||
|
|
const windowObj = System.windows.find(w => w.id === windowId);
|
|||
|
|
if (windowObj) {
|
|||
|
|
windowObj.zIndex = System.windows.length + 200;
|
|||
|
|
windowObj.element.style.zIndex = windowObj.zIndex;
|
|||
|
|
windowObj.element.classList.add('active');
|
|||
|
|
System.activeWindow = windowObj;
|
|||
|
|
|
|||
|
|
// 更新任务栏
|
|||
|
|
document.querySelectorAll('.taskbar-app').forEach(app => {
|
|||
|
|
app.classList.remove('active');
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const taskbarApp = document.querySelector(`.taskbar-app[data-window="${windowId}"]`);
|
|||
|
|
if (taskbarApp) taskbarApp.classList.add('active');
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 最小化窗口
|
|||
|
|
function minimizeWindow(windowId) {
|
|||
|
|
const windowObj = System.windows.find(w => w.id === windowId);
|
|||
|
|
if (windowObj) {
|
|||
|
|
windowObj.element.style.display = 'none';
|
|||
|
|
windowObj.minimized = true;
|
|||
|
|
|
|||
|
|
// 更新任务栏
|
|||
|
|
const taskbarApp = document.querySelector(`.taskbar-app[data-window="${windowId}"]`);
|
|||
|
|
if (taskbarApp) taskbarApp.classList.add('minimized');
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 最大化窗口
|
|||
|
|
function toggleMaximizeWindow(windowId) {
|
|||
|
|
const windowObj = System.windows.find(w => w.id === windowId);
|
|||
|
|
if (windowObj) {
|
|||
|
|
if (windowObj.maximized) {
|
|||
|
|
// 恢复窗口大小
|
|||
|
|
windowObj.element.style.width = '800px';
|
|||
|
|
windowObj.element.style.height = '500px';
|
|||
|
|
windowObj.element.style.left = '100px';
|
|||
|
|
windowObj.element.style.top = '100px';
|
|||
|
|
windowObj.maximized = false;
|
|||
|
|
} else {
|
|||
|
|
// 最大化窗口
|
|||
|
|
windowObj.element.style.width = 'calc(100% - 40px)';
|
|||
|
|
windowObj.element.style.height = 'calc(100% - 90px)';
|
|||
|
|
windowObj.element.style.left = '20px';
|
|||
|
|
windowObj.element.style.top = '20px';
|
|||
|
|
windowObj.maximized = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 关闭窗口
|
|||
|
|
function closeWindow(windowId) {
|
|||
|
|
const windowObj = System.windows.find(w => w.id === windowId);
|
|||
|
|
if (windowObj) {
|
|||
|
|
// 从DOM中移除
|
|||
|
|
windowObj.element.remove();
|
|||
|
|
|
|||
|
|
// 从任务栏移除
|
|||
|
|
removeFromTaskbar(windowId);
|
|||
|
|
|
|||
|
|
// 从窗口列表中移除
|
|||
|
|
System.windows = System.windows.filter(w => w.id !== windowId);
|
|||
|
|
|
|||
|
|
// 如果关闭的是活动窗口,激活下一个窗口
|
|||
|
|
if (System.activeWindow && System.activeWindow.id === windowId) {
|
|||
|
|
if (System.windows.length > 0) {
|
|||
|
|
focusWindow(System.windows[System.windows.length - 1].id);
|
|||
|
|
} else {
|
|||
|
|
System.activeWindow = null;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
showNotification('窗口已关闭', '应用窗口已关闭', 'info');
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 添加到任务栏
|
|||
|
|
function addToTaskbar(windowId, app) {
|
|||
|
|
const taskbarApps = document.getElementById('taskbar-apps');
|
|||
|
|
const appElement = document.createElement('div');
|
|||
|
|
appElement.className = 'taskbar-app';
|
|||
|
|
appElement.setAttribute('data-window', windowId);
|
|||
|
|
appElement.innerHTML = `
|
|||
|
|
<i class="fas ${app.icon}"></i>
|
|||
|
|
<span>${app.name}</span>
|
|||
|
|
`;
|
|||
|
|
|
|||
|
|
appElement.addEventListener('click', function() {
|
|||
|
|
const windowObj = System.windows.find(w => w.id === windowId);
|
|||
|
|
if (windowObj) {
|
|||
|
|
if (windowObj.minimized) {
|
|||
|
|
// 如果窗口已最小化,则恢复
|
|||
|
|
windowObj.element.style.display = 'flex';
|
|||
|
|
windowObj.minimized = false;
|
|||
|
|
this.classList.remove('minimized');
|
|||
|
|
}
|
|||
|
|
focusWindow(windowId);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
taskbarApps.appendChild(appElement);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 从任务栏移除
|
|||
|
|
function removeFromTaskbar(windowId) {
|
|||
|
|
const taskbarApp = document.querySelector(`.taskbar-app[data-window="${windowId}"]`);
|
|||
|
|
if (taskbarApp) {
|
|||
|
|
taskbarApp.remove();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 初始化终端命令
|
|||
|
|
function initTerminalCommands() {
|
|||
|
|
System.terminal.commands = {
|
|||
|
|
help: {
|
|||
|
|
desc: '显示帮助信息',
|
|||
|
|
execute: function(args) {
|
|||
|
|
return `
|
|||
|
|
<div class="terminal-line">NEO-OS 终端命令列表:</div>
|
|||
|
|
<div class="terminal-line">help - 显示帮助信息</div>
|
|||
|
|
<div class="terminal-line">clear - 清屏</div>
|
|||
|
|
<div class="terminal-line">date - 显示当前日期时间</div>
|
|||
|
|
<div class="terminal-line">whoami - 显示当前用户</div>
|
|||
|
|
<div class="terminal-line">ls/dir - 列出文件</div>
|
|||
|
|
<div class="terminal-line">cd - 切换目录</div>
|
|||
|
|
<div class="terminal-line">cat/type - 查看文件内容</div>
|
|||
|
|
<div class="terminal-line">echo - 输出文本</div>
|
|||
|
|
<div class="terminal-line">neofetch - 显示系统信息</div>
|
|||
|
|
<div class="terminal-line">matrix - 启动矩阵雨特效</div>
|
|||
|
|
<div class="terminal-line">theme - 切换系统主题</div>
|
|||
|
|
<div class="terminal-line">reboot - 重启系统(刷新页面)</div>
|
|||
|
|
`;
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
clear: {
|
|||
|
|
desc: '清屏',
|
|||
|
|
execute: function(args) {
|
|||
|
|
const terminalBody = document.querySelector(`#${System.terminal.currentWindowId} .terminal-body`);
|
|||
|
|
terminalBody.innerHTML = '';
|
|||
|
|
return '';
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
date: {
|
|||
|
|
desc: '显示当前日期时间',
|
|||
|
|
execute: function(args) {
|
|||
|
|
return new Date().toLocaleString('zh-CN');
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
whoami: {
|
|||
|
|
desc: '显示当前用户',
|
|||
|
|
execute: function(args) {
|
|||
|
|
return System.user.name;
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
ls: {
|
|||
|
|
desc: '列出文件',
|
|||
|
|
execute: function(args) {
|
|||
|
|
let output = '';
|
|||
|
|
const dir = getCurrentDir();
|
|||
|
|
dir.children.forEach(item => {
|
|||
|
|
output += `<div class="terminal-line">${item.type === 'dir' ? '📁' : '📄'} ${item.name}</div>`;
|
|||
|
|
});
|
|||
|
|
return output || '目录为空';
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
dir: {
|
|||
|
|
desc: '列出文件 (同 ls)',
|
|||
|
|
execute: function(args) {
|
|||
|
|
return System.terminal.commands.ls.execute(args);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
cd: {
|
|||
|
|
desc: '切换目录',
|
|||
|
|
execute: function(args) {
|
|||
|
|
if (!args[0]) return '用法: cd [目录名]';
|
|||
|
|
if (args[0] === '..') {
|
|||
|
|
System.terminal.currentDir = '/';
|
|||
|
|
return '已切换到根目录';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const dir = getCurrentDir();
|
|||
|
|
const target = dir.children.find(item => item.name === args[0] && item.type === 'dir');
|
|||
|
|
if (target) {
|
|||
|
|
System.terminal.currentDir = args[0];
|
|||
|
|
return `已切换到目录: ${args[0]}`;
|
|||
|
|
} else {
|
|||
|
|
return `目录不存在: ${args[0]}`;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
cat: {
|
|||
|
|
desc: '查看文件内容',
|
|||
|
|
execute: function(args) {
|
|||
|
|
if (!args[0]) return '用法: cat [文件名]';
|
|||
|
|
|
|||
|
|
const dir = getCurrentDir();
|
|||
|
|
const file = dir.children.find(item => item.name === args[0] && item.type === 'file');
|
|||
|
|
if (file) {
|
|||
|
|
return file.content;
|
|||
|
|
} else {
|
|||
|
|
return `文件不存在: ${args[0]}`;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
echo: {
|
|||
|
|
desc: '输出文本',
|
|||
|
|
execute: function(args) {
|
|||
|
|
return args.join(' ');
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
neofetch: {
|
|||
|
|
desc: '显示系统信息',
|
|||
|
|
execute: function(args) {
|
|||
|
|
return `
|
|||
|
|
<div class="terminal-line">
|
|||
|
|
<pre style="color: var(--neon-blue);">
|
|||
|
|
_ __ _______ ____ _____
|
|||
|
|
/ | / / / ____/ | / / / / ___/
|
|||
|
|
/ |/ / / __/ | | / / / \__ \
|
|||
|
|
/ /| / / /___ | |/ / /___ ___/ /
|
|||
|
|
/_/ |_/ /_____/ |___/_____//____/
|
|||
|
|
</pre>
|
|||
|
|
</div>
|
|||
|
|
<div class="terminal-line">OS: NEO-OS v2.0.7</div>
|
|||
|
|
<div class="terminal-line">主机: CyberPunk-2077</div>
|
|||
|
|
<div class="terminal-line">内核: 5.15.0-neo</div>
|
|||
|
|
<div class="terminal-line">用户: ${System.user.name}</div>
|
|||
|
|
<div class="terminal-line">终端: neo-terminal</div>
|
|||
|
|
<div class="terminal-line">主题: 赛博朋克</div>
|
|||
|
|
`;
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
matrix: {
|
|||
|
|
desc: '启动矩阵雨特效',
|
|||
|
|
execute: function(args) {
|
|||
|
|
startMatrixEffect();
|
|||
|
|
return '矩阵雨特效已启动 (按ESC退出)';
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
theme: {
|
|||
|
|
desc: '切换系统主题',
|
|||
|
|
execute: function(args) {
|
|||
|
|
const themes = ['cyberpunk', 'dark', 'light', 'neon'];
|
|||
|
|
const currentIndex = themes.indexOf(System.settings.theme);
|
|||
|
|
const nextIndex = (currentIndex + 1) % themes.length;
|
|||
|
|
System.settings.theme = themes[nextIndex];
|
|||
|
|
saveSettings();
|
|||
|
|
return `主题已切换为: ${themes[nextIndex]}`;
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
reboot: {
|
|||
|
|
desc: '重启系统(刷新页面)',
|
|||
|
|
execute: function(args) {
|
|||
|
|
setTimeout(() => {
|
|||
|
|
window.location.reload();
|
|||
|
|
}, 1000);
|
|||
|
|
return '系统重启中...';
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取当前目录
|
|||
|
|
function getCurrentDir() {
|
|||
|
|
if (System.terminal.currentDir === '/') {
|
|||
|
|
return System.fs.root;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return System.fs.root.children.find(item => item.name === System.terminal.currentDir && item.type === 'dir') || System.fs.root;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 应用组件创建函数
|
|||
|
|
function createFileManager(windowId, app) {
|
|||
|
|
System.terminal.currentWindowId = windowId;
|
|||
|
|
return `
|
|||
|
|
<div class="app-content">
|
|||
|
|
<div class="file-explorer">
|
|||
|
|
<div class="file-sidebar">
|
|||
|
|
<div style="padding: 0 15px 15px; color: var(--neon-blue); font-weight: 600; border-bottom: 1px solid rgba(0, 255, 255, 0.2); margin-bottom: 15px;">
|
|||
|
|
<i class="fas fa-folder"></i> 位置
|
|||
|
|
</div>
|
|||
|
|
<div class="sidebar-item" style="padding: 10px 15px; cursor: pointer; border-radius: 5px; margin: 5px; transition: var(--transition-smooth);">
|
|||
|
|
<i class="fas fa-home"></i> 主目录
|
|||
|
|
</div>
|
|||
|
|
<div class="sidebar-item" style="padding: 10px 15px; cursor: pointer; border-radius: 5px; margin: 5px; transition: var(--transition-smooth);">
|
|||
|
|
<i class="fas fa-download"></i> 下载
|
|||
|
|
</div>
|
|||
|
|
<div class="sidebar-item" style="padding: 10px 15px; cursor: pointer; border-radius: 5px; margin: 5px; transition: var(--transition-smooth);">
|
|||
|
|
<i class="fas fa-music"></i> 音乐
|
|||
|
|
</div>
|
|||
|
|
<div class="sidebar-item" style="padding: 10px 15px; cursor: pointer; border-radius: 5px; margin: 5px; transition: var(--transition-smooth);">
|
|||
|
|
<i class="fas fa-image"></i> 图片
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="file-list">
|
|||
|
|
${System.fs.root.children.map(item => `
|
|||
|
|
<div class="file-item">
|
|||
|
|
<i class="fas ${item.type === 'dir' ? 'fa-folder' : 'fa-file'}"></i>
|
|||
|
|
<span>${item.name}</span>
|
|||
|
|
</div>
|
|||
|
|
`).join('')}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function createTerminal(windowId, app) {
|
|||
|
|
System.terminal.currentWindowId = windowId;
|
|||
|
|
return `
|
|||
|
|
<div class="app-content">
|
|||
|
|
<div class="terminal-header">
|
|||
|
|
<i class="fas fa-terminal"></i> NEO-OS 终端模拟器
|
|||
|
|
</div>
|
|||
|
|
<div class="terminal-body" id="terminal-body-${windowId}">
|
|||
|
|
<div class="terminal-line">
|
|||
|
|
<span class="terminal-prompt">${System.user.name}@neo-os:~$</span>
|
|||
|
|
<span>欢迎使用 NEO-OS 终端</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="terminal-line">
|
|||
|
|
<span class="terminal-prompt">${System.user.name}@neo-os:~$</span>
|
|||
|
|
<span>输入 'help' 查看可用命令</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="terminal-line" id="terminal-input-line-${windowId}">
|
|||
|
|
<span class="terminal-prompt">${System.user.name}@neo-os:~$</span>
|
|||
|
|
<input type="text" class="terminal-input" id="terminal-input-${windowId}" autocomplete="off" spellcheck="false">
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function createBrowser(windowId, app) {
|
|||
|
|
return `
|
|||
|
|
<div class="app-content">
|
|||
|
|
<div class="browser-nav">
|
|||
|
|
<button style="background: rgba(0, 255, 255, 0.1); border: none; color: var(--neon-blue); padding: 8px 15px; border-radius: 5px; cursor: pointer;">
|
|||
|
|
<i class="fas fa-arrow-left"></i>
|
|||
|
|
</button>
|
|||
|
|
<button style="background: rgba(0, 255, 255, 0.1); border: none; color: var(--neon-blue); padding: 8px 15px; border-radius: 5px; cursor: pointer;">
|
|||
|
|
<i class="fas fa-arrow-right"></i>
|
|||
|
|
</button>
|
|||
|
|
<button style="background: rgba(0, 255, 255, 0.1); border: none; color: var(--neon-blue); padding: 8px 15px; border-radius: 5px; cursor: pointer;">
|
|||
|
|
<i class="fas fa-redo"></i>
|
|||
|
|
</button>
|
|||
|
|
<input type="text" class="browser-url" value="https://neo-os.cyberpunk/home" id="browser-url-${windowId}">
|
|||
|
|
<button style="background: linear-gradient(90deg, var(--neon-pink), var(--neon-blue)); border: none; color: white; padding: 8px 20px; border-radius: 5px; cursor: pointer; font-weight: 600;">
|
|||
|
|
前往
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
<div style="flex: 1; padding: 15px; display: flex; flex-direction: column; align-items: center; justify-content: center; background: rgba(0, 0, 0, 0.5);">
|
|||
|
|
<i class="fas fa-globe-americas" style="font-size: 4rem; color: var(--neon-blue); margin-bottom: 20px;"></i>
|
|||
|
|
<h2 style="color: var(--neon-blue); margin-bottom: 10px;">NEO-OS 浏览器</h2>
|
|||
|
|
<p style="color: var(--text-secondary); text-align: center; max-width: 500px;">
|
|||
|
|
这是一个模拟的浏览器应用。在实际系统中,这里将显示网页内容。
|
|||
|
|
输入URL并点击"前往"按钮以加载网页。
|
|||
|
|
</p>
|
|||
|
|
<div style="margin-top: 30px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px;">
|
|||
|
|
<div style="background: rgba(0, 255, 255, 0.1); padding: 15px; border-radius: 10px; text-align: center;">
|
|||
|
|
<i class="fas fa-newspaper" style="font-size: 2rem; color: var(--neon-green); margin-bottom: 10px;"></i>
|
|||
|
|
<div>新闻门户</div>
|
|||
|
|
</div>
|
|||
|
|
<div style="background: rgba(0, 255, 255, 0.1); padding: 15px; border-radius: 10px; text-align: center;">
|
|||
|
|
<i class="fas fa-video" style="font-size: 2rem; color: var(--neon-pink); margin-bottom: 10px;"></i>
|
|||
|
|
<div>媒体中心</div>
|
|||
|
|
</div>
|
|||
|
|
<div style="background: rgba(0, 255, 255, 0.1); padding: 15px; border-radius: 10px; text-align: center;">
|
|||
|
|
<i class="fas fa-cloud" style="font-size: 2rem; color: var(--neon-blue); margin-bottom: 10px;"></i>
|
|||
|
|
<div>云端服务</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function createSettings(windowId, app) {
|
|||
|
|
return `
|
|||
|
|
<div class="app-content">
|
|||
|
|
<div class="settings-tabs">
|
|||
|
|
<div class="settings-tab active" data-tab="theme">主题</div>
|
|||
|
|
<div class="settings-tab" data-tab="display">显示</div>
|
|||
|
|
<div class="settings-tab" data-tab="sound">声音</div>
|
|||
|
|
<div class="settings-tab" data-tab="privacy">隐私</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="settings-content">
|
|||
|
|
<div class="setting-item">
|
|||
|
|
<h3 style="color: var(--neon-blue); margin-bottom: 10px;">主题设置</h3>
|
|||
|
|
<div style="display: flex; gap: 15px; margin-bottom: 20px;">
|
|||
|
|
<div style="width: 100px; height: 60px; background: linear-gradient(45deg, #0a0a16, #1a1a2e); border-radius: 8px; border: 2px solid var(--neon-blue); cursor: pointer; display: flex; align-items: center; justify-content: center;">
|
|||
|
|
赛博朋克
|
|||
|
|
</div>
|
|||
|
|
<div style="width: 100px; height: 60px; background: linear-gradient(45deg, #111, #222); border-radius: 8px; border: 2px solid rgba(255, 255, 255, 0.2); cursor: pointer; display: flex; align-items: center; justify-content: center;">
|
|||
|
|
深色
|
|||
|
|
</div>
|
|||
|
|
<div style="width: 100px; height: 60px; background: linear-gradient(45deg, #fff, #f0f0f0); border-radius: 8px; border: 2px solid rgba(0, 0, 0, 0.2); cursor: pointer; display: flex; align-items: center; justify-content: center; color: #333;">
|
|||
|
|
浅色
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="setting-item">
|
|||
|
|
<h3 style="color: var(--neon-blue); margin-bottom: 10px;">壁纸设置</h3>
|
|||
|
|
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px; margin-bottom: 20px;">
|
|||
|
|
<div style="height: 80px; background: linear-gradient(45deg, #050510, #151530); border-radius: 8px; border: 2px solid var(--neon-blue); cursor: pointer;"></div>
|
|||
|
|
<div style="height: 80px; background: linear-gradient(45deg, #1a0a2e, #3a1a5e); border-radius: 8px; border: 2px solid rgba(255, 255, 255, 0.2); cursor: pointer;"></div>
|
|||
|
|
<div style="height: 80px; background: linear-gradient(45deg, #0a2e1a, #1a5e3a); border-radius: 8px; border: 2px solid rgba(255, 255, 255, 0.2); cursor: pointer;"></div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="setting-item">
|
|||
|
|
<h3 style="color: var(--neon-blue); margin-bottom: 10px;">音量控制</h3>
|
|||
|
|
<div style="display: flex; align-items: center; gap: 15px;">
|
|||
|
|
<i class="fas fa-volume-down" style="color: var(--neon-green);"></i>
|
|||
|
|
<input type="range" min="0" max="100" value="75" style="flex: 1; height: 8px; background: rgba(0, 255, 255, 0.2); border-radius: 4px; outline: none;">
|
|||
|
|
<i class="fas fa-volume-up" style="color: var(--neon-green);"></i>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div style="margin-top: 30px; display: flex; justify-content: flex-end;">
|
|||
|
|
<button style="background: linear-gradient(90deg, var(--neon-pink), var(--neon-blue)); border: none; color: white; padding: 10px 30px; border-radius: 8px; cursor: pointer; font-weight: 600;">
|
|||
|
|
保存设置
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function createMusicPlayer(windowId, app) {
|
|||
|
|
return `
|
|||
|
|
<div class="app-content">
|
|||
|
|
<div style="display: flex; height: 100%;">
|
|||
|
|
<div style="width: 300px; border-right: 1px solid rgba(0, 255, 255, 0.2); padding: 20px;">
|
|||
|
|
<h3 style="color: var(--neon-blue); margin-bottom: 15px;">播放列表</h3>
|
|||
|
|
<div style="display: flex; flex-direction: column; gap: 10px;">
|
|||
|
|
<div style="padding: 10px; background: rgba(0, 255, 255, 0.1); border-radius: 8px; cursor: pointer;">
|
|||
|
|
<div style="font-weight: 600; color: var(--neon-green);">Cyberpunk 2077 OST</div>
|
|||
|
|
<div style="font-size: 0.9rem; color: var(--text-secondary);">Samurai</div>
|
|||
|
|
</div>
|
|||
|
|
<div style="padding: 10px; background: rgba(0, 0, 0, 0.3); border-radius: 8px; cursor: pointer;">
|
|||
|
|
<div style="font-weight: 600;">Neon Dreams</div>
|
|||
|
|
<div style="font-size: 0.9rem; color: var(--text-secondary);">Synthwave</div>
|
|||
|
|
</div>
|
|||
|
|
<div style="padding: 10px; background: rgba(0, 0, 0, 0.3); border-radius: 8px; cursor: pointer;">
|
|||
|
|
<div style="font-weight: 600;">Digital Rain</div>
|
|||
|
|
<div style="font-size: 0.9rem; color: var(--text-secondary);">Ambient</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div style="flex: 1; padding: 20px; display: flex; flex-direction: column; align-items: center; justify-content: center;">
|
|||
|
|
<div style="width: 200px; height: 200px; background: linear-gradient(45deg, var(--neon-pink), var(--neon-blue)); border-radius: 10px; margin-bottom: 30px; display: flex; align-items: center; justify-content: center; font-size: 4rem;">
|
|||
|
|
<i class="fas fa-music"></i>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<h2 style="color: var(--neon-blue); margin-bottom: 10px;">Cyberpunk 2077 OST</h2>
|
|||
|
|
<p style="color: var(--text-secondary); margin-bottom: 30px;">Samurai • 播放中</p>
|
|||
|
|
|
|||
|
|
<div style="width: 100%; max-width: 500px;">
|
|||
|
|
<div style="height: 6px; background: rgba(0, 255, 255, 0.2); border-radius: 3px; margin-bottom: 10px; overflow: hidden;">
|
|||
|
|
<div style="width: 45%; height: 100%; background: linear-gradient(90deg, var(--neon-pink), var(--neon-blue));"></div>
|
|||
|
|
</div>
|
|||
|
|
<div style="display: flex; justify-content: space-between; margin-bottom: 30px;">
|
|||
|
|
<span>1:30</span>
|
|||
|
|
<span>3:45</span>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="player-controls">
|
|||
|
|
<div class="player-btn">
|
|||
|
|
<i class="fas fa-step-backward"></i>
|
|||
|
|
</div>
|
|||
|
|
<div class="player-btn" style="width: 60px; height: 60px;">
|
|||
|
|
<i class="fas fa-play"></i>
|
|||
|
|
</div>
|
|||
|
|
<div class="player-btn">
|
|||
|
|
<i class="fas fa-step-forward"></i>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function createNotes(windowId, app) {
|
|||
|
|
return `
|
|||
|
|
<div class="app-content">
|
|||
|
|
<div style="display: flex; height: 100%;">
|
|||
|
|
<div style="width: 250px; border-right: 1px solid rgba(0, 255, 255, 0.2); padding: 20px;">
|
|||
|
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
|
|||
|
|
<h3 style="color: var(--neon-blue);">笔记</h3>
|
|||
|
|
<button style="background: rgba(0, 255, 255, 0.1); border: none; color: var(--neon-blue); padding: 8px 15px; border-radius: 5px; cursor: pointer;">
|
|||
|
|
<i class="fas fa-plus"></i>
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div style="display: flex; flex-direction: column; gap: 10px;">
|
|||
|
|
<div style="padding: 10px; background: rgba(0, 255, 255, 0.1); border-radius: 8px; cursor: pointer;">
|
|||
|
|
<div style="font-weight: 600; color: var(--neon-green);">系统备忘录</div>
|
|||
|
|
<div style="font-size: 0.8rem; color: var(--text-secondary);">今天 10:30</div>
|
|||
|
|
</div>
|
|||
|
|
<div style="padding: 10px; background: rgba(0, 0, 0, 0.3); border-radius: 8px; cursor: pointer;">
|
|||
|
|
<div style="font-weight: 600;">项目计划</div>
|
|||
|
|
<div style="font-size: 0.8rem; color: var(--text-secondary);">昨天 16:45</div>
|
|||
|
|
</div>
|
|||
|
|
<div style="padding: 10px; background: rgba(0, 0, 0, 0.3); border-radius: 8px; cursor: pointer;">
|
|||
|
|
<div style="font-weight: 600;">会议记录</div>
|
|||
|
|
<div style="font-size: 0.8rem; color: var(--text-secondary);">2023-12-20</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div style="flex: 1; padding: 20px; display: flex; flex-direction: column;">
|
|||
|
|
<div style="display: flex; align-items: center; gap: 15px; margin-bottom: 20px;">
|
|||
|
|
<input type="text" value="系统备忘录" style="flex: 1; background: transparent; border: none; color: var(--neon-blue); font-size: 1.5rem; font-weight: 600; outline: none;">
|
|||
|
|
<button style="background: linear-gradient(90deg, var(--neon-pink), var(--neon-blue)); border: none; color: white; padding: 8px 20px; border-radius: 5px; cursor: pointer; font-weight: 600;">
|
|||
|
|
保存
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<textarea style="flex: 1; background: transparent; border: 1px solid rgba(0, 255, 255, 0.2); border-radius: 8px; padding: 15px; color: var(--text-primary); font-family: 'Rajdhani', sans-serif; font-size: 1rem; outline: none; resize: none;">
|
|||
|
|
# 系统备忘录
|
|||
|
|
## NEO-OS v2.0.7
|
|||
|
|
|
|||
|
|
### 已完成功能
|
|||
|
|
- [x] 窗口管理系统
|
|||
|
|
- [x] 任务栏和开始菜单
|
|||
|
|
- [x] 终端模拟器
|
|||
|
|
- [x] 文件管理器
|
|||
|
|
- [x] 设置中心
|
|||
|
|
- [x] 音乐播放器
|
|||
|
|
- [x] 便签应用
|
|||
|
|
- [x] 系统监控
|
|||
|
|
|
|||
|
|
### 待办事项
|
|||
|
|
- [ ] 优化移动端触控
|
|||
|
|
- [ ] 添加更多应用
|
|||
|
|
- [ ] 完善文件系统
|
|||
|
|
- [ ] 添加多用户支持
|
|||
|
|
|
|||
|
|
### 系统信息
|
|||
|
|
- 版本: 2.0.7
|
|||
|
|
- 构建日期: 2077-01-01
|
|||
|
|
- 用户: Admin
|
|||
|
|
- 状态: 运行正常
|
|||
|
|
</textarea>
|
|||
|
|
|
|||
|
|
<div style="display: flex; gap: 10px; margin-top: 15px;">
|
|||
|
|
<button style="background: rgba(0, 255, 255, 0.1); border: none; color: var(--neon-blue); padding: 8px 15px; border-radius: 5px; cursor: pointer;">
|
|||
|
|
<i class="fas fa-bold"></i>
|
|||
|
|
</button>
|
|||
|
|
<button style="background: rgba(0, 255, 255, 0.1); border: none; color: var(--neon-blue); padding: 8px 15px; border-radius: 5px; cursor: pointer;">
|
|||
|
|
<i class="fas fa-italic"></i>
|
|||
|
|
</button>
|
|||
|
|
<button style="background: rgba(0, 255, 255, 0.1); border: none; color: var(--neon-blue); padding: 8px 15px; border-radius: 5px; cursor: pointer;">
|
|||
|
|
<i class="fas fa-list-ul"></i>
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function createSystemMonitor(windowId, app) {
|
|||
|
|
return `
|
|||
|
|
<div class="app-content">
|
|||
|
|
<div style="padding: 20px; height: 100%; display: flex; flex-direction: column;">
|
|||
|
|
<h2 style="color: var(--neon-blue); margin-bottom: 20px; display: flex; align-items: center; gap: 10px;">
|
|||
|
|
<i class="fas fa-chart-line"></i> 系统监控面板
|
|||
|
|
</h2>
|
|||
|
|
|
|||
|
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; flex: 1;">
|
|||
|
|
<div style="background: rgba(10, 10, 30, 0.5); border-radius: 10px; padding: 20px; border: 1px solid rgba(0, 255, 255, 0.2);">
|
|||
|
|
<h3 style="color: var(--neon-green); margin-bottom: 15px;">CPU 使用率</h3>
|
|||
|
|
<canvas id="cpu-chart-${windowId}" style="width: 100%; height: 200px;"></canvas>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div style="background: rgba(10, 10, 30, 0.5); border-radius: 10px; padding: 20px; border: 1px solid rgba(0, 255, 255, 0.2);">
|
|||
|
|
<h3 style="color: var(--neon-pink); margin-bottom: 15px;">内存使用率</h3>
|
|||
|
|
<canvas id="ram-chart-${windowId}" style="width: 100%; height: 200px;"></canvas>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div style="background: rgba(10, 10, 30, 0.5); border-radius: 10px; padding: 20px; border: 1px solid rgba(0, 255, 255, 0.2); grid-column: span 2;">
|
|||
|
|
<h3 style="color: var(--neon-blue); margin-bottom: 15px;">系统状态</h3>
|
|||
|
|
<div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 15px;">
|
|||
|
|
<div style="background: rgba(0, 255, 255, 0.1); padding: 15px; border-radius: 8px;">
|
|||
|
|
<div style="font-size: 0.9rem; color: var(--text-secondary); margin-bottom: 5px;">CPU温度</div>
|
|||
|
|
<div style="font-size: 1.5rem; color: var(--neon-green);">42°C</div>
|
|||
|
|
</div>
|
|||
|
|
<div style="background: rgba(0, 255, 255, 0.1); padding: 15px; border-radius: 8px;">
|
|||
|
|
<div style="font-size: 0.9rem; color: var(--text-secondary); margin-bottom: 5px;">网络速度</div>
|
|||
|
|
<div style="font-size: 1.5rem; color: var(--neon-blue);">1.2 Gbps</div>
|
|||
|
|
</div>
|
|||
|
|
<div style="background: rgba(0, 255, 255, 0.1); padding: 15px; border-radius: 8px;">
|
|||
|
|
<div style="font-size: 0.9rem; color: var(--text-secondary); margin-bottom: 5px;">磁盘使用</div>
|
|||
|
|
<div style="font-size: 1.5rem; color: var(--neon-pink);">78%</div>
|
|||
|
|
</div>
|
|||
|
|
<div style="background: rgba(0, 255, 255, 0.1); padding: 15px; border-radius: 8px;">
|
|||
|
|
<div style="font-size: 0.9rem; color: var(--text-secondary); margin-bottom: 5px;">运行时间</div>
|
|||
|
|
<div style="font-size: 1.5rem; color: var(--neon-green);">7:32:15</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 加载设置
|
|||
|
|
function loadSettings() {
|
|||
|
|
const savedSettings = localStorage.getItem('neo-os-settings');
|
|||
|
|
if (savedSettings) {
|
|||
|
|
System.settings = { ...System.settings, ...JSON.parse(savedSettings) };
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 保存设置
|
|||
|
|
function saveSettings() {
|
|||
|
|
localStorage.setItem('neo-os-settings', JSON.stringify(System.settings));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 矩阵雨特效
|
|||
|
|
function startMatrixEffect() {
|
|||
|
|
const chars = "01アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン";
|
|||
|
|
const container = document.getElementById('wallpaper');
|
|||
|
|
|
|||
|
|
// 创建画布
|
|||
|
|
const canvas = document.createElement('canvas');
|
|||
|
|
const ctx = canvas.getContext('2d');
|
|||
|
|
|
|||
|
|
canvas.width = window.innerWidth;
|
|||
|
|
canvas.height = window.innerHeight;
|
|||
|
|
canvas.style.position = 'absolute';
|
|||
|
|
canvas.style.top = '0';
|
|||
|
|
canvas.style.left = '0';
|
|||
|
|
canvas.style.zIndex = '5';
|
|||
|
|
|
|||
|
|
container.appendChild(canvas);
|
|||
|
|
|
|||
|
|
const fontSize = 14;
|
|||
|
|
const columns = canvas.width / fontSize;
|
|||
|
|
const drops = [];
|
|||
|
|
|
|||
|
|
for (let i = 0; i < columns; i++) {
|
|||
|
|
drops[i] = 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function drawMatrix() {
|
|||
|
|
ctx.fillStyle = 'rgba(10, 10, 22, 0.05)';
|
|||
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|||
|
|
|
|||
|
|
ctx.fillStyle = '#0F0';
|
|||
|
|
ctx.font = fontSize + 'px monospace';
|
|||
|
|
|
|||
|
|
for (let i = 0; i < drops.length; i++) {
|
|||
|
|
const text = chars[Math.floor(Math.random() * chars.length)];
|
|||
|
|
ctx.fillText(text, i * fontSize, drops[i] * fontSize);
|
|||
|
|
|
|||
|
|
if (drops[i] * fontSize > canvas.height && Math.random() > 0.975) {
|
|||
|
|
drops[i] = 0;
|
|||
|
|
}
|
|||
|
|
drops[i]++;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const matrixInterval = setInterval(drawMatrix, 35);
|
|||
|
|
|
|||
|
|
// 按ESC退出
|
|||
|
|
function exitMatrix(e) {
|
|||
|
|
if (e.key === 'Escape') {
|
|||
|
|
clearInterval(matrixInterval);
|
|||
|
|
container.removeChild(canvas);
|
|||
|
|
document.removeEventListener('keydown', exitMatrix);
|
|||
|
|
showNotification('矩阵雨', '特效已关闭', 'info');
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
document.addEventListener('keydown', exitMatrix);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 延迟初始化终端输入处理
|
|||
|
|
setTimeout(() => {
|
|||
|
|
// 初始化所有终端窗口的输入处理
|
|||
|
|
document.addEventListener('keydown', function(e) {
|
|||
|
|
if (e.target.classList.contains('terminal-input')) {
|
|||
|
|
if (e.key === 'Enter') {
|
|||
|
|
const input = e.target;
|
|||
|
|
const windowId = input.id.replace('terminal-input-', '');
|
|||
|
|
const command = input.value.trim();
|
|||
|
|
input.value = '';
|
|||
|
|
|
|||
|
|
// 获取终端输出区域
|
|||
|
|
const terminalBody = document.getElementById(`terminal-body-${windowId}`);
|
|||
|
|
|
|||
|
|
// 添加输入行到历史
|
|||
|
|
const inputLine = document.createElement('div');
|
|||
|
|
inputLine.className = 'terminal-line';
|
|||
|
|
inputLine.innerHTML = `
|
|||
|
|
<span class="terminal-prompt">${System.user.name}@neo-os:~$</span>
|
|||
|
|
<span>${command}</span>
|
|||
|
|
`;
|
|||
|
|
terminalBody.appendChild(inputLine);
|
|||
|
|
|
|||
|
|
// 处理命令
|
|||
|
|
if (command) {
|
|||
|
|
const args = command.split(' ');
|
|||
|
|
const cmd = args[0].toLowerCase();
|
|||
|
|
args.shift();
|
|||
|
|
|
|||
|
|
if (System.terminal.commands[cmd]) {
|
|||
|
|
const output = System.terminal.commands[cmd].execute(args);
|
|||
|
|
if (output) {
|
|||
|
|
const outputLine = document.createElement('div');
|
|||
|
|
outputLine.innerHTML = output;
|
|||
|
|
terminalBody.appendChild(outputLine);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
const errorLine = document.createElement('div');
|
|||
|
|
errorLine.className = 'terminal-line';
|
|||
|
|
errorLine.style.color = 'var(--neon-pink)';
|
|||
|
|
errorLine.textContent = `命令未找到: ${cmd}. 输入 'help' 查看可用命令。`;
|
|||
|
|
terminalBody.appendChild(errorLine);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 添加新的输入行
|
|||
|
|
const newInputLine = document.createElement('div');
|
|||
|
|
newInputLine.className = 'terminal-line';
|
|||
|
|
newInputLine.id = `terminal-input-line-${windowId}`;
|
|||
|
|
newInputLine.innerHTML = `
|
|||
|
|
<span class="terminal-prompt">${System.user.name}@neo-os:~$</span>
|
|||
|
|
<input type="text" class="terminal-input" id="terminal-input-${windowId}" autocomplete="off" spellcheck="false">
|
|||
|
|
`;
|
|||
|
|
terminalBody.appendChild(newInputLine);
|
|||
|
|
|
|||
|
|
// 滚动到底部并聚焦新输入
|
|||
|
|
terminalBody.scrollTop = terminalBody.scrollHeight;
|
|||
|
|
document.getElementById(`terminal-input-${windowId}`).focus();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 初始化设置标签页
|
|||
|
|
document.addEventListener('click', function(e) {
|
|||
|
|
if (e.target.classList.contains('settings-tab')) {
|
|||
|
|
// 移除所有活动标签
|
|||
|
|
document.querySelectorAll('.settings-tab').forEach(tab => {
|
|||
|
|
tab.classList.remove('active');
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 激活点击的标签
|
|||
|
|
e.target.classList.add('active');
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}, 500);
|
|||
|
|
|
|||
|
|
// 初始化图表(延迟执行以确保DOM已加载)
|
|||
|
|
setTimeout(() => {
|
|||
|
|
// 如果系统监控窗口已打开,初始化图表
|
|||
|
|
const monitorWindows = System.windows.filter(w => w.appId === 'monitor');
|
|||
|
|
monitorWindows.forEach(win => {
|
|||
|
|
const cpuCtx = document.getElementById(`cpu-chart-${win.id}`).getContext('2d');
|
|||
|
|
const ramCtx = document.getElementById(`ram-chart-${win.id}`).getContext('2d');
|
|||
|
|
|
|||
|
|
// CPU图表
|
|||
|
|
new Chart(cpuCtx, {
|
|||
|
|
type: 'line',
|
|||
|
|
data: {
|
|||
|
|
labels: ['1m', '2m', '3m', '4m', '5m', '6m'],
|
|||
|
|
datasets: [{
|
|||
|
|
label: 'CPU使用率',
|
|||
|
|
data: [25, 30, 45, 35, 50, 40],
|
|||
|
|
borderColor: '#00ff9d',
|
|||
|
|
backgroundColor: 'rgba(0, 255, 157, 0.1)',
|
|||
|
|
borderWidth: 2,
|
|||
|
|
tension: 0.4,
|
|||
|
|
fill: true
|
|||
|
|
}]
|
|||
|
|
},
|
|||
|
|
options: {
|
|||
|
|
responsive: true,
|
|||
|
|
plugins: {
|
|||
|
|
legend: {
|
|||
|
|
labels: {
|
|||
|
|
color: '#e0e0ff'
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
scales: {
|
|||
|
|
y: {
|
|||
|
|
min: 0,
|
|||
|
|
max: 100,
|
|||
|
|
ticks: {
|
|||
|
|
color: '#a0a0ff'
|
|||
|
|
},
|
|||
|
|
grid: {
|
|||
|
|
color: 'rgba(0, 255, 255, 0.1)'
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
x: {
|
|||
|
|
ticks: {
|
|||
|
|
color: '#a0a0ff'
|
|||
|
|
},
|
|||
|
|
grid: {
|
|||
|
|
color: 'rgba(0, 255, 255, 0.1)'
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 内存图表
|
|||
|
|
new Chart(ramCtx, {
|
|||
|
|
type: 'doughnut',
|
|||
|
|
data: {
|
|||
|
|
labels: ['已使用', '可用'],
|
|||
|
|
datasets: [{
|
|||
|
|
data: [68, 32],
|
|||
|
|
backgroundColor: ['#ff00ff', 'rgba(255, 0, 255, 0.2)'],
|
|||
|
|
borderWidth: 0
|
|||
|
|
}]
|
|||
|
|
},
|
|||
|
|
options: {
|
|||
|
|
responsive: true,
|
|||
|
|
plugins: {
|
|||
|
|
legend: {
|
|||
|
|
labels: {
|
|||
|
|
color: '#e0e0ff'
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}, 1000);
|
|||
|
|
|
|||
|
|
// 显示欢迎消息
|
|||
|
|
setTimeout(() => {
|
|||
|
|
if (!localStorage.getItem('neo-os-first-run')) {
|
|||
|
|
showNotification('欢迎使用 NEO-OS', '赛博朋克未来都市操作系统已启动。点击桌面图标或开始菜单打开应用。', 'success');
|
|||
|
|
localStorage.setItem('neo-os-first-run', 'true');
|
|||
|
|
}
|
|||
|
|
}, 4000);
|
|||
|
|
</script>
|
|||
|
|
</body>
|
|||
|
|
</html>
|