Skip to content

Commit

Permalink
Run puffin_viewer in the browser
Browse files Browse the repository at this point in the history
Sometimes works, sometimes doesn't
  • Loading branch information
emilk authored and TimonPost committed Oct 10, 2022
1 parent 6b68f58 commit 5a9f4e3
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 0 deletions.
41 changes: 41 additions & 0 deletions build_web.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/bash
set -eu

# ./setup_web.sh # <- call this first!

CRATE_NAME="puffin_viewer"
CRATE_NAME_SNAKE_CASE="${CRATE_NAME//-/_}" # for those who name crates with-kebab-case

# This is required to enable the web_sys clipboard API which egui_web uses
# https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Clipboard.html
# https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html
export RUSTFLAGS=--cfg=web_sys_unstable_apis

# Clear output from old stuff:
rm -f docs/${CRATE_NAME_SNAKE_CASE}_bg.wasm

echo "Building rust…"
BUILD=release
cargo build --release -p ${CRATE_NAME} --lib --target wasm32-unknown-unknown

echo "Generating JS bindings for wasm…"
TARGET_NAME="${CRATE_NAME_SNAKE_CASE}.wasm"
wasm-bindgen "target/wasm32-unknown-unknown/${BUILD}/${TARGET_NAME}" \
--out-dir docs --no-modules --no-typescript

# to get wasm-opt: apt/brew/dnf install binaryen
# echo "Optimizing wasm…"
# wasm-opt docs/${CRATE_NAME_SNAKE_CASE}_bg.wasm -O2 --fast-math -o docs/${CRATE_NAME_SNAKE_CASE}_bg.wasm # add -g to get debug symbols

echo "Finished: docs/${CRATE_NAME_SNAKE_CASE}.wasm"

if [[ "$OSTYPE" == "linux-gnu"* ]]; then
# Linux, ex: Fedora
xdg-open http://localhost:8888/index.html
elif [[ "$OSTYPE" == "msys" ]]; then
# Windows
start http://localhost:8888/index.html
else
# Darwin/MacOS, or something else
open http://localhost:8888/index.html
fi
91 changes: 91 additions & 0 deletions docs/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<!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>Puffin Viewer</title>
<style>
html {
/* Remove touch delay: */
touch-action: manipulation;
}

body {
/* 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;
}

/* Position canvas in center-top: */
canvas {
margin-right: auto;
margin-left: auto;
display: block;
position: absolute;
top: 0%;
left: 50%;
transform: translate(-50%, 0%);
}
</style>
<link rel="manifest" href="./manifest.json">
<script>
// register ServiceWorker
window.onload = () => {
'use strict';

if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('./sw.js');
}
}
</script>
</head>

<body>
<!-- The WASM code will resize this canvas to cover the entire screen -->
<canvas id="the_canvas_id"></canvas>

<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="puffin_viewer.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.
wasm_bindgen("./puffin_viewer_bg.wasm")
.then(on_wasm_loaded)["catch"](console.error);

function on_wasm_loaded() {
// This call installs a bunch of callbacks and then returns.
wasm_bindgen.start("the_canvas_id");
}
</script>
</body>

</html>

<!-- Powered by egui: https://github.com/emilk/egui/ -->
9 changes: 9 additions & 0 deletions setup_web.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash
set -eu
script_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
cd "$script_path"

# Pre-requisites:
rustup target add wasm32-unknown-unknown
cargo install wasm-bindgen-cli
cargo update -p wasm-bindgen
16 changes: 16 additions & 0 deletions start_server.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash
set -eu
script_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
cd "$script_path"

# Starts a local web-server that serves the contents of the `doc/` folder,
# i.e. the web-version of `egui_demo_app`.

echo "ensuring basic-http-server is installed…"
cargo install basic-http-server

echo "starting server…"
echo "serving at http://localhost:8888"

(cd docs && basic-http-server --addr 127.0.0.1:8888 .)
# (cd docs && python3 -m http.server 8888 --bind 127.0.0.1)

0 comments on commit 5a9f4e3

Please sign in to comment.