345 lines
10 KiB
JavaScript
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); |