本项目 Fork 自 https://github.com/gkamradt/MultiTerminalCodeViz
本地化改进说明:
- ✅ 中文化翻译 - README 文档已从英文完整翻译为中文版本
- ✅ 文档完善 - 对原项目文档进行了大幅补充和完善,增加了更详细的使用说明
- ✅ 架构图表 - 新增了项目架构图、数据流图和用户交互流程图
- ✅ 开发指南 - 添加了完整的开发指南、API 文档和贡献指南
- ✅ 技术说明 - 详细解释了真实 vs 模拟的技术实现原理
🎉 这是一个有趣的项目 - 欢迎提交 PR!
一个基于 React 的多终端代码可视化工具,可以显示多个可拖拽、可调整大小的终端窗口,具有动画打字效果。每个终端显示不同的开发场景,支持自定义主题和可变打字速度。
- 🖥️ 多终端窗口 - 支持同时显示多个终端窗口(1-10000个)
- 🎨 多种主题 - 内置多种终端主题(Dark、Light、Matrix、Dracula、Solarized等)
- 🎭 动画效果 - 逼真的打字动画效果,模拟真实的编程场景
- 🎯 拖拽调整 - 终端窗口可自由拖拽和调整大小
- 🎵 背景音乐 - 集成 YouTube 音频播放器,支持 lofi 背景音乐
- 🐰 彩蛋功能 - 可爱的弹跳兔子动画
- 📱 响应式设计 - 支持不同屏幕尺寸
- 🎪 ASCII 艺术 - 内置 ASCII 艺术生成器
很多人会好奇:这个项目是真的可以让1000多个终端同时运行吗?还是模拟做的界面?
答案是:这是真实的多终端窗口系统,但内容是模拟的开发场景,并且使用了聪明的性能优化。
- 终端窗口组件 - 每个都是真实的React组件,有独立的状态和生命周期
- 拖拽和调整大小 - 真实的用户交互,使用
react-draggable和react-resizable - 独立的动画状态 - 每个终端有自己的打字动画和循环逻辑
- 主题切换 - 真实的样式变化,影响所有终端
- 数量计数 - 真实可以创建到10,000个终端实例
- 终端内容 - 不是真实的命令行执行,而是预设的开发场景文本
- 打字效果 - 模拟的逐字符显示动画,不是真实的命令输出
- 开发场景 - 包含构建、测试、调试等预设的开发者日常工作内容
// 智能渲染优化
const maxRenderedTerminals = actualTerminalCount > 1000 ? 40 : 80;这意味着:
- 逻辑上:可以有10,000个终端(状态中记录和管理)
- 视觉上:只渲染最新的40-80个终端(DOM中实际存在)
- 用户体验:感觉像是有很多终端在同时运行
- 日常演示: 50个以下终端效果最佳,流畅且美观
- 性能测试: 可以测试到1000+个,会有一定性能影响
- 极限测试: 理论上可以到10,000个,但主要是数字展示
这种设计让项目既能提供真实的多终端体验,又能保持良好的性能表现。
# 克隆项目
git clone https://github.com/nicekate/MultiTerminalCodeViz
cd MultiTerminalCodeViz
# 安装依赖
npm install
# 启动开发服务器
npm run dev
# 在浏览器中打开 http://localhost:5173- React 18.2.0 - 用户界面库
- TypeScript 5.2.2 - 类型安全的 JavaScript
- Vite 5.2.0 - 现代化构建工具
- Tailwind CSS 3.4.3 - 实用优先的 CSS 框架
- react-draggable - 拖拽功能实现
- react-resizable - 窗口大小调整
- react-router-dom - 路由管理
- html2canvas - 截图功能
- @vercel/analytics - 网站分析
- ESLint - 代码质量检查
- Prettier - 代码格式化
- Vitest - 单元测试框架
- @testing-library/react - React 组件测试
graph TB
subgraph "应用层"
App[App.tsx]
Router[React Router]
Analytics[Vercel Analytics]
end
subgraph "上下文层"
AppContext[AppContext - 应用状态]
ThemeContext[ThemeContext - 主题管理]
end
subgraph "页面层"
MainPage[主页面 - 多终端显示]
AsciiTyper[ASCII 艺术生成器]
end
subgraph "组件层"
TerminalWindow[TerminalWindow - 终端窗口]
ControlsPanel[ControlsPanel - 控制面板]
BouncyBunny[BouncyBunny - 弹跳兔子]
YouTubePlayer[YouTube 音频播放器]
end
subgraph "Hook层"
useTypewriter[useTypewriter - 打字动画]
useTheme[useTheme - 主题钩子]
useAppContext[useAppContext - 应用状态钩子]
end
subgraph "数据层"
TerminalOutputs[terminalOutputs.ts - 终端输出数据]
ColorThemes[colorThemes.ts - 主题配置]
AsciiArt[asciiArt.ts - ASCII 艺术字符]
end
subgraph "工具层"
Utils[工具函数]
end
App --> Router
App --> Analytics
App --> AppContext
App --> ThemeContext
Router --> MainPage
Router --> AsciiTyper
MainPage --> TerminalWindow
MainPage --> ControlsPanel
MainPage --> BouncyBunny
ControlsPanel --> YouTubePlayer
TerminalWindow --> useTypewriter
TerminalWindow --> useTheme
ControlsPanel --> useAppContext
ControlsPanel --> useTheme
useTypewriter --> TerminalOutputs
useTheme --> ColorThemes
AsciiTyper --> AsciiArt
TerminalWindow --> Utils
sequenceDiagram
participant User as 用户
participant Controls as 控制面板
participant Context as 应用上下文
participant Terminal as 终端窗口
participant Typewriter as 打字动画Hook
participant Data as 数据层
User->>Controls: 调整终端数量/主题
Controls->>Context: 更新应用状态
Context->>Terminal: 状态变化通知
Terminal->>Typewriter: 启动/更新动画
Typewriter->>Data: 获取终端输出数据
Data->>Typewriter: 返回文本内容
Typewriter->>Terminal: 逐步显示文本
Terminal->>User: 展示动画效果
flowchart TD
Start([用户访问网站]) --> Load[加载应用]
Load --> MainInterface[显示主界面]
MainInterface --> Controls{用户操作控制面板}
Controls -->|增加终端| AddTerminal[创建新终端窗口]
Controls -->|减少终端| RemoveTerminal[移除终端窗口]
Controls -->|切换主题| ChangeTheme[更新所有终端主题]
Controls -->|播放音乐| PlayMusic[启动YouTube播放器]
Controls -->|添加兔子| AddBunny[创建弹跳兔子]
AddTerminal --> Animation[启动打字动画]
RemoveTerminal --> Update[更新终端列表]
ChangeTheme --> Refresh[刷新界面样式]
PlayMusic --> Audio[播放背景音乐]
AddBunny --> Bounce[兔子开始弹跳]
Animation --> Loop[循环播放内容]
Update --> MainInterface
Refresh --> MainInterface
Audio --> MainInterface
Bounce --> MainInterface
Loop --> MainInterface
MainInterface -->|拖拽终端| DragTerminal[移动终端位置]
MainInterface -->|调整大小| ResizeTerminal[改变终端尺寸]
MainInterface -->|访问ASCII生成器| AsciiPage[跳转到/typer页面]
DragTerminal --> MainInterface
ResizeTerminal --> MainInterface
AsciiPage --> AsciiInterface[ASCII艺术生成界面]
AsciiInterface -->|返回主页| MainInterface
MultiTerminalCodeViz/
├── public/ # 静态资源
│ ├── favicon.ico # 网站图标
│ ├── bunny.gif # 彩蛋兔子动画
│ ├── sonomaBackground.jpg # 背景图片
│ └── og.png # Open Graph 图片
├── src/ # 源代码
│ ├── components/ # React 组件
│ │ ├── BouncyBunny/ # 弹跳兔子组件
│ │ │ └── BouncyBunny.tsx
│ │ ├── ControlsPanel/ # 控制面板组件
│ │ │ └── ControlsPanel.tsx
│ │ ├── TerminalWindow/ # 终端窗口组件
│ │ │ ├── TerminalWindow.tsx
│ │ │ └── TerminalWindow.css
│ │ └── YouTubeAudioPlayer/ # YouTube 音频播放器
│ │ ├── YouTubeAudioPlayer.tsx
│ │ └── SimpleYouTubePlayer.tsx
│ ├── contexts/ # React 上下文
│ │ ├── AppContext.tsx # 应用全局状态
│ │ ├── ThemeContext.tsx # 主题管理
│ │ └── __tests__/ # 上下文测试
│ ├── data/ # 数据文件
│ │ ├── colorThemes.ts # 终端主题配置
│ │ └── terminalOutputs.ts # 终端输出内容
│ ├── hooks/ # 自定义 Hook
│ │ └── useTypewriter.ts # 打字动画 Hook
│ ├── pages/ # 页面组件
│ │ └── AsciiTyper.tsx # ASCII 艺术生成器页面
│ ├── utils/ # 工具函数
│ │ └── asciiArt.ts # ASCII 艺术生成工具
│ ├── App.tsx # 主应用组件
│ ├── App.css # 应用样式
│ ├── main.tsx # 应用入口
│ └── index.css # 全局样式
├── planning/ # 项目规划文档
│ ├── plan.md # 开发计划
│ ├── spec.md # 项目规格说明
│ └── todo.md # 待办事项
├── package.json # 项目配置
├── vite.config.ts # Vite 配置
├── tailwind.config.js # Tailwind CSS 配置
├── tsconfig.json # TypeScript 配置
└── vercel.json # Vercel 部署配置
- Node.js >= 16.0.0
- npm >= 8.0.0 或 yarn >= 1.22.0
-
克隆仓库
git clone https://github.com/nicekate/MultiTerminalCodeViz.git cd MultiTerminalCodeViz -
安装依赖
npm install # 或使用 yarn yarn install -
启动开发服务器
npm run dev # 或使用 yarn yarn dev -
构建生产版本
npm run build # 或使用 yarn yarn build -
预览生产版本
npm run preview # 或使用 yarn yarn preview
- ES7+ React/Redux/React-Native snippets - React 代码片段
- TypeScript Importer - 自动导入 TypeScript 类型
- Tailwind CSS IntelliSense - Tailwind CSS 智能提示
- ESLint - 代码质量检查
- Prettier - 代码格式化
项目目前不需要特殊的环境变量配置,所有功能都是客户端实现。
位置: src/components/TerminalWindow/TerminalWindow.tsx
功能特性:
- ✅ Mac 风格的终端界面设计
- ✅ 可拖拽和调整大小
- ✅ 多种主题支持
- ✅ 逼真的打字动画效果
- ✅ 自动循环播放内容
核心代码示例:
interface TerminalWindowProps {
id: string;
initialPosition?: { x: number; y: number };
title?: string;
onClose?: () => void;
zIndex?: number;
totalTerminalCount?: number;
}位置: src/components/ControlsPanel/ControlsPanel.tsx
功能特性:
- ✅ 终端数量控制(1-10000个)
- ✅ 主题切换
- ✅ 音频播放器集成
- ✅ 兔子动画控制
- ✅ 面板显示/隐藏切换
使用方法:
<ControlsPanel
terminalCount={terminalCount}
onTerminalCountChange={handleTerminalCountChange}
onArrangeTerminals={handleArrangeTerminals}
bunnyCount={bunnies.length}
onRemoveAllBunnies={handleRemoveAllBunnies}
/>位置: src/hooks/useTypewriter.ts
功能特性:
- ✅ 基于令牌的打字效果(3-6字符块)
- ✅ 可配置的打字速度
- ✅ 循环播放支持
- ✅ 延迟控制
使用示例:
const { displayedLines, isTyping } = useTypewriter({
lines: terminalOutputs.conversation,
speed: 50, // 毫秒每令牌
enabled: true,
loop: true,
loopDelay: 3000
});位置: src/contexts/ThemeContext.tsx 和 src/data/colorThemes.ts
支持的主题:
- 🌙 Dark - 经典深色主题
- ☀️ Light - 明亮浅色主题
- 🟢 Matrix - 黑客帝国风格
- 🧛 Dracula - Dracula 配色方案
- 🌅 Solarized - Solarized Dark 主题
主题配置结构:
interface TerminalTheme {
name: string;
background: string;
colors: Record<TerminalColorRole, string>;
}位置: src/pages/AsciiTyper.tsx 和 src/utils/asciiArt.ts
功能特性:
- ✅ 实时 ASCII 艺术生成
- ✅ 多行文本支持
- ✅ 自定义颜色配置
- ✅ 文本和图片导出功能
访问方式: 访问 /typer 路径
位置: src/components/BouncyBunny/BouncyBunny.tsx
功能特性:
- ✅ 物理引擎模拟的弹跳效果
- ✅ 边界碰撞检测
- ✅ 性能优化(基于兔子数量的帧率调节)
- ✅ 响应式窗口大小调整
# 开发相关
npm run dev # 启动开发服务器
npm run build # 构建生产版本
npm run preview # 预览生产版本
# 代码质量
npm run lint # 运行 ESLint 检查
npm run format # 使用 Prettier 格式化代码
# 测试相关
npm run test # 运行单元测试
npm run test:ui # 运行测试 UI 界面
# 部署相关
npm run vercel-build # Vercel 部署构建项目使用 Vitest 作为测试框架,配合 @testing-library/react 进行组件测试。
运行测试:
# 运行所有测试
npm run test
# 运行测试并显示覆盖率
npm run test -- --coverage
# 运行测试 UI 界面
npm run test:ui测试文件位置:
- 组件测试:
src/components/**/__tests__/ - 上下文测试:
src/contexts/__tests__/ - Hook 测试:
src/hooks/__tests__/
项目使用 ESLint 和 Prettier 确保代码质量和一致性。
ESLint 配置:
- 基于 Airbnb 配置
- TypeScript 支持
- React Hooks 规则
- 可访问性检查
代码格式化:
# 格式化所有文件
npm run format
# 检查代码规范
npm run lint- 终端数量控制: 建议同时显示的终端数量不超过 100 个
- 动画性能: 大量终端时会自动降低帧率
- 内存管理: 组件卸载时会自动清理定时器和动画
- 懒加载: 考虑对大量组件实施虚拟化
在 src/data/terminalOutputs.ts 中添加新的输出数据:
export const newOutputType: TerminalLine[] = [
{ text: "Your new content here", colorRole: "primary" },
// ... 更多行
];
// 在 terminalOutputs 对象中注册
export const terminalOutputs = {
// ... 现有类型
newType: newOutputType
};在 src/data/colorThemes.ts 中添加新主题:
export const terminalThemes: Record<string, TerminalTheme> = {
// ... 现有主题
newTheme: {
name: 'New Theme',
background: 'bg-custom-color',
colors: {
primary: 'text-custom-primary',
// ... 其他颜色角色
}
}
};- 在
src/components/下创建新文件夹 - 创建组件文件和样式文件
- 添加对应的测试文件
- 在需要的地方导入和使用
interface UseTypewriterProps {
lines: TerminalLine[]; // 要显示的文本行
speed?: number; // 打字速度(毫秒/令牌)
enabled?: boolean; // 是否启用动画
loop?: boolean; // 是否循环播放
loopDelay?: number; // 循环间隔时间
}
interface UseTypewriterReturn {
displayedLines: TerminalLine[]; // 当前显示的行
isTyping: boolean; // 是否正在打字
reset: () => void; // 重置动画
}interface ThemeContextType {
currentTheme: TerminalTheme; // 当前主题
themeName: string; // 主题名称
setTheme: (themeName: string) => void; // 设置主题
getThemeNames: () => string[]; // 获取所有主题名称
getColorForRole: (role: TerminalColorRole) => string; // 获取角色颜色
}interface TerminalWindowProps {
id: string; // 终端唯一标识
initialPosition?: { x: number; y: number }; // 初始位置
initialSize?: { width?: number; height?: number }; // 初始大小
title?: string; // 窗口标题
onClose?: () => void; // 关闭回调
onPositionChange?: (id: string, position: { x: number; y: number }) => void; // 位置变化回调
zIndex?: number; // 层级
onFocus?: (id: string) => void; // 聚焦回调
totalTerminalCount?: number; // 总终端数量
}interface ControlsPanelProps {
terminalCount: number; // 当前终端数量
onTerminalCountChange: (count: number) => void; // 终端数量变化回调
onArrangeTerminals?: () => void; // 重新排列终端回调
minTerminals?: number; // 最小终端数量
maxTerminals?: number; // 最大终端数量
bunnyCount?: number; // 兔子数量
onRemoveAllBunnies?: () => void; // 移除所有兔子回调
}我们欢迎所有形式的贡献!无论是 bug 报告、功能请求还是代码贡献。
-
Fork 项目
# 点击 GitHub 页面上的 Fork 按钮 -
克隆你的 Fork
git clone https://github.com/your-username/MultiTerminalCodeViz.git cd MultiTerminalCodeViz -
创建功能分支
git checkout -b feature/your-feature-name # 或 git checkout -b fix/your-bug-fix -
进行开发
- 遵循现有的代码风格
- 添加必要的测试
- 确保所有测试通过
-
提交更改
git add . git commit -m "feat: add your feature description" # 或 git commit -m "fix: fix your bug description"
-
推送到你的 Fork
git push origin feature/your-feature-name
-
创建 Pull Request
- 在 GitHub 上创建 PR
- 详细描述你的更改
- 等待代码审查
使用 Conventional Commits 规范:
feat:新功能fix:Bug 修复docs:文档更新style:代码格式化refactor:代码重构test:测试相关chore:构建过程或辅助工具的变动
- ✅ 代码符合 ESLint 规则
- ✅ 所有测试通过
- ✅ 新功能有对应的测试
- ✅ 代码有适当的注释
- ✅ 性能影响在可接受范围内
A: 这是正常现象。当终端数量超过 100 个时,系统会自动降低动画帧率来保持性能。建议:
- 日常使用保持在 50 个以下
- 演示时可以短暂使用更多终端
- 关闭不必要的浏览器标签页
A: 有两种方式:
- 修改现有数据: 编辑
src/data/terminalOutputs.ts文件 - 添加新类型: 在同一文件中添加新的输出类型并注册
// 示例:添加自定义内容
export const customOutput: TerminalLine[] = [
{ text: "你的自定义内容", colorRole: "primary" }
];A: 编辑 src/data/colorThemes.ts 文件:
// 添加新主题
myCustomTheme: {
name: 'My Theme',
background: 'bg-gray-900',
colors: {
primary: 'text-green-400',
// ... 其他颜色
}
}A: 可能的原因和解决方案:
- 浏览器自动播放策略: 现代浏览器需要用户交互才能播放音频
- 网络问题: 检查网络连接
- YouTube 限制: 某些视频可能有嵌入限制
A: 项目主要为桌面设计,但在移动设备上也可以基本使用:
- 终端窗口会自动缩放
- 拖拽功能在触屏上可能不够流畅
- 建议使用横屏模式获得更好体验
A: 项目是纯静态网站,可以部署到任何静态托管服务:
# 构建项目
npm run build
# dist 文件夹包含所有静态文件
# 上传到你的服务器或 CDN支持的平台:
- Vercel (推荐)
- Netlify
- GitHub Pages
- AWS S3
- 任何支持静态文件的服务器
A: 请在 GitHub 上创建 Issue:
- 访问 Issues 页面
- 点击 "New Issue"
- 选择合适的模板
- 详细描述问题或需求
本项目采用 MIT 许可证。详见 LICENSE 文件。
- 感谢所有贡献者的努力
- 特别感谢开源社区提供的优秀工具和库
- 灵感来源于经典的终端模拟器和开发者工具
🎉 享受编码的乐趣!如果这个项目对你有帮助,请给我们一个 ⭐️