|
|
|
<!DOCTYPE html>
|
|
|
|
<html>
|
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
|
|
|
|
|
|
<!-- Disable zooming: -->
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
|
|
|
|
|
|
|
<head>
|
|
|
|
<title>egui – An immediate mode GUI written in Rust</title>
|
|
|
|
<style>
|
|
|
|
html {
|
|
|
|
/* Remove touch delay: */
|
|
|
|
touch-action: manipulation;
|
|
|
|
}
|
|
|
|
|
|
|
|
body {
|
|
|
|
/* Light mode background color for what is not covered by the egui canvas,
|
|
|
|
or where the egui canvas is translucent. */
|
|
|
|
background: #909090;
|
|
|
|
}
|
|
|
|
|
|
|
|
@media (prefers-color-scheme: dark) {
|
|
|
|
body {
|
|
|
|
/* Dark mode background color for what is not covered by the egui canvas,
|
|
|
|
or where the egui canvas is translucent. */
|
|
|
|
background: #404040;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allow canvas to fill entire web page: */
|
|
|
|
html,
|
|
|
|
body {
|
|
|
|
overflow: hidden;
|
|
|
|
margin: 0 !important;
|
|
|
|
padding: 0 !important;
|
|
|
|
height: 100%;
|
|
|
|
width: 100%;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make canvas fill entire document: */
|
|
|
|
canvas {
|
|
|
|
margin-right: auto;
|
|
|
|
margin-left: auto;
|
|
|
|
display: block;
|
|
|
|
position: absolute;
|
Use ResizeObserver instead of `resize` event (#4536)
Currently, if the size of the canvas element changes independently of
the size of the browser window (e.g. due to its parent element
shrinking), then no repaints are scheduled.
This PR replaces the `resize` event with a `ResizeObserver`, which
ensures that _any_ resize of the canvas element (including those caused
by browser window resizes) trigger a repaint. The repaint is done
synchronously as part of the resize event, to reduce any potential
flickering.
The result seems to pass the rendering tests on most platform+browser
combinations. We tested:
- Chrome, Firefox, Safari on macOS
- Chrome, Firefox on Linux (ubuntu and arch, both running wayland)
- Chrome, Firefox on Windows
Firefox still has some antialiasing issues on Linux platforms, but this
antialiasing also happens on `master`, so this PR is not a regression
there.
The code setting `canvas.style.width` and `canvas.style.height` at the
start of `AppRunner::logic` was also removed - the canvas _display_ size
is now fully controlled by CSS, e.g. by setting `canvas { width: 100%;
height: 100%; }`.
The approach used here is described in
https://webglfundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html
Note: The only remaining place where egui updates the style of the
canvas it is rendering to is some of the IME/mobile input handling code.
Fixing that is out of scope for this PR, and will be done in a followup
PR.
5 months ago
|
|
|
top: 0;
|
|
|
|
left: 0;
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
}
|
|
|
|
|
|
|
|
.centered {
|
|
|
|
margin-right: auto;
|
|
|
|
margin-left: auto;
|
|
|
|
display: block;
|
|
|
|
position: absolute;
|
|
|
|
top: 50%;
|
|
|
|
left: 50%;
|
|
|
|
transform: translate(-50%, -50%);
|
|
|
|
color: #f0f0f0;
|
|
|
|
font-size: 24px;
|
|
|
|
font-family: Ubuntu-Light, Helvetica, sans-serif;
|
|
|
|
text-align: center;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ---------------------------------------------- */
|
|
|
|
/* Loading animation from https://loading.io/css/ */
|
|
|
|
.lds-dual-ring {
|
|
|
|
display: inline-block;
|
|
|
|
width: 24px;
|
|
|
|
height: 24px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.lds-dual-ring:after {
|
|
|
|
content: " ";
|
|
|
|
display: block;
|
|
|
|
width: 24px;
|
|
|
|
height: 24px;
|
|
|
|
margin: 0px;
|
|
|
|
border-radius: 50%;
|
|
|
|
border: 3px solid #fff;
|
|
|
|
border-color: #fff transparent #fff transparent;
|
|
|
|
animation: lds-dual-ring 1.2s linear infinite;
|
|
|
|
}
|
|
|
|
|
|
|
|
@keyframes lds-dual-ring {
|
|
|
|
0% {
|
|
|
|
transform: rotate(0deg);
|
|
|
|
}
|
|
|
|
|
|
|
|
100% {
|
|
|
|
transform: rotate(360deg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
</head>
|
|
|
|
|
|
|
|
<body>
|
|
|
|
<canvas id="the_canvas_id"></canvas>
|
|
|
|
|
|
|
|
<div class="centered" id="center_text">
|
|
|
|
<p style="font-size:16px">
|
|
|
|
Loading…
|
|
|
|
</p>
|
|
|
|
<div class="lds-dual-ring"></div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
// The `--no-modules`-generated JS from `wasm-bindgen` attempts to use
|
|
|
|
// `WebAssembly.instantiateStreaming` to instantiate the wasm module,
|
|
|
|
// but this doesn't work with `file://` urls. This example is frequently
|
|
|
|
// viewed by simply opening `index.html` in a browser (with a `file://`
|
|
|
|
// url), so it would fail if we were to call this function!
|
|
|
|
//
|
|
|
|
// Work around this for now by deleting the function to ensure that the
|
|
|
|
// `no_modules.js` script doesn't have access to it. You won't need this
|
|
|
|
// hack when deploying over HTTP.
|
|
|
|
delete WebAssembly.instantiateStreaming;
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<!-- this is the JS generated by the `wasm-bindgen` CLI tool -->
|
|
|
|
<script src="egui_demo_app.js"></script>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
// We'll defer our execution until the wasm is ready to go.
|
|
|
|
// Here we tell bindgen the path to the wasm file so it can start
|
|
|
|
// initialization and return to us a promise when it's done.
|
|
|
|
console.debug("Loading wasm…");
|
|
|
|
wasm_bindgen("./egui_demo_app_bg.wasm")
|
|
|
|
.then(on_wasm_loaded)
|
|
|
|
.catch(on_error);
|
|
|
|
|
|
|
|
function on_wasm_loaded() {
|
|
|
|
console.debug("Wasm loaded. Starting app…");
|
|
|
|
|
|
|
|
let handle = new wasm_bindgen.WebHandle();
|
|
|
|
|
|
|
|
function check_for_panic() {
|
|
|
|
if (handle.has_panicked()) {
|
|
|
|
console.error("The egui app has crashed");
|
|
|
|
|
|
|
|
// The demo app already logs the panic message and callstack, but you
|
|
|
|
// can access them like this if you want to show them in the html:
|
|
|
|
// console.error(`${handle.panic_message()}`);
|
|
|
|
// console.error(`${handle.panic_callstack()}`);
|
|
|
|
|
|
|
|
document.getElementById("the_canvas_id").remove();
|
|
|
|
document.getElementById("center_text").innerHTML = `
|
|
|
|
<p>
|
|
|
|
The egui app has crashed.
|
|
|
|
</p>
|
|
|
|
<p style="font-size:10px" align="left">
|
|
|
|
${handle.panic_message()}
|
|
|
|
</p>
|
|
|
|
<p style="font-size:14px">
|
|
|
|
See the console for details.
|
|
|
|
</p>
|
|
|
|
<p style="font-size:14px">
|
|
|
|
Reload the page to try again.
|
|
|
|
</p>`;
|
|
|
|
} else {
|
|
|
|
let delay_ms = 1000;
|
|
|
|
setTimeout(check_for_panic, delay_ms);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
check_for_panic();
|
|
|
|
|
|
|
|
handle.start("the_canvas_id").then(on_app_started).catch(on_error);
|
|
|
|
}
|
|
|
|
|
|
|
|
function on_app_started(handle) {
|
|
|
|
// Call `handle.destroy()` to stop. Uncomment to quick result:
|
|
|
|
// setTimeout(() => { handle.destroy(); handle.free()) }, 2000)
|
|
|
|
|
|
|
|
console.debug("App started.");
|
|
|
|
document.getElementById("center_text").innerHTML = '';
|
|
|
|
|
|
|
|
// Make sure the canvas is focused so it can receive keyboard events right away:
|
|
|
|
document.getElementById("the_canvas_id").focus();
|
|
|
|
}
|
|
|
|
|
|
|
|
function on_error(error) {
|
|
|
|
console.error("Failed to start: " + error);
|
|
|
|
document.getElementById("the_canvas_id").remove();
|
|
|
|
document.getElementById("center_text").innerHTML = `
|
|
|
|
<p>
|
|
|
|
An error occurred during loading:
|
|
|
|
</p>
|
|
|
|
<p style="font-family:Courier New">
|
|
|
|
${error}
|
|
|
|
</p>
|
|
|
|
<p style="font-size:14px">
|
|
|
|
Make sure you use a modern browser with WebGL and WASM enabled.
|
|
|
|
</p>`;
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
</body>
|
|
|
|
|
|
|
|
</html>
|
|
|
|
|
|
|
|
<!-- Powered by egui: https://github.com/emilk/egui/ -->
|