├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── Makefile ├── README.md ├── rust-toolchain ├── src └── main.rs └── static └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | **/*.rs.bk 3 | /site/ 4 | *~ 5 | *#*# 6 | *#* 7 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "base-x" 3 | version = "0.2.2" 4 | source = "registry+https://github.com/rust-lang/crates.io-index" 5 | 6 | [[package]] 7 | name = "dtoa" 8 | version = "0.4.2" 9 | source = "registry+https://github.com/rust-lang/crates.io-index" 10 | 11 | [[package]] 12 | name = "futures" 13 | version = "0.1.18" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | 16 | [[package]] 17 | name = "itoa" 18 | version = "0.3.4" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | 21 | [[package]] 22 | name = "num-traits" 23 | version = "0.1.41" 24 | source = "registry+https://github.com/rust-lang/crates.io-index" 25 | 26 | [[package]] 27 | name = "proc-macro2" 28 | version = "0.2.3" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | dependencies = [ 31 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 32 | ] 33 | 34 | [[package]] 35 | name = "quote" 36 | version = "0.3.15" 37 | source = "registry+https://github.com/rust-lang/crates.io-index" 38 | 39 | [[package]] 40 | name = "quote" 41 | version = "0.4.2" 42 | source = "registry+https://github.com/rust-lang/crates.io-index" 43 | dependencies = [ 44 | "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 45 | ] 46 | 47 | [[package]] 48 | name = "serde" 49 | version = "1.0.27" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | 52 | [[package]] 53 | name = "serde_derive" 54 | version = "1.0.27" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | dependencies = [ 57 | "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 58 | "serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", 59 | "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", 60 | ] 61 | 62 | [[package]] 63 | name = "serde_derive_internals" 64 | version = "0.19.0" 65 | source = "registry+https://github.com/rust-lang/crates.io-index" 66 | dependencies = [ 67 | "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", 68 | "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", 69 | ] 70 | 71 | [[package]] 72 | name = "serde_json" 73 | version = "1.0.9" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | dependencies = [ 76 | "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 77 | "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 78 | "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", 79 | "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", 80 | ] 81 | 82 | [[package]] 83 | name = "stdweb" 84 | version = "0.4.1" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | dependencies = [ 87 | "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", 88 | "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", 89 | "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", 90 | "stdweb-derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 91 | "stdweb-internal-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 92 | ] 93 | 94 | [[package]] 95 | name = "stdweb-derive" 96 | version = "0.4.0" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | dependencies = [ 99 | "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 100 | "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", 101 | "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", 102 | "syn 0.12.13 (registry+https://github.com/rust-lang/crates.io-index)", 103 | ] 104 | 105 | [[package]] 106 | name = "stdweb-internal-macros" 107 | version = "0.1.0" 108 | source = "registry+https://github.com/rust-lang/crates.io-index" 109 | dependencies = [ 110 | "base-x 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 111 | "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 112 | "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", 113 | "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", 114 | "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", 115 | "syn 0.12.13 (registry+https://github.com/rust-lang/crates.io-index)", 116 | ] 117 | 118 | [[package]] 119 | name = "syn" 120 | version = "0.11.11" 121 | source = "registry+https://github.com/rust-lang/crates.io-index" 122 | dependencies = [ 123 | "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 124 | "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", 125 | "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 126 | ] 127 | 128 | [[package]] 129 | name = "syn" 130 | version = "0.12.13" 131 | source = "registry+https://github.com/rust-lang/crates.io-index" 132 | dependencies = [ 133 | "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 134 | "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 135 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 136 | ] 137 | 138 | [[package]] 139 | name = "synom" 140 | version = "0.11.3" 141 | source = "registry+https://github.com/rust-lang/crates.io-index" 142 | dependencies = [ 143 | "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 144 | ] 145 | 146 | [[package]] 147 | name = "unicode-xid" 148 | version = "0.0.4" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | 151 | [[package]] 152 | name = "unicode-xid" 153 | version = "0.1.0" 154 | source = "registry+https://github.com/rust-lang/crates.io-index" 155 | 156 | [[package]] 157 | name = "wasm-demo-rs" 158 | version = "0.2.1" 159 | dependencies = [ 160 | "stdweb 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 161 | ] 162 | 163 | [metadata] 164 | "checksum base-x 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f59103b47307f76e03bef1633aec7fa9e29bfb5aa6daf5a334f94233c71f6c1" 165 | "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" 166 | "checksum futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0bab5b5e94f5c31fc764ba5dd9ad16568aae5d4825538c01d6bca680c9bf94a7" 167 | "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" 168 | "checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070" 169 | "checksum proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cd07deb3c6d1d9ff827999c7f9b04cdfd66b1b17ae508e14fe47b620f2282ae0" 170 | "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" 171 | "checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408" 172 | "checksum serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "db99f3919e20faa51bb2996057f5031d8685019b5a06139b1ce761da671b8526" 173 | "checksum serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "f4ba7591cfe93755e89eeecdbcc668885624829b020050e6aec99c2a03bd3fd0" 174 | "checksum serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e03f1c9530c3fb0a0a5c9b826bdd9246a5921ae995d75f512ac917fc4dd55b5" 175 | "checksum serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9db7266c7d63a4c4b7fe8719656ccdd51acf1bed6124b174f933b009fb10bcb" 176 | "checksum stdweb 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd1acfdd499655f9aec6078e5cbb36a4cae3cb5235fd6fff572ca82b63b9d97f" 177 | "checksum stdweb-derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6aa46e9b38ea028a8a327ae6db35a486ace3eb834f5600bb3b6a71c0b6b1bd4b" 178 | "checksum stdweb-internal-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0bb3289dfd46bba44d80ed47a9b3d4c43bf6c1d7931b29e2fa86bd6697ccf59" 179 | "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" 180 | "checksum syn 0.12.13 (registry+https://github.com/rust-lang/crates.io-index)" = "517f6da31bc53bf080b9a77b29fbd0ff8da2f5a2ebd24c73c2238274a94ac7cb" 181 | "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" 182 | "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" 183 | "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 184 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "wasm-demo-rs" 3 | version = "0.2.1" 4 | authors = ["Lucas Vieira "] 5 | description = "A basic example of Rust being compiled to WebAssembly, using Rust's own native tools. Requires nightly toolchain." 6 | 7 | [dependencies] 8 | stdweb = "0.4.1" 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Lucas Vieira 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Please notice that this is not really a very well-structured Makefile. 2 | 3 | # If you just want to debug and run a live server, run the command: 4 | # $ cargo +nightly web start --target-webasm --release 5 | # Do not try to compile this on debug builds, the feature is currently broken. 6 | # I have successfully seen that this works if you run `lite-server` (you can 7 | # install it using `npm`) on the site/ folder. 8 | 9 | 10 | # The original name of the project changed, so I thought I should 11 | # centralize the project name. If you change the binary name in 12 | # Cargo.toml, update this. 13 | name=wasm-demo-rs 14 | 15 | 16 | 17 | # Those targets theoretically produce no files. 18 | # That's not really true here, but... 19 | .PHONY: folder wasm webstart clean 20 | 21 | # To build, we need to create folders, copy our index.html, 22 | # and also copy our wasm and js files. 23 | all: folder site/index.html site/$(name).wasm 24 | 25 | 26 | 27 | 28 | # Producing the html file is just a matter of copying 29 | # the static index.html file and replacing "js/app.js" (for cargo web 30 | # start) with the actual name of the js file. 31 | # Notice that we also copy whatever is in the static/ folder, for 32 | # convenience. 33 | site/index.html: static/index.html 34 | cp static/* site/ 35 | find site/index.html -type f -exec sed -i 's/js\/app.js/$(name).js/g' {} + 36 | 37 | # After building our wasm files, we copy them to the output folder. 38 | site/$(name).wasm: wasm 39 | cp target/wasm32-unknown-unknown/release/*.wasm site/ 40 | cp target/wasm32-unknown-unknown/release/*.js site/ 41 | 42 | 43 | 44 | 45 | # Building the wasm files requires cargo web, which we have installed with the 46 | # nightly toolchain. 47 | wasm: src/main.rs 48 | cargo web build --target wasm32-unknown-unknown --release 49 | 50 | 51 | 52 | 53 | # Folder creation magic. 54 | folder: 55 | mkdir -p site 56 | 57 | 58 | # Though using the Makefile to handle this is not really something very handy, 59 | # you can run `make webstart` to run the server, which will also watch for code 60 | # changes to execute compilation. 61 | webstart: 62 | cargo web start --target wasm32-unknown-unknown --release 63 | 64 | clean: 65 | cargo clean 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wasm-demo-rs 2 | A basic example of Rust compiled to WebAssembly, using Rust's own native tools. 3 | 4 | ## Changelog 5 | - 03/07/2018 -- Set toolchain to `nightly-2018-02-18`; `nightly-2018-03-06` breaks on linking. 6 | - 03/06/2018 -- Upgraded version of `stdweb` to `0.4.1`, which includes many canvas 2D features, but still lacks some things. 7 | - 02/24/2018 -- Upgraded version of `stdweb` to `0.4.0` and upgraded toolchain to latest `nightly`. 8 | - 02/19/2018 -- Latest `nightly` breaks compilation. Used a `rust-toolchain` file to stop the nightly version at `nightly-2018-01-21`, like the `servo` project.. 9 | 10 | 11 | ## About 12 | This is a simple demo for compiling Rust to WebAssembly. 13 | This demo uses the nightly toolchain, `cargo-web`, and the `stdweb` crate. 14 | While this is a new feature, there is some setup that you will need to do so you can build and run this. I recommend doing it on Linux, since we'll be using a single Makefile I wrote to make my life easier, but you could also replicate its commands manually on your favorite OS, assuming it runs Rust, `cargo-web` and `stdweb` fine. 15 | 16 | I felt the need to create this repository for future reference, so it is only a simple demo with small considerations. I might add or remove things, if necessary. 17 | 18 | ## Dependencies 19 | As stated above, this demo depends on the nightly toolchain (for now), and the `cargo-web` tool. 20 | 21 | ### Notes on toolchain selection 22 | The Nightly toolchain might panic when building anything that uses `stdweb` or possibly `wasm32-unknown-unknown`. On a previous version, I've switched to a nice solution (thanks to Elias from the Rust Brazil community on Telegram for this): we have a `rust-toolchain` file specifying which toolchain we intend to use, and more than that, its specific version. 23 | 24 | For this example, you can use `nightly-2018-02-23`, if latest `nightly` fails, so just type in the toolchain name with version like this on the `rust-toolchain` file. Also, you might want to install this specific version of nightly with `rustup`, as instructed below. 25 | 26 | You can also open an issue on this repo in case compilation fails so I can check it out. 27 | 28 | ### Installing the toolchain 29 | 30 | Assuming you have `rustup` installed, you can install the nightly toolchain with the following command: 31 | 32 | ```bash 33 | $ rustup toolchain install nightly 34 | ``` 35 | 36 | After that, you can add Rust's native WASM target with this command: 37 | 38 | ```bash 39 | $ rustup target add wasm32-unknown-unknown --toolchain nightly 40 | ``` 41 | 42 | (I'm not sure the `--toolchain` is needed here though, but hey, whatever) 43 | 44 | And that ought to take care of things on the toolchain side. Now, you'll need to install `cargo-web` (v0.6.8). 45 | 46 | ```bash 47 | $ cargo install cargo-web 48 | ``` 49 | 50 | That should provide you with the latest version of `cargo-web`. 51 | 52 | ## Compiling 53 | 54 | ### Using provided Makefile 55 | I've written a well-documented Makefile that should make stuff easier for compiling. 56 | When you run `make`, a "site" folder will appear, containing an `index.html` file, along with the `wasm` binary and the `js` glue code. This will export the application, ready to be uploaded anywhere you'd like for a live demo. 57 | 58 | If you just want to test it, you can run `make webstart`, and your browser will be fired up at `localhost:8000` with your demo app. 59 | 60 | ### Compiling by hand 61 | You can compile directly using `cargo` as well, only instead of building, you'll have to use `cargo-web` to generate your files. 62 | Fire up your terminal and use the following command on the root folder: 63 | 64 | ```bash 65 | $ cargo web build --target wasm32-unknown-unknown --release 66 | ``` 67 | This should give you your .js and .wasm files on `target/wasm32-unknown-unknown/release`. 68 | If you only want to test your demo app, you can use `cargo web start` to run it on `localhost:8000`. This will also fire up your browser: 69 | 70 | ```bash 71 | $ cargo web start --target wasm32-unknown-unknown --release 72 | ``` 73 | 74 | Notice that changing your Rust files will also recompile your project, but you'll have to refresh the browser page manually so it takes effect. 75 | 76 | #### Considerations about this method 77 | Notice that the static `index.html` refers to `js/app.js` instead of `wasm-demo-rs.js`. This is done on purpose, since `cargo web start` asks you to refer to this file on your `html`. To fix this, you can use a small substitution, such as using `sed`, when copying the index.html file to your output folder (this is done on the Makefile, so refer to it for an example). 78 | 79 | ## Useful links 80 | - Koute's stdweb crate [repository](https://github.com/koute/stdweb) and [documentation](https://docs.rs/stdweb/*/stdweb/). 81 | - [Setting up the native WASM target for Rust](https://www.hellorust.com/setup/wasm-target/) 82 | - [Koute's awesome NES emulator, Pinky, running on the web](https://github.com/koute/pinky/tree/master/pinky-web), which inspired this small demo. Also has bindings for Emscripten and asmjs targets. 83 | - [raphamorim's awesome WASM + Rust tutorial](https://github.com/raphamorim/wasm-and-rust), which covers the Emscripten side of things while also explaining some aspects of WASM. 84 | - [My reimplementation of an old game, Super BrickBreak, in Rust/WASM](https://github.com/luksamuk/super-brickbreak-rs), which uses this very code as a template. 85 | -------------------------------------------------------------------------------- /rust-toolchain: -------------------------------------------------------------------------------- 1 | nightly-2018-02-18 2 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | #![recursion_limit="2048"] 2 | 3 | #[macro_use] 4 | extern crate stdweb; 5 | 6 | use stdweb::unstable::TryInto; 7 | use stdweb::traits::IMouseEvent; 8 | use stdweb::web::html_element::CanvasElement; 9 | use stdweb::web::{ 10 | self, 11 | IEventTarget, 12 | INonElementParentNode, 13 | CanvasRenderingContext2d, 14 | }; 15 | use stdweb::web::event::{ 16 | IEvent, 17 | IKeyboardEvent, 18 | KeyDownEvent, 19 | KeyUpEvent, 20 | KeyboardLocation, 21 | 22 | MouseButton, 23 | MouseDownEvent, 24 | MouseUpEvent, 25 | MouseMoveEvent 26 | }; 27 | use std::f64::consts::PI; 28 | 29 | 30 | /// Handles keyboard events. 31 | fn on_key(key: &str, location: KeyboardLocation, is_pressed: bool) -> bool { 32 | let location = format!("{:?}", location); 33 | console!(log, "Key: ", key, ", location: ", location, ", pressed: ", is_pressed); 34 | 35 | true 36 | } 37 | 38 | 39 | /// Handles mouse presses (up and down). 40 | fn on_mouse_click(btn: MouseButton, is_pressed: bool, pos: (f64, f64)) -> bool { 41 | let btn = format!("{:?}", btn); 42 | console!(log, "MPos: (", pos.0, ", ", pos.1, ") MBtn: ", btn, " pressed: ", is_pressed); 43 | true 44 | } 45 | 46 | /// Handles sole mouse movement, without presses. 47 | fn on_mouse_move(pos: (f64, f64)) -> bool { 48 | console!(log, "MPos: (", pos.0, ", ", pos.1, ")"); 49 | true 50 | } 51 | 52 | 53 | 54 | /// Draws a colored box. 55 | fn draw_box(ctx: &CanvasRenderingContext2d, color: &str, pos: (f64, f64), size: (f64, f64)) { 56 | ctx.set_fill_style_color(color); 57 | ctx.fill_rect(pos.0, pos.1, size.0, size.1); 58 | } 59 | 60 | /// Draws a colored circle. 61 | fn draw_circle(ctx: &CanvasRenderingContext2d, color: &str, pos: (f64, f64), radius: f64) { 62 | // Still needs to be done manually 63 | ctx.begin_path(); 64 | ctx.set_fill_style_color(color); 65 | ctx.arc(pos.0, pos.1, radius, 0.0, PI * 2.0, false); 66 | //ctx.fill(); 67 | js!{ @(no_return) @{ctx}.fill(); }; // Still waiting for implementation 68 | ctx.close_path(); 69 | } 70 | 71 | 72 | 73 | fn main() { 74 | stdweb::initialize(); 75 | 76 | // Retrieve canvas 77 | let canvas: CanvasElement = web::document().get_element_by_id("viewport") 78 | .unwrap() 79 | .try_into() 80 | .unwrap(); 81 | 82 | // Retrieve context 83 | let ctx: CanvasRenderingContext2d = canvas.get_context().unwrap(); 84 | 85 | 86 | // === Drawing tests === 87 | 88 | // Draw three boxes 89 | draw_box(&ctx, "red", (20.0, 20.0), (150.0, 100.0)); 90 | draw_box(&ctx, "blue", (40.0, 40.0), (150.0, 100.0)); 91 | draw_box(&ctx, "green", (60.0, 60.0), (150.0, 100.0)); 92 | 93 | // Draw a circle out of convenience 94 | draw_circle(&ctx, "white", (95.0, 70.0), 20.0); 95 | 96 | 97 | // === Event bindings === 98 | 99 | // Keyboard 100 | web::window().add_event_listener(|event: KeyDownEvent| { 101 | if on_key(&event.key(), event.location(), true) { 102 | event.prevent_default(); 103 | } 104 | }); 105 | 106 | web::window().add_event_listener(|event: KeyUpEvent| { 107 | if on_key(&event.key(), event.location(), false) { 108 | event.prevent_default(); 109 | } 110 | }); 111 | 112 | 113 | 114 | // Mouse 115 | web::window().add_event_listener(|event: MouseDownEvent| { 116 | if on_mouse_click(event.button(), true, (event.client_x() as f64, 117 | event.client_y() as f64)) { 118 | event.prevent_default(); 119 | } 120 | }); 121 | 122 | web::window().add_event_listener(|event: MouseUpEvent| { 123 | if on_mouse_click(event.button(), false, (event.client_x() as f64, 124 | event.client_y() as f64)) { 125 | event.prevent_default(); 126 | } 127 | }); 128 | 129 | web::window().add_event_listener(|event: MouseMoveEvent| { 130 | if on_mouse_move((event.client_x() as f64, event.client_y() as f64)) { 131 | event.prevent_default(); 132 | } 133 | }); 134 | 135 | 136 | 137 | stdweb::event_loop(); 138 | } 139 | -------------------------------------------------------------------------------- /static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebAssembly + Rust Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | --------------------------------------------------------------------------------