154 lines
5.5 KiB
Rust
154 lines
5.5 KiB
Rust
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::<Canvas>(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::<web_sys::CanvasRenderingContext2d>();
|
|
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::<dyn FnMut(_)>::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,
|
|
<div class={class}>
|
|
<canvas node_ref=canvas></canvas>
|
|
</div>
|
|
}
|
|
}
|