INIT
This commit is contained in:
91
docs/src/README.md
Normal file
91
docs/src/README.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# Introduction to bevy_cef
|
||||
|
||||
**bevy_cef** is a powerful Bevy plugin that integrates the Chromium Embedded Framework (CEF) into Bevy applications, enabling you to render web content as 3D objects in your game world or as UI overlays.
|
||||
|
||||
## What is bevy_cef?
|
||||
|
||||
bevy_cef bridges the gap between modern web technologies and Bevy's 3D engine by:
|
||||
|
||||
- **Embedding webviews** as textures on 3D meshes or 2D sprites
|
||||
- **Supporting bidirectional communication** between JavaScript and Bevy systems
|
||||
- **Providing a multi-process architecture** for stability and performance
|
||||
- **Offering local asset serving** through a custom URL scheme
|
||||
- **Enabling developer tools integration** for debugging web content
|
||||
|
||||
## Key Features
|
||||
|
||||
### 🌐 Web Content Rendering
|
||||
- Render any web page as a texture on 3D objects
|
||||
- Support for HTML5, CSS3, and modern JavaScript
|
||||
- Local file serving via the `cef://localhost/` scheme
|
||||
- Remote web page loading with full browser compatibility
|
||||
|
||||
### 🔄 Inter-Process Communication (IPC)
|
||||
- **JS Emit**: Send events from JavaScript to Bevy systems
|
||||
- **Host Emit**: Send events from Bevy to JavaScript
|
||||
- **Bevy Remote Protocol (BRP)**: Bidirectional RPC communication
|
||||
|
||||
### 🎮 Interactive Controls
|
||||
- Keyboard input forwarding to webviews
|
||||
- Mouse interaction support
|
||||
- Navigation controls (back, forward, refresh)
|
||||
- Zoom level management
|
||||
- Audio muting capabilities
|
||||
|
||||
### 🔧 Developer Experience
|
||||
- Chrome DevTools integration for debugging
|
||||
- Hot-reload support for local assets
|
||||
- Comprehensive error handling and logging
|
||||
- Extensive customization options
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
bevy_cef uses a multi-process architecture similar to modern web browsers:
|
||||
|
||||
- **Browser Process**: The main Bevy application process
|
||||
- **Render Process**: Separate CEF process for web content rendering
|
||||
- **IPC Communication**: Secure inter-process communication channels
|
||||
|
||||
This design ensures stability - if a web page crashes, it won't bring down your entire application.
|
||||
|
||||
## Use Cases
|
||||
|
||||
### Game UI
|
||||
Create rich, responsive game interfaces using familiar web technologies:
|
||||
```rust
|
||||
commands.spawn((
|
||||
CefWebviewUri::local("ui/main-menu.html"),
|
||||
// Render as 2D sprite overlay
|
||||
));
|
||||
```
|
||||
|
||||
### In-World Displays
|
||||
Embed interactive web content directly in your 3D world:
|
||||
```rust
|
||||
commands.spawn((
|
||||
CefWebviewUri::new("https://example.com"),
|
||||
Mesh3d(meshes.add(Plane3d::new(Vec3::Z, Vec2::ONE))),
|
||||
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial::default())),
|
||||
));
|
||||
```
|
||||
|
||||
### Data Visualization
|
||||
Display real-time data using web-based charting libraries:
|
||||
```rust
|
||||
// Load a local HTML file with Chart.js or D3.js
|
||||
commands.spawn((
|
||||
CefWebviewUri::local("charts/dashboard.html"),
|
||||
WebviewSize(Vec2::new(1920.0, 1080.0)),
|
||||
));
|
||||
```
|
||||
|
||||
### Development Tools
|
||||
Integrate web-based development and debugging interfaces directly into your game editor or development build.
|
||||
|
||||
## Getting Started
|
||||
|
||||
Ready to integrate web content into your Bevy application? Check out the [Quick Start](quick-start.md) guide to get up and running in minutes, or dive into [Basic Concepts](basic-concepts.md) to understand the fundamental components and systems.
|
||||
|
||||
## Platform Support
|
||||
|
||||
Currently, bevy_cef focuses on macOS development with plans for expanded platform support. The plugin automatically handles CEF framework installation and configuration on supported platforms.
|
||||
12
docs/src/SUMMARY.md
Normal file
12
docs/src/SUMMARY.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Summary
|
||||
|
||||
[Introduction](README.md)
|
||||
|
||||
# Getting Started
|
||||
- [Installation](installation.md)
|
||||
- [Quick Start](quick-start.md)
|
||||
- [Basic Concepts](basic-concepts.md)
|
||||
|
||||
# User Guide
|
||||
- [Core Components](core-components.md)
|
||||
|
||||
274
docs/src/basic-concepts.md
Normal file
274
docs/src/basic-concepts.md
Normal file
@@ -0,0 +1,274 @@
|
||||
# Basic Concepts
|
||||
|
||||
Understanding these fundamental concepts will help you make the most of bevy_cef in your projects.
|
||||
|
||||
## Multi-Process Architecture
|
||||
|
||||
bevy_cef follows a multi-process architecture similar to modern web browsers:
|
||||
|
||||
### Browser Process
|
||||
- **Main Application**: Your Bevy game/app runs here
|
||||
- **CEF Management**: Handles browser creation and management
|
||||
- **IPC Coordination**: Manages communication with render processes
|
||||
|
||||
### Render Process
|
||||
- **Web Content**: Each webview runs in a separate process
|
||||
- **Isolation**: Crashes in web content don't affect your main application
|
||||
- **Sandboxing**: Enhanced security through process separation
|
||||
|
||||
### Benefits
|
||||
- **Stability**: Web content crashes won't crash your game
|
||||
- **Performance**: CPU-intensive web content won't block your game loop
|
||||
- **Security**: Sandboxed execution of untrusted web content
|
||||
|
||||
## Core Components
|
||||
|
||||
bevy_cef provides several key components that work together:
|
||||
|
||||
### CefWebviewUri
|
||||
The primary component that defines what web content to display:
|
||||
|
||||
```rust
|
||||
// Remote web page
|
||||
CefWebviewUri::new("https://example.com")
|
||||
|
||||
// Local HTML file from assets/
|
||||
CefWebviewUri::local("ui/menu.html")
|
||||
|
||||
// Equivalent to above
|
||||
CefWebviewUri::new("cef://localhost/ui/menu.html")
|
||||
```
|
||||
|
||||
### WebviewSize
|
||||
Controls the rendering resolution of the webview (not the 3D object size):
|
||||
|
||||
```rust
|
||||
WebviewSize(Vec2::new(1920.0, 1080.0)) // High resolution
|
||||
WebviewSize(Vec2::new(800.0, 600.0)) // Standard resolution
|
||||
WebviewSize::default() // 800x800 pixels
|
||||
```
|
||||
|
||||
### Material Integration
|
||||
Webviews integrate with Bevy's material system:
|
||||
|
||||
```rust
|
||||
// Standard material with webview texture
|
||||
WebviewExtendStandardMaterial::default()
|
||||
|
||||
// Custom material properties
|
||||
WebviewExtendStandardMaterial {
|
||||
base: StandardMaterial {
|
||||
unlit: true,
|
||||
emissive: Color::WHITE.into(),
|
||||
..default()
|
||||
},
|
||||
..default()
|
||||
}
|
||||
```
|
||||
|
||||
## Component Requirements
|
||||
|
||||
When you add a `CefWebviewUri` component, bevy_cef automatically requires several other components:
|
||||
|
||||
```rust
|
||||
#[require(WebviewSize, ZoomLevel, AudioMuted)]
|
||||
pub struct CefWebviewUri(pub String);
|
||||
```
|
||||
|
||||
This means every webview entity automatically gets:
|
||||
- **WebviewSize**: Default 800x800 resolution
|
||||
- **ZoomLevel**: Default zoom (0.0 = browser default)
|
||||
- **AudioMuted**: Default unmuted (false)
|
||||
|
||||
## Rendering Modes
|
||||
|
||||
bevy_cef supports different rendering approaches:
|
||||
|
||||
### 3D Mesh Rendering
|
||||
Render web content on 3D objects in your world:
|
||||
|
||||
```rust
|
||||
commands.spawn((
|
||||
CefWebviewUri::local("interface.html"),
|
||||
Mesh3d(meshes.add(Plane3d::new(Vec3::Z, Vec2::ONE))),
|
||||
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial::default())),
|
||||
));
|
||||
```
|
||||
|
||||
### 2D Sprite Rendering
|
||||
Render web content as UI overlays:
|
||||
|
||||
```rust
|
||||
commands.spawn((
|
||||
CefWebviewUri::local("hud.html"),
|
||||
Sprite::default(),
|
||||
WebviewSpriteMaterial::default(),
|
||||
));
|
||||
```
|
||||
|
||||
## Local Asset Serving
|
||||
|
||||
bevy_cef includes a built-in web server that serves files from your `assets/` directory:
|
||||
|
||||
### Custom Scheme
|
||||
- **Scheme**: `cef://localhost/`
|
||||
- **Path Mapping**: `assets/` directory maps to the root
|
||||
- **Example**: `assets/ui/menu.html` → `cef://localhost/ui/menu.html`
|
||||
|
||||
### Supported File Types
|
||||
- HTML, CSS, JavaScript
|
||||
- Images (PNG, JPG, SVG, etc.)
|
||||
- Fonts (WOFF, TTF, etc.)
|
||||
- JSON, XML, and other data files
|
||||
|
||||
### Asset Organization
|
||||
```
|
||||
assets/
|
||||
├── ui/
|
||||
│ ├── menu.html
|
||||
│ ├── styles.css
|
||||
│ └── script.js
|
||||
├── images/
|
||||
│ └── logo.png
|
||||
└── data/
|
||||
└── config.json
|
||||
```
|
||||
|
||||
## Inter-Process Communication (IPC)
|
||||
|
||||
bevy_cef provides three communication patterns:
|
||||
|
||||
### 1. JavaScript to Bevy (JS Emit)
|
||||
Send events from web content to Bevy systems:
|
||||
|
||||
```javascript
|
||||
// In your HTML/JavaScript
|
||||
window.cef.emit('player_action', { action: 'jump', power: 10 });
|
||||
```
|
||||
|
||||
```rust
|
||||
fn main(){
|
||||
App::new()
|
||||
.add_plugins(JsEmitEventPlugin::<PlayerAction>::default())
|
||||
// ...
|
||||
}
|
||||
|
||||
// In your Bevy system
|
||||
#[derive(Event, Deserialize)]
|
||||
struct PlayerAction {
|
||||
action: String,
|
||||
power: i32,
|
||||
}
|
||||
|
||||
fn handle_player_action(trigger: Trigger<PlayerAction>) {
|
||||
let action = trigger.event();
|
||||
info!("Player action: {} with power {}", action.action, action.power);
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Bevy to JavaScript (Host Emit)
|
||||
Send events from Bevy to web content:
|
||||
|
||||
```rust
|
||||
// In your Bevy system
|
||||
commands.entity(webview_entity).trigger(HostEmitEvent {
|
||||
event_name: "score_update".to_string(),
|
||||
data: json!({ "score": 1000, "level": 3 }),
|
||||
});
|
||||
```
|
||||
|
||||
```javascript
|
||||
// In your HTML/JavaScript
|
||||
window.cef.listen('score_update', (data) => {
|
||||
document.getElementById('score').textContent = data.score;
|
||||
document.getElementById('level').textContent = data.level;
|
||||
});
|
||||
```
|
||||
|
||||
### 3. Bevy Remote Protocol (BRP)
|
||||
|
||||
Please see [here](https://gist.github.com/coreh/1baf6f255d7e86e4be29874d00137d1d) for about the Bevy Remote Protocol (BRP).
|
||||
|
||||
Bidirectional RPC calls for complex interactions:
|
||||
|
||||
```rust
|
||||
// Register BRP method in Bevy
|
||||
app.add_plugins(RemotePlugin::default().with_method("get_player_stats", get_stats));
|
||||
```
|
||||
|
||||
```javascript
|
||||
// Call from JavaScript
|
||||
const stats = await window.cef.brp({
|
||||
method: 'get_player_stats',
|
||||
params: { playerId: 42 }
|
||||
});
|
||||
```
|
||||
|
||||
## User Interaction
|
||||
|
||||
### Input Handling
|
||||
Webviews automatically receive keyboard and mouse input when focused:
|
||||
- **Keyboard**: All keyboard events are forwarded
|
||||
- **Mouse**: Click, scroll, and hover events work naturally
|
||||
- **Focus**: Multiple webviews can coexist; input goes to the focused one
|
||||
|
||||
### Navigation
|
||||
Control web navigation programmatically:
|
||||
|
||||
```rust
|
||||
commands.entity(webview).trigger(RequestGoBack);
|
||||
commands.entity(webview).trigger(ReqeustGoForward);
|
||||
```
|
||||
|
||||
### Zoom Control
|
||||
Manage zoom levels per webview:
|
||||
|
||||
```rust
|
||||
// Set zoom level (0.0 = default, positive = zoom in, negative = zoom out)
|
||||
commands.entity(webview).insert(ZoomLevel(1.2));
|
||||
|
||||
// Reset to default zoom
|
||||
commands.entity(webview).insert(ZoomLevel(0.0));
|
||||
```
|
||||
|
||||
## Developer Experience
|
||||
|
||||
### Developer Tools
|
||||
Access Chrome DevTools for debugging:
|
||||
|
||||
```rust
|
||||
// Show developer tools for a webview
|
||||
commands.entity(webview).trigger(RequestShowDevTool);
|
||||
|
||||
// Close developer tools
|
||||
commands.entity(webview).trigger(RequestCloseDevtool);
|
||||
```
|
||||
|
||||
### Hot Reload
|
||||
Local assets automatically reload when changed during development.
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Component Organization
|
||||
```rust
|
||||
// Good: Group related components
|
||||
commands.spawn((
|
||||
// The uri convert to `cef://localhost/index.html`
|
||||
CefWebviewUri::local("index.html"),
|
||||
WebviewSize(Vec2::new(1920.0, 200.0)),
|
||||
ZoomLevel(0.8),
|
||||
AudioMuted(true),
|
||||
Transform::from_translation(Vec3::new(0.0, 5.0, 0.0)),
|
||||
Mesh3d(meshes.add(Quad::new(Vec2::new(4.0, 1.0)))),
|
||||
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial::default())),
|
||||
));
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
Now that you understand the basic concepts:
|
||||
|
||||
- Explore [Core Components](core-components.md) in detail
|
||||
- Learn about [Webview Rendering](webview-rendering.md) techniques
|
||||
- Dive into [Inter-Process Communication](ipc.md) patterns
|
||||
- Check out practical [Examples](examples/simple.md)
|
||||
407
docs/src/core-components.md
Normal file
407
docs/src/core-components.md
Normal file
@@ -0,0 +1,407 @@
|
||||
# Core Components
|
||||
|
||||
bevy_cef provides several essential components that control webview behavior. Understanding these components is crucial
|
||||
for effective use of the library.
|
||||
|
||||
## Component Overview
|
||||
|
||||
| Component | Purpose | Default Value | Required |
|
||||
|-----------------|-------------------------------|-----------------|--------------|
|
||||
| `CefWebviewUri` | Specifies web content URL | None | ✅ Primary |
|
||||
| `WebviewSize` | Controls rendering resolution | 800×800 | ✅ Auto-added |
|
||||
| `ZoomLevel` | Controls webview zoom | 0.0 (default) | ✅ Auto-added |
|
||||
| `AudioMuted` | Controls audio output | false (unmuted) | ✅ Auto-added |
|
||||
| `HostWindow` | Parent window specification | Primary window | ❌ Optional |
|
||||
|
||||
## CefWebviewUri
|
||||
|
||||
The primary component that defines what web content to display.
|
||||
|
||||
### Usage
|
||||
|
||||
```rust
|
||||
use bevy_cef::prelude::*;
|
||||
|
||||
// Remote web page
|
||||
let webview = CefWebviewUri::new("https://example.com");
|
||||
|
||||
// Local HTML file from assets/ directory
|
||||
let webview = CefWebviewUri::local("ui/menu.html");
|
||||
|
||||
// Equivalent to local() method
|
||||
let webview = CefWebviewUri::new("cef://localhost/ui/menu.html");
|
||||
```
|
||||
|
||||
### Implementation Details
|
||||
|
||||
```rust
|
||||
#[derive(Component, Debug, Clone, PartialEq, Eq, Hash, Reflect)]
|
||||
#[require(WebviewSize, ZoomLevel, AudioMuted)]
|
||||
pub struct CefWebviewUri(pub String);
|
||||
```
|
||||
|
||||
The `#[require(...)]` attribute ensures that every webview automatically gets the essential supporting components.
|
||||
|
||||
### Methods
|
||||
|
||||
- **`new(uri)`**: Create with any valid URL (http, https, cef://localhost/)
|
||||
- **`local(path)`**: Create with local file path, automatically prefixed with `cef://localhost/`
|
||||
|
||||
### Local File Serving
|
||||
|
||||
When using local files, bevy_cef serves them through a custom scheme:
|
||||
|
||||
- **Scheme**: `cef://localhost/`
|
||||
- **Root Directory**: Your project's `assets/` folder
|
||||
- **Path Resolution**: Relative paths from assets/ root
|
||||
|
||||
**Example File Structure:**
|
||||
|
||||
```
|
||||
assets/
|
||||
├── index.html → cef://localhost/index.html
|
||||
├── ui/
|
||||
│ ├── menu.html → cef://localhost/ui/menu.html
|
||||
│ └── styles.css → cef://localhost/ui/styles.css
|
||||
└── js/
|
||||
└── app.js → cef://localhost/js/app.js
|
||||
```
|
||||
|
||||
## WebviewSize
|
||||
|
||||
Controls the internal rendering resolution of the webview, independent of the 3D object size.
|
||||
|
||||
### Usage
|
||||
|
||||
```rust
|
||||
use bevy::math::Vec2;
|
||||
|
||||
// High resolution webview
|
||||
WebviewSize(Vec2::new(1920.0, 1080.0))
|
||||
|
||||
// Standard resolution
|
||||
WebviewSize(Vec2::new(800.0, 600.0))
|
||||
|
||||
// Square webview
|
||||
WebviewSize(Vec2::splat(512.0))
|
||||
|
||||
// Default size
|
||||
WebviewSize::default () // 800×800
|
||||
```
|
||||
|
||||
### Performance Considerations
|
||||
|
||||
- **Higher Resolution**: Better quality, more memory usage
|
||||
- **Lower Resolution**: Better performance, potential pixelation
|
||||
- **Aspect Ratio**: Match your 3D mesh proportions for best results
|
||||
|
||||
```rust
|
||||
// Example: Widescreen webview for cinematic content
|
||||
commands.spawn((
|
||||
CefWebviewUri::local("video-player.html"),
|
||||
WebviewSize(Vec2::new(1920.0, 800.0)), // 21:9 aspect ratio
|
||||
Mesh3d(meshes.add(Quad::new(Vec2::new(4.8, 2.0)))), // Match aspect in 3D
|
||||
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial::default ())),
|
||||
));
|
||||
```
|
||||
|
||||
### Dynamic Resizing
|
||||
|
||||
You can change webview size at runtime:
|
||||
|
||||
```rust
|
||||
fn resize_webview(
|
||||
mut webviews: Query<&mut WebviewSize>,
|
||||
keyboard: Res<ButtonInput<KeyCode>>,
|
||||
) {
|
||||
if keyboard.just_pressed(KeyCode::KeyR) {
|
||||
for mut size in webviews.iter_mut() {
|
||||
size.0 *= 1.5; // Increase resolution by 50%
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## ZoomLevel
|
||||
|
||||
Controls the zoom level of web content within the webview.
|
||||
|
||||
### Usage
|
||||
|
||||
```rust
|
||||
// Default zoom (browser default)
|
||||
ZoomLevel(0.0)
|
||||
|
||||
// Zoom in 20%
|
||||
ZoomLevel(1.2)
|
||||
|
||||
// Zoom out 20%
|
||||
ZoomLevel(0.8)
|
||||
|
||||
// Maximum zoom in
|
||||
ZoomLevel(3.0)
|
||||
|
||||
// Maximum zoom out
|
||||
ZoomLevel(0.25)
|
||||
```
|
||||
|
||||
### Zoom Behavior
|
||||
|
||||
- **0.0**: Browser default zoom level
|
||||
- **Positive values**: Zoom in (1.2 = 120% of default)
|
||||
- **Negative values**: Zoom out (0.8 = 80% of default)
|
||||
- **Range**: Typically 0.25 to 3.0 (25% to 300%)
|
||||
|
||||
### Dynamic Zoom Control
|
||||
|
||||
```rust
|
||||
fn zoom_control(
|
||||
mut webviews: Query<&mut ZoomLevel>,
|
||||
keyboard: Res<ButtonInput<KeyCode>>,
|
||||
) {
|
||||
for mut zoom in webviews.iter_mut() {
|
||||
if keyboard.just_pressed(KeyCode::Equal) {
|
||||
zoom.0 = (zoom.0 + 0.1).min(3.0); // Zoom in
|
||||
}
|
||||
if keyboard.just_pressed(KeyCode::Minus) {
|
||||
zoom.0 = (zoom.0 - 0.1).max(0.25); // Zoom out
|
||||
}
|
||||
if keyboard.just_pressed(KeyCode::Digit0) {
|
||||
zoom.0 = 0.0; // Reset zoom
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Use Cases
|
||||
|
||||
- **Accessibility**: Larger text for readability
|
||||
- **Dense Content**: Fit more information in limited space
|
||||
- **Responsive Design**: Adapt to different screen sizes
|
||||
- **User Preference**: Allow users to adjust comfortable viewing size
|
||||
|
||||
## AudioMuted
|
||||
|
||||
Controls whether audio from the webview is muted.
|
||||
|
||||
### Usage
|
||||
|
||||
```rust
|
||||
// Audio enabled (default)
|
||||
AudioMuted(false)
|
||||
|
||||
// Audio muted
|
||||
AudioMuted(true)
|
||||
```
|
||||
|
||||
### Dynamic Audio Control
|
||||
|
||||
```rust
|
||||
fn toggle_audio(
|
||||
mut webviews: Query<&mut AudioMuted>,
|
||||
keyboard: Res<ButtonInput<KeyCode>>,
|
||||
) {
|
||||
if keyboard.just_pressed(KeyCode::KeyM) {
|
||||
for mut muted in webviews.iter_mut() {
|
||||
muted.0 = !muted.0; // Toggle mute state
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Use Cases
|
||||
|
||||
- **Background Content**: Mute decorative webviews
|
||||
- **Multiple Webviews**: Prevent audio conflicts
|
||||
- **User Control**: Provide mute/unmute functionality
|
||||
- **Game State**: Mute during pause or cutscenes
|
||||
|
||||
## HostWindow (Optional)
|
||||
|
||||
Specifies which Bevy window should be the parent of the webview. If not provided, the primary window is used.
|
||||
|
||||
### Usage
|
||||
|
||||
```rust
|
||||
// Use primary window (default behavior)
|
||||
commands.spawn((
|
||||
CefWebviewUri::local("ui.html"),
|
||||
// No HostWindow component needed
|
||||
));
|
||||
|
||||
// Specify a particular window
|
||||
commands.spawn((
|
||||
CefWebviewUri::local("ui.html"),
|
||||
HostWindow(secondary_window_entity),
|
||||
));
|
||||
```
|
||||
|
||||
### Multi-Window Applications
|
||||
|
||||
```rust
|
||||
fn setup_multi_window(
|
||||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<WebviewExtendStandardMaterial>>,
|
||||
) {
|
||||
// Create secondary window
|
||||
let secondary_window = commands.spawn(Window {
|
||||
title: "Secondary Display".to_string(),
|
||||
resolution: (800.0, 600.0).into(),
|
||||
..default()
|
||||
}).id();
|
||||
|
||||
// Main webview in primary window
|
||||
commands.spawn((
|
||||
CefWebviewUri::local("main-ui.html"),
|
||||
Mesh3d(meshes.add(Plane3d::new(Vec3::Z, Vec2::ONE))),
|
||||
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial::default())),
|
||||
));
|
||||
|
||||
// Secondary webview in secondary window
|
||||
commands.spawn((
|
||||
CefWebviewUri::local("secondary-ui.html"),
|
||||
HostWindow(secondary_window),
|
||||
Mesh3d(meshes.add(Plane3d::new(Vec3::Z, Vec2::ONE))),
|
||||
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial::default())),
|
||||
));
|
||||
}
|
||||
```
|
||||
|
||||
## Component Combinations
|
||||
|
||||
### Common Patterns
|
||||
|
||||
**High-Resolution Interactive Display:**
|
||||
|
||||
```rust
|
||||
commands.spawn((
|
||||
CefWebviewUri::local("dashboard.html"),
|
||||
WebviewSize(Vec2::new(2560.0, 1440.0)),
|
||||
ZoomLevel(0.0),
|
||||
AudioMuted(false),
|
||||
));
|
||||
```
|
||||
|
||||
**Compact Information Panel:**
|
||||
|
||||
```rust
|
||||
commands.spawn((
|
||||
CefWebviewUri::local("info-panel.html"),
|
||||
WebviewSize(Vec2::new(400.0, 300.0)),
|
||||
ZoomLevel(0.8),
|
||||
AudioMuted(true),
|
||||
));
|
||||
```
|
||||
|
||||
**Video Player:**
|
||||
|
||||
```rust
|
||||
commands.spawn((
|
||||
CefWebviewUri::new("https://player.example.com"),
|
||||
WebviewSize(Vec2::new(1920.0, 1080.0)),
|
||||
ZoomLevel(0.0),
|
||||
AudioMuted(false), // Keep audio for video
|
||||
));
|
||||
```
|
||||
|
||||
**Background Decoration:**
|
||||
|
||||
```rust
|
||||
commands.spawn((
|
||||
CefWebviewUri::local("animated-bg.html"),
|
||||
WebviewSize(Vec2::new(1024.0, 1024.0)),
|
||||
ZoomLevel(0.0),
|
||||
AudioMuted(true), // No audio for decoration
|
||||
));
|
||||
```
|
||||
|
||||
## Component Lifecycle
|
||||
|
||||
### Automatic Requirements
|
||||
|
||||
When you add `CefWebviewUri`, the required components are automatically added with default values:
|
||||
|
||||
```rust
|
||||
// You only need to specify this:
|
||||
commands.spawn(CefWebviewUri::local("page.html"));
|
||||
|
||||
// But the entity automatically gets:
|
||||
// - WebviewSize(Vec2::splat(800.0))
|
||||
// - ZoomLevel(0.0)
|
||||
// - AudioMuted(false)
|
||||
```
|
||||
|
||||
### Manual Override
|
||||
|
||||
You can override the defaults by adding components explicitly:
|
||||
|
||||
```rust
|
||||
commands.spawn((
|
||||
CefWebviewUri::local("page.html"),
|
||||
WebviewSize(Vec2::new(1024.0, 768.0)), // Override default
|
||||
ZoomLevel(1.2), // Override default
|
||||
AudioMuted(true), // Override default
|
||||
));
|
||||
```
|
||||
|
||||
### Runtime Modification
|
||||
|
||||
All components can be modified at runtime through standard Bevy systems:
|
||||
|
||||
```rust
|
||||
fn modify_webview_properties(
|
||||
mut query: Query<(&mut WebviewSize, &mut ZoomLevel, &mut AudioMuted)>,
|
||||
time: Res<Time>,
|
||||
) {
|
||||
for (mut size, mut zoom, mut muted) in query.iter_mut() {
|
||||
// Dynamic effects based on time, input, game state, etc.
|
||||
let scale = (time.elapsed_secs().sin() + 1.0) / 2.0;
|
||||
zoom.0 = 0.8 + scale * 0.4; // Oscillate between 0.8 and 1.2
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Performance Optimization
|
||||
|
||||
```rust
|
||||
// Good: Appropriate resolution for use case
|
||||
WebviewSize(Vec2::new(800.0, 600.0)) // Standard UI
|
||||
|
||||
// Avoid: Excessive resolution unless needed
|
||||
WebviewSize(Vec2::new(4096.0, 4096.0)) // Only for high-detail content
|
||||
```
|
||||
|
||||
### Memory Management
|
||||
|
||||
```rust
|
||||
// Good: Mute background content
|
||||
commands.spawn((
|
||||
CefWebviewUri::local("ambient-display.html"),
|
||||
AudioMuted(true), // Prevent memory usage for audio processing
|
||||
));
|
||||
```
|
||||
|
||||
### User Experience
|
||||
|
||||
```rust
|
||||
// Good: Consistent zoom across related webviews
|
||||
let ui_zoom = ZoomLevel(1.1);
|
||||
for ui_component in ["menu.html", "inventory.html", "settings.html"] {
|
||||
commands.spawn((
|
||||
CefWebviewUri::local(ui_component),
|
||||
ui_zoom,
|
||||
));
|
||||
}
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Learn about [Webview Rendering](webview-rendering.md) techniques
|
||||
- Explore [Inter-Process Communication](ipc.md) patterns
|
||||
- Check component-specific guides:
|
||||
- [CefWebviewUri Details](core-components/webview-uri.md)
|
||||
- [WebviewSize Details](core-components/webview-size.md)
|
||||
- [HostWindow Details](core-components/host-window.md)
|
||||
137
docs/src/installation.md
Normal file
137
docs/src/installation.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# Installation
|
||||
|
||||
This guide will help you set up bevy_cef in your Bevy project.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### System Requirements
|
||||
|
||||
- **macOS**: Currently the primary supported platform
|
||||
- **Rust**: 1.70 or later
|
||||
- **Bevy**: 0.16 or later
|
||||
|
||||
## Adding bevy_cef to Your Project
|
||||
|
||||
### 1. Add the Dependency
|
||||
|
||||
Add bevy_cef to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
bevy = "0.16"
|
||||
bevy_cef = { version = "0.1", features = ["debug"] }
|
||||
```
|
||||
|
||||
### 2. Enable the Plugin
|
||||
|
||||
Add the `CefPlugin` to your Bevy app:
|
||||
|
||||
```rust
|
||||
use bevy::prelude::*;
|
||||
use bevy_cef::prelude::*;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins((DefaultPlugins, CefPlugin))
|
||||
.run();
|
||||
}
|
||||
```
|
||||
|
||||
## Automatic Setup with Debug Feature
|
||||
|
||||
When you enable the `debug` feature (recommended for development), the build system automatically handles everything for you:
|
||||
|
||||
✅ **Downloads** and extracts CEF framework to `$HOME/.local/share/cef`
|
||||
✅ **Installs** the `bevy_cef_debug_render_process` tool
|
||||
✅ **Installs** the `export-cef-dir` tool
|
||||
✅ **Configures** all necessary environment variables
|
||||
|
||||
Simply run your project:
|
||||
|
||||
```bash
|
||||
cargo run
|
||||
```
|
||||
|
||||
That's it! No manual installation required.
|
||||
|
||||
## Production Builds
|
||||
|
||||
For production builds where you want to minimize dependencies, you can omit the debug feature:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
bevy = "0.16"
|
||||
bevy_cef = "0.1" # No debug feature
|
||||
```
|
||||
|
||||
However, you'll need to ensure the CEF framework is available at runtime. The debug feature is recommended for most development scenarios.
|
||||
|
||||
## Verification
|
||||
|
||||
To verify your installation is working correctly, try running this simple example:
|
||||
|
||||
```rust
|
||||
use bevy::prelude::*;
|
||||
use bevy_cef::prelude::*;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins((DefaultPlugins, CefPlugin))
|
||||
.add_systems(Startup, setup)
|
||||
.run();
|
||||
}
|
||||
|
||||
fn setup(
|
||||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<WebviewExtendStandardMaterial>>,
|
||||
) {
|
||||
// Camera
|
||||
commands.spawn((
|
||||
Camera3d::default(),
|
||||
Transform::from_xyz(0.0, 0.0, 3.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||
));
|
||||
|
||||
// Light
|
||||
commands.spawn((
|
||||
DirectionalLight::default(),
|
||||
Transform::from_xyz(1.0, 1.0, 1.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||
));
|
||||
|
||||
// Webview
|
||||
commands.spawn((
|
||||
CefWebviewUri::new("https://bevy.org"),
|
||||
Mesh3d(meshes.add(Plane3d::new(Vec3::Z, Vec2::ONE))),
|
||||
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial::default())),
|
||||
));
|
||||
}
|
||||
```
|
||||
|
||||
If you see the Bevy website rendered on a plane in your 3D scene, your installation is successful!
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Installation Issues
|
||||
|
||||
#### Build Fails with Debug Feature
|
||||
- Ensure you have internet connection for CEF download
|
||||
- Check available disk space in `$HOME/.local/share/`
|
||||
- Try cleaning and rebuilding: `cargo clean && cargo build`
|
||||
|
||||
#### CEF Framework Issues
|
||||
- The debug feature handles CEF installation automatically
|
||||
- If issues persist, delete `$HOME/.local/share/cef` and rebuild
|
||||
|
||||
#### Linker Errors on macOS
|
||||
- Verify Xcode Command Line Tools are installed: `xcode-select --install`
|
||||
- The debug feature should handle DYLD environment variables automatically
|
||||
|
||||
For more troubleshooting information, see the [Troubleshooting](troubleshooting/common-issues.md) section.
|
||||
|
||||
## Next Steps
|
||||
|
||||
Now that you have bevy_cef installed, check out:
|
||||
|
||||
- [Quick Start](quick-start.md) - Build your first webview in minutes
|
||||
- [Basic Concepts](basic-concepts.md) - Understand the core components
|
||||
- [Examples](examples/simple.md) - Explore practical examples
|
||||
220
docs/src/quick-start.md
Normal file
220
docs/src/quick-start.md
Normal file
@@ -0,0 +1,220 @@
|
||||
# Quick Start
|
||||
|
||||
Get up and running with bevy_cef in just a few minutes! This guide will walk you through creating your first webview-enabled Bevy application.
|
||||
|
||||
## Create a New Project
|
||||
|
||||
Start by creating a new Bevy project:
|
||||
|
||||
```bash
|
||||
cargo new my_webview_app
|
||||
cd my_webview_app
|
||||
```
|
||||
|
||||
## Add Dependencies
|
||||
|
||||
Add bevy_cef to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
bevy = "0.16"
|
||||
bevy_cef = { version = "0.1", features = ["debug"] }
|
||||
```
|
||||
|
||||
## Your First Webview
|
||||
|
||||
Replace the contents of `src/main.rs` with:
|
||||
|
||||
```rust
|
||||
use bevy::prelude::*;
|
||||
use bevy_cef::prelude::*;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins((DefaultPlugins, CefPlugin))
|
||||
.add_systems(Startup, setup)
|
||||
.run();
|
||||
}
|
||||
|
||||
fn setup(
|
||||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<WebviewExtendStandardMaterial>>,
|
||||
) {
|
||||
// Spawn a camera
|
||||
commands.spawn((
|
||||
Camera3d::default(),
|
||||
Transform::from_translation(Vec3::new(0.0, 0.0, 3.0))
|
||||
.looking_at(Vec3::ZERO, Vec3::Y),
|
||||
));
|
||||
|
||||
// Spawn a light
|
||||
commands.spawn((
|
||||
DirectionalLight::default(),
|
||||
Transform::from_translation(Vec3::new(1.0, 1.0, 1.0))
|
||||
.looking_at(Vec3::ZERO, Vec3::Y),
|
||||
));
|
||||
|
||||
// Spawn a webview on a 3D plane
|
||||
commands.spawn((
|
||||
CefWebviewUri::new("https://bevy.org"),
|
||||
Mesh3d(meshes.add(Plane3d::new(Vec3::Z, Vec2::ONE))),
|
||||
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial::default())),
|
||||
));
|
||||
}
|
||||
```
|
||||
|
||||
## Run Your Application
|
||||
|
||||
```bash
|
||||
cargo run
|
||||
```
|
||||
|
||||
That's it! You should see the Bevy website rendered on a 3D plane in your application. The first run might take a moment as bevy_cef downloads and sets up the CEF framework automatically.
|
||||
|
||||
## What Just Happened?
|
||||
|
||||
Let's break down the key components:
|
||||
|
||||
### 1. CefPlugin
|
||||
```rust
|
||||
.add_plugins((DefaultPlugins, CefPlugin))
|
||||
```
|
||||
The `CefPlugin` initializes the CEF framework and sets up all necessary systems for webview rendering.
|
||||
|
||||
### 2. CefWebviewUri
|
||||
```rust
|
||||
CefWebviewUri::new("https://bevy.org")
|
||||
```
|
||||
This component specifies what web content to load. You can use:
|
||||
- **Remote URLs**: `"https://example.com"`
|
||||
- **Local files**: `CefWebviewUri::local("index.html")`
|
||||
|
||||
### 3. WebviewExtendStandardMaterial
|
||||
```rust
|
||||
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial::default()))
|
||||
```
|
||||
This special material renders the webview content as a texture on your 3D mesh.
|
||||
|
||||
## Try Local Content
|
||||
|
||||
Create an `assets/` directory and add a simple HTML file:
|
||||
|
||||
```bash
|
||||
mkdir assets
|
||||
```
|
||||
|
||||
Create `assets/hello.html`:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Hello bevy_cef!</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background: linear-gradient(45deg, #ff6b6b, #4ecdc4);
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 50px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello from bevy_cef! 🎮</h1>
|
||||
<p>This HTML is rendered directly on a 3D mesh!</p>
|
||||
<p>Current time: <span id="time"></span></p>
|
||||
|
||||
<script>
|
||||
function updateTime() {
|
||||
document.getElementById('time').textContent = new Date().toLocaleTimeString();
|
||||
}
|
||||
setInterval(updateTime, 1000);
|
||||
updateTime();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
Update your webview URI in `main.rs`:
|
||||
|
||||
```rust
|
||||
CefWebviewUri::local("hello.html"), // Load local file
|
||||
```
|
||||
|
||||
Run again:
|
||||
|
||||
```bash
|
||||
cargo run
|
||||
```
|
||||
|
||||
You'll see your custom HTML content with a live-updating clock!
|
||||
|
||||
## Next Steps
|
||||
|
||||
### Explore More Features
|
||||
|
||||
- **[JavaScript Communication](ipc/js-emit.md)**: Send data from web pages to Bevy
|
||||
- **[Host Communication](ipc/host-emit.md)**: Send data from Bevy to web pages
|
||||
- **[2D Sprites](webview-rendering/2d-sprite.md)**: Render webviews as UI elements
|
||||
- **[Developer Tools](developer-tools.md)**: Debug your web content
|
||||
|
||||
### Try More Examples
|
||||
|
||||
- **Navigation**: Add back/forward buttons
|
||||
- **Zoom Controls**: Implement zoom in/out functionality
|
||||
- **Multiple Webviews**: Render different content on multiple objects
|
||||
|
||||
### Learn the Architecture
|
||||
|
||||
- **[Basic Concepts](basic-concepts.md)**: Understand core components
|
||||
- **[Multi-Process Design](architecture/multi-process.md)**: How CEF integration works
|
||||
- **[Plugin System](architecture/plugin-system.md)**: Deep dive into the plugin architecture
|
||||
|
||||
## Common First Steps
|
||||
|
||||
### Adding Interaction
|
||||
Make your webview interactive by enabling input:
|
||||
|
||||
```rust
|
||||
// In your setup system, also spawn input handling
|
||||
commands.spawn((
|
||||
CefWebviewUri::local("interactive.html"),
|
||||
WebviewSize(Vec2::new(800.0, 600.0)),
|
||||
// Webview will automatically receive keyboard and mouse input
|
||||
Mesh3d(meshes.add(Plane3d::new(Vec3::Z, Vec2::ONE))),
|
||||
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial::default())),
|
||||
));
|
||||
```
|
||||
|
||||
### Sizing Your Webview
|
||||
Control the resolution of your webview:
|
||||
|
||||
```rust
|
||||
WebviewSize(Vec2::new(1920.0, 1080.0)), // High resolution
|
||||
WebviewSize(Vec2::new(800.0, 600.0)), // Standard resolution
|
||||
```
|
||||
|
||||
### Multiple Webviews
|
||||
You can have multiple webviews in the same scene:
|
||||
|
||||
```rust
|
||||
// First webview
|
||||
commands.spawn((
|
||||
CefWebviewUri::new("https://news.ycombinator.com"),
|
||||
Transform::from_translation(Vec3::new(-2.0, 0.0, 0.0)),
|
||||
Mesh3d(meshes.add(Plane3d::new(Vec3::Z, Vec2::ONE))),
|
||||
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial::default())),
|
||||
));
|
||||
|
||||
// Second webview
|
||||
commands.spawn((
|
||||
CefWebviewUri::local("dashboard.html"),
|
||||
Transform::from_translation(Vec3::new(2.0, 0.0, 0.0)),
|
||||
Mesh3d(meshes.add(Plane3d::new(Vec3::Z, Vec2::ONE))),
|
||||
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial::default())),
|
||||
));
|
||||
```
|
||||
|
||||
You're now ready to build amazing applications that blend 3D graphics with modern web technologies!
|
||||
Reference in New Issue
Block a user