From 62b04e44c423228e6206b65d35c1b293b976d580 Mon Sep 17 00:00:00 2001 From: Anton Danilkin Date: Thu, 13 Sep 2018 02:10:23 +0300 Subject: [PATCH] Add paint example --- Cargo.toml | 1 + examples/paint/.gitignore | 4 ++ examples/paint/Cargo.toml | 26 +++++++++++ examples/paint/README.md | 15 ++++++ examples/paint/build.sh | 15 ++++++ examples/paint/index.html | 7 +++ examples/paint/index.js | 5 ++ examples/paint/package.json | 11 +++++ examples/paint/src/lib.rs | 78 ++++++++++++++++++++++++++++++++ examples/paint/webpack.config.js | 16 +++++++ 10 files changed, 178 insertions(+) create mode 100644 examples/paint/.gitignore create mode 100644 examples/paint/Cargo.toml create mode 100644 examples/paint/README.md create mode 100755 examples/paint/build.sh create mode 100644 examples/paint/index.html create mode 100644 examples/paint/index.js create mode 100644 examples/paint/package.json create mode 100755 examples/paint/src/lib.rs create mode 100644 examples/paint/webpack.config.js diff --git a/Cargo.toml b/Cargo.toml index 6f93abd4..3c785576 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,6 +73,7 @@ members = [ "examples/julia_set", "examples/math", "examples/no_modules", + "examples/paint", "examples/performance", "examples/smorgasboard", "examples/wasm-in-wasm", diff --git a/examples/paint/.gitignore b/examples/paint/.gitignore new file mode 100644 index 00000000..4f5a7e18 --- /dev/null +++ b/examples/paint/.gitignore @@ -0,0 +1,4 @@ +package-lock.json +wasm_bindgen_paint.js +wasm_bindgen_paint_bg.js +wasm_bindgen_paint_bg.wasm diff --git a/examples/paint/Cargo.toml b/examples/paint/Cargo.toml new file mode 100644 index 00000000..7ca8c5e5 --- /dev/null +++ b/examples/paint/Cargo.toml @@ -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', +] diff --git a/examples/paint/README.md b/examples/paint/README.md new file mode 100644 index 00000000..cc833b69 --- /dev/null +++ b/examples/paint/README.md @@ -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. diff --git a/examples/paint/build.sh b/examples/paint/build.sh new file mode 100755 index 00000000..d5f85599 --- /dev/null +++ b/examples/paint/build.sh @@ -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 diff --git a/examples/paint/index.html b/examples/paint/index.html new file mode 100644 index 00000000..6b7bece1 --- /dev/null +++ b/examples/paint/index.html @@ -0,0 +1,7 @@ + + + + + + + diff --git a/examples/paint/index.js b/examples/paint/index.js new file mode 100644 index 00000000..27187919 --- /dev/null +++ b/examples/paint/index.js @@ -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(); +}); diff --git a/examples/paint/package.json b/examples/paint/package.json new file mode 100644 index 00000000..176a69a4 --- /dev/null +++ b/examples/paint/package.json @@ -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" + } +} diff --git a/examples/paint/src/lib.rs b/examples/paint/src/lib.rs new file mode 100755 index 00000000..6596820f --- /dev/null +++ b/examples/paint/src/lib.rs @@ -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::() + .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::() + .unwrap(); + let context = Rc::new(context); + let pressed = Rc::new(RefCell::new(false)); + { + let context = context.clone(); + let pressed = pressed.clone(); + let closure: Closure = 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 = 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 = 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(); + } +} diff --git a/examples/paint/webpack.config.js b/examples/paint/webpack.config.js new file mode 100644 index 00000000..453a1a59 --- /dev/null +++ b/examples/paint/webpack.config.js @@ -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' +};