Sync Bevy canvas size with browser viewport size

This commit is contained in:
Danny McGee
2023-09-29 22:15:18 -04:00
parent c1f92cc2d6
commit 2e3979b336
7 changed files with 120 additions and 20 deletions
+17 -13
View File
@@ -17,21 +17,25 @@ pub fn init(viewport_size: ViewportSize) {
#[cfg(target_arch = "wasm32")]
console_error_panic_hook::set_once();
App::new()
.add_plugins((
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
resolution: viewport_size.into(),
..default()
}),
let mut app = App::new();
#[cfg(target_arch = "wasm32")]
app.add_plugins(viewport::wasm::ViewportPlugin);
app.add_plugins((
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
resolution: viewport_size.into(),
..default()
}),
OrbitCamPlugin,
TestScenePlugin,
UiLayerPlugin,
))
.add_systems(Update, draw_world_axes.after(orbit_cam::pan_orbit_camera))
.run();
..default()
}),
OrbitCamPlugin,
TestScenePlugin,
UiLayerPlugin,
))
.add_systems(Update, draw_world_axes.after(orbit_cam::pan_orbit_camera))
.run();
}
fn draw_world_axes(mut gizmos: Gizmos, q: Query<&OrbitCam>) {
+66
View File
@@ -1,7 +1,10 @@
use core::fmt;
use bevy::window::WindowResolution;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
#[derive(Clone, Copy)]
pub struct ViewportSize {
pub width: f32,
pub height: f32,
@@ -35,3 +38,66 @@ impl From<WindowResolution> for ViewportSize {
}
}
}
impl fmt::Debug for ViewportSize {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("({:.2}, {:.2})", self.width, self.height))
}
}
#[cfg(target_arch = "wasm32")]
pub mod wasm {
use std::{cell::RefCell, sync::OnceLock};
use bevy::prelude::*;
use parking_lot::ReentrantMutex;
use wasm_bindgen::prelude::*;
use super::ViewportSize;
static RESIZE_BUF: OnceLock<ReentrantMutex<RefCell<Option<ViewportSize>>>> = OnceLock::new();
#[wasm_bindgen]
pub fn resize(viewport_size: ViewportSize) {
let buffer = RESIZE_BUF.get_or_init(|| ReentrantMutex::new(RefCell::new(None)));
if let Some(lock) = buffer.try_lock() {
*lock.borrow_mut() = Some(viewport_size);
}
}
pub struct ViewportPlugin;
impl Plugin for ViewportPlugin {
fn build(&self, app: &mut App) {
app.add_event::<ViewportResizeEvent>()
.add_systems(PreUpdate, dispatch_viewport_events)
.add_systems(Update, sync_window_to_viewport);
}
}
#[derive(Event, Clone, Copy)]
struct ViewportResizeEvent(ViewportSize);
fn sync_window_to_viewport(
mut events: EventReader<ViewportResizeEvent>,
mut window: Query<&mut Window>,
) {
let mut resize = None;
for event in events.into_iter() {
resize = Some(event.0);
}
if let Some(ViewportSize { width, height }) = resize {
window.single_mut().resolution.set(width, height);
}
}
fn dispatch_viewport_events(mut events: EventWriter<ViewportResizeEvent>) {
let buffer = RESIZE_BUF.get_or_init(|| ReentrantMutex::new(RefCell::new(None)));
if let Some(lock) = buffer.try_lock() {
if let Some(resize) = lock.borrow_mut().take() {
events.send(ViewportResizeEvent(resize));
}
}
}
}