some fixes to web

This commit is contained in:
Ben Hansen 2021-12-03 14:17:36 -07:00
parent 19c1c08b62
commit bd6721dde2
7 changed files with 95 additions and 29 deletions

View File

@ -6,6 +6,5 @@
## Things I'd like
* Screen shots
* Create gifs
* Displaying random models as wireframe and solid
* loading obj models
* Create gifs of examples running (?)
* Displaying random models as wireframe and solid

View File

@ -27,8 +27,8 @@ console_error_panic_hook = "0.1.6"
console_log = "0.2.0"
getrandom = { version = "0.2", features = ["js"] }
rodio = { version = "0.14", default-features = false, features = ["wasm-bindgen", "wav"] }
wasm-bindgen = "0.2.76"
wasm-bindgen-futures = "0.4.20"
wasm-bindgen = "0.2.76"
web-sys = { version = "0.3.53", features = [
"Document",
"Window",

View File

@ -20,7 +20,7 @@ use winit::window::{Fullscreen, WindowBuilder};
pub fn start() {
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
console_log::init_with_level(log::Level::Info).expect("Could't initialize logger");
console_log::init_with_level(log::Level::Warn).expect("Could't initialize logger");
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
} else {
env_logger::init();
@ -49,11 +49,20 @@ pub fn start() {
use winit::platform::web::WindowExtWebSys;
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| doc.body())
.and_then(|body| {
body.append_child(&web_sys::Element::from(window.canvas())).ok()
.and_then(|doc| {
let dst = doc.get_element_by_id("wasm-example")?;
let canvas = web_sys::Element::from(window.canvas());
dst.append_child(&canvas).ok()?;
// Request fullscreen, if denied, continue as normal
match canvas.request_fullscreen() {
Ok(_) => {},
Err(_) => ()
}
Some(())
})
.expect("Couldn't append cavas to document body.");
.expect("Couldn't append canvas to document body.");
}
log::info!("Setup...");
@ -183,6 +192,12 @@ pub fn start() {
process_input(element_state, key, control_flow);
}
}
Event::WindowEvent {
event: WindowEvent::Resized(size), ..
} => {
render.resize(size);
events.push(state::Event::Resize(size.width as f32, size.height as f32));
}
Event::RedrawRequested(_) => {
for event in &events {
match event {
@ -195,6 +210,12 @@ pub fn start() {
state::Event::Score(_) => {
sound_system.queue(sound_pack.bounce());
}
state::Event::Resize(width, height) => {
// TODO: their should be a system that handles this
state.player1_score.position = (width * 0.25, 20.0).into();
state.player2_score.position = (width * 0.75, 20.0).into();
state.win_text.position = (width * 0.5, height * 0.5).into();
}
}
}
events.clear();

View File

@ -37,6 +37,7 @@ impl Render {
}
pub async fn new(window: &Window, size: PhysicalSize<u32>) -> Self {
log::warn!("size: {:?}", size);
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::Backends::all());
@ -117,6 +118,12 @@ impl Render {
}
}
pub fn resize(&mut self, size: PhysicalSize<u32>) {
self.config.width = size.width;
self.config.height = size.height;
self.surface.configure(&self.device, &self.config);
}
pub fn render_state(&mut self, state: &state::State) {
let mut encoder = self
.device

View File

@ -88,6 +88,7 @@ pub enum Event {
FocusChanged,
BallBounce(cgmath::Vector2<f32>),
Score(u32),
Resize(f32, f32),
}
#[cfg(test)]

View File

@ -1,34 +1,72 @@
<template>
<div class="wasm-example">
<div id="wasm-example">
<div class="error" v-if="error">
{{ error }}
</div>
<button v-if="!exampleStarted && !autoLoad" @click="loadExample()" :disabled="loading">Try {{exampleName}}!</button>
</div>
</template>
<script>
// Found at https://stackoverflow.com/questions/196972/convert-string-to-title-case-with-javascript
function toTitleCase(str) {
return str.replace(
/\w\S*/g,
function(txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
}
);
}
export default {
props: { example: "" },
props: {
example: "",
autoLoad: false,
},
data() {
return {
error: {
value: "",
required: true,
},
error: "",
loading: false,
exampleStarted: false,
};
},
async mounted() {
await this.$nextTick();
try {
const init = await import(`./wasm/${this.example}/${this.example}.js`);
init().then(() => {
console.log("WASM Loaded");
});
} catch (e) {
this.error = `An error occurred loading "${this.example}": ${e}`;
console.error(e);
computed: {
exampleName() {
return toTitleCase(this.example);
}
},
methods: {
async loadExample() {
this.loading = true;
try {
const init = await import(`./wasm/${this.example}/${this.example}.js`);
init().then(() => {
console.log("WASM Loaded");
});
} catch (e) {
// TODO: Figure out a better way to ignore "control flow" errors
if (`${e}` != "Error: Using exceptions for control flow, don't mind me. This isn't actually an error!") {
this.error = `An error occurred loading "${this.example}": ${e}`;
console.error(e);
this.exampleStarted = false;
} else {
this.exampleStarted = true;
}
}
this.loading = false;
},
},
async mounted() {
await this.$nextTick()
if (this.autoLoad) {
await this.loadExample()
}
}
};
</script>
</script>
<style>
#wasm-example canvas {
background-color: black;
}
</style>

View File

@ -8,8 +8,8 @@
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "build-wasm.sh && vuepress dev docs",
"build": "build-wasm.sh && vuepress build docs",
"dev": "./build-wasm.sh && vuepress dev docs",
"build": "./build-wasm.sh && vuepress build docs",
"deploy": "sh deploy.sh"
},
"author": "",