hyperpixel/
lib.rs

1use js_ffi::*;
2
3pub struct HyperPixel {
4    instance: Option<JSObject>,
5    fn_init: JSInvoker,
6    fn_render: JSInvoker,
7    fn_width: JSInvoker,
8    fn_height: JSInvoker,
9}
10
11impl HyperPixel {
12    /// Create an instance of HyperPixel from a selector to a canvas element.
13    pub fn new(selector: &str) -> HyperPixel {
14        let mut h = HyperPixel {
15            instance: None,
16            fn_init: js!((selector)=>{
17                return new HyperPixel(document.querySelector(selector));
18            }),
19            fn_render: js!((function(mem,ptr,length){
20                let p = ptr/4;
21                let pixelView = (new Float32Array(mem)).subarray(p,p+length);
22                this.render(pixelView);
23            })),
24            fn_width: js!((function(mem,ptr,length){
25                return this.width;
26            })),
27            fn_height: js!((function(mem,ptr,length){
28                return this.height;
29            })),
30        };
31        h.init(selector);
32        h
33    }
34
35    fn init(&mut self, selector: &str) {
36        self.instance = Some(JSObject(self.fn_init.invoke_1(selector)))
37    }
38
39    /// Dimensions of the screen as tuple (width,height).
40    pub fn dimensions(&self) -> (usize, usize) {
41        let w = self.fn_width.call_0(self.instance.as_ref().unwrap()) as usize;
42        let h = self.fn_height.call_0(self.instance.as_ref().unwrap()) as usize;
43        (w, h)
44    }
45
46    /// Send a slice of float32 values to be pushed to the GPU and update the framebuffer immediately.
47    pub fn render(&self, colors: &[f32]) {
48        self.fn_render.call_3(
49            self.instance.as_ref().unwrap(),
50            WasmMemory,
51            colors.as_ptr() as u32,
52            colors.len() as u32,
53        );
54    }
55}