Web: show the SolidCraft mark being cut from a cube while loading (#1908)

Thanks @shuff57.
This commit is contained in:
Steven Huff authored and GitHub committed 2026-10-17 06:22:52 -04:00
1 parent 29dfa6bd32
commit 7d44359cf6
6 files changed
+121 -4

No files matched your search

+1 -1
View File
@@ -29,5 +29,5 @@ web-sys = { version = "0.3", features = [
"Window", "Document", "Element", "HtmlElement", "HtmlCanvasElement", "Location", "Navigator", "StorageManager",
"FileSystemHandle", "FileSystemDirectoryHandle", "FileSystemFileHandle", "FileSystemGetFileOptions", "FileSystemWritableFileStream",
"WritableStream", "File", "FileList", "Blob", "BlobPropertyBag", "Url", "HtmlAnchorElement", "HtmlInputElement", "Storage",
"BeforeUnloadEvent", "Event", "EventTarget", "Response", "MediaQueryList", "Gamepad",
"BeforeUnloadEvent", "Event", "EventTarget", "Response", "MediaQueryList", "Gamepad", "Performance",
] }
+2 -1
View File
@@ -23,6 +23,7 @@
<link data-trunk rel="copy-file" href="../../assets/fonts/biz-udp-gothic/BIZUDPGothic-Regular.ttf" data-target-path="fonts" />
<link data-trunk rel="copy-file" href="../../assets/fonts/biz-udp-gothic/OFL.txt" data-target-path="fonts" />
<link data-trunk rel="css" href="../../assets/styles/web/loading.css" />
<link data-trunk rel="copy-file" href="../../assets/styles/web/loading-logo.svg" />
<!-- Installable as an app (manifest.webmanifest); the icons are the Linux exports of the app mark. -->
<meta name="theme-color" content="#343840">
<link rel="manifest" href="manifest.webmanifest">
@@ -35,7 +36,7 @@
</head>
<body>
<canvas id="solidcraft_canvas"></canvas>
<div id="solidcraft_loading">Loading SolidCraft&hellip;</div>
<div id="solidcraft_loading" role="status"><img src="loading-logo.svg" alt=""><span class="sr-only">Loading SolidCraft&hellip;</span></div>
<script>
// Offline use and updates (sw.js; written into release builds by `cargo xtask web-offline`).
if ("serviceWorker" in navigator) {
+26 -1
View File
@@ -31,6 +31,31 @@ mod web {
/// draws it with reversed depth, whose precision follows the distance from the eye (#1434).
const DEPTH_BITS: u8 = 32;
/// The loading animation (assets/styles/web/loading-logo.svg) settles into the finished mark
/// about 3.2 s after the page starts; this adds a short hold. The app doesn't land before it.
const LOADING_MIN_MS: f64 = 3600.0;
/// The fade from the loading screen into the app.
const LOADING_FADE_MS: i32 = 300;
/// Take the loading screen away once the animation has played to the finished mark: wait out
/// what is left of `LOADING_MIN_MS`, fade it, then remove it.
fn dismiss_loading(el: web_sys::Element) {
let Some(window) = web_sys::window() else {
el.remove();
return;
};
let now = window.performance().map_or(LOADING_MIN_MS, |p| p.now());
let wait = (LOADING_MIN_MS - now).max(0.0) as i32;
let fade = wasm_bindgen::closure::Closure::once_into_js(move || {
let _ = el.set_attribute("class", "done");
let gone = wasm_bindgen::closure::Closure::once_into_js(move || el.remove());
if let Some(window) = web_sys::window() {
let _ = window.set_timeout_with_callback_and_timeout_and_arguments_0(gone.unchecked_ref(), LOADING_FADE_MS);
}
});
let _ = window.set_timeout_with_callback_and_timeout_and_arguments_0(fade.unchecked_ref(), wait);
}
/// Seconds between autosaves of unsaved work.
const AUTOSAVE_S: f64 = 30.0;
@@ -534,7 +559,7 @@ mod web {
.await;
if let Some(el) = document.get_element_by_id(LOADING_ID) {
match result {
Ok(()) => el.remove(),
Ok(()) => dismiss_loading(el),
Err(e) => {
el.set_inner_html(&format!("<p>SolidCraft failed to start: {e:?}</p><p>A browser with WebGPU or WebGL2 is required.</p>"))
}