Reorganize and rewrite examples

This commit is a large-ish scale reorganization of our examples. The
main goal here is to have a dedicated section of the guide for example,
and all examples will be listed there. Each example's `README` is now
just boilerplate pointing at the guide along with a blurb about how to
run it.

Some examples like `math` and `smorgasboard` have been deleted as they
didn't really serve much purpose, and others like `closures` have been
rewritten with `web-sys` instead of hand-bound bindings.

Overall it's hoped that this puts us in a good and consistent state for
our examples, with all of them being described in the guide, excerpts
are in the guide, and they're all relatively idiomatically using
`web-sys`.
This commit is contained in:
Alex Crichton
2018-09-20 16:20:42 -07:00
parent a85e49a2b4
commit 3efe51eb8b
128 changed files with 939 additions and 1304 deletions

View File

@ -8,6 +8,24 @@
- [Basic Usage](./whirlwind-tour/basic-usage.md)
- [What Just Happened?](./whirlwind-tour/what-just-happened.md)
- [What Else Can We Do?](./whirlwind-tour/what-else-can-we-do.md)
- [Examples](./examples/index.md)
- [Hello, World!](./examples/hello-world.md)
- [Using `console.log`](./examples/console-log.md)
- [Small wasm files](./examples/add.md)
- [Using `--no-modules`](./examples/no-modules.md)
- [Converting WebAssembly to JS](./examples/wasm2js.md)
- [Importing functions from JS](./examples/import-js.md)
- [Working with `char`](./examples/char.md)
- [js-sys: WebAssembly in WebAssembly](./examples/wasm-in-wasm.md)
- [web-sys: DOM hello world](./examples/dom.md)
- [web-sys: Closures](./examples/closures.md)
- [web-sys: `performance.now`](./examples/performance.md)
- [web-sys: using `fetch`](./examples/fetch.md)
- [web-sys: `canvas` hello world](./examples/2d-canvas.md)
- [web-sys: `canvas` Julia set](./examples/julia.md)
- [web-sys: WebAudio](./examples/web-audio.md)
- [web-sys: WebGL](./examples/webgl.md)
- [web-sys: A Simple Paint Program](./examples/paint.md)
- [Reference](./reference/index.md)
- [Passing Rust Closures to JS](./reference/passing-rust-closures-to-js.md)
- [Receiving JS Closures in Rust](./reference/receiving-js-closures-in-rust.md)
@ -58,12 +76,6 @@
- [Cargo Features](./web-sys/cargo-features.md)
- [Function Overloads](./web-sys/function-overloads.md)
- [Type Translations](./web-sys/type-translations.md)
- [Examples](./web-sys/examples/index.md)
- [The `fetch` API](./web-sys/examples/fetch.md)
- [2D Canvas](./web-sys/examples/2d-canvas.md)
- [WebAudio](./web-sys/examples/web-audio.md)
- [WebGL](./web-sys/examples/webgl.md)
- [A Simple Paint Program](./web-sys/examples/paint.md)
--------------------------------------------------------------------------------

View File

@ -31,7 +31,7 @@ The only thing `src/lib.rs` does is include the bindings generated at compile
time in `build.rs`. Here is the whole `src/lib.rs` file:
```rust
{{#include ../../../crates/web-sys/src/lib.rs}}
{{#include ../../../../crates/web-sys/src/lib.rs}}
```
### Cargo features

View File

@ -1,13 +1,14 @@
# 2D Canvas
[View full source code][code]
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/canvas
Drawing a smiley face with the 2D canvas API. This is a port of part of [this
MDN
tutorial](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes#Moving_the_pen)
to `web-sys`.
[See the full source at
`wasm-bindgen/examples/canvas`.](https://github.com/rustwasm/wasm-bindgen/tree/master/examples/canvas)
![A smiley face](./2d-canvas.png)
## `Cargo.toml`
@ -16,7 +17,7 @@ The `Cargo.toml` enables features necessary to query the DOM and work with 2D
canvas.
```toml
{{#include ../../../../examples/canvas/Cargo.toml}}
{{#include ../../../examples/canvas/Cargo.toml}}
```
## `src/lib.rs`
@ -25,5 +26,5 @@ Gets the `<canvas>` element, creates a 2D rendering context, and draws the
smiley face.
```rust
{{#include ../../../../examples/canvas/src/lib.rs}}
{{#include ../../../examples/canvas/src/lib.rs}}
```

View File

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

68
guide/src/examples/add.md Normal file
View File

@ -0,0 +1,68 @@
# Small wasm files
[View full source code][code]
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/add
One of `wasm-bindgen`'s core goals is a pay-only-for-what-you-use philosophy, so
if we don't use much then we shouldn't be paying much! As a result
`#[wasm_bindgen]` can generate super-small executables
Currently this code...
```rust
{{#include ../../../examples/add/src/lib.rs}}
```
generates a 723 byte wasm binary:
```
$ ls -l add_bg.wasm
-rw-rw-r-- 1 alex alex 723 Sep 19 17:32 add_bg.wasm
```
If you run [wasm-opt], a C++ tool for optimize WebAssembly, you can make it
even smaller too!
```
$ wasm-opt -Os add_bg.wasm -o add.wasm
$ ls -l add.wasm
-rw-rw-r-- 1 alex alex 182 Sep 19 17:33 add.wasm
```
And sure enough, using the [wasm2wat] tool it's quite small!
```
$ wasm2wat add.wasm
(module
(type (;0;) (func (param i32 i32) (result i32)))
(func (;0;) (type 0) (param i32 i32) (result i32)
i32.const 1048640
i32.const 0
i32.store
get_local 1
get_local 0
i32.add)
(table (;0;) 1 1 anyfunc)
(memory (;0;) 17)
(global (;0;) i32 (i32.const 1049118))
(global (;1;) i32 (i32.const 1049118))
(export "memory" (memory 0))
(export "__indirect_function_table" (table 0))
(export "__heap_base" (global 0))
(export "__data_end" (global 1))
(export "add" (func 0))
(data (i32.const 1049096) "invalid malloc request"))
```
Also don't forget to compile in release mode for the smallest binaries! For
larger applications you'll likely also want to turn on LTO to generate the
smallest binaries:
```toml
[profile.release]
lto = true
```
[wasm2wat]: https://github.com/webassembly/wabt
[wasm-opt]: https://github.com/webassembly/binaryen

View File

@ -0,0 +1,30 @@
# Working with the `char` type
[View full source code][code]
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/char
The `#[wasm_bindgen]` macro will convert the rust `char` type to a single
code-point js `string`, and this example shows how to work with this.
Opening this example should display a single counter with a random character
for it's `key` and 0 for its `count`. You can click the `+` button to increase a
counter's count. By clicking on the "add counter" button you should see a new
counter added to the list with a different random character for it's `key`.
Under the hood javascript is choosing a random character from an Array of
characters and passing that to the rust Counter struct's constructor so the
character you are seeing on the page has made the full round trip from js to
rust and back to js.
## `src/lib.rs`
```rust
{{#include ../../../examples/char/src/lib.rs}}
```
## `index.js`
```js
{{#include ../../../examples/char/index.js}}
```

View File

@ -0,0 +1,15 @@
# web-sys: Closures
[View full source code][code]
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/closures
One of the features of `#[wasm_bindgen]` is that you can pass closures defined
in Rust off to JS. This can be a bit tricky at times, though, so the example
here shows how to interact with some standard web APIs with closures.
## `src/lib.rs`
```rust
{{#include ../../../examples/closures/src/lib.rs}}
```

View File

@ -0,0 +1,14 @@
# `console.log`
[View full source code][code]
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/console_log
This example shows off how to use `console.log` in a variety of ways, all the
way from bare-bones usage to a `println!`-like macro with `web_sys`.
## `src/lib.rs`
```rust
{{#include ../../../examples/console_log/src/lib.rs}}
```

25
guide/src/examples/dom.md Normal file
View File

@ -0,0 +1,25 @@
# web-sys: DOM hello world
[View full source code][code]
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/dom
Using `web-sys` we're able to interact with all the standard web platform
methods, including those of the DOM! Here we take a look at a simple "Hello,
world!" which manufactures a DOM element in Rust, customizes it, and then
appends it to the page.
## `Cargo.toml`
You can see here how we depend on `web-sys` and activate associated features to
enable all the various APIs:
```toml
{{#include ../../../examples/dom/Cargo.toml}}
```
## `src/lib.rs`
```rust
{{#include ../../../examples/dom/src/lib.rs}}
```

View File

@ -1,11 +1,12 @@
# The `fetch` API
[View full source code][code]
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/fetch
This example uses the `fetch` API to make an HTTP request to the GitHub API and
then parses the resulting JSON.
[See the full source at
`wasm-bindgen/examples/fetch`.](https://github.com/rustwasm/wasm-bindgen/tree/master/examples/fetch)
## `Cargo.toml`
The `Cargo.toml` enables a number of features related to the `fetch` API and
@ -13,11 +14,11 @@ types used: `Headers`, `Request`, etc. It also enables `wasm-bindgen`'s `serde`
support.
```toml
{{#include ../../../../examples/fetch/Cargo.toml}}
{{#include ../../../examples/fetch/Cargo.toml}}
```
## `src/lib.rs`
```rust
{{#include ../../../../examples/fetch/src/lib.rs}}
{{#include ../../../examples/fetch/src/lib.rs}}
```

View File

@ -0,0 +1,55 @@
# Hello, World!
[View full source code][code]
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/hello_world
This is the "Hello, world!" example of `#[wasm_bindgen]` showing how to set up
a project, export a function to JS, call it from JS, and then call the `alert`
function in Rust.
## `Cargo.toml`
The `Cargo.toml` enables depends on the `wasm-bindgen` crate. Here we're using
a `path` dependency because this example lives in the `wasm-bindgen` repository
itself, but you'd use the commented out version beneath it instead.
Also of note is the `crate-type = ["cdylib"]` which is largely used for wasm
final artifacts today.
```toml
{{#include ../../../examples/hello_world/Cargo.toml}}
```
## `src/lib.rs`
Here we define our Rust entry point along with calling the `alert` function.
```rust
{{#include ../../../examples/hello_world/src/lib.rs}}
```
## `index.js`
Our JS entry point is quite small!
```js
{{#include ../../../examples/hello_world/index.js}}
```
## Webpack-specific files
And finally here's the Webpack configuration and `package.json` for this
project:
**webpack.config.js**
```js
{{#include ../../../examples/hello_world/webpack.config.js}}
```
**package.json**
```json
{{#include ../../../examples/hello_world/package.json}}
```

View File

@ -0,0 +1,26 @@
# Importing non-browser JS
[View full source code][code]
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/import_js
The `#[wasm_bindgen]` attribute can be used on `extern { .. }` blocks to import
functionality from JS. This is how the `js-sys` and the `web-sys` crates are
built, but you can also use it in your own crate!
For example if you're working with this JS file:
```js
// defined-in-js.js
{{#include ../../../examples/import_js/defined-in-js.js}}
```
you can use it in Rust with:
```rust
{{#include ../../../examples/import_js/src/lib.rs}}
```
You can also [explore the full list of ways to configure imports][attr]
[attr]: ../reference/attributes/on-js-imports/index.html

View File

@ -0,0 +1,15 @@
# Examples of using `wasm-bindgen`, `js-sys`, and `web-sys`
This subsection contains examples of using the `wasm-bindgen`, `js-sys`, and
`web-sys` crates. Each example should have more information about what it's
doing.
The source code for all examples can also be [found online][code] to download an
run locally. Each example is accompanied with a `build.sh` script to outline the
steps necessary to build and run it as well.
Note that most examples currently use Webpack to assemble the final output
artifact, but this is not required! You can use the bundler of choice,
`--no-modules`, or native browser ESM support as alternatives to Webpack.
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples

View File

@ -0,0 +1,24 @@
# Julia Set
[View full source code][code]
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/julia_set
While not showing off a lot of `web_sys` API surface area, this example shows a
neat fractal that you can make!
## `index.js`
A small bit of glue is added for this example
```js
{{#include ../../../examples/julia_set/index.js}}
```
## `src/lib.rs`
The bulk of the logic is in the generation of the fractal
```rust
{{#include ../../../examples/julia_set/src/lib.rs}}
```

View File

@ -0,0 +1,20 @@
# Using `--no-modules`
[View full source code][code]
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/no_modules
This example shows how the `--no-modules` flag can be used load code in a
browser directly (using the same code as the [hello world example][hello]).
Most of the magic happens in `index.html`:
```html
{{#include ../../../examples/no_modules/index.html}}
```
And that's it! It's worth pointing out that if [`#[wasm_bindgen(module =
"...")]` imports are used][mod-imp] then `wasm-bindgen --no-modules` will fail
(as it doesn't know how to import modules).
[hello]: hello-world.html
[mod-imp]: ../reference/attributes/on-js-imports/module.html

View File

@ -1,17 +1,18 @@
# Paint
# Paint Example
[View full source code][code]
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/paint
A simple painting program.
[See the full source at
`wasm-bindgen/examples/paint`.](https://github.com/rustwasm/wasm-bindgen/tree/master/examples/paint)
## `Cargo.toml`
The `Cargo.toml` enables features necessary to work with the DOM, events and
2D canvas.
```toml
{{#include ../../../../examples/paint/Cargo.toml}}
{{#include ../../../examples/paint/Cargo.toml}}
```
## `src/lib.rs`
@ -20,5 +21,5 @@ Creates the `<canvas>` element, applies a CSS style to it, adds it to the docume
get a 2D rendering context and adds listeners for mouse events.
```rust
{{#include ../../../../examples/paint/src/lib.rs}}
{{#include ../../../examples/paint/src/lib.rs}}
```

View File

@ -0,0 +1,15 @@
# web-sys: `performance.now`
[View full source code][code]
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/performance
Want to profile some Rust code in the browser? No problem! You can use the
`performance.now()` API and friends to get timing information to see how long
things take.
## `src/lib.rs`
```rust
{{#include ../../../examples/performance/src/lib.rs}}
```

View File

@ -0,0 +1,14 @@
# js-sys: WebAssembly in WebAssembly
[View full source code][code]
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/wasm-in-wasm
Using the `js-sys` crate we can get pretty meta and instantiate `WebAssembly`
modules from inside `WebAssembly` modules!
## `src/lib.rs`
```rust
{{#include ../../../examples/wasm-in-wasm/src/lib.rs}}
```

View File

@ -0,0 +1,38 @@
# Converting WebAssembly to JS
[View full source code][code]
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/wasm2js
Not all browsers have support for `WebAssembly` at this time (although all major
ones do). If you'd like to support older browsers, you probably want a method
that doesn't involve keeping two codebases in sync!
Thankfully there's a tool from [binaryen] called `wasm2js` to convert a wasm
file to JS. This JS file, if successfully produced, is equivalent to the wasm
file (albeit a little bit larger and slower), and can be loaded into practically
any browser.
This example is relatively simple (cribbing from the [`console.log`
example][console_log]):
```rust
{{#include ../../../examples/wasm2js/src/lib.rs}}
```
The real magic happens when you actually build the app. Just after
`wasm-bindgen` we see here how we execute `wasm2js` in our build script:
```sh
{{#include ../../../examples/wasm2js/build.sh}}
```
Note that the `wasm2js` tool is still pretty early days so there's likely to be
a number of bugs to run into or work around. If any are encountered though
please feel free to report them upstream!
Also note that eventually this will ideally be automatically done by your
bundler and no action would be needed from you to work in older browsers via
`wasm2js`!
[binaryen]: https://github.com/WebAssembly/binaryen

View File

@ -1,21 +1,22 @@
# WebAudio
[View full source code][code]
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/webaudio
This example creates an [FM
oscillator](https://en.wikipedia.org/wiki/Frequency_modulation_synthesis) using
the [WebAudio
API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API) and
`web-sys`.
[See the full source at
`wasm-bindgen/examples/webaudio`.](https://github.com/rustwasm/wasm-bindgen/tree/master/examples/webaudio)
## `Cargo.toml`
The `Cargo.toml` enables the types needed to use the relevant bits of the
WebAudio API.
```toml
{{#include ../../../../examples/webaudio/Cargo.toml}}
{{#include ../../../examples/webaudio/Cargo.toml}}
```
## `src/lib.rs`
@ -23,7 +24,7 @@ WebAudio API.
The Rust code implements the FM oscillator.
```rust
{{#include ../../../../examples/webaudio/src/lib.rs}}
{{#include ../../../examples/webaudio/src/lib.rs}}
```
## `index.js`
@ -32,5 +33,5 @@ A small bit of JavaScript glues the rust module to input widgets and translates
events into calls into wasm code.
```js
{{#include ../../../../examples/webaudio/index.js}}
{{#include ../../../examples/webaudio/index.js}}
```

View File

@ -1,17 +1,18 @@
# 2D Canvas
# WebGL Example
[View full source code][code]
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/webgl
This example draws a triangle to the screen using the WebGL API.
[See the full source at
`wasm-bindgen/examples/webgl`.](https://github.com/rustwasm/wasm-bindgen/tree/master/examples/webgl)
## `Cargo.toml`
The `Cargo.toml` enables features necessary to obtain and use a WebGL
rendering context.
```toml
{{#include ../../../../examples/webgl/Cargo.toml}}
{{#include ../../../examples/webgl/Cargo.toml}}
```
## `src/lib.rs`
@ -21,5 +22,5 @@ context, compile shaders, fill a buffer with vertex coordinates, and draw a
triangle to the screen.
```rust
{{#include ../../../../examples/webgl/src/lib.rs}}
{{#include ../../../examples/webgl/src/lib.rs}}
```

View File

@ -19,7 +19,7 @@ Notable features of this project includes:
* Importing JS functionality in to Rust such as [DOM manipulation][dom-ex],
[console logging][console-log], or [performance monitoring][perf-ex].
* [Exporting Rust functionality][smorg-ex] to JS such as classes, functions, etc.
* Exporting Rust functionality to JS such as classes, functions, etc.
* Working with rich types like strings, numbers, classes, closures, and objects
rather than simply `u32` and floats.
@ -32,5 +32,4 @@ what this crate can do, check out the [design doc].
[dom-ex]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/dom
[console-log]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/console_log
[perf-ex]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/performance
[smorg-ex]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/smorgasboard
[hello-online]: https://webassembly.studio/?f=gzubao6tg3

View File

@ -1,3 +0,0 @@
# Examples of using `web-sys`
This subsection contains examples of using the `web-sys` crate.