From 9efc362c82df1c45c7ccfa09ace200e17974de5f Mon Sep 17 00:00:00 2001 From: Joel Martin Date: Wed, 25 Jul 2018 16:48:48 +0900 Subject: [PATCH] wasm: draw/fill a canvas with solid color. --- core/wasm/README.md | 11 +++++++++++ core/wasm/index.html | 1 + core/wasm/index.js | 22 ++++++++++++++++----- core/wasm/src/lib.rs | 47 ++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 72 insertions(+), 9 deletions(-) diff --git a/core/wasm/README.md b/core/wasm/README.md index f73c6666..b55f449e 100644 --- a/core/wasm/README.md +++ b/core/wasm/README.md @@ -1,3 +1,14 @@ +# noVNC + wasm + +The following example is based on this tutorial: + +https://hacks.mozilla.org/2018/04/javascript-to-rust-and-back-again-a-wasm-bindgen-tale/ + +and this example: + +https://github.com/rustwasm/wasm-bindgen/blob/master/examples/julia\_set/ + + ## Prep: ``` diff --git a/core/wasm/index.html b/core/wasm/index.html index bad47a7c..e4f4ce04 100644 --- a/core/wasm/index.html +++ b/core/wasm/index.html @@ -3,6 +3,7 @@ + diff --git a/core/wasm/index.js b/core/wasm/index.js index e8e86fb9..b427e090 100644 --- a/core/wasm/index.js +++ b/core/wasm/index.js @@ -1,6 +1,18 @@ -// Note that a dynamic `import` statement here is required due to -// webpack/webpack#6615, but in theory `import { greet } from './hello_world';` -// will work here one day as well! -const rust = import('./novnc'); +const WIDTH = 1024 +const HEIGHT = 768 -rust.then(m => m.greet('World!')); +import('./novnc') + .then(wasm => { + const canvas = document.getElementById('target') + const ctx = canvas.getContext('2d') + + canvas.addEventListener('click', () => { + const startMs = (new Date()).getTime() + wasm.draw(ctx, WIDTH, HEIGHT, + parseInt(Math.random()*256), + parseInt(Math.random()*256), + parseInt(Math.random()*256)) + console.log("elapsed:", (new Date()).getTime() - startMs) + }); + wasm.draw(ctx, WIDTH, HEIGHT, 50, 150, 150) + }) diff --git a/core/wasm/src/lib.rs b/core/wasm/src/lib.rs index 1199c7fc..db61e8bb 100644 --- a/core/wasm/src/lib.rs +++ b/core/wasm/src/lib.rs @@ -5,11 +5,50 @@ extern crate wasm_bindgen; use wasm_bindgen::prelude::*; #[wasm_bindgen] -extern { - fn alert(s: &str); +extern "C" { + pub type ImageData; + + #[wasm_bindgen(constructor)] + pub fn new(arr: &Uint8ClampedArray, width: u32, height: u32) -> ImageData; } #[wasm_bindgen] -pub fn greet(name: &str) { - alert(&format!("Hi, {}!", name)); +extern "C" { + pub type Uint8ClampedArray; + + #[wasm_bindgen(constructor)] + pub fn new(arr: &[u8]) -> Uint8ClampedArray; +} + +#[wasm_bindgen] +extern "C" { + pub type CanvasRenderingContext2D; + + #[wasm_bindgen(method, js_name = putImageData)] + pub fn put_image_data(this: &CanvasRenderingContext2D, image_data: &ImageData, p_1: i32, p_2: i32); +} + +#[wasm_bindgen] +pub fn draw(ctx: &CanvasRenderingContext2D, width: u32, height: u32, red: u8, green: u8, blue: u8) { + let data = fill(width, height, red, green, blue); + let uint8_array = Uint8ClampedArray::new(&data); + + ctx.put_image_data(&ImageData::new(&uint8_array, width, height), 0, 0); +} + +/////////////////////////////////////////////////// + +pub fn fill(width: u32, height: u32, red: u8, green: u8, blue: u8) -> Vec { + let mut data: Vec = vec![]; + + for _x in 0..width { + for _y in 0..height { + data.push(red as u8); + data.push(green as u8); + data.push(blue as u8); + data.push(255); + } + } + + data }