sim/ui/src/canvas.rs

87 lines
2.4 KiB
Rust
Raw Normal View History

use crate::model::{Sel, State, T, Terrain, canvas_len, tile_offset};
use wasm_bindgen::JsCast;
use web_sys::{CanvasRenderingContext2d, HtmlCanvasElement};
const COLORS: [&str; 7] = [
"#10305e", "#2a62a8", "#e0d08a", "#6aaa4a", "#3f7d3a", "#8a8a6a", "#aaaaaa",
];
pub fn draw(canvas: &HtmlCanvasElement, t: &Terrain, s: &State, sel: Option<Sel>) {
canvas.set_width(canvas_len(t.w));
canvas.set_height(canvas_len(t.h));
let Some(ctx) = canvas
.get_context("2d")
.ok()
.flatten()
.and_then(|c| c.dyn_into::<CanvasRenderingContext2d>().ok())
else {
return;
};
for y in 0..t.h {
for x in 0..t.w {
ctx.set_fill_style_str(COLORS[t.kind(x, y)]);
ctx.fill_rect(tile_offset(x), tile_offset(y), T, T);
}
}
let dot = |x: usize, y: usize, r: f64, color: &str| {
ctx.set_fill_style_str(color);
ctx.begin_path();
let _ = ctx.arc(
tile_offset(x) + T / 2.0,
tile_offset(y) + T / 2.0,
r,
0.0,
std::f64::consts::TAU,
);
ctx.fill();
};
for r in &s.res {
match r.2 {
1 => dot(r.0, r.1, 3.5, "#1d4a1d"),
2 => dot(r.0, r.1, 2.0, "#e85a8a"),
_ => {
ctx.set_fill_style_str("#666");
ctx.fill_rect(tile_offset(r.0) + 2.0, tile_offset(r.1) + 2.0, 6.0, 6.0);
}
}
}
ctx.set_fill_style_str("#7a4a22");
for h in &s.houses {
ctx.fill_rect(
tile_offset(h.0) + 1.0,
tile_offset(h.1) + 1.0,
T - 2.0,
T - 2.0,
);
}
ctx.set_fill_style_str("#b05a2a");
ctx.fill_rect(tile_offset(s.home.0), tile_offset(s.home.1), T, T);
for a in &s.rabbits {
dot(a.0, a.1, 2.5, "#fff");
}
for a in &s.wolves {
dot(a.0, a.1, 4.0, "#d22");
}
for p in &s.people {
dot(p.1, p.2, 4.0, "#ff0");
}
ctx.set_fill_style_str(&format!("rgba(5,10,50,{})", (1.0 - s.daylight) * 0.65));
ctx.fill_rect(0.0, 0.0, tile_offset(t.w), tile_offset(t.h));
if let Some(sel) = sel {
let (x0, y0, x1, y1) = sel.rect();
ctx.set_stroke_style_str("#fff");
ctx.set_line_width(2.0);
ctx.stroke_rect(
tile_offset(x0),
tile_offset(y0),
tile_offset(x1 - x0 + 1),
tile_offset(y1 - y0 + 1),
);
}
}