From 7a290c15391105b70ddb0dcc0565c0dd64a1291a Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Sun, 6 Jan 2019 15:37:30 +0100 Subject: [PATCH 1/6] Use wasm-bindgen instead of stdweb --- piet-web/Cargo.toml | 6 +++++- piet-web/src/lib.rs | 25 +++++++++++-------------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/piet-web/Cargo.toml b/piet-web/Cargo.toml index e0b0b6a14..4c24b2ac7 100644 --- a/piet-web/Cargo.toml +++ b/piet-web/Cargo.toml @@ -12,4 +12,8 @@ categories = ["rendering::graphics-api", "wasm"] kurbo = "0.1.2" piet = { path = "../piet" } -stdweb = "0.4.12" +wasm-bindgen = "0.2.29" + +[dependencies.web-sys] +version = "0.3.6" +features = ["CanvasRenderingContext2d", "CanvasWindingRule"] \ No newline at end of file diff --git a/piet-web/src/lib.rs b/piet-web/src/lib.rs index fba6c5508..f2da9cee7 100644 --- a/piet-web/src/lib.rs +++ b/piet-web/src/lib.rs @@ -1,6 +1,7 @@ //! The Web Canvas backend for the Piet 2D graphics abstraction. -use stdweb::web::{CanvasRenderingContext2d, FillRule}; +use wasm_bindgen::JsValue; +use web_sys::{CanvasRenderingContext2d, CanvasWindingRule}; use kurbo::{PathEl, Shape, Vec2}; @@ -25,15 +26,15 @@ pub enum StrokeStyle { Default, } -fn convert_fill_rule(fill_rule: piet::FillRule) -> FillRule { +fn convert_fill_rule(fill_rule: piet::FillRule) -> CanvasWindingRule { match fill_rule { - piet::FillRule::NonZero => FillRule::NonZero, - piet::FillRule::EvenOdd => FillRule::EvenOdd, + piet::FillRule::NonZero => CanvasWindingRule::Nonzero, + piet::FillRule::EvenOdd => CanvasWindingRule::Evenodd, } } impl<'a> RenderContext for WebRenderContext<'a> { - /// stdweb doesn't have a native Point type, so use kurbo's. + /// wasm-bindgen doesn't have a native Point type, so use kurbo's. type Point = Vec2; type Coord = f64; type Brush = Brush; @@ -47,15 +48,11 @@ impl<'a> RenderContext for WebRenderContext<'a> { Brush::Solid(rgba) } - fn fill( - &mut self, - shape: &impl Shape, - brush: &Self::Brush, - fill_rule: piet::FillRule, - ) { + fn fill(&mut self, shape: &impl Shape, brush: &Self::Brush, fill_rule: piet::FillRule) { self.set_path(shape); self.set_brush(brush, true); - self.ctx.fill(convert_fill_rule(fill_rule)); + self.ctx + .fill_with_canvas_winding_rule(convert_fill_rule(fill_rule)); } fn stroke( @@ -94,9 +91,9 @@ impl<'a> WebRenderContext<'a> { ) }; if is_fill { - self.ctx.set_fill_style_color(&color_str); + self.ctx.set_fill_style(&JsValue::from_str(&color_str)); } else { - self.ctx.set_stroke_style_color(&color_str); + self.ctx.set_stroke_style(&JsValue::from_str(&color_str)); } } } From 881321561c62726513b3f368c3d376b7460df5c6 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Mon, 7 Jan 2019 11:00:44 +0100 Subject: [PATCH 2/6] Add wasm-bindgen based example to piet-web --- Cargo.toml | 1 + piet-web/Cargo.toml | 2 +- piet-web/README.md | 8 ++--- piet-web/examples/basic/.gitignore | 3 ++ piet-web/examples/basic/Cargo.toml | 18 +++++++++++ .../{ => basic}/basic-web-static/index.html | 2 +- .../examples/basic/basic-web-static/index.js | 5 ++++ .../basic/basic-web-static/package.json | 13 ++++++++ .../basic/basic-web-static/webpack.config.js | 20 +++++++++++++ piet-web/examples/basic/build.sh | 15 ++++++++++ .../{basic-web.rs => basic/src/lib.rs} | 30 ++++++++++--------- 11 files changed, 97 insertions(+), 20 deletions(-) create mode 100644 piet-web/examples/basic/.gitignore create mode 100644 piet-web/examples/basic/Cargo.toml rename piet-web/examples/{ => basic}/basic-web-static/index.html (90%) create mode 100644 piet-web/examples/basic/basic-web-static/index.js create mode 100644 piet-web/examples/basic/basic-web-static/package.json create mode 100644 piet-web/examples/basic/basic-web-static/webpack.config.js create mode 100755 piet-web/examples/basic/build.sh rename piet-web/examples/{basic-web.rs => basic/src/lib.rs} (70%) diff --git a/Cargo.toml b/Cargo.toml index 6322b8a9e..0e3528427 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,4 +5,5 @@ members = [ "piet-cairo", "piet-direct2d", "piet-web", + "piet-web/examples/basic" ] diff --git a/piet-web/Cargo.toml b/piet-web/Cargo.toml index 4c24b2ac7..346657173 100644 --- a/piet-web/Cargo.toml +++ b/piet-web/Cargo.toml @@ -16,4 +16,4 @@ wasm-bindgen = "0.2.29" [dependencies.web-sys] version = "0.3.6" -features = ["CanvasRenderingContext2d", "CanvasWindingRule"] \ No newline at end of file +features = ["CanvasRenderingContext2d", "CanvasWindingRule"] diff --git a/piet-web/README.md b/piet-web/README.md index adc66a31e..12ec8d912 100644 --- a/piet-web/README.md +++ b/piet-web/README.md @@ -1,11 +1,11 @@ # Running the examples -Generally follow the directions at [stdweb]. +Ensure both cargo and [npm] are installed. -`$ cargo install -f cargo-web` +`$ cargo install -f wasm-bindgen` -`$ cargo web start --target=wasm32-unknown-unknown --example basic-web` +`$ cd examples/basic && ./build.sh` Then navigate browser to local web server. -[stdweb]: https://github.com/koute/stdweb +[npm]: https://www.npmjs.com/get-npm diff --git a/piet-web/examples/basic/.gitignore b/piet-web/examples/basic/.gitignore new file mode 100644 index 000000000..1a993212d --- /dev/null +++ b/piet-web/examples/basic/.gitignore @@ -0,0 +1,3 @@ +dist/ +node_modules/ +package-lock.json diff --git a/piet-web/examples/basic/Cargo.toml b/piet-web/examples/basic/Cargo.toml new file mode 100644 index 000000000..0e4ba144e --- /dev/null +++ b/piet-web/examples/basic/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "piet-web-example" +version = "0.0.1" +authors = ["Ryan Levick "] +edition = "2018" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +piet = { path = "../../../piet" } +piet-web = { path = "../.." } +wasm-bindgen = "0.2.29" +kurbo = "0.1.2" + +[dependencies.web-sys] +version = "0.3.6" +features = ["CanvasRenderingContext2d", "Window", "Document", "Element", "HtmlElement", "HtmlCanvasElement"] diff --git a/piet-web/examples/basic-web-static/index.html b/piet-web/examples/basic/basic-web-static/index.html similarity index 90% rename from piet-web/examples/basic-web-static/index.html rename to piet-web/examples/basic/basic-web-static/index.html index 1235d3934..c01736773 100644 --- a/piet-web/examples/basic-web-static/index.html +++ b/piet-web/examples/basic/basic-web-static/index.html @@ -15,6 +15,6 @@ - + diff --git a/piet-web/examples/basic/basic-web-static/index.js b/piet-web/examples/basic/basic-web-static/index.js new file mode 100644 index 000000000..3d3a96264 --- /dev/null +++ b/piet-web/examples/basic/basic-web-static/index.js @@ -0,0 +1,5 @@ +const rust = import('./dist/piet_web_example'); + +rust + .then(m => m.run()) + .catch(console.error); diff --git a/piet-web/examples/basic/basic-web-static/package.json b/piet-web/examples/basic/basic-web-static/package.json new file mode 100644 index 000000000..806119cdb --- /dev/null +++ b/piet-web/examples/basic/basic-web-static/package.json @@ -0,0 +1,13 @@ +{ + "scripts": { + "build": "webpack", + "serve": "webpack-dev-server" + }, + "devDependencies": { + "text-encoding": "^0.7.0", + "html-webpack-plugin": "^3.2.0", + "webpack": "^4.11.1", + "webpack-cli": "^3.1.1", + "webpack-dev-server": "^3.1.0" + } +} diff --git a/piet-web/examples/basic/basic-web-static/webpack.config.js b/piet-web/examples/basic/basic-web-static/webpack.config.js new file mode 100644 index 000000000..44c481841 --- /dev/null +++ b/piet-web/examples/basic/basic-web-static/webpack.config.js @@ -0,0 +1,20 @@ +const path = require('path'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const webpack = require('webpack'); + +module.exports = { + entry: './index.js', + output: { + path: path.resolve(__dirname), + filename: 'index.js', + }, + plugins: [ + // Have this example work in Edge which doesn't ship `TextEncoder` or + // `TextDecoder` at this time. + new webpack.ProvidePlugin({ + TextDecoder: ['text-encoding', 'TextDecoder'], + TextEncoder: ['text-encoding', 'TextEncoder'] + }) + ], + mode: 'development' +}; diff --git a/piet-web/examples/basic/build.sh b/piet-web/examples/basic/build.sh new file mode 100755 index 000000000..318d1a927 --- /dev/null +++ b/piet-web/examples/basic/build.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +set -ex + +# Build the `hello_world.wasm` file using Cargo/rustc +cargo build --target wasm32-unknown-unknown + +# Run the `wasm-bindgen` CLI tool to postprocess the wasm file emitted by the +# Rust compiler to emit the JS support glue that's necessary +wasm-bindgen ../../../target/wasm32-unknown-unknown/debug/piet_web_example.wasm --out-dir basic-web-static/dist + +# Finally, package everything up using Webpack and start a server so we can +# browse the result +npm install --prefix basic-web-static +npm run serve --prefix basic-web-static diff --git a/piet-web/examples/basic-web.rs b/piet-web/examples/basic/src/lib.rs similarity index 70% rename from piet-web/examples/basic-web.rs rename to piet-web/examples/basic/src/lib.rs index 762526393..454b0a742 100644 --- a/piet-web/examples/basic-web.rs +++ b/piet-web/examples/basic/src/lib.rs @@ -2,11 +2,9 @@ use kurbo::{BezPath, Line}; -use stdweb::traits::*; -use stdweb::unstable::TryInto; -use stdweb::web::{document, CanvasRenderingContext2d}; - -use stdweb::web::html_element::CanvasElement; +use wasm_bindgen::prelude::*; +use wasm_bindgen::JsCast; +use web_sys::{window, HtmlCanvasElement}; use piet::{FillRule, RenderContext}; use piet_web::WebRenderContext; @@ -29,22 +27,26 @@ fn draw_pretty_picture(rc: &mut R) { rc.fill(&path, &brush, FillRule::NonZero); } -fn main() { - stdweb::initialize(); - - let canvas: CanvasElement = document() - .query_selector("#canvas") +#[wasm_bindgen] +pub fn run() { + let canvas = window() .unwrap() + .document() .unwrap() - .try_into() + .get_element_by_id("canvas") + .unwrap() + .dyn_into::() + .unwrap(); + let mut context = canvas + .get_context("2d") + .unwrap() + .unwrap() + .dyn_into::() .unwrap(); - let mut context: CanvasRenderingContext2d = canvas.get_context().unwrap(); canvas.set_width(canvas.offset_width() as u32); canvas.set_height(canvas.offset_height() as u32); let mut piet_context = WebRenderContext::new(&mut context); draw_pretty_picture(&mut piet_context); - - stdweb::event_loop(); } From e282525e7de0dca61c5a3d71eb31aff6be422b44 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Mon, 7 Jan 2019 17:12:31 +0100 Subject: [PATCH 3/6] Keep dist folder --- piet-web/examples/basic/.gitignore | 1 - piet-web/examples/basic/basic-web-static/dist/.gitkeep | 0 2 files changed, 1 deletion(-) create mode 100644 piet-web/examples/basic/basic-web-static/dist/.gitkeep diff --git a/piet-web/examples/basic/.gitignore b/piet-web/examples/basic/.gitignore index 1a993212d..504afef81 100644 --- a/piet-web/examples/basic/.gitignore +++ b/piet-web/examples/basic/.gitignore @@ -1,3 +1,2 @@ -dist/ node_modules/ package-lock.json diff --git a/piet-web/examples/basic/basic-web-static/dist/.gitkeep b/piet-web/examples/basic/basic-web-static/dist/.gitkeep new file mode 100644 index 000000000..e69de29bb From 8be4132ed801c0be01ded2ddee5dcf6aa8f111da Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Mon, 7 Jan 2019 17:20:03 +0100 Subject: [PATCH 4/6] Ignore files in dist folder --- piet-web/examples/basic/basic-web-static/dist/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 piet-web/examples/basic/basic-web-static/dist/.gitignore diff --git a/piet-web/examples/basic/basic-web-static/dist/.gitignore b/piet-web/examples/basic/basic-web-static/dist/.gitignore new file mode 100644 index 000000000..d6b7ef32c --- /dev/null +++ b/piet-web/examples/basic/basic-web-static/dist/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore From cb1d23484267c2f91b75a1598d17644686cb52f3 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Mon, 7 Jan 2019 17:34:03 +0100 Subject: [PATCH 5/6] Allow the correct lib types --- piet-web/Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/piet-web/Cargo.toml b/piet-web/Cargo.toml index 346657173..8081ebca3 100644 --- a/piet-web/Cargo.toml +++ b/piet-web/Cargo.toml @@ -8,6 +8,9 @@ edition = "2018" keywords = ["graphics", "2d"] categories = ["rendering::graphics-api", "wasm"] +[lib] +crate-type = ["cdylib", "rlib"] + [dependencies] kurbo = "0.1.2" piet = { path = "../piet" } From cecc1792774bd3defd09a83fa849a57cca72e2d4 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Mon, 7 Jan 2019 19:00:24 +0100 Subject: [PATCH 6/6] Ensure piet-web example build script works on Windows --- piet-web/Cargo.toml | 2 +- piet-web/README.md | 5 ++++- piet-web/examples/basic/Cargo.toml | 2 +- piet-web/examples/basic/build.sh | 7 ++++--- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/piet-web/Cargo.toml b/piet-web/Cargo.toml index 8081ebca3..d1f8b6bfe 100644 --- a/piet-web/Cargo.toml +++ b/piet-web/Cargo.toml @@ -15,7 +15,7 @@ crate-type = ["cdylib", "rlib"] kurbo = "0.1.2" piet = { path = "../piet" } -wasm-bindgen = "0.2.29" +wasm-bindgen = "0.2.30" [dependencies.web-sys] version = "0.3.6" diff --git a/piet-web/README.md b/piet-web/README.md index 12ec8d912..32e1287be 100644 --- a/piet-web/README.md +++ b/piet-web/README.md @@ -2,7 +2,10 @@ Ensure both cargo and [npm] are installed. -`$ cargo install -f wasm-bindgen` +Make sure that wasm-bindgen is installed. This needs to be the same version of +wasm-bindgen used by piet-web. + +`$ cargo install -f wasm-bindgen-cli` `$ cd examples/basic && ./build.sh` diff --git a/piet-web/examples/basic/Cargo.toml b/piet-web/examples/basic/Cargo.toml index 0e4ba144e..3fca65027 100644 --- a/piet-web/examples/basic/Cargo.toml +++ b/piet-web/examples/basic/Cargo.toml @@ -10,7 +10,7 @@ crate-type = ["cdylib"] [dependencies] piet = { path = "../../../piet" } piet-web = { path = "../.." } -wasm-bindgen = "0.2.29" +wasm-bindgen = "0.2.30" kurbo = "0.1.2" [dependencies.web-sys] diff --git a/piet-web/examples/basic/build.sh b/piet-web/examples/basic/build.sh index 318d1a927..439aaabc6 100755 --- a/piet-web/examples/basic/build.sh +++ b/piet-web/examples/basic/build.sh @@ -2,7 +2,7 @@ set -ex -# Build the `hello_world.wasm` file using Cargo/rustc +# Build the `hello_world.wasm` file using Cargo cargo build --target wasm32-unknown-unknown # Run the `wasm-bindgen` CLI tool to postprocess the wasm file emitted by the @@ -11,5 +11,6 @@ wasm-bindgen ../../../target/wasm32-unknown-unknown/debug/piet_web_example.wasm # Finally, package everything up using Webpack and start a server so we can # browse the result -npm install --prefix basic-web-static -npm run serve --prefix basic-web-static +cd basic-web-static +npm install +npm run serve