diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 47f49cb5..5018c56e 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -309,7 +309,8 @@ - [Borrow Checker](webassembly/limitations/borrow-checker.md) - [Closures](webassembly/limitations/closures.md) - [Async](webassembly/async.md) - +- [Exercises](exercises/webassembly/webassembly.md) + - [Camera](exercises/webassembly/camera.md) # Final Words diff --git a/src/exercises/webassembly/camera.md b/src/exercises/webassembly/camera.md new file mode 100644 index 00000000..4d4a8911 --- /dev/null +++ b/src/exercises/webassembly/camera.md @@ -0,0 +1,48 @@ +# Camera + +In this exercise we will play with the camera in real time. + +Serve the web server and navigate to [http://localhost:8000/exercises/camera/](http://localhost:8000/exercises/camera/). + +You will edit [lib.rs](../../rust-wasm-template/lib.rs) as usual. + +Here is the basic code you will need: + +```rust +extern crate console_error_panic_hook; + +use js_sys::Uint8ClampedArray; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +extern "C" { + fn alert(s: &str); + + #[wasm_bindgen(js_namespace = console)] + pub fn log(s: &str); +} + +#[wasm_bindgen] +pub fn set_panic_hook() { + console_error_panic_hook::set_once(); +} + +#[wasm_bindgen] +pub fn edit_bitmap(image_data: &Uint8ClampedArray, width: u32, height: u32) { +} + +``` + +We want to edit the function `edit_bitmap`. `image_data` is a reference to the [Uint8ClampedArray](https://rustwasm.github.io/wasm-bindgen/api/js_sys/struct.Uint8ClampedArray.html) being rendered on your screen. `Uint8ClampedArray` is a flat array of unsigned int of `8` bits. +It represents `srgb` image, which means that each pixel is represented as a vector of 4 elements [red, green, blue, illumination]. +The image can be thought of as a matrix of dimension `(width, height, 4)`, it is row-major. + +We will reuse our different implementations. So do not erase them when going from one exercise to the next. + +1. The first exercise is to turn the top half the image to black. +2. Turn the left half of the image to white. +3. Create an X-ray effect. This is done by mapping colors to their opposite, for instance `0<->255`, `100<->155`. Beware of illumination. +4. You can play with the function, for instance you can implement greyscale, or add random noise. +5. In the `setup` function create a dropdown (``) that will change which transformation to apply to the image. +```rust +static METHODS: [&str; 3] = ["xray", "top-black", "left-white"]; + +#[wasm_bindgen] +pub fn setup() -> Result<(), JsValue> { + console_error_panic_hook::set_once(); + let window = web_sys::window().expect("no global `window` exists"); + let document = window.document().expect("should have a document on window"); + let body = document.body().expect("document should have a body"); + + let select = document.create_element("select")?; + for option_value in METHODS { + let option = document.create_element("option")?; + option.set_inner_html(option_value); + option.set_attribute("value", option_value)?; + select.append_child(&option)?; + } + body.append_child(&select)?; + Ok(()) +} + +#[wasm_bindgen] +pub fn edit_bitmap( + image_data: &Uint8ClampedArray, + width: u32, + height: u32, +) -> Result<(), JsValue> { + let window = web_sys::window().expect("no global `window` exists"); + let document = window.document().expect("should have a document on window"); + let select = document + .query_selector("select")? + .expect("No select") + .dyn_into::() + .expect("Failed to cast