docs: 更新README和文档主题样式
This commit is contained in:
383
README.md
383
README.md
@@ -1,90 +1,61 @@
|
|||||||
# ECS Framework
|
# ESEngine
|
||||||
|
|
||||||
[](https://github.com/esengine/ecs-framework/actions)
|
**English** | [中文](./README_CN.md)
|
||||||
[](https://codecov.io/gh/esengine/ecs-framework)
|
|
||||||
[](https://badge.fury.io/js/%40esengine%2Fecs-framework)
|
|
||||||
[](https://www.npmjs.com/package/@esengine/ecs-framework)
|
|
||||||
[](https://bundlephobia.com/package/@esengine/ecs-framework)
|
|
||||||
[](https://www.typescriptlang.org/)
|
|
||||||
[](https://opensource.org/licenses/MIT)
|
|
||||||
[](#contributors)
|
|
||||||
[](https://github.com/esengine/ecs-framework/stargazers)
|
|
||||||
[](https://deepwiki.com/esengine/ecs-framework)
|
|
||||||
|
|
||||||
<div align="center">
|
**[Documentation](https://esengine.github.io/ecs-framework/) | [API Reference](https://esengine.github.io/ecs-framework/api/) | [Examples](./examples/)**
|
||||||
|
|
||||||
<p>一个高性能的 TypeScript ECS (Entity-Component-System) 框架,专为现代游戏开发而设计。</p>
|
ESEngine is a cross-platform 2D game engine for creating games from a unified interface. It provides a comprehensive set of common tools so that developers can focus on making games without having to reinvent the wheel.
|
||||||
|
|
||||||
<p>A high-performance TypeScript ECS (Entity-Component-System) framework designed for modern game development.</p>
|
Games can be exported to multiple platforms including Web browsers, WeChat Mini Games, and other mini-game platforms.
|
||||||
|
|
||||||
</div>
|
## Free and Open Source
|
||||||
|
|
||||||
---
|
ESEngine is completely free and open source under the MIT license. No strings attached, no royalties. Your games are yours.
|
||||||
|
|
||||||
## 📊 项目统计 / Project Stats
|
## Features
|
||||||
|
|
||||||
<div align="center">
|
- **Data-Driven Architecture**: Built on Entity-Component-System (ECS) pattern for flexible and performant game logic
|
||||||
|
- **High-Performance Rendering**: Rust/WebAssembly 2D renderer with sprite batching and WebGL 2.0 backend
|
||||||
|
- **Visual Editor**: Cross-platform desktop editor with scene management, asset browser, and visual tools
|
||||||
|
- **Modular Design**: Use only what you need. Each feature is a separate module that can be included independently
|
||||||
|
- **Multi-Platform**: Deploy to Web, WeChat Mini Games, and more from a single codebase
|
||||||
|
|
||||||
[](https://star-history.com/#esengine/ecs-framework&Date)
|
## Getting the Engine
|
||||||
|
|
||||||
</div>
|
### Using npm
|
||||||
|
|
||||||
<div align="center">
|
|
||||||
|
|
||||||
<a href="https://github.com/esengine/ecs-framework/graphs/contributors">
|
|
||||||
<img src="https://contrib.rocks/image?repo=esengine/ecs-framework" />
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
### 📈 下载趋势 / Download Trends
|
|
||||||
|
|
||||||
<div align="center">
|
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/@esengine/ecs-framework)
|
|
||||||
|
|
||||||
[](https://npmtrends.com/@esengine/ecs-framework)
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 特性
|
|
||||||
|
|
||||||
- **高性能** - 针对大规模实体优化,支持SoA存储和批量处理
|
|
||||||
- **多线程计算** - Worker系统支持真正的并行处理,充分利用多核CPU性能
|
|
||||||
- **类型安全** - 完整的TypeScript支持,编译时类型检查
|
|
||||||
- **现代架构** - 支持多World、多Scene的分层架构设计
|
|
||||||
- **开发友好** - 内置调试工具和性能监控
|
|
||||||
- **跨平台** - 支持Cocos Creator、Laya引擎和Web平台
|
|
||||||
|
|
||||||
## 安装
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install @esengine/ecs-framework
|
npm install @esengine/ecs-framework
|
||||||
```
|
```
|
||||||
|
|
||||||
## 快速开始
|
### Building from Source
|
||||||
|
|
||||||
|
See [Building from Source](#building-from-source) for detailed instructions.
|
||||||
|
|
||||||
|
### Editor Download
|
||||||
|
|
||||||
|
Pre-built editor binaries are available on the [Releases](https://github.com/esengine/ecs-framework/releases) page for Windows and macOS.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { Core, Scene, Component, EntitySystem, ECSComponent, ECSSystem, Matcher, Time } from '@esengine/ecs-framework';
|
import {
|
||||||
|
Core, Scene, Entity, Component, EntitySystem,
|
||||||
|
Matcher, Time, ECSComponent, ECSSystem
|
||||||
|
} from '@esengine/ecs-framework';
|
||||||
|
|
||||||
// 定义组件
|
|
||||||
@ECSComponent('Position')
|
@ECSComponent('Position')
|
||||||
class Position extends Component {
|
class Position extends Component {
|
||||||
constructor(public x = 0, public y = 0) {
|
x = 0;
|
||||||
super();
|
y = 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ECSComponent('Velocity')
|
@ECSComponent('Velocity')
|
||||||
class Velocity extends Component {
|
class Velocity extends Component {
|
||||||
constructor(public dx = 0, public dy = 0) {
|
dx = 0;
|
||||||
super();
|
dy = 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建系统
|
|
||||||
@ECSSystem('Movement')
|
@ECSSystem('Movement')
|
||||||
class MovementSystem extends EntitySystem {
|
class MovementSystem extends EntitySystem {
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -93,177 +64,171 @@ class MovementSystem extends EntitySystem {
|
|||||||
|
|
||||||
protected process(entities: readonly Entity[]): void {
|
protected process(entities: readonly Entity[]): void {
|
||||||
for (const entity of entities) {
|
for (const entity of entities) {
|
||||||
const position = entity.getComponent(Position)!;
|
const pos = entity.getComponent(Position);
|
||||||
const velocity = entity.getComponent(Velocity)!;
|
const vel = entity.getComponent(Velocity);
|
||||||
|
pos.x += vel.dx * Time.deltaTime;
|
||||||
position.x += velocity.dx * Time.deltaTime;
|
pos.y += vel.dy * Time.deltaTime;
|
||||||
position.y += velocity.dy * Time.deltaTime;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建场景并启动
|
|
||||||
class GameScene extends Scene {
|
|
||||||
protected initialize(): void {
|
|
||||||
this.addSystem(new MovementSystem());
|
|
||||||
|
|
||||||
const player = this.createEntity("Player");
|
|
||||||
player.addComponent(new Position(100, 100));
|
|
||||||
player.addComponent(new Velocity(50, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 启动游戏
|
|
||||||
Core.create();
|
Core.create();
|
||||||
Core.setScene(new GameScene());
|
const scene = new Scene();
|
||||||
|
scene.addSystem(new MovementSystem());
|
||||||
|
|
||||||
// 游戏循环中更新
|
const player = scene.createEntity('Player');
|
||||||
function gameLoop(deltaTime: number) {
|
player.addComponent(new Position());
|
||||||
Core.update(deltaTime);
|
player.addComponent(new Velocity());
|
||||||
}
|
|
||||||
|
Core.setScene(scene);
|
||||||
```
|
```
|
||||||
|
|
||||||
## 核心特性
|
## Modules
|
||||||
|
|
||||||
- **实体查询** - 使用 Matcher API 进行高效的实体过滤
|
ESEngine is organized into modular packages. Each feature has a runtime module and an optional editor extension.
|
||||||
- **事件系统** - 类型安全的事件发布/订阅机制
|
|
||||||
- **性能优化** - SoA 存储优化,支持大规模实体处理
|
|
||||||
- **多线程支持** - Worker系统实现真正的并行计算,充分利用多核CPU
|
|
||||||
- **多场景** - 支持 World/Scene 分层架构
|
|
||||||
- **时间管理** - 内置定时器和时间控制系统
|
|
||||||
|
|
||||||
## 🏗️ 架构设计 / Architecture
|
### Core
|
||||||
|
|
||||||
```mermaid
|
| Package | Description |
|
||||||
graph TB
|
|---------|-------------|
|
||||||
A[Core 核心] --> B[World 世界]
|
| `@esengine/ecs-framework` | Core ECS framework with entity management, component system, and queries |
|
||||||
B --> C[Scene 场景]
|
| `@esengine/math` | Vector, matrix, and mathematical utilities |
|
||||||
C --> D[EntityManager 实体管理器]
|
| `@esengine/engine` | Rust/WASM 2D renderer |
|
||||||
C --> E[SystemManager 系统管理器]
|
| `@esengine/engine-core` | Engine module system and lifecycle management |
|
||||||
D --> F[Entity 实体]
|
|
||||||
F --> G[Component 组件]
|
|
||||||
E --> H[EntitySystem 实体系统]
|
|
||||||
E --> I[WorkerSystem 工作线程系统]
|
|
||||||
|
|
||||||
style A fill:#e1f5ff
|
### Runtime Modules
|
||||||
style B fill:#fff3e0
|
|
||||||
style C fill:#f3e5f5
|
| Package | Description |
|
||||||
style D fill:#e8f5e9
|
|---------|-------------|
|
||||||
style E fill:#fff9c4
|
| `@esengine/sprite` | 2D sprite rendering and animation |
|
||||||
style F fill:#ffebee
|
| `@esengine/tilemap` | Tile-based map rendering with animation support |
|
||||||
style G fill:#e0f2f1
|
| `@esengine/physics-rapier2d` | 2D physics simulation powered by Rapier |
|
||||||
style H fill:#fce4ec
|
| `@esengine/behavior-tree` | Behavior tree AI system |
|
||||||
style I fill:#f1f8e9
|
| `@esengine/blueprint` | Visual scripting runtime |
|
||||||
|
| `@esengine/camera` | Camera control and management |
|
||||||
|
| `@esengine/audio` | Audio playback |
|
||||||
|
| `@esengine/ui` | UI components |
|
||||||
|
| `@esengine/material-system` | Material and shader system |
|
||||||
|
| `@esengine/asset-system` | Asset loading and management |
|
||||||
|
|
||||||
|
### Editor Extensions
|
||||||
|
|
||||||
|
| Package | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `@esengine/sprite-editor` | Sprite inspector and tools |
|
||||||
|
| `@esengine/tilemap-editor` | Visual tilemap editor with brush tools |
|
||||||
|
| `@esengine/physics-rapier2d-editor` | Physics collider visualization and editing |
|
||||||
|
| `@esengine/behavior-tree-editor` | Visual behavior tree editor |
|
||||||
|
| `@esengine/blueprint-editor` | Visual scripting editor |
|
||||||
|
| `@esengine/material-editor` | Material and shader editor |
|
||||||
|
| `@esengine/shader-editor` | Shader code editor |
|
||||||
|
|
||||||
|
### Platform
|
||||||
|
|
||||||
|
| Package | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `@esengine/platform-common` | Platform abstraction interfaces |
|
||||||
|
| `@esengine/platform-web` | Web browser runtime |
|
||||||
|
| `@esengine/platform-wechat` | WeChat Mini Game runtime |
|
||||||
|
|
||||||
|
## Editor
|
||||||
|
|
||||||
|
ESEngine Editor is a cross-platform desktop application built with Tauri and React.
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- Scene hierarchy and entity management
|
||||||
|
- Component inspector with custom editors
|
||||||
|
- Asset browser with drag-and-drop support
|
||||||
|
- Tilemap editor with paint, fill, and selection tools
|
||||||
|
- Behavior tree visual editor
|
||||||
|
- Blueprint visual scripting
|
||||||
|
- Material and shader editing
|
||||||
|
- Built-in performance profiler
|
||||||
|
- Localization support (English, Chinese)
|
||||||
|
|
||||||
|
### Screenshot
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Supported Platforms
|
||||||
|
|
||||||
|
| Platform | Runtime | Editor |
|
||||||
|
|----------|---------|--------|
|
||||||
|
| Web Browser | Yes | - |
|
||||||
|
| Windows | - | Yes |
|
||||||
|
| macOS | - | Yes |
|
||||||
|
| WeChat Mini Game | In Progress | - |
|
||||||
|
| Playable Ads | Planned | - |
|
||||||
|
| Android | Planned | - |
|
||||||
|
| iOS | Planned | - |
|
||||||
|
| Windows Native | Planned | - |
|
||||||
|
| Other Platforms | Planned | - |
|
||||||
|
|
||||||
|
## Building from Source
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Node.js 18 or later
|
||||||
|
- pnpm 10 or later
|
||||||
|
- Rust toolchain (for WASM renderer)
|
||||||
|
- wasm-pack
|
||||||
|
|
||||||
|
### Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone repository
|
||||||
|
git clone https://github.com/esengine/ecs-framework.git
|
||||||
|
cd ecs-framework
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
pnpm install
|
||||||
|
|
||||||
|
# Build all packages
|
||||||
|
pnpm build
|
||||||
|
|
||||||
|
# Build WASM renderer (optional)
|
||||||
|
pnpm build:wasm
|
||||||
```
|
```
|
||||||
|
|
||||||
## 平台支持
|
### Running the Editor
|
||||||
|
|
||||||
支持主流游戏引擎和 Web 平台:
|
```bash
|
||||||
|
cd packages/editor-app
|
||||||
|
pnpm tauri:dev
|
||||||
|
```
|
||||||
|
|
||||||
- **Cocos Creator**
|
### Project Structure
|
||||||
- **Laya 引擎**
|
|
||||||
- **原生 Web** - 浏览器环境直接运行
|
|
||||||
- **小游戏平台** - 微信、支付宝等小游戏
|
|
||||||
|
|
||||||
## ECS Framework Editor
|
```
|
||||||
|
ecs-framework/
|
||||||
|
├── packages/ Engine packages (runtime, editor, platform)
|
||||||
|
├── docs/ Documentation source
|
||||||
|
├── examples/ Example projects
|
||||||
|
├── scripts/ Build utilities
|
||||||
|
└── thirdparty/ Third-party dependencies
|
||||||
|
```
|
||||||
|
|
||||||
跨平台桌面编辑器,提供可视化开发和调试工具。
|
## Documentation
|
||||||
|
|
||||||
### 主要功能
|
- [Getting Started](https://esengine.github.io/ecs-framework/guide/getting-started.html)
|
||||||
|
- [Architecture Guide](https://esengine.github.io/ecs-framework/guide/)
|
||||||
|
- [API Reference](https://esengine.github.io/ecs-framework/api/)
|
||||||
|
|
||||||
- **场景管理** - 可视化场景层级和实体管理
|
## Community
|
||||||
- **组件检视** - 实时查看和编辑实体组件
|
|
||||||
- **性能分析** - 内置 Profiler 监控系统性能
|
|
||||||
- **插件系统** - 可扩展的插件架构
|
|
||||||
- **远程调试** - 连接运行中的游戏进行实时调试
|
|
||||||
- **自动更新** - 支持热更新,自动获取最新版本
|
|
||||||
|
|
||||||
### 下载
|
- [GitHub Issues](https://github.com/esengine/ecs-framework/issues) - Bug reports and feature requests
|
||||||
|
- [GitHub Discussions](https://github.com/esengine/ecs-framework/discussions) - Questions and ideas
|
||||||
|
|
||||||
[](https://github.com/esengine/ecs-framework/releases/latest)
|
## Contributing
|
||||||
|
|
||||||
支持 Windows、macOS (Intel & Apple Silicon)
|
Contributions are welcome. Please read the contributing guidelines before submitting a pull request.
|
||||||
|
|
||||||
### 截图
|
1. Fork the repository
|
||||||
|
2. Create a feature branch
|
||||||
|
3. Make changes with tests
|
||||||
|
4. Submit a pull request
|
||||||
|
|
||||||
<img src="screenshots/main_screetshot.png" alt="ECS Framework Editor" width="800">
|
## License
|
||||||
|
|
||||||
<details>
|
ESEngine is licensed under the [MIT License](LICENSE).
|
||||||
<summary>查看更多截图</summary>
|
|
||||||
|
|
||||||
**性能分析器**
|
|
||||||
<img src="screenshots/performance_profiler.png" alt="Performance Profiler" width="600">
|
|
||||||
|
|
||||||
**插件管理**
|
|
||||||
<img src="screenshots/plugin_manager.png" alt="Plugin Manager" width="600">
|
|
||||||
|
|
||||||
**设置界面**
|
|
||||||
<img src="screenshots/settings.png" alt="Settings" width="600">
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
## 示例项目
|
|
||||||
|
|
||||||
- [Worker系统演示](https://esengine.github.io/ecs-framework/demos/worker-system/) - 多线程物理系统演示,展示高性能并行计算
|
|
||||||
- [割草机演示](https://github.com/esengine/lawn-mower-demo) - 完整的游戏示例
|
|
||||||
|
|
||||||
## 文档
|
|
||||||
|
|
||||||
- [📚 AI智能文档](https://deepwiki.com/esengine/ecs-framework) - AI助手随时解答你的问题
|
|
||||||
- [快速入门](https://esengine.github.io/ecs-framework/guide/getting-started.html) - 详细教程和平台集成
|
|
||||||
- [完整指南](https://esengine.github.io/ecs-framework/guide/) - ECS 概念和使用指南
|
|
||||||
- [API 参考](https://esengine.github.io/ecs-framework/api/) - 完整 API 文档
|
|
||||||
|
|
||||||
## 💪 支持项目 / Support the Project
|
|
||||||
|
|
||||||
如果这个项目对你有帮助,请考虑:
|
|
||||||
|
|
||||||
If this project helps you, please consider:
|
|
||||||
|
|
||||||
<div align="center">
|
|
||||||
|
|
||||||
[](https://github.com/sponsors/esengine)
|
|
||||||
[](https://github.com/esengine/ecs-framework)
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
- ⭐ 给项目点个 Star
|
|
||||||
- 🐛 报告 Bug 或提出新功能
|
|
||||||
- 📝 改进文档
|
|
||||||
- 💖 成为赞助者
|
|
||||||
|
|
||||||
## 社区与支持
|
|
||||||
|
|
||||||
- [问题反馈](https://github.com/esengine/ecs-framework/issues) - Bug 报告和功能建议
|
|
||||||
- [讨论区](https://github.com/esengine/ecs-framework/discussions) - 提问、分享想法
|
|
||||||
- [QQ 交流群](https://jq.qq.com/?_wv=1027&k=29w1Nud6) - ecs游戏框架交流
|
|
||||||
|
|
||||||
## 贡献者 / Contributors
|
|
||||||
|
|
||||||
感谢所有为这个项目做出贡献的人!
|
|
||||||
|
|
||||||
Thanks goes to these wonderful people:
|
|
||||||
|
|
||||||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
|
||||||
<!-- prettier-ignore-start -->
|
|
||||||
<!-- markdownlint-disable -->
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/esengine"><img src="https://avatars.githubusercontent.com/esengine?s=100" width="100px;" alt="esengine"/><br /><sub><b>esengine</b></sub></a><br /><a href="#maintenance-esengine" title="Maintenance">🚧</a> <a href="https://github.com/esengine/ecs-framework/commits?author=esengine" title="Code">💻</a> <a href="#design-esengine" title="Design">🎨</a></td>
|
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/foxling"><img src="https://avatars.githubusercontent.com/foxling?s=100" width="100px;" alt="LING YE"/><br /><sub><b>LING YE</b></sub></a><br /><a href="https://github.com/esengine/ecs-framework/commits?author=foxling" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MirageTank"><img src="https://avatars.githubusercontent.com/MirageTank?s=100" width="100px;" alt="MirageTank"/><br /><sub><b>MirageTank</b></sub></a><br /><a href="https://github.com/esengine/ecs-framework/commits?author=MirageTank" title="Code">💻</a></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<!-- markdownlint-restore -->
|
|
||||||
<!-- prettier-ignore-end -->
|
|
||||||
|
|
||||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
|
||||||
|
|
||||||
本项目遵循 [all-contributors](https://github.com/all-contributors/all-contributors) 规范。欢迎任何形式的贡献!
|
|
||||||
|
|
||||||
## 许可证
|
|
||||||
|
|
||||||
[MIT](LICENSE) © 2025 ECS Framework
|
|
||||||
|
|||||||
235
README_CN.md
Normal file
235
README_CN.md
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
# ESEngine
|
||||||
|
|
||||||
|
[English](./README.md) | **中文**
|
||||||
|
|
||||||
|
**[文档](https://esengine.github.io/ecs-framework/) | [API 参考](https://esengine.github.io/ecs-framework/api/) | [示例](./examples/)**
|
||||||
|
|
||||||
|
ESEngine 是一个跨平台 2D 游戏引擎,提供统一的开发界面。它包含完整的常用工具集,让开发者专注于游戏创作本身。
|
||||||
|
|
||||||
|
游戏可以导出到多个平台,包括 Web 浏览器、微信小游戏等小游戏平台。
|
||||||
|
|
||||||
|
## 免费开源
|
||||||
|
|
||||||
|
ESEngine 基于 MIT 协议完全免费开源。无附加条件,无版税。你的游戏完全属于你。
|
||||||
|
|
||||||
|
## 特性
|
||||||
|
|
||||||
|
- **数据驱动架构**:基于 ECS(实体-组件-系统)模式构建,提供灵活高效的游戏逻辑
|
||||||
|
- **高性能渲染**:Rust/WebAssembly 2D 渲染器,支持精灵批处理和 WebGL 2.0
|
||||||
|
- **可视化编辑器**:跨平台桌面编辑器,包含场景管理、资源浏览器和可视化工具
|
||||||
|
- **模块化设计**:按需使用,每个功能都是独立模块,可单独引入
|
||||||
|
- **多平台支持**:一套代码部署到 Web、微信小游戏等多个平台
|
||||||
|
|
||||||
|
## 获取引擎
|
||||||
|
|
||||||
|
### 通过 npm 安装
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install @esengine/ecs-framework
|
||||||
|
```
|
||||||
|
|
||||||
|
### 从源码构建
|
||||||
|
|
||||||
|
详见 [从源码构建](#从源码构建) 章节。
|
||||||
|
|
||||||
|
### 编辑器下载
|
||||||
|
|
||||||
|
预编译的编辑器可在 [Releases](https://github.com/esengine/ecs-framework/releases) 页面下载,支持 Windows 和 macOS。
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import {
|
||||||
|
Core, Scene, Entity, Component, EntitySystem,
|
||||||
|
Matcher, Time, ECSComponent, ECSSystem
|
||||||
|
} from '@esengine/ecs-framework';
|
||||||
|
|
||||||
|
@ECSComponent('Position')
|
||||||
|
class Position extends Component {
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ECSComponent('Velocity')
|
||||||
|
class Velocity extends Component {
|
||||||
|
dx = 0;
|
||||||
|
dy = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ECSSystem('Movement')
|
||||||
|
class MovementSystem extends EntitySystem {
|
||||||
|
constructor() {
|
||||||
|
super(Matcher.all(Position, Velocity));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected process(entities: readonly Entity[]): void {
|
||||||
|
for (const entity of entities) {
|
||||||
|
const pos = entity.getComponent(Position);
|
||||||
|
const vel = entity.getComponent(Velocity);
|
||||||
|
pos.x += vel.dx * Time.deltaTime;
|
||||||
|
pos.y += vel.dy * Time.deltaTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Core.create();
|
||||||
|
const scene = new Scene();
|
||||||
|
scene.addSystem(new MovementSystem());
|
||||||
|
|
||||||
|
const player = scene.createEntity('Player');
|
||||||
|
player.addComponent(new Position());
|
||||||
|
player.addComponent(new Velocity());
|
||||||
|
|
||||||
|
Core.setScene(scene);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 模块
|
||||||
|
|
||||||
|
ESEngine 采用模块化组织。每个功能都有运行时模块和可选的编辑器扩展。
|
||||||
|
|
||||||
|
### 核心
|
||||||
|
|
||||||
|
| 包名 | 描述 |
|
||||||
|
|------|------|
|
||||||
|
| `@esengine/ecs-framework` | ECS 框架核心,包含实体管理、组件系统和查询 |
|
||||||
|
| `@esengine/math` | 向量、矩阵和数学工具 |
|
||||||
|
| `@esengine/engine` | Rust/WASM 2D 渲染器 |
|
||||||
|
| `@esengine/engine-core` | 引擎模块系统和生命周期管理 |
|
||||||
|
|
||||||
|
### 运行时模块
|
||||||
|
|
||||||
|
| 包名 | 描述 |
|
||||||
|
|------|------|
|
||||||
|
| `@esengine/sprite` | 2D 精灵渲染和动画 |
|
||||||
|
| `@esengine/tilemap` | Tilemap 渲染,支持动画 |
|
||||||
|
| `@esengine/physics-rapier2d` | 基于 Rapier 的 2D 物理模拟 |
|
||||||
|
| `@esengine/behavior-tree` | 行为树 AI 系统 |
|
||||||
|
| `@esengine/blueprint` | 可视化脚本运行时 |
|
||||||
|
| `@esengine/camera` | 相机控制和管理 |
|
||||||
|
| `@esengine/audio` | 音频播放 |
|
||||||
|
| `@esengine/ui` | UI 组件 |
|
||||||
|
| `@esengine/material-system` | 材质和着色器系统 |
|
||||||
|
| `@esengine/asset-system` | 资源加载和管理 |
|
||||||
|
|
||||||
|
### 编辑器扩展
|
||||||
|
|
||||||
|
| 包名 | 描述 |
|
||||||
|
|------|------|
|
||||||
|
| `@esengine/sprite-editor` | 精灵检视器和工具 |
|
||||||
|
| `@esengine/tilemap-editor` | 可视化 Tilemap 编辑器,支持笔刷工具 |
|
||||||
|
| `@esengine/physics-rapier2d-editor` | 物理碰撞体可视化和编辑 |
|
||||||
|
| `@esengine/behavior-tree-editor` | 可视化行为树编辑器 |
|
||||||
|
| `@esengine/blueprint-editor` | 可视化脚本编辑器 |
|
||||||
|
| `@esengine/material-editor` | 材质和着色器编辑器 |
|
||||||
|
| `@esengine/shader-editor` | 着色器代码编辑器 |
|
||||||
|
|
||||||
|
### 平台
|
||||||
|
|
||||||
|
| 包名 | 描述 |
|
||||||
|
|------|------|
|
||||||
|
| `@esengine/platform-common` | 平台抽象接口 |
|
||||||
|
| `@esengine/platform-web` | Web 浏览器运行时 |
|
||||||
|
| `@esengine/platform-wechat` | 微信小游戏运行时 |
|
||||||
|
|
||||||
|
## 编辑器
|
||||||
|
|
||||||
|
ESEngine 编辑器是基于 Tauri 和 React 构建的跨平台桌面应用。
|
||||||
|
|
||||||
|
### 功能
|
||||||
|
|
||||||
|
- 场景层级和实体管理
|
||||||
|
- 组件检视器,支持自定义编辑器
|
||||||
|
- 资源浏览器,支持拖放
|
||||||
|
- Tilemap 编辑器,支持绘制、填充、选择工具
|
||||||
|
- 行为树可视化编辑器
|
||||||
|
- 蓝图可视化脚本
|
||||||
|
- 材质和着色器编辑
|
||||||
|
- 内置性能分析器
|
||||||
|
- 多语言支持(英文、中文)
|
||||||
|
|
||||||
|
### 截图
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 支持的平台
|
||||||
|
|
||||||
|
| 平台 | 运行时 | 编辑器 |
|
||||||
|
|------|--------|--------|
|
||||||
|
| Web 浏览器 | 支持 | - |
|
||||||
|
| Windows | - | 支持 |
|
||||||
|
| macOS | - | 支持 |
|
||||||
|
| 微信小游戏 | 开发中 | - |
|
||||||
|
| Playable 可玩广告 | 计划中 | - |
|
||||||
|
| Android | 计划中 | - |
|
||||||
|
| iOS | 计划中 | - |
|
||||||
|
| Windows 原生 | 计划中 | - |
|
||||||
|
| 其他平台 | 计划中 | - |
|
||||||
|
|
||||||
|
## 从源码构建
|
||||||
|
|
||||||
|
### 前置要求
|
||||||
|
|
||||||
|
- Node.js 18 或更高版本
|
||||||
|
- pnpm 10 或更高版本
|
||||||
|
- Rust 工具链(用于 WASM 渲染器)
|
||||||
|
- wasm-pack
|
||||||
|
|
||||||
|
### 安装
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 克隆仓库
|
||||||
|
git clone https://github.com/esengine/ecs-framework.git
|
||||||
|
cd ecs-framework
|
||||||
|
|
||||||
|
# 安装依赖
|
||||||
|
pnpm install
|
||||||
|
|
||||||
|
# 构建所有包
|
||||||
|
pnpm build
|
||||||
|
|
||||||
|
# 构建 WASM 渲染器(可选)
|
||||||
|
pnpm build:wasm
|
||||||
|
```
|
||||||
|
|
||||||
|
### 运行编辑器
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd packages/editor-app
|
||||||
|
pnpm tauri:dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
ecs-framework/
|
||||||
|
├── packages/ 引擎包(运行时、编辑器、平台)
|
||||||
|
├── docs/ 文档源码
|
||||||
|
├── examples/ 示例项目
|
||||||
|
├── scripts/ 构建工具
|
||||||
|
└── thirdparty/ 第三方依赖
|
||||||
|
```
|
||||||
|
|
||||||
|
## 文档
|
||||||
|
|
||||||
|
- [快速入门](https://esengine.github.io/ecs-framework/guide/getting-started.html)
|
||||||
|
- [架构指南](https://esengine.github.io/ecs-framework/guide/)
|
||||||
|
- [API 参考](https://esengine.github.io/ecs-framework/api/)
|
||||||
|
|
||||||
|
## 社区
|
||||||
|
|
||||||
|
- [GitHub Issues](https://github.com/esengine/ecs-framework/issues) - Bug 反馈和功能建议
|
||||||
|
- [GitHub Discussions](https://github.com/esengine/ecs-framework/discussions) - 问题和想法
|
||||||
|
- [QQ 交流群](https://jq.qq.com/?_wv=1027&k=29w1Nud6) - 中文社区
|
||||||
|
|
||||||
|
## 贡献
|
||||||
|
|
||||||
|
欢迎贡献代码。提交 PR 前请阅读贡献指南。
|
||||||
|
|
||||||
|
1. Fork 仓库
|
||||||
|
2. 创建功能分支
|
||||||
|
3. 修改代码并测试
|
||||||
|
4. 提交 PR
|
||||||
|
|
||||||
|
## 许可证
|
||||||
|
|
||||||
|
ESEngine 基于 [MIT 协议](LICENSE) 开源。
|
||||||
@@ -1,78 +1,84 @@
|
|||||||
/* ============================================
|
|
||||||
ESEngine 文档站主题样式
|
|
||||||
============================================ */
|
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
color-scheme: dark;
|
color-scheme: dark;
|
||||||
--vp-nav-height: 64px;
|
--vp-nav-height: 64px;
|
||||||
|
|
||||||
|
--es-bg-base: #1e1e1e;
|
||||||
|
--es-bg-elevated: #252526;
|
||||||
|
--es-bg-overlay: #2d2d2d;
|
||||||
|
--es-bg-input: #3c3c3c;
|
||||||
|
--es-bg-inset: #181818;
|
||||||
|
--es-bg-hover: #2a2d2e;
|
||||||
|
--es-bg-active: #37373d;
|
||||||
|
--es-bg-sidebar: #262626;
|
||||||
|
--es-bg-card: #2a2a2a;
|
||||||
|
--es-bg-header: #2d2d2d;
|
||||||
|
|
||||||
|
--es-text-primary: #cccccc;
|
||||||
|
--es-text-secondary: #9d9d9d;
|
||||||
|
--es-text-tertiary: #6a6a6a;
|
||||||
|
--es-text-inverse: #ffffff;
|
||||||
|
--es-text-muted: #aaaaaa;
|
||||||
|
--es-text-dim: #6a6a6a;
|
||||||
|
|
||||||
|
--es-font-xs: 11px;
|
||||||
|
--es-font-sm: 12px;
|
||||||
|
--es-font-base: 13px;
|
||||||
|
--es-font-md: 14px;
|
||||||
|
--es-font-lg: 16px;
|
||||||
|
|
||||||
|
--es-border-default: #3a3a3a;
|
||||||
|
--es-border-subtle: #1a1a1a;
|
||||||
|
--es-border-strong: #4a4a4a;
|
||||||
|
|
||||||
|
--es-primary: #3b82f6;
|
||||||
|
--es-primary-hover: #2563eb;
|
||||||
|
--es-success: #4ade80;
|
||||||
|
--es-warning: #f59e0b;
|
||||||
|
--es-error: #ef4444;
|
||||||
|
--es-info: #3b82f6;
|
||||||
|
|
||||||
|
--es-selected: #3d5a80;
|
||||||
|
--es-selected-hover: #4a6a90;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background: #0d0d0d !important;
|
background: var(--es-bg-base) !important;
|
||||||
}
|
|
||||||
|
|
||||||
.VPContent.has-sidebar {
|
|
||||||
background: linear-gradient(180deg, #1e3a5f 0%, #152540 30vh, #0d1a2a 50vh, #0d0d0d 70vh) !important;
|
|
||||||
background-repeat: no-repeat !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
html,
|
html,
|
||||||
html.dark {
|
html.dark {
|
||||||
--vp-c-bg: #0d0d0d;
|
--vp-c-bg: var(--es-bg-base);
|
||||||
--vp-c-bg-soft: #1a1a1a;
|
--vp-c-bg-soft: var(--es-bg-elevated);
|
||||||
--vp-c-bg-mute: #1f1f1f;
|
--vp-c-bg-mute: var(--es-bg-overlay);
|
||||||
--vp-c-bg-alt: #1a1a1a;
|
--vp-c-bg-alt: var(--es-bg-sidebar);
|
||||||
--vp-c-text-1: #e0e0e0;
|
--vp-c-text-1: var(--es-text-primary);
|
||||||
--vp-c-text-2: #a0a0a0;
|
--vp-c-text-2: var(--es-text-tertiary);
|
||||||
--vp-c-text-3: #707070;
|
--vp-c-text-3: var(--es-text-muted);
|
||||||
--vp-c-divider: #2a2a2a;
|
--vp-c-divider: var(--es-border-default);
|
||||||
--vp-c-divider-light: #222222;
|
--vp-c-divider-light: var(--es-border-subtle);
|
||||||
}
|
}
|
||||||
|
|
||||||
html:not(.dark) {
|
html:not(.dark) {
|
||||||
--vp-c-bg: #0d0d0d !important;
|
--vp-c-bg: var(--es-bg-base) !important;
|
||||||
--vp-c-bg-soft: #1a1a1a !important;
|
--vp-c-bg-soft: var(--es-bg-elevated) !important;
|
||||||
--vp-c-bg-mute: #1f1f1f !important;
|
--vp-c-bg-mute: var(--es-bg-overlay) !important;
|
||||||
--vp-c-bg-alt: #1a1a1a !important;
|
--vp-c-bg-alt: var(--es-bg-sidebar) !important;
|
||||||
--vp-c-text-1: #e0e0e0 !important;
|
--vp-c-text-1: var(--es-text-primary) !important;
|
||||||
--vp-c-text-2: #a0a0a0 !important;
|
--vp-c-text-2: var(--es-text-tertiary) !important;
|
||||||
--vp-c-text-3: #707070 !important;
|
--vp-c-text-3: var(--es-text-muted) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
|
||||||
--es-bg-base: #0d0d0d;
|
|
||||||
--es-bg-sidebar: #1a1a1a;
|
|
||||||
--es-bg-card: #1f1f1f;
|
|
||||||
--es-bg-hover: #252525;
|
|
||||||
--es-bg-selected: #0e4a7c;
|
|
||||||
|
|
||||||
--es-text-primary: #e0e0e0;
|
|
||||||
--es-text-secondary: #a0a0a0;
|
|
||||||
--es-text-tertiary: #707070;
|
|
||||||
--es-text-inverse: #ffffff;
|
|
||||||
|
|
||||||
--es-border-default: #2a2a2a;
|
|
||||||
--es-border-subtle: #222222;
|
|
||||||
|
|
||||||
--es-primary: #3b9eff;
|
|
||||||
--es-warning: #c9a227;
|
|
||||||
--es-info: #3b9eff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
导航栏
|
|
||||||
============================================ */
|
|
||||||
.VPNav {
|
.VPNav {
|
||||||
background: #0d0d0d !important;
|
background: var(--es-bg-header) !important;
|
||||||
border-bottom: 1px solid #2a2a2a !important;
|
border-bottom: 1px solid var(--es-border-subtle) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPNav .VPNavBar {
|
.VPNav .VPNavBar {
|
||||||
background: #0d0d0d !important;
|
background: var(--es-bg-header) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPNav .VPNavBar .wrapper {
|
.VPNav .VPNavBar .wrapper {
|
||||||
background: #0d0d0d !important;
|
background: var(--es-bg-header) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPNav .VPNavBar::before,
|
.VPNav .VPNavBar::before,
|
||||||
@@ -81,7 +87,7 @@ html:not(.dark) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.VPNavBar {
|
.VPNavBar {
|
||||||
background: #0d0d0d !important;
|
background: var(--es-bg-header) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPNavBar::before {
|
.VPNavBar::before {
|
||||||
@@ -89,127 +95,110 @@ html:not(.dark) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.VPNavBarTitle .title {
|
.VPNavBarTitle .title {
|
||||||
color: #ffffff;
|
color: var(--es-text-primary);
|
||||||
font-weight: 600;
|
font-weight: 500;
|
||||||
font-size: 15px;
|
font-size: var(--es-font-base);
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPNavBarMenuLink {
|
.VPNavBarMenuLink {
|
||||||
color: #a0a0a0 !important;
|
color: var(--es-text-secondary) !important;
|
||||||
font-size: 14px !important;
|
font-size: var(--es-font-sm) !important;
|
||||||
font-weight: 400 !important;
|
font-weight: 400 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPNavBarMenuLink:hover {
|
.VPNavBarMenuLink:hover {
|
||||||
color: #ffffff !important;
|
color: var(--es-text-primary) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPNavBarMenuLink.active {
|
.VPNavBarMenuLink.active {
|
||||||
color: #ffffff !important;
|
color: var(--es-text-primary) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPNavBarSearch .DocSearch-Button {
|
.VPNavBarSearch .DocSearch-Button {
|
||||||
background: #1a1a1a !important;
|
background: var(--es-bg-input) !important;
|
||||||
border: 1px solid #2a2a2a !important;
|
border: 1px solid var(--es-border-default) !important;
|
||||||
border-radius: 6px;
|
border-radius: 2px;
|
||||||
|
height: 26px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
侧边栏
|
|
||||||
============================================ */
|
|
||||||
.VPSidebar {
|
.VPSidebar {
|
||||||
background: transparent !important;
|
background: var(--es-bg-sidebar) !important;
|
||||||
border-right: 1px solid rgba(255, 255, 255, 0.1) !important;
|
border-right: 1px solid var(--es-border-subtle) !important;
|
||||||
padding: 16px 0 !important;
|
|
||||||
width: 280px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.VPSidebar .nav {
|
|
||||||
padding: 0 16px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPSidebarItem.level-0 > .item {
|
.VPSidebarItem.level-0 > .item {
|
||||||
padding: 12px 0 6px 0;
|
padding: 8px 0 4px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPSidebarItem.level-0 > .item > .text {
|
.VPSidebarItem.level-0 > .item > .text {
|
||||||
font-weight: 400;
|
font-weight: 600;
|
||||||
font-size: 13px;
|
font-size: var(--es-font-xs);
|
||||||
color: #808080;
|
color: var(--es-text-secondary);
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.5px;
|
letter-spacing: 0.05em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPSidebarItem .link {
|
.VPSidebarItem .link {
|
||||||
padding: 6px 12px;
|
padding: 4px 8px;
|
||||||
margin: 1px 0;
|
margin: 1px 0;
|
||||||
border-radius: 4px;
|
border-radius: 2px;
|
||||||
color: #9d9d9d;
|
color: var(--es-text-primary);
|
||||||
font-size: 14px;
|
font-size: var(--es-font-sm);
|
||||||
transition: all 0.15s;
|
transition: all 0.1s ease;
|
||||||
position: relative;
|
|
||||||
border-left: 2px solid transparent;
|
border-left: 2px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPSidebarItem .link:hover {
|
.VPSidebarItem .link:hover {
|
||||||
background: rgba(255, 255, 255, 0.05);
|
background: rgba(255, 255, 255, 0.03);
|
||||||
color: #ffffff;
|
color: var(--es-text-inverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPSidebarItem.is-active > .item > .link {
|
.VPSidebarItem.is-active > .item > .link {
|
||||||
background: transparent;
|
background: var(--es-selected);
|
||||||
color: #ffffff;
|
color: var(--es-text-inverse);
|
||||||
border-left: 2px solid #3b9eff;
|
border-left: 2px solid var(--es-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPSidebarItem.is-active > .item > .link:hover {
|
||||||
|
background: var(--es-selected-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPSidebarItem.level-1 .link {
|
.VPSidebarItem.level-1 .link {
|
||||||
padding-left: 24px;
|
padding-left: 20px;
|
||||||
font-size: 13px;
|
font-size: var(--es-font-sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPSidebarItem.level-2 .link {
|
.VPSidebarItem.level-2 .link {
|
||||||
padding-left: 36px;
|
padding-left: 32px;
|
||||||
font-size: 13px;
|
font-size: var(--es-font-sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPSidebarItem .caret {
|
.VPSidebarItem .caret {
|
||||||
color: #606060;
|
color: var(--es-text-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPSidebarItem .caret:hover {
|
.VPSidebarItem .caret:hover {
|
||||||
color: #9d9d9d;
|
color: var(--es-text-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
内容区域
|
|
||||||
============================================ */
|
|
||||||
.VPContent {
|
.VPContent {
|
||||||
background: transparent !important;
|
background: var(--es-bg-card) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPContent.has-sidebar {
|
||||||
|
background: var(--es-bg-card) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPDoc {
|
.VPDoc {
|
||||||
background: transparent !important;
|
background: transparent !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPDoc .container {
|
|
||||||
max-width: 100% !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.VPDoc .content {
|
|
||||||
max-width: 860px !important;
|
|
||||||
padding: 80px 60px 48px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.VPNavBar {
|
|
||||||
background: #0d0d0d !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.VPNavBar .content {
|
.VPNavBar .content {
|
||||||
background: #0d0d0d !important;
|
background: var(--es-bg-header) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPNavBar .content-body {
|
.VPNavBar .content-body {
|
||||||
background: #0d0d0d !important;
|
background: var(--es-bg-header) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPNavBar .divider {
|
.VPNavBar .divider {
|
||||||
@@ -217,16 +206,16 @@ html:not(.dark) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.VPLocalNav {
|
.VPLocalNav {
|
||||||
background: #0d0d0d !important;
|
background: var(--es-bg-header) !important;
|
||||||
border-bottom: 1px solid #2a2a2a !important;
|
border-bottom: 1px solid var(--es-border-subtle) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPNavScreenMenu {
|
.VPNavScreenMenu {
|
||||||
background: #0d0d0d !important;
|
background: var(--es-bg-base) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPNavScreen {
|
.VPNavScreen {
|
||||||
background: #0d0d0d !important;
|
background: var(--es-bg-base) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.curtain {
|
.curtain {
|
||||||
@@ -248,68 +237,71 @@ html:not(.dark) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc {
|
.vp-doc {
|
||||||
color: #e0e0e0;
|
color: var(--es-text-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc h1 {
|
.vp-doc h1 {
|
||||||
font-size: 32px;
|
font-size: var(--es-font-lg);
|
||||||
font-weight: 700;
|
font-weight: 600;
|
||||||
color: #ffffff;
|
color: var(--es-text-inverse);
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
margin-bottom: 32px;
|
margin-bottom: 16px;
|
||||||
line-height: 1.2;
|
line-height: 1.3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc h2 {
|
.vp-doc h2 {
|
||||||
font-size: 24px;
|
font-size: var(--es-font-md);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #ffffff;
|
color: var(--es-text-inverse);
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
margin-top: 48px;
|
margin-top: 32px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 12px;
|
||||||
|
padding: 6px 12px;
|
||||||
|
background: var(--es-bg-header);
|
||||||
|
border-left: 3px solid var(--es-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc h3 {
|
.vp-doc h3 {
|
||||||
font-size: 18px;
|
font-size: var(--es-font-base);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #ffffff;
|
color: var(--es-text-primary);
|
||||||
margin-top: 32px;
|
margin-top: 20px;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc p {
|
.vp-doc p {
|
||||||
color: #a0a0a0;
|
color: var(--es-text-primary);
|
||||||
line-height: 1.8;
|
line-height: 1.7;
|
||||||
font-size: 15px;
|
font-size: var(--es-font-base);
|
||||||
margin: 20px 0;
|
margin: 12px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc ul,
|
.vp-doc ul,
|
||||||
.vp-doc ol {
|
.vp-doc ol {
|
||||||
padding-left: 24px;
|
padding-left: 20px;
|
||||||
margin: 20px 0;
|
margin: 12px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc li {
|
.vp-doc li {
|
||||||
line-height: 1.8;
|
line-height: 1.7;
|
||||||
margin: 8px 0;
|
margin: 4px 0;
|
||||||
color: #a0a0a0;
|
color: var(--es-text-primary);
|
||||||
font-size: 15px;
|
font-size: var(--es-font-base);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc li::marker {
|
.vp-doc li::marker {
|
||||||
color: #707070;
|
color: var(--es-text-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc strong {
|
.vp-doc strong {
|
||||||
color: #ffffff;
|
color: var(--es-text-primary);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc a {
|
.vp-doc a {
|
||||||
color: #3b9eff;
|
color: var(--es-primary);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,12 +309,9 @@ html:not(.dark) {
|
|||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
右侧大纲
|
|
||||||
============================================ */
|
|
||||||
.VPDocAside {
|
.VPDocAside {
|
||||||
padding-left: 32px;
|
padding-left: 16px;
|
||||||
border-left: 1px solid #2a2a2a;
|
border-left: 1px solid var(--es-border-subtle);
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPDocAsideOutline {
|
.VPDocAsideOutline {
|
||||||
@@ -336,71 +325,66 @@ html:not(.dark) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.VPDocAsideOutline .outline-title {
|
.VPDocAsideOutline .outline-title {
|
||||||
font-size: 14px;
|
font-size: var(--es-font-xs);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
text-transform: none;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0;
|
letter-spacing: 0.05em;
|
||||||
color: #ffffff;
|
color: var(--es-text-secondary);
|
||||||
padding-bottom: 16px;
|
padding-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPDocAsideOutline .outline-link {
|
.VPDocAsideOutline .outline-link {
|
||||||
color: #707070;
|
color: var(--es-text-secondary);
|
||||||
font-size: 13px;
|
font-size: var(--es-font-xs);
|
||||||
padding: 6px 0;
|
padding: 4px 0;
|
||||||
line-height: 1.5;
|
line-height: 1.4;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPDocAsideOutline .outline-link:hover {
|
.VPDocAsideOutline .outline-link:hover {
|
||||||
color: #a0a0a0;
|
color: var(--es-text-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPDocAsideOutline .outline-link.active {
|
.VPDocAsideOutline .outline-link.active {
|
||||||
color: #3b9eff;
|
color: var(--es-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPDocAsideOutline .outline-marker {
|
.VPDocAsideOutline .outline-marker {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
代码块
|
|
||||||
============================================ */
|
|
||||||
div[class*='language-'] {
|
div[class*='language-'] {
|
||||||
background: #1a1a1a !important;
|
background: var(--es-bg-inset) !important;
|
||||||
border: 1px solid #2a2a2a;
|
border: 1px solid var(--es-border-default);
|
||||||
border-radius: 8px;
|
border-radius: 2px;
|
||||||
margin: 20px 0;
|
margin: 12px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-code-group .tabs {
|
.vp-code-group .tabs {
|
||||||
background: #1f1f1f;
|
background: var(--es-bg-header);
|
||||||
border-bottom: 1px solid #2a2a2a;
|
border-bottom: 1px solid var(--es-border-subtle);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc :not(pre) > code {
|
.vp-doc :not(pre) > code {
|
||||||
background: #1f1f1f;
|
background: var(--es-bg-input);
|
||||||
color: #3b9eff;
|
color: var(--es-primary);
|
||||||
padding: 3px 8px;
|
padding: 2px 6px;
|
||||||
border-radius: 4px;
|
border-radius: 2px;
|
||||||
font-size: 0.9em;
|
font-size: var(--es-font-xs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
表格
|
|
||||||
============================================ */
|
|
||||||
.vp-doc table {
|
.vp-doc table {
|
||||||
display: table;
|
display: table;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
border: none;
|
border: none;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
margin: 24px 0;
|
margin: 16px 0;
|
||||||
|
font-size: var(--es-font-sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc tr {
|
.vp-doc tr {
|
||||||
border-bottom: 1px solid #2a2a2a;
|
border-bottom: 1px solid var(--es-border-subtle);
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,224 +392,193 @@ div[class*='language-'] {
|
|||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.vp-doc tr:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.02);
|
||||||
|
}
|
||||||
|
|
||||||
.vp-doc th {
|
.vp-doc th {
|
||||||
background: #1f1f1f;
|
background: var(--es-bg-header);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 14px;
|
font-size: var(--es-font-xs);
|
||||||
color: #a0a0a0;
|
color: var(--es-text-secondary);
|
||||||
text-align: left;
|
text-align: left;
|
||||||
padding: 14px 20px;
|
padding: 8px 12px;
|
||||||
border-bottom: 1px solid #2a2a2a;
|
border-bottom: 1px solid var(--es-border-subtle);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc td {
|
.vp-doc td {
|
||||||
font-size: 15px;
|
font-size: var(--es-font-sm);
|
||||||
color: #e0e0e0;
|
color: var(--es-text-primary);
|
||||||
padding: 14px 20px;
|
padding: 8px 12px;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
line-height: 1.6;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc td:first-child {
|
.vp-doc td:first-child {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #a0a0a0;
|
color: var(--es-text-primary);
|
||||||
min-width: 120px;
|
min-width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
提示框
|
|
||||||
============================================ */
|
|
||||||
.vp-doc .warning,
|
.vp-doc .warning,
|
||||||
.vp-doc .custom-block.warning {
|
.vp-doc .custom-block.warning {
|
||||||
background: rgba(201, 162, 39, 0.08);
|
background: rgba(245, 158, 11, 0.08);
|
||||||
border: none;
|
border: none;
|
||||||
border-left: 4px solid #c9a227;
|
border-left: 3px solid var(--es-warning);
|
||||||
border-radius: 0 8px 8px 0;
|
border-radius: 0 2px 2px 0;
|
||||||
padding: 16px 24px;
|
padding: 10px 12px;
|
||||||
margin: 24px 0;
|
margin: 16px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc .warning .custom-block-title,
|
.vp-doc .warning .custom-block-title,
|
||||||
.vp-doc .custom-block.warning .custom-block-title {
|
.vp-doc .custom-block.warning .custom-block-title {
|
||||||
color: #c9a227;
|
color: var(--es-warning);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 15px;
|
font-size: var(--es-font-xs);
|
||||||
margin-bottom: 8px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc .warning p {
|
.vp-doc .warning p {
|
||||||
color: #a0a0a0;
|
color: var(--es-text-primary);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
font-size: var(--es-font-xs);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc .tip,
|
.vp-doc .tip,
|
||||||
.vp-doc .custom-block.tip {
|
.vp-doc .custom-block.tip {
|
||||||
background: rgba(59, 158, 255, 0.08);
|
background: rgba(59, 130, 246, 0.08);
|
||||||
border: none;
|
border: none;
|
||||||
border-left: 4px solid #3b9eff;
|
border-left: 3px solid var(--es-primary);
|
||||||
border-radius: 0 8px 8px 0;
|
border-radius: 0 2px 2px 0;
|
||||||
padding: 16px 24px;
|
padding: 10px 12px;
|
||||||
margin: 24px 0;
|
margin: 16px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc .tip .custom-block-title,
|
.vp-doc .tip .custom-block-title,
|
||||||
.vp-doc .custom-block.tip .custom-block-title {
|
.vp-doc .custom-block.tip .custom-block-title {
|
||||||
color: #3b9eff;
|
color: var(--es-primary);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 15px;
|
font-size: var(--es-font-xs);
|
||||||
margin-bottom: 8px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc .tip p {
|
.vp-doc .tip p {
|
||||||
color: #a0a0a0;
|
color: var(--es-text-primary);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
font-size: var(--es-font-xs);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc .info,
|
.vp-doc .info,
|
||||||
.vp-doc .custom-block.info {
|
.vp-doc .custom-block.info {
|
||||||
background: rgba(78, 201, 176, 0.08);
|
background: rgba(74, 222, 128, 0.08);
|
||||||
border: none;
|
border: none;
|
||||||
border-left: 4px solid #4ec9b0;
|
border-left: 3px solid var(--es-success);
|
||||||
border-radius: 0 8px 8px 0;
|
border-radius: 0 2px 2px 0;
|
||||||
padding: 16px 24px;
|
padding: 10px 12px;
|
||||||
margin: 24px 0;
|
margin: 16px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc .info .custom-block-title,
|
.vp-doc .info .custom-block-title,
|
||||||
.vp-doc .custom-block.info .custom-block-title {
|
.vp-doc .custom-block.info .custom-block-title {
|
||||||
color: #4ec9b0;
|
color: var(--es-success);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 15px;
|
font-size: var(--es-font-xs);
|
||||||
margin-bottom: 8px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc .danger,
|
.vp-doc .danger,
|
||||||
.vp-doc .custom-block.danger {
|
.vp-doc .custom-block.danger {
|
||||||
background: rgba(244, 135, 113, 0.08);
|
background: rgba(239, 68, 68, 0.08);
|
||||||
border: none;
|
border: none;
|
||||||
border-left: 4px solid #f48771;
|
border-left: 3px solid var(--es-error);
|
||||||
border-radius: 0 8px 8px 0;
|
border-radius: 0 2px 2px 0;
|
||||||
padding: 16px 24px;
|
padding: 10px 12px;
|
||||||
margin: 24px 0;
|
margin: 16px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc .danger .custom-block-title,
|
.vp-doc .danger .custom-block-title,
|
||||||
.vp-doc .custom-block.danger .custom-block-title {
|
.vp-doc .custom-block.danger .custom-block-title {
|
||||||
color: #f48771;
|
color: var(--es-error);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 15px;
|
font-size: var(--es-font-xs);
|
||||||
margin-bottom: 8px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
卡片样式
|
|
||||||
============================================ */
|
|
||||||
.vp-doc .card {
|
.vp-doc .card {
|
||||||
background: #1f1f1f;
|
background: var(--es-bg-sidebar);
|
||||||
border-radius: 12px;
|
border: 1px solid var(--es-border-subtle);
|
||||||
padding: 24px;
|
border-radius: 4px;
|
||||||
margin: 24px 0;
|
padding: 12px;
|
||||||
|
margin: 16px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc .card-title {
|
.vp-doc .card-title {
|
||||||
font-size: 18px;
|
font-size: var(--es-font-sm);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #ffffff;
|
color: var(--es-text-primary);
|
||||||
margin-bottom: 8px;
|
margin-bottom: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vp-doc .card-description {
|
.vp-doc .card-description {
|
||||||
font-size: 14px;
|
font-size: var(--es-font-xs);
|
||||||
color: #707070;
|
color: var(--es-text-muted);
|
||||||
line-height: 1.6;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
标签样式
|
|
||||||
============================================ */
|
|
||||||
.vp-doc .tag {
|
.vp-doc .tag {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 4px 12px;
|
padding: 2px 8px;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
border: 1px solid #3a3a3a;
|
border: 1px solid var(--es-border-default);
|
||||||
border-radius: 16px;
|
border-radius: 2px;
|
||||||
color: #a0a0a0;
|
color: var(--es-text-secondary);
|
||||||
font-size: 13px;
|
font-size: var(--es-font-xs);
|
||||||
margin-right: 8px;
|
margin-right: 4px;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
链接行样式
|
|
||||||
============================================ */
|
|
||||||
.vp-doc .link-row {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 12px;
|
|
||||||
padding: 12px 0;
|
|
||||||
color: #a0a0a0;
|
|
||||||
font-size: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vp-doc .link-row a {
|
|
||||||
color: #3b9eff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
页脚
|
|
||||||
============================================ */
|
|
||||||
.VPFooter {
|
.VPFooter {
|
||||||
background: #1a1a1a !important;
|
background: var(--es-bg-sidebar) !important;
|
||||||
border-top: 1px solid #2a2a2a !important;
|
border-top: 1px solid var(--es-border-subtle) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
滚动条
|
|
||||||
============================================ */
|
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
width: 8px;
|
width: 8px;
|
||||||
height: 8px;
|
height: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
::-webkit-scrollbar-track {
|
||||||
background: transparent;
|
background: var(--es-bg-card);
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
::-webkit-scrollbar-thumb {
|
||||||
background: #3a3a3a;
|
background: var(--es-border-strong);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
border: 2px solid var(--es-bg-card);
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb:hover {
|
::-webkit-scrollbar-thumb:hover {
|
||||||
background: #4a4a4a;
|
background: #5a5a5a;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-corner {
|
::-webkit-scrollbar-corner {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
首页专用样式
|
|
||||||
============================================ */
|
|
||||||
.home-container {
|
.home-container {
|
||||||
max-width: 1200px;
|
max-width: 1000px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0 24px;
|
padding: 0 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.home-section {
|
.home-section {
|
||||||
padding: 48px 0;
|
padding: 32px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
响应式
|
|
||||||
============================================ */
|
|
||||||
@media (max-width: 960px) {
|
@media (max-width: 960px) {
|
||||||
.VPDoc .content {
|
.VPDoc .content {
|
||||||
padding: 24px !important;
|
padding: 16px !important;
|
||||||
}
|
|
||||||
|
|
||||||
.VPSidebar {
|
|
||||||
width: 100% !important;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user