Skip to content

Commit

Permalink
Merge pull request #6 from rylev/wasm-bindgen
Browse files Browse the repository at this point in the history
Use wasm-bindgen instead of stdweb
  • Loading branch information
rylev authored Jan 7, 2019
2 parents eba963f + cecc179 commit eaaab3c
Show file tree
Hide file tree
Showing 14 changed files with 120 additions and 34 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ members = [
"piet-cairo",
"piet-direct2d",
"piet-web",
"piet-web/examples/basic"
]
9 changes: 8 additions & 1 deletion piet-web/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,15 @@ edition = "2018"
keywords = ["graphics", "2d"]
categories = ["rendering::graphics-api", "wasm"]

[lib]
crate-type = ["cdylib", "rlib"]

[dependencies]
kurbo = "0.1.2"
piet = { path = "../piet" }

stdweb = "0.4.12"
wasm-bindgen = "0.2.30"

[dependencies.web-sys]
version = "0.3.6"
features = ["CanvasRenderingContext2d", "CanvasWindingRule"]
11 changes: 7 additions & 4 deletions piet-web/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# Running the examples

Generally follow the directions at [stdweb].
Ensure both cargo and [npm] are installed.

`$ cargo install -f cargo-web`
Make sure that wasm-bindgen is installed. This needs to be the same version of
wasm-bindgen used by piet-web.

`$ cargo web start --target=wasm32-unknown-unknown --example basic-web`
`$ cargo install -f wasm-bindgen-cli`

`$ 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
2 changes: 2 additions & 0 deletions piet-web/examples/basic/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/
package-lock.json
18 changes: 18 additions & 0 deletions piet-web/examples/basic/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "piet-web-example"
version = "0.0.1"
authors = ["Ryan Levick <[email protected]>"]
edition = "2018"

[lib]
crate-type = ["cdylib"]

[dependencies]
piet = { path = "../../../piet" }
piet-web = { path = "../.." }
wasm-bindgen = "0.2.30"
kurbo = "0.1.2"

[dependencies.web-sys]
version = "0.3.6"
features = ["CanvasRenderingContext2d", "Window", "Document", "Element", "HtmlElement", "HtmlCanvasElement"]
2 changes: 2 additions & 0 deletions piet-web/examples/basic/basic-web-static/dist/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@
</head>
<body>
<canvas id="canvas"></canvas>
<script src="basic-web.js"></script>
<script src="index.js"></script>
</body>
</html>
5 changes: 5 additions & 0 deletions piet-web/examples/basic/basic-web-static/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const rust = import('./dist/piet_web_example');

rust
.then(m => m.run())
.catch(console.error);
13 changes: 13 additions & 0 deletions piet-web/examples/basic/basic-web-static/package.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
20 changes: 20 additions & 0 deletions piet-web/examples/basic/basic-web-static/webpack.config.js
Original file line number Diff line number Diff line change
@@ -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'
};
16 changes: 16 additions & 0 deletions piet-web/examples/basic/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/sh

set -ex

# 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
# 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
cd basic-web-static
npm install
npm run serve
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -29,22 +27,26 @@ fn draw_pretty_picture<R: RenderContext>(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::<HtmlCanvasElement>()
.unwrap();
let mut context = canvas
.get_context("2d")
.unwrap()
.unwrap()
.dyn_into::<web_sys::CanvasRenderingContext2d>()
.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();
}
25 changes: 11 additions & 14 deletions piet-web/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand All @@ -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;
Expand All @@ -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(
Expand Down Expand Up @@ -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));
}
}
}
Expand Down

0 comments on commit eaaab3c

Please sign in to comment.