Skip to main content

autumn_plugin_three/
lib.rs

1//! This crate adds Three.js 3D scenes to Autumn apps. It works with Maud
2//! and htmx.
3//!
4//! Add [`ThreePlugin`] to the app. Put [`three_stylesheet()`] and
5//! [`three_script()`] in the page `<head>`. Then write a [`Scene`]:
6//!
7//! ```rust,no_run
8//! use autumn_plugin_three::{
9//!     Color, Controls, Environment, Mesh, Scene, ThreePlugin, three_script, three_stylesheet,
10//! };
11//! use autumn_web::prelude::*;
12//!
13//! #[get("/")]
14//! async fn index() -> Markup {
15//!     html! {
16//!         html {
17//!             head { (three_stylesheet()) (three_script()) }
18//!             body {
19//!                 (Scene::new()
20//!                     .label("An orange torus knot")
21//!                     .environment(Environment::Room)
22//!                     .controls(Controls::Orbit)
23//!                     .turntable(20.0)
24//!                     .add(Mesh::torus_knot(0.8, 0.25).color(Color::hex(0xff7a18)).metalness(0.6)))
25//!             }
26//!         }
27//!     }
28//! }
29//!
30//! # async fn run() {
31//! autumn_web::app()
32//!     .plugin(ThreePlugin::new())
33//!     .routes(routes![index])
34//!     .run()
35//!     .await;
36//! # }
37//! ```
38//!
39//! # How it works
40//!
41//! - The crate contains [Three.js](https://threejs.org) 0.185.1 (MIT) and
42//!   five addons. It does not use npm or a bundler. [`THREE_ASSETS`] serves
43//!   them under `/static/_plugins/three/`. SRI covers `init.js` and the
44//!   core modules. The addons load from the same origin without SRI.
45//! - The builder renders `data-three-*` attributes. `init.js` reads them and
46//!   builds the scene. You can also write the attributes by hand.
47//! - `init.js` scans on load, on `htmx:afterSwap`, and on each DOM insertion.
48//!   It disposes a scene when its element leaves the document.
49//! - The `three:ready` event gives your own JavaScript the scene, camera,
50//!   renderer, and the shared Three.js module.
51//!
52//! # Limits
53//!
54//! - The plugin uses WebGL only. It does not support the WebGPU renderer.
55//! - The declarative layer has no shadows, post-processing, or physics. Use
56//!   the `three:ready` event for custom code.
57//! - Each scene has its own WebGL context. Browsers keep about 16 contexts.
58//!   When the browser drops a context, the scene shows its fallback.
59//! - The plugin loads only glTF 2.0 and GLB files. It does not decode
60//!   Draco, KTX2, or Meshopt compression. Images inside a GLB work with the
61//!   default CSP. External model and image URLs need a CSP that allows them.
62//! - Do not let user content keep `data-three-*` attributes. User markup
63//!   could then start scenes and load model URLs.
64
65mod assets;
66mod plugin;
67mod scene;
68mod script;
69
70pub use assets::{
71    ASSETS_NAMESPACE, THREE_ASSETS, THREE_MODULE_URL, THREE_VERSION, VENDORED, VendoredFile,
72};
73pub use plugin::{PLUGIN_NAME, ThreePlugin};
74pub use scene::{
75    Aspect, Camera, Clip, Color, Controls, Environment, Geometry, Light, LightKind, Material, Mesh,
76    Model, Scene, SceneObject, Vec3,
77};
78pub use script::{three_script, three_stylesheet};