use std::cell::RefCell; use std::rc::Rc; use leptos::html::Canvas; use leptos::*; use wasm_bindgen::prelude::Closure; use wasm_bindgen::JsCast; use wasm_bindgen::JsValue; use web_sys::window; use crate::space_colonization::Node; use crate::space_colonization::Point; use crate::space_colonization::SpaceColonization; #[component] pub fn Background(cx: Scope, class: &'static str) -> impl IntoView { let canvas = create_node_ref::(cx); canvas.on_load(cx, move |_| { let canvas = canvas.get().expect("canvas is mounted"); let canvas_parent = canvas.parent_element().unwrap(); let width = canvas_parent.client_width(); let height = canvas_parent.client_height(); let window_width = u32::try_from(width).unwrap(); let window_height = u32::try_from(height).unwrap(); canvas.set_width(window_width); canvas.set_height(window_height); let context = canvas .get_context("2d") .ok() .flatten() .expect("canvas to have context") .unchecked_into::(); log!("context = {:#?}", context); context.set_stroke_style(&JsValue::from("white")); let context_to_render = context.clone(); // let render_node_fn : 'a Fn(&Node, &Node) = |n: &Node, child: &Node| { let render_node_fn = move |n: &Node, child: &Node| { context_to_render.move_to(n.position.x.into(), n.position.y.into()); context_to_render.line_to(child.position.x.into(), child.position.y.into()); }; let mut sc = SpaceColonization::new( width.try_into().unwrap(), height.try_into().unwrap(), render_node_fn, ); let nodes = Rc::new(RefCell::new(Vec::new())); { let mut nodesMut = nodes.borrow_mut(); nodesMut.push(Node::new(Point::new(( (window_width / 3) as i32, (window_height / 3) as i32, )))); nodesMut.push(Node::new(Point::new(( (window_width / 2) as i32, (window_height / 3) as i32, )))); nodesMut.push(Node::new(Point::new(( (window_width / 3) as i32, (window_height / 2) as i32, )))); nodesMut.push(Node::new(Point::new(( (window_width - 200) as i32, (window_height / 3) as i32, )))); nodesMut.push(Node::new(Point::new(( (window_width - 100) as i32, (window_height - 100) as i32, )))); } // TODO Resize on window resize log!( "TODO resize on window resize canvas parent size = {} {}", canvas_parent.client_width(), canvas_parent.client_height() ); context.set_stroke_style(&JsValue::from("white")); context.set_fill_style(&JsValue::from("yellow")); log!("About to render nodes"); let start_time = window().unwrap().performance().unwrap().now(); context.begin_path(); /* let render_node_fn = |n: &Node, child: &Node| { context.move_to(n.position.x.into(), n.position.y.into()); context.line_to(child.position.x.into(), child.position.y.into()); }; */ // let render_id = window().unwrap().performance().unwrap().now(); // sc.render_all_nodes(&nodes.borrow(), render_id, render_node_fn); context.stroke(); let end_time = window().unwrap().performance().unwrap().now(); log!( "Rendering nodes and {} attractors took {}", sc.attractors.size(), end_time - start_time ); let context = context.clone(); let closure = Closure::::new(move |_: web_sys::MouseEvent| { let start_time = window().unwrap().performance().unwrap().now(); { let mut nodesMut = nodes.borrow_mut(); sc.grow(&mut nodesMut); } // let render_id = window().unwrap().performance().unwrap().now(); // context.begin_path(); // sc.render_nodes(&nodes.borrow(), render_id, render_node_fn); /* context.set_fill_style(&JsValue::from("magenta")); for a in sc.attractors.iter().filter(|a| a.dead) { context.fill_rect(a.position.x.into(), a.position.y.into(), 5.0, 5.0); } context.set_fill_style(&JsValue::from("red")); for a in sc.attractors.iter().filter(|a| !a.dead) { context.fill_rect(a.position.x.into(), a.position.y.into(), 5.0, 5.0); } */ context.stroke(); let end_time = window().unwrap().performance().unwrap().now(); log!( "Rendering nodes and {} attractors took {}", sc.attractors.size(), end_time - start_time ); }); let window = window().unwrap(); window .set_interval_with_callback_and_timeout_and_arguments_0( closure.as_ref().unchecked_ref(), 30, ) .unwrap(); // window // .add_event_listener_with_callback( // "click", // closure.as_ref().unchecked_ref(), // ) // .unwrap(); closure.forget(); }); let class = format!("canvas {}", class); view! { cx,
} }