Skip to content
This repository was archived by the owner on Jul 18, 2024. It is now read-only.

Commit 7b6fb14

Browse files
committed
Added a WASM demo.
1 parent 8ade7a1 commit 7b6fb14

File tree

13 files changed

+477
-1
lines changed

13 files changed

+477
-1
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
- uses: actions-rs/cargo@v1
1717
with:
1818
command: check
19-
args: --all
19+
args: --all --exclude web
2020

2121
test:
2222
name: Test Suite

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ members = [
2121
"demo",
2222
"e2e-tests",
2323
"forma",
24+
"web",
2425
]
2526
resolver = "2"
2627

forma/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ pub mod prelude {
142142
},
143143
Channel, BGR0, BGR1, BGRA, RGB0, RGB1, RGBA,
144144
};
145+
#[cfg(feature = "gpu")]
145146
pub use crate::gpu::Timings;
146147
pub use crate::{
147148
math::{AffineTransform, GeomPresTransform, Point},

web/.cargo/config.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[target.wasm32-unknown-unknown]
2+
rustflags = ["-C", "target-feature=+simd128,+atomics,+bulk-memory,+mutable-globals"]
3+
4+
[unstable]
5+
build-std = ["panic_abort", "std"]

web/.proxyrc.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
module.exports = function (app) {
16+
app.use((req, res, next) => {
17+
res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
18+
res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
19+
20+
next();
21+
});
22+
}

web/Cargo.toml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Copyright 2022 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
[package]
16+
name = "web"
17+
version = "0.1.0"
18+
edition = "2021"
19+
20+
[package.metadata.wasm-pack.profile.release]
21+
wasm-opt = false
22+
23+
[lib]
24+
crate-type = ["cdylib", "rlib"]
25+
26+
[features]
27+
default = ["console_error_panic_hook"]
28+
29+
[dependencies]
30+
forma = { path = "../forma", package = "forma-render", default-features = false }
31+
getrandom = { version = "0.2", features = ["js"] }
32+
nalgebra = "0.31.4"
33+
rand = { version = "0.8", features = ["small_rng"] }
34+
wasm-bindgen = "0.2.63"
35+
wasm-bindgen-rayon = "1.0"
36+
winit = "0.27.1"
37+
38+
# The `console_error_panic_hook` crate provides better debugging of panics by
39+
# logging them with `console.error`. This is great for development, but requires
40+
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
41+
# code size when deploying.
42+
console_error_panic_hook = { version = "0.1.6", optional = true }
43+
44+
[dev-dependencies]
45+
wasm-bindgen-test = "0.3.13"

web/index.html

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<!--
2+
Copyright 2022 Google LLC
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
https://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
-->
16+
<html>
17+
<head>
18+
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
19+
</head>
20+
<body>
21+
<main>
22+
<input type="checkbox" id="partials" name="partials">
23+
<label for="partials">Visualize partial updates</label>
24+
<p id="fps">FPS: ??? (???/???)</p>
25+
<canvas id="drawing" width="1000" height="1000" style="width: 500;"></canvas>
26+
<script src="index.js" type="module"></script>
27+
</main>
28+
</body>
29+
</html>

web/index.js

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
const partials = document.getElementById('partials');
16+
17+
const canvas = document.getElementById('drawing');
18+
const ctx = canvas.getContext('2d');
19+
20+
var controls = 0b0000;
21+
22+
document.addEventListener('keydown', (event) => {
23+
switch (event.key) {
24+
case "Up":
25+
case "ArrowUp":
26+
controls |= 0b1000;
27+
break;
28+
case "Right":
29+
case "ArrowRight":
30+
controls |= 0b0100;
31+
break;
32+
case "Down":
33+
case "ArrowDown":
34+
controls |= 0b0010;
35+
break;
36+
case "Left":
37+
case "ArrowLeft":
38+
controls |= 0b0001;
39+
break;
40+
}
41+
}, false);
42+
document.addEventListener('keyup', (event) => {
43+
switch (event.key) {
44+
case "Up":
45+
case "ArrowUp":
46+
controls &= 0b0111;
47+
break;
48+
case "Right":
49+
case "ArrowRight":
50+
controls &= 0b1011;
51+
break;
52+
case "Down":
53+
case "ArrowDown":
54+
controls &= 0b1101;
55+
break;
56+
case "Left":
57+
case "ArrowLeft":
58+
controls &= 0b1110;
59+
break;
60+
}
61+
}, false);
62+
63+
const worker = new Worker(new URL('./worker.js', import.meta.url), {
64+
type: 'module'
65+
});
66+
worker.postMessage({
67+
'width': canvas.width,
68+
'height': canvas.height,
69+
'partials': partials.checked,
70+
});
71+
72+
const fps = document.getElementById('fps');
73+
74+
let timings = [];
75+
function pushTiming(timing) {
76+
timings.push(timing);
77+
78+
if (timings.length == 50) {
79+
const sum = timings.reduce((a, b) => a + b, 0);
80+
const avg = (sum / timings.length) || 0;
81+
const min = Math.min(...timings);
82+
const max = Math.max(...timings);
83+
84+
fps.innerHTML = 'FPS: ' + (1 / avg).toFixed(2) + ' (' + (1 / max).toFixed(2) + '/' + (1 / min).toFixed(2) + ')';
85+
86+
timings = [];
87+
}
88+
}
89+
90+
let last_timestamp = 0;
91+
function animation(timestamp) {
92+
const elapsed = timestamp - last_timestamp;
93+
last_timestamp = timestamp;
94+
95+
pushTiming(elapsed / 1000);
96+
97+
worker.postMessage({
98+
'elapsed': elapsed,
99+
'width': canvas.width,
100+
'height': canvas.height,
101+
'partials': partials.checked,
102+
'controls': controls,
103+
});
104+
}
105+
106+
worker.onmessage = function(message) {
107+
ctx.putImageData(new ImageData(
108+
new Uint8ClampedArray(message.data),
109+
canvas.width,
110+
canvas.height
111+
), 0, 0);
112+
113+
window.requestAnimationFrame(animation);
114+
}

web/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"devDependencies": {
3+
"parcel": "^2.8.2"
4+
}
5+
}

web/rust-toolchain

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
nightly

0 commit comments

Comments
 (0)