// 全局状态
let currentStep = 0;
let isExpanded = false;
let demoRunning = false;
// 步骤配置
const steps = [
{
type: 'thinking',
icon: 'brain',
summary: '正在思考如何搜索...',
duration: 2000
},
{
type: 'tool',
icon: 'search',
summary: '搜索:AI技术发展趋势 2026',
duration: 2500
},
{
type: 'thinking',
icon: 'brain',
summary: '搜索结果显示了一些有价值的信息。现在我需要执行...',
duration: 2000
},
{
type: 'tool',
icon: 'terminal',
summary: '执行命令:获取网页内容并分析',
duration: 2500
},
{
type: 'thinking',
icon: 'brain',
summary: '很好,我已经收集到了足够的信息。现在我可以整理...',
duration: 2000
}
];
// 开始演示
async function startDemo() {
if (demoRunning) return;
demoRunning = true;
resetDemo();
// 显示等待动画
const placeholder = document.getElementById('generatingPlaceholder');
placeholder.style.display = 'flex';
await sleep(1500);
// 隐藏等待动画,显示摘要行
placeholder.style.display = 'none';
const summaryLine = document.getElementById('summaryLine');
summaryLine.style.display = 'flex';
// 执行每个步骤
for (let i = 0; i < steps.length; i++) {
currentStep = i;
await executeStep(i);
}
// 完成后显示最终输出
await sleep(1000);
summaryLine.classList.add('completed');
// 如果展开状态,显示最后一步
if (isExpanded) {
await showDetailStep(currentStep, true);
}
// 淡化摘要并显示第一个步骤(极快)
await fadeAndSwitch(summaryLine, steps[0].summary, true);
await sleep(800);
// 显示最终输出
const textOutput = document.getElementById('textOutput');
textOutput.style.display = 'block';
setTimeout(() => {
textOutput.classList.add('show');
}, 50);
demoRunning = false;
}
// 执行单个步骤
async function executeStep(stepIndex) {
const step = steps[stepIndex];
// 更新摘要文本
updateSummary(step);
// 如果展开状态,显示详细内容
if (isExpanded) {
await showDetailStep(stepIndex);
}
await sleep(step.duration);
}
// 更新摘要
function updateSummary(step) {
const summaryText = document.getElementById('summaryText');
const summaryIcon = document.querySelector('.summary-icon');
// 更新图标
summaryIcon.innerHTML = getIconSVG(step.icon);
// 更新文本
summaryText.textContent = step.summary;
}
// 显示详细步骤
async function showDetailStep(stepIndex, isNewStep = false) {
const timelineItem = document.querySelector(`.timeline-item[data-step="${stepIndex}"]`);
const contentItem = document.querySelector(`.content-item[data-step="${stepIndex}"]`);
if (!timelineItem || !contentItem) return;
// 添加动画类
if (isNewStep) {
timelineItem.classList.add('animated');
contentItem.classList.add('animated');
} else {
timelineItem.classList.add('instant');
contentItem.classList.add('instant');
}
// 显示时间线项和内容
timelineItem.style.display = 'flex';
contentItem.style.display = 'block';
// 计算并设置竖线高度
await sleep(isNewStep ? 100 : 10);
updateLineHeight(stepIndex);
await sleep(isNewStep ? 200 : 10);
}
// 更新竖线高度
function updateLineHeight(stepIndex) {
const timelineItem = document.querySelector(`.timeline-item[data-step="${stepIndex}"]`);
const contentItem = document.querySelector(`.content-item[data-step="${stepIndex}"]`);
if (!timelineItem || !contentItem) return;
const line = timelineItem.querySelector('.timeline-line');
if (!line) return;
// 获取内容的实际高度
const contentHeight = contentItem.offsetHeight;
// 对于第一个步骤(没有图标),竖线从顶部开始
if (stepIndex === 0) {
const gap = 20; // 到下一个步骤的间距
const lineHeight = contentHeight + gap;
line.style.height = `${lineHeight}px`;
return;
}
// 对于其他步骤,计算竖线高度
const iconHeight = 20; // 图标高度
const gap = 20; // 间距
// 如果是最后一个步骤,不需要竖线
if (stepIndex >= steps.length - 1) {
line.style.height = '0';
return;
}
// 计算竖线应该的高度:内容高度 + 间距 - 图标高度
const lineHeight = Math.max(contentHeight + gap - iconHeight, 40);
line.style.height = `${lineHeight}px`;
}
// 切换展开/折叠
async function toggleSummary() {
const summaryLine = document.getElementById('summaryLine');
const detailView = document.getElementById('detailView');
if (summaryLine.style.display === 'none') return;
isExpanded = !isExpanded;
if (isExpanded) {
// 展开:极快淡化当前摘要,显示第一个步骤的内容
summaryLine.classList.add('expanded');
await fadeAndSwitch(summaryLine, steps[0].summary, true);
// 显示详细视图(快速)
detailView.style.display = 'block';
setTimeout(() => {
detailView.classList.add('show');
}, 10);
// 已完成的步骤快速显示,当前步骤慢速动画
for (let i = 0; i <= currentStep; i++) {
const isCurrentStep = i === currentStep && demoRunning;
await showDetailStep(i, isCurrentStep);
if (isCurrentStep) {
await sleep(400); // 只有新步骤才有较慢的动画
} else {
await sleep(50); // 已有内容快速出现
}
}
} else {
// 折叠:极快淡化第一个步骤,显示当前摘要
summaryLine.classList.remove('expanded');
await fadeAndSwitch(summaryLine, steps[currentStep].summary, true);
// 隐藏详细视图(快速)
detailView.classList.remove('show');
await sleep(150);
detailView.style.display = 'none';
// 重置所有步骤显示
document.querySelectorAll('.timeline-item').forEach(item => {
item.style.display = 'none';
item.classList.remove('instant', 'animated');
});
document.querySelectorAll('.content-item').forEach(item => {
item.style.display = 'none';
item.classList.remove('instant', 'animated');
});
}
}
// 淡化并切换文本
async function fadeAndSwitch(element, newText, fast = false) {
const summaryText = element.querySelector('.summary-text');
const duration = fast ? 75 : 200;
// 淡出
element.style.opacity = '0.3';
await sleep(duration);
// 切换文本
summaryText.textContent = newText;
// 淡入
element.style.opacity = '1';
await sleep(duration);
}
// 展开思考内容
function expandThinking(stepIndex) {
const thinkingContent = document.getElementById(`thinkingContent${stepIndex}`);
const thinkingContentFull = document.getElementById(`thinkingContentFull${stepIndex}`);
thinkingContent.style.display = 'none';
thinkingContentFull.style.display = 'block';
// 重新计算并更新竖线高度
setTimeout(() => {
updateLineHeight(stepIndex);
}, 50);
}
// 收起思考内容
function collapseThinking(stepIndex) {
const thinkingContent = document.getElementById(`thinkingContent${stepIndex}`);
const thinkingContentFull = document.getElementById(`thinkingContentFull${stepIndex}`);
thinkingContent.style.display = 'block';
thinkingContentFull.style.display = 'none';
// 重新计算并更新竖线高度
setTimeout(() => {
updateLineHeight(stepIndex);
}, 50);
}
// 重置演示
function resetDemo() {
currentStep = 0;
isExpanded = false;
demoRunning = false;
// 隐藏所有元素
document.getElementById('generatingPlaceholder').style.display = 'none';
const summaryLine = document.getElementById('summaryLine');
summaryLine.style.display = 'none';
summaryLine.classList.remove('completed', 'expanded');
summaryLine.style.opacity = '1';
document.getElementById('detailView').style.display = 'none';
document.getElementById('detailView').classList.remove('show');
document.getElementById('textOutput').style.display = 'none';
document.getElementById('textOutput').classList.remove('show');
// 重置所有步骤
document.querySelectorAll('.timeline-item').forEach(item => {
item.style.display = 'none';
item.classList.remove('instant', 'animated');
const line = item.querySelector('.timeline-line');
if (line) {
line.style.height = '0';
}
});
document.querySelectorAll('.content-item').forEach(item => {
item.style.display = 'none';
item.classList.remove('instant', 'animated');
});
// 重置思考内容
document.querySelectorAll('.thinking-content').forEach(item => {
item.style.display = 'block';
});
document.querySelectorAll('.thinking-content-full').forEach(item => {
item.style.display = 'none';
});
}
// 获取图标SVG
function getIconSVG(iconType) {
const icons = {
brain: '',
search: '',
terminal: ''
};
return icons[iconType] || icons.brain;
}
// 工具函数:延迟
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// 点击摘要行切换展开/折叠
document.getElementById('summaryLine').addEventListener('click', toggleSummary);