mirror of
https://github.com/storytold/storyteller-bevy.git
synced 2026-10-18 00:23:14 +00:00
Single-object viewer POC (#14)
This commit implements a Sketchfab-style single-object viewer as a minimal proof-of-concept. ### `@storyteller/studio-web` This is a new package to house web components for interfacing with the `@storyteller/studio` WASM library. It currently includes a single component, `<sts-viewer />`, which is exported from `@storyteller/studio-web/viewer`. ### `react-frontend` This is a new application intended as a proof-of-concept and testbed for React interop with `@storyteller/studio-web`. Web components are currently a little bit fiddly to use in a React application. `react-frontend/src/app/studio-viewer.tsx` demonstrates how a React-idiomatic component can be written as a thin wrapper around a web component, and `react-frontend/src/app/app.tsx` demonstrates that wrapper component in use.
This commit is contained in:
+89
-12
@@ -2,27 +2,36 @@
|
||||
|
||||
use bevy::prelude::*;
|
||||
use bevy_mod_picking::DefaultPickingPlugins;
|
||||
use camera_controller::CameraControllerPlugin;
|
||||
use debug::DebugPlugin;
|
||||
use input::StudioInputPlugin;
|
||||
use interaction::InteractionPlugin;
|
||||
use math::InterpolationPlugin;
|
||||
use scene::ScenePlugin;
|
||||
use skybox::SkyboxPlugin;
|
||||
use ui::UiLayerPlugin;
|
||||
use viewport::ViewportSize;
|
||||
|
||||
#[cfg(feature = "wasm")]
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
mod camera_controller;
|
||||
mod debug;
|
||||
mod design_system;
|
||||
mod input;
|
||||
mod inspector;
|
||||
mod interaction;
|
||||
mod math;
|
||||
mod scene;
|
||||
mod skybox;
|
||||
mod ui;
|
||||
mod viewport;
|
||||
mod world_grid;
|
||||
|
||||
use crate::{
|
||||
camera_controller::CameraControllerPlugin,
|
||||
debug::DebugPlugin,
|
||||
input::StudioInputPlugin,
|
||||
inspector::InspectorPlugin,
|
||||
interaction::InteractionPlugin,
|
||||
math::InterpolationPlugin,
|
||||
scene::{LoadSceneEvent, ScenePlugin},
|
||||
skybox::{SkyboxId, SkyboxPlugin},
|
||||
ui::UiLayerPlugin,
|
||||
viewport::ViewportSize,
|
||||
world_grid::WorldGridPlugin,
|
||||
};
|
||||
|
||||
#[cfg(feature = "wasm")]
|
||||
mod wasm;
|
||||
@@ -30,7 +39,7 @@ mod wasm;
|
||||
#[derive(Component)]
|
||||
pub(crate) struct MainCamera;
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[cfg_attr(feature = "wasm", wasm_bindgen)]
|
||||
pub fn init(viewport_size: ViewportSize) {
|
||||
#[cfg(feature = "wasm")]
|
||||
console_error_panic_hook::set_once();
|
||||
@@ -62,12 +71,80 @@ pub fn init(viewport_size: ViewportSize) {
|
||||
DefaultPickingPlugins,
|
||||
DebugPlugin,
|
||||
InteractionPlugin,
|
||||
InspectorPlugin,
|
||||
StudioInputPlugin,
|
||||
InterpolationPlugin,
|
||||
CameraControllerPlugin,
|
||||
ScenePlugin,
|
||||
SkyboxPlugin,
|
||||
UiLayerPlugin,
|
||||
))
|
||||
.run();
|
||||
WorldGridPlugin,
|
||||
));
|
||||
|
||||
#[cfg(feature = "wasm")]
|
||||
wasm::initialize();
|
||||
|
||||
app.run();
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "wasm", wasm_bindgen(js_name = startViewer))]
|
||||
/// Start the application as a read-only viewer for a single library object.
|
||||
///
|
||||
/// @param object_id ID of the library object to load.
|
||||
/// @param skybox_id ID of the Skybox to use
|
||||
/// @param canvas_selector A CSS selector for the canvas that will host the Bevy
|
||||
/// application. This should be unique (i.e. `querySelectorAll` should not
|
||||
/// return more than one element), so using an ID selector is a good idea.
|
||||
/// @param canvas_alt `alt` text for the HTML canvas element.
|
||||
/// @param viewport_size The size of the canvas in CSS `px` units.
|
||||
pub fn start_viewer(
|
||||
object_id: &str,
|
||||
skybox_id: &str,
|
||||
canvas_selector: &str,
|
||||
canvas_alt: &str,
|
||||
viewport_size: ViewportSize,
|
||||
) {
|
||||
#[cfg(feature = "wasm")]
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
let object_id = object_id.to_string();
|
||||
let skybox_id = skybox_id.to_string();
|
||||
|
||||
let mut app = App::new();
|
||||
app.add_plugins((
|
||||
#[cfg(feature = "wasm")]
|
||||
viewport::wasm::ViewportPlugin,
|
||||
DefaultPlugins.set(WindowPlugin {
|
||||
primary_window: Some(Window {
|
||||
resolution: viewport_size.into(),
|
||||
title: canvas_alt.into(),
|
||||
canvas: Some(canvas_selector.into()),
|
||||
..default()
|
||||
}),
|
||||
..default()
|
||||
}),
|
||||
DefaultPickingPlugins,
|
||||
DebugPlugin,
|
||||
InteractionPlugin,
|
||||
InspectorPlugin,
|
||||
StudioInputPlugin,
|
||||
InterpolationPlugin,
|
||||
CameraControllerPlugin,
|
||||
ScenePlugin,
|
||||
SkyboxPlugin,
|
||||
UiLayerPlugin,
|
||||
WorldGridPlugin,
|
||||
))
|
||||
.add_systems(
|
||||
Startup,
|
||||
move |mut cmd: Commands, mut ew: EventWriter<LoadSceneEvent>| {
|
||||
cmd.insert_resource(SkyboxId(skybox_id.clone()));
|
||||
ew.send(LoadSceneEvent(object_id.clone()));
|
||||
},
|
||||
);
|
||||
|
||||
#[cfg(feature = "wasm")]
|
||||
wasm::initialize();
|
||||
|
||||
app.run();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user