From 4a7adc6a898d1f4eab986181b0871741ea3f7688 Mon Sep 17 00:00:00 2001 From: djmil Date: Wed, 3 Jul 2024 22:22:53 +0200 Subject: [PATCH] web assembly + trunk --- .gitignore | 2 + Cargo.toml | 42 +++++++++++++-- assets/sw.js | 25 +++++++++ index.html | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/app.rs | 15 +++--- src/circle.rs | 11 ++-- src/main.rs | 42 ++++++++++++++- 7 files changed, 261 insertions(+), 16 deletions(-) create mode 100644 assets/sw.js create mode 100644 index.html diff --git a/.gitignore b/.gitignore index a1a5044..79dc8b0 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,5 @@ Cargo.lock # MSVC Windows builds of rustc generate these, which store debugging information *.pdb +# trunk output folder +dist diff --git a/Cargo.toml b/Cargo.toml index 8057ffe..0c627f4 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,42 @@ [package] name = "egui-circles" -version = "0.1.0" +version = "0.2.0" +authors = ["Andriy Djmil "] edition = "2021" -rust-version = "1.56" +rust-version = "1.76" + +[package.metadata.docs.rs] +all-features = true +targets = ["x86_64-unknown-linux-gnu", "wasm32-unknown-unknown"] [dependencies] -eframe = "0.24.0" # Gives us egui, epi and web+native backends -emath = "0.24.0" -rand = "0.8" \ No newline at end of file +egui = "0.28" +eframe = { version = "0.28", default-features = false, features = [ +# "accesskit", # Make egui compatible with screen readers. NOTE: adds a lot of dependencies. + "default_fonts", # Embed the default egui fonts. + "glow", # Use the glow rendering backend. Alternative: "wgpu". +# "persistence", # Enable restoring app state when restarting the app. +] } +log = "0.4" +emath = "0.28.0" +rand = "0.8" +getrandom = { version = "0.2", features = ["js"] } + +# native: +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +env_logger = "0.10" + +# web: +[target.'cfg(target_arch = "wasm32")'.dependencies] +wasm-bindgen-futures = "0.4" + +# to access the DOM (to hide the loading text) +[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys] +version = "0.3.4" + +[profile.release] +opt-level = 2 # fast and small wasm + +# Optimize all dependencies even in debug builds: +[profile.dev.package."*"] +opt-level = 2 diff --git a/assets/sw.js b/assets/sw.js new file mode 100644 index 0000000..7ecd229 --- /dev/null +++ b/assets/sw.js @@ -0,0 +1,25 @@ +var cacheName = 'egui-template-pwa'; +var filesToCache = [ + './', + './index.html', + './eframe_template.js', + './eframe_template_bg.wasm', +]; + +/* Start the service worker and cache all of the app's content */ +self.addEventListener('install', function (e) { + e.waitUntil( + caches.open(cacheName).then(function (cache) { + return cache.addAll(filesToCache); + }) + ); +}); + +/* Serve cached content when offline */ +self.addEventListener('fetch', function (e) { + e.respondWith( + caches.match(e.request).then(function (response) { + return response || fetch(e.request); + }) + ); +}); diff --git a/index.html b/index.html new file mode 100644 index 0000000..ba10e11 --- /dev/null +++ b/index.html @@ -0,0 +1,140 @@ + + + + + + + + + + eframe template + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/app.rs b/src/app.rs index cbc47b5..f936714 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,8 +1,12 @@ -use emath::Vec2; -use eframe::egui; -use egui::Color32; -use egui::Stroke; -use rand::Rng; +extern crate emath; +extern crate rand; +extern crate eframe; + +use self::emath::Vec2; +use self::eframe::egui; +use self::egui::Color32; +use self::egui::Stroke; +use self::rand::Rng; use crate::circle::Circle; @@ -39,7 +43,6 @@ impl eframe::App for Simulation { y: rand::thread_rng().gen_range(-2.0..2.0)}); }; - ui.add(egui::Slider::new(&mut self.circles_count, 0..=25).text("circles count")); let diff = (self.circles.len() as i32) - (self.circles_count as i32); diff --git a/src/circle.rs b/src/circle.rs index 8be5263..f4508f4 100644 --- a/src/circle.rs +++ b/src/circle.rs @@ -1,7 +1,10 @@ -use emath::Vec2; -use emath::Pos2; -use emath::Rect; -use rand::Rng; +extern crate emath; +extern crate rand; + +use self::emath::Vec2; +use self::emath::Pos2; +use self::emath::Rect; +use self::rand::Rng; pub static FRICTION: f32 = 0.995; diff --git a/src/main.rs b/src/main.rs index cd5c5f3..a3501a3 100755 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,8 @@ mod app; mod circle; +// When compiling natively: +#[cfg(not(target_arch = "wasm32"))] fn main() -> eframe::Result<()> { //env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`). @@ -19,6 +21,44 @@ fn main() -> eframe::Result<()> { eframe::run_native( "egui-circles", native_options, - Box::new(|_| Box::::default()), + Box::new(|_| Ok(Box::::default())), ) } + +// When compiling to web using trunk: +#[cfg(target_arch = "wasm32")] +fn main() { + // Redirect `log` message to `console.log` and friends: + eframe::WebLogger::init(log::LevelFilter::Debug).ok(); + + let web_options = eframe::WebOptions::default(); + + wasm_bindgen_futures::spawn_local(async { + let start_result = eframe::WebRunner::new() + .start( + "the_canvas_id", + web_options, + //Box::new(|cc| Ok(Box::new(eframe_template::TemplateApp::new(cc)))), + Box::new(|_| Ok(Box::::default())), + ) + .await; + + // Remove the loading text and spinner: + let loading_text = web_sys::window() + .and_then(|w| w.document()) + .and_then(|d| d.get_element_by_id("loading_text")); + if let Some(loading_text) = loading_text { + match start_result { + Ok(_) => { + loading_text.remove(); + } + Err(e) => { + loading_text.set_inner_html( + "

The app has crashed. See the developer console for details.

", + ); + panic!("Failed to start eframe: {e:?}"); + } + } + } + }); +} \ No newline at end of file