Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)