liurenchaxin/website/script.js

345 lines
10 KiB
JavaScript

// 全局变量
let agents = [
{ id: 'code-reviewer', name: 'Code Reviewer', status: 'active', commits: 12, tasks: 3 },
{ id: 'test-runner', name: 'Test Runner', status: 'active', commits: 8, tasks: 5 },
{ id: 'deploy-bot', name: 'Deploy Bot', status: 'inactive', commits: 3, tasks: 0 },
{ id: 'doc-writer', name: 'Doc Writer', status: 'active', commits: 15, tasks: 2 }
];
let activities = [
{ type: 'commit', message: 'Code Reviewer pushed 3 new commits', time: '2 minutes ago' },
{ type: 'test', message: 'Test Runner completed 5 test cases', time: '5 minutes ago' },
{ type: 'deploy', message: 'Deploy Bot deployed to staging', time: '10 minutes ago' },
{ type: 'docs', message: 'Doc Writer updated API documentation', time: '15 minutes ago' }
];
// 初始化
document.addEventListener('DOMContentLoaded', function() {
initializeDemo();
initializeTerminal();
initializeStats();
setupScrollEffects();
});
// 演示区域初始化
function initializeDemo() {
updateAgentGrid();
updateActivityFeed();
// 每3秒更新一次演示数据
setInterval(updateDemoData, 3000);
}
// 更新代理网格
function updateAgentGrid() {
const grid = document.getElementById('agent-grid');
if (!grid) return;
grid.innerHTML = '';
agents.forEach(agent => {
const card = createAgentCard(agent);
grid.appendChild(card);
});
}
// 创建代理卡片
function createAgentCard(agent) {
const card = document.createElement('div');
card.className = `agent-card agent-status-${agent.status}`;
const statusIcon = agent.status === 'active' ? '🟢' : '🔴';
card.innerHTML = `
<div>
<strong>${agent.name}</strong>
<div style="font-size: 0.9rem; color: #666;">
${statusIcon} ${agent.status}
</div>
</div>
<div style="text-align: right; font-size: 0.9rem;">
<div>📊 ${agent.commits} commits</div>
<div>📝 ${agent.tasks} tasks</div>
</div>
`;
return card;
}
// 更新活动流
function updateActivityFeed() {
const feed = document.getElementById('activity-feed');
if (!feed) return;
feed.innerHTML = '';
activities.forEach(activity => {
const item = createActivityItem(activity);
feed.appendChild(item);
});
}
// 创建活动项
function createActivityItem(activity) {
const item = document.createElement('div');
item.className = 'activity-item';
const icon = getActivityIcon(activity.type);
item.innerHTML = `
<div style="display: flex; align-items: center; gap: 0.5rem;">
<span>${icon}</span>
<span>${activity.message}</span>
</div>
<div style="font-size: 0.8rem; color: #666; margin-top: 0.5rem;">
${activity.time}
</div>
`;
return item;
}
// 获取活动图标
function getActivityIcon(type) {
const icons = {
'commit': '💻',
'test': '🧪',
'deploy': '🚀',
'docs': '📚'
};
return icons[type] || '📝';
}
// 更新演示数据
function updateDemoData() {
// 随机更新代理状态
agents.forEach(agent => {
if (Math.random() > 0.7) {
agent.status = agent.status === 'active' ? 'inactive' : 'active';
}
if (Math.random() > 0.5) {
agent.commits += Math.floor(Math.random() * 3);
}
});
// 添加新活动
const newActivity = generateRandomActivity();
activities.unshift(newActivity);
if (activities.length > 5) {
activities.pop();
}
updateAgentGrid();
updateActivityFeed();
updateStats();
}
// 生成随机活动
function generateRandomActivity() {
const types = ['commit', 'test', 'deploy', 'docs'];
const messages = {
'commit': ['Code Reviewer pushed new features', 'Test Runner fixed bugs', 'Deploy Bot merged PR'],
'test': ['Test Runner passed all tests', 'Code Reviewer added unit tests', 'Doc Writer tested examples'],
'deploy': ['Deploy Bot deployed to production', 'Code Reviewer released v2.0', 'Test Runner deployed hotfix'],
'docs': ['Doc Writer updated README', 'Code Reviewer improved comments', 'Deploy Bot added changelog']
};
const type = types[Math.floor(Math.random() * types.length)];
const message = messages[type][Math.floor(Math.random() * messages[type].length)];
return {
type: type,
message: message,
time: 'just now'
};
}
// 终端模拟
function initializeTerminal() {
const terminal = document.getElementById('terminal-content');
if (!terminal) return;
const commands = [
{ prompt: 'user@spore-colony:~$', command: 'spore init', output: '✓ Initializing Spore Colony...\n✓ Creating agent identities...\n✓ Setting up Git repositories...\n✓ Spore Colony initialized successfully!' },
{ prompt: 'user@spore-colony:~$', command: 'spore agent list', output: '🟢 code-reviewer (Active)\n🟢 test-runner (Active)\n🔴 deploy-bot (Inactive)\n🟢 doc-writer (Active)' },
{ prompt: 'user@spore-colony:~$', command: 'spore task create "Add new feature"', output: '✓ Task created and assigned to code-reviewer\n📊 Progress: 0% → 25% → 50% → 75% → 100%\n✅ Task completed successfully!' }
];
let currentCommand = 0;
function typeCommand() {
if (currentCommand >= commands.length) return;
const cmd = commands[currentCommand];
const line = document.createElement('div');
line.className = 'terminal-line';
line.innerHTML = `<span class="prompt">${cmd.prompt}</span> <span class="command">${cmd.command}</span>`;
terminal.appendChild(line);
setTimeout(() => {
const outputLine = document.createElement('div');
outputLine.className = 'terminal-line';
outputLine.innerHTML = `<span class="success">${cmd.output}</span>`;
terminal.appendChild(outputLine);
currentCommand++;
if (currentCommand < commands.length) {
setTimeout(typeCommand, 2000);
}
}, 1500);
}
typeCommand();
}
// 统计信息
function initializeStats() {
updateStats();
}
function updateStats() {
const totalCommits = agents.reduce((sum, agent) => sum + agent.commits, 0);
const activeAgents = agents.filter(agent => agent.status === 'active').length;
const totalTasks = agents.reduce((sum, agent) => sum + agent.tasks, 0);
animateCounter('total-commits', totalCommits);
animateCounter('active-agents', activeAgents);
animateCounter('total-tasks', totalTasks);
updateProgressBars();
}
// 数字动画
function animateCounter(elementId, targetValue) {
const element = document.getElementById(elementId);
if (!element) return;
const startValue = parseInt(element.textContent) || 0;
const duration = 1000;
const startTime = performance.now();
function updateCounter(currentTime) {
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1);
const currentValue = Math.floor(startValue + (targetValue - startValue) * progress);
element.textContent = currentValue;
if (progress < 1) {
requestAnimationFrame(updateCounter);
}
}
requestAnimationFrame(updateCounter);
}
// 进度条更新
function updateProgressBars() {
const progressBars = document.querySelectorAll('.bar div');
progressBars.forEach(bar => {
const width = Math.floor(Math.random() * 30) + 70; // 70-100%
bar.style.width = width + '%';
});
}
// 滚动效果
function setupScrollEffects() {
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('animate-in');
}
});
}, observerOptions);
// 观察所有需要动画的元素
document.querySelectorAll('.feature-card, .demo-panel, .install-card, .doc-card').forEach(el => {
observer.observe(el);
});
}
// 平滑滚动到锚点
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
});
});
// 响应式菜单
function toggleMobileMenu() {
const navMenu = document.querySelector('.nav-menu');
navMenu.classList.toggle('active');
}
// 复制代码功能
function copyToClipboard(elementId) {
const element = document.getElementById(elementId);
if (!element) return;
const text = element.textContent;
navigator.clipboard.writeText(text).then(() => {
// 显示复制成功提示
const toast = document.createElement('div');
toast.textContent = 'Copied to clipboard!';
toast.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: #27ca3f;
color: white;
padding: 1rem;
border-radius: 0.5rem;
z-index: 1000;
animation: slideIn 0.3s ease;
`;
document.body.appendChild(toast);
setTimeout(() => {
toast.remove();
}, 2000);
});
}
// 添加CSS动画
const style = document.createElement('style');
style.textContent = `
@keyframes slideIn {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.animate-in {
animation: fadeInUp 0.6s ease forwards;
}
@media (max-width: 768px) {
.nav-menu.active {
display: flex;
flex-direction: column;
position: absolute;
top: 100%;
left: 0;
width: 100%;
background: white;
padding: 1rem;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
}
`;
document.head.appendChild(style);