|
|
|
<!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 -->
|
Add PR preview deployments (#5131)
This adds preview deployments that will deploy a version of
egui_demo_app for each pull request, making things easier to review /
test.
Some notes on security:
The preview deployment is split in two workflows, preview_build and
preview_deploy.
`preview_build` runs on pull_request, so it won't have any access to the
repositories secrets, so it is safe to
build / execute untrusted code.
`preview_deploy` has access to the repositories secrets (so it can push
to the pr preview repo) but won't run
any untrusted code (it will just extract the build artifact and push it
to the pages branch where it will
automatically be deployed).
To set this up, a DEPLOY_KEY secret needs to be added, which allows the
action to push the compiled artifacts into this repository:
https://github.com/egui-pr-preview/pr
The deploy key is the private key part of a key generated via
ssh-keygen. The public key is set as a deploy key in that repo.
I have created the repo on a separate github org, so it won't be
directly associated with emil or egui in case someone pushes something
naughty.
I have set this up in my fork of egui to show how this works:
- I created a PR: https://github.com/lucasmerlin/egui/pull/2
- The code will be compiled and pushed to the egui-pr-preview/pr repo
and deployed via github pages
- The bot leaves a comment on the pr with a link to the preview
- The preview is available at
https://egui-pr-preview.github.io/pr/2-pr-preview-demo/
(It's unfortunately only available a couple seconds after the bot writes
the comment, because the pages deployment action is run independently on
the other repository)
- Once the PR is merged / closed the preview will be cleaned up
(unfortunately the empty folder will remain, it seems like it's not
possible to remove that via the JamesIves/github-pages-deploy-action
action I use, but I don't think that it's a big issue)
I'll leave the PR in draft until the DEPLOY_KEY is set up
2 months ago
|
|
|
<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(document.getElementById("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/ -->
|