| Crates.io | director-engine |
| lib.rs | director-engine |
| version | 1.1.1 |
| created_at | 2025-11-29 14:56:36.673203+00 |
| updated_at | 2025-12-08 00:30:55.976601+00 |
| description | A high-performance 2D rendering engine using Skia and Taffy |
| homepage | |
| repository | https://github.com/babybirdprd/rust-skia-engine |
| max_upload_size | |
| id | 1956837 |
| size | 796,296 |
A high-performance, frame-based 2D rendering engine written in Rust.
Designed to be embedded in Rust applications, director-engine combines a Scene Graph, CSS-like layout (Taffy), Skia for high-quality rasterization, and Rhai for scripting to enable programmatic video generation.
The engine operates on a Frame-Based, State-Driven model:
Director.video-rs) for MP4 encoding.graph TD
Script[Rhai Script] -->|Commands| API[Scripting API]
API -->|Mutate| Director[Director Context]
subgraph Engine Core
Director -->|Manage| Timeline[Timeline]
Director -->|Manage| AssetLoader[Asset Loader]
Director -->|Manage| Mixer[Audio Mixer]
Director -->|Update| SceneGraph[Scene Graph]
end
SceneGraph -->|Style| Taffy[Taffy Layout]
Timeline -->|Current Time| Animation[Animation System]
Animation -->|Interpolate| SceneGraph
subgraph Rendering Pipeline
SceneGraph -->|Draw| Skia[Skia Rasterizer]
Mixer -->|Samples| Encoder[Video/Audio Encoder]
Skia -->|Pixels| Encoder
end
Encoder -->|MP4| Output[output.mp4]
Add this to your Cargo.toml:
[dependencies]
director-engine = "1.1.1"
rhai = "1.19.0" # Recommended to match engine's version
anyhow = "1.0"
This crate depends on skia-safe and video-rs (ffmpeg).
sudo apt install libavutil-dev libavformat-dev libavcodec-dev libswscale-devbrew install ffmpegInitialize the engine and run a script from your Rust application.
use director_engine::{scripting, DefaultAssetLoader, render::render_export};
use rhai::Engine;
use std::sync::Arc;
use std::path::PathBuf;
fn main() -> anyhow::Result<()> {
// 1. Initialize Rhai Engine with Director API
let mut engine = Engine::new();
scripting::register_rhai_api(&mut engine, Arc::new(DefaultAssetLoader));
// 2. Define Script
let script = r#"
let movie = new_director(1920, 1080, 30);
let scene = movie.add_scene(5.0);
scene.add_text(#{
content: "Hello World",
size: 100.0,
color: "#FFFFFF"
});
movie
"#;
// 3. Compile & Execute
let movie_handle = engine.eval::<scripting::MovieHandle>(script)?;
// 4. Render
println!("Rendering...");
let mut director = movie_handle.director.lock().unwrap();
render_export(&mut director, PathBuf::from("output.mp4"), None, None)?;
println!("Done!");
Ok(())
}
The scripting API is designed to be intuitive and CSS-like.
let movie = new_director(1080, 1920, 30);
let scene = movie.add_scene(5.0);
// Flexbox Layout
let box = scene.add_box(#{
width: "100%",
height: "100%",
justify_content: "center",
align_items: "center",
bg_color: "#1e1e1e"
});
// Rich Text
let text = box.add_text(#{
content: "Director Engine",
size: 80.0,
color: "#ffffff",
weight: "bold"
});
// Animation
text.animate("scale", 0.0, 1.0, 1.5, "bounce_out");
movie
Composition nodes with their own isolated timelines.src/lib.rs: Library entry point.src/director.rs: Core engine coordinator.src/scripting.rs: Rhai bindings and API definition.src/render.rs: Skia rendering pipeline.src/node.rs: Visual node implementations.