Add paint example

This commit is contained in:
Anton Danilkin 2018-09-13 02:10:23 +03:00
parent c6ede65856
commit 62b04e44c4
10 changed files with 178 additions and 0 deletions

View File

@ -73,6 +73,7 @@ members = [
"examples/julia_set",
"examples/math",
"examples/no_modules",
"examples/paint",
"examples/performance",
"examples/smorgasboard",
"examples/wasm-in-wasm",

4
examples/paint/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
package-lock.json
wasm_bindgen_paint.js
wasm_bindgen_paint_bg.js
wasm_bindgen_paint_bg.wasm

26
examples/paint/Cargo.toml Normal file
View File

@ -0,0 +1,26 @@
[package]
name = "wasm-bindgen-paint"
version = "0.1.0"
authors = ["The wasm-bindgen Developers"]
[lib]
crate-type = ["cdylib"]
[dependencies]
js-sys = { path = "../../crates/js-sys" }
wasm-bindgen = { path = "../..", features = ["nightly"] }
[dependencies.web-sys]
path = "../../crates/web-sys"
features = [
'CanvasRenderingContext2d',
'CssStyleDeclaration',
'Document',
'Element',
'EventTarget',
'HtmlCanvasElement',
'HtmlElement',
'MouseEvent',
'Node',
'Window',
]

15
examples/paint/README.md Normal file
View File

@ -0,0 +1,15 @@
# Paint Example
This directory is an example of using the `web-sys` crate for making a simple
painting program with all of the logic written in Rust.
You can build and run the example with:
```
$ ./build.sh
```
(or running the commands on Windows manually)
and then opening up `http://localhost:8080/` in a web browser should show a
blank canvas on which you can draw.

15
examples/paint/build.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/sh
# For more coments about what's going on here, see the `hello_world` example
set -ex
cd "$(dirname $0)"
cargo +nightly build --target wasm32-unknown-unknown
cargo +nightly run --manifest-path ../../crates/cli/Cargo.toml \
--bin wasm-bindgen -- \
../../target/wasm32-unknown-unknown/debug/wasm_bindgen_paint.wasm --out-dir .
npm install
npm run serve

View File

@ -0,0 +1,7 @@
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
</head>
<body>
</body>
</html>

5
examples/paint/index.js Normal file
View File

@ -0,0 +1,5 @@
// For more comments about what's going on here, check out the `hello_world`
// example.
import('./wasm_bindgen_paint').then(paint => {
paint.main();
});

View File

@ -0,0 +1,11 @@
{
"scripts": {
"serve": "webpack-dev-server"
},
"devDependencies": {
"html-webpack-plugin": "^3.2.0",
"webpack": "^4.11.1",
"webpack-cli": "^2.0.10",
"webpack-dev-server": "^3.1.0"
}
}

78
examples/paint/src/lib.rs Executable file
View File

@ -0,0 +1,78 @@
extern crate js_sys;
extern crate wasm_bindgen;
extern crate web_sys;
use std::cell::RefCell;
use std::rc::Rc;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
#[wasm_bindgen]
pub fn main() {
let document = web_sys::Window::document().unwrap();
let canvas = document
.create_element("canvas")
.unwrap()
.dyn_into::<web_sys::HtmlCanvasElement>()
.map_err(|_| ())
.unwrap();
(document.body().unwrap().as_ref() as &web_sys::Node)
.append_child(canvas.as_ref() as &web_sys::Node)
.unwrap();
canvas.set_width(640);
canvas.set_height(480);
(canvas.as_ref() as &web_sys::HtmlElement)
.style()
.set_property("border", "solid")
.unwrap();
let context = canvas
.get_context("2d")
.unwrap()
.unwrap()
.dyn_into::<web_sys::CanvasRenderingContext2d>()
.unwrap();
let context = Rc::new(context);
let pressed = Rc::new(RefCell::new(false));
{
let context = context.clone();
let pressed = pressed.clone();
let closure: Closure<FnMut(_)> = Closure::new(move |event: web_sys::MouseEvent| {
context.begin_path();
context.move_to(event.offset_x() as f64, event.offset_y() as f64);
*pressed.borrow_mut() = true;
});
(canvas.as_ref() as &web_sys::EventTarget)
.add_event_listener_with_callback("mousedown", closure.as_ref().unchecked_ref())
.unwrap();
closure.forget();
}
{
let context = context.clone();
let pressed = pressed.clone();
let closure: Closure<FnMut(_)> = Closure::new(move |event: web_sys::MouseEvent| {
if *pressed.borrow() {
context.line_to(event.offset_x() as f64, event.offset_y() as f64);
context.stroke();
context.begin_path();
context.move_to(event.offset_x() as f64, event.offset_y() as f64);
}
});
(canvas.as_ref() as &web_sys::EventTarget)
.add_event_listener_with_callback("mousemove", closure.as_ref().unchecked_ref())
.unwrap();
closure.forget();
}
{
let context = context.clone();
let pressed = pressed.clone();
let closure: Closure<FnMut(_)> = Closure::new(move |event: web_sys::MouseEvent| {
*pressed.borrow_mut() = false;
context.line_to(event.offset_x() as f64, event.offset_y() as f64);
context.stroke();
});
(canvas.as_ref() as &web_sys::EventTarget)
.add_event_listener_with_callback("mouseup", closure.as_ref().unchecked_ref())
.unwrap();
closure.forget();
}
}

View File

@ -0,0 +1,16 @@
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
},
plugins: [
new HtmlWebpackPlugin({
template: "index.html"
})
],
mode: 'development'
};