use notan::draw::*;
use notan::math::{Mat3, Vec2};
use notan::prelude::*;
#[derive(AppState)]
struct State {
count: f32,
container_a: Container,
container_b: Container,
container_c: Container,
container_d: Container,
container_e: Container,
}
impl State {
fn new() -> Self {
let container_a = Container::new(500.0, 500.0, Color::WHITE);
let container_b = Container::new(230.0, 350.0, Color::from_rgb(1.0, 1.0, 0.5));
let container_c = Container::new(130.0, 130.0, Color::from_rgb(0.5, 1.0, 0.5));
let container_d = Container::new(130.0, 130.0, Color::from_rgb(1.0, 0.5, 1.0));
let container_e = Container::new(130.0, 130.0, Color::from_rgb(0.5, 1.0, 1.0));
Self {
count: 0.0,
container_a,
container_b,
container_c,
container_d,
container_e,
}
}
}
fn draw_container<F: FnMut(&mut Draw, &Container)>(
draw: &mut Draw,
container: &Container,
mut f: F,
) {
draw.transform().push(container.matrix());
draw.rect((0.0, 0.0), (container.size.x, container.size.y))
.color(container.color)
.stroke(5.0);
f(draw, container);
draw.transform().pop();
}
#[notan_main]
fn main() -> Result<(), String> {
notan::init_with(State::new)
.add_config(DrawConfig)
.update(update)
.draw(draw)
.build()
}
fn draw(gfx: &mut Graphics, state: &mut State) {
let mut draw = gfx.create_draw();
draw.clear(Color::BLACK);
draw_container(&mut draw, &state.container_a, |draw, _c| {
draw_container(draw, &state.container_b, |draw, _c| {
draw_container(draw, &state.container_c, |draw, c| {
draw_triangle(draw, c.size, state.count.cos());
});
});
draw_container(draw, &state.container_d, |draw, c| {
draw_triangle(draw, c.size, state.count.cos());
});
draw_container(draw, &state.container_e, |draw, c| {
draw_triangle(draw, c.size, state.count.cos());
});
});
gfx.render(&draw);
}
fn update(app: &mut App, state: &mut State) {
let offset = state.count.sin();
let center_x = app.window().width() as f32 * 0.5;
let center_y = app.window().height() as f32 * 0.5;
state.container_a.pos.x = center_x - state.container_a.size.x * 0.5 + offset * 120.0;
state.container_a.pos.y = center_y - state.container_a.size.y * 0.5;
state.container_b.pos.x = 20.0;
state.container_b.pos.y =
state.container_a.size.y * 0.5 - state.container_b.size.y * 0.5 + offset * 50.0;
state.container_c.pos.x =
state.container_b.size.x * 0.5 - state.container_c.size.x * 0.5 - offset * 32.0;
state.container_c.pos.y =
state.container_b.size.y * 0.5 - state.container_c.size.y * 0.5 - offset * 90.0;
state.container_d.pos.x = state.container_a.size.x * 0.75 - state.container_d.size.x * 0.5;
state.container_d.pos.y = state.container_a.size.y * 0.25 - state.container_d.size.y * 0.5;
state.container_d.rotation = offset * 1.0;
state.container_e.pos.x = state.container_a.size.x * 0.75 - state.container_e.size.x * 0.5;
state.container_e.pos.y = state.container_a.size.y * 0.75 - state.container_e.size.y * 0.5;
state.container_e.scale.x = 1.0 - offset * 0.3;
state.container_e.scale.y = 1.0 + offset * 0.3;
state.count += app.timer.delta_f32();
}
struct Container {
pos: Vec2,
rotation: f32,
scale: Vec2,
size: Vec2,
color: Color,
}
impl Container {
fn new(width: f32, height: f32, color: Color) -> Self {
Self {
pos: Vec2::new(0.0, 0.0),
rotation: 0.0,
scale: Vec2::new(1.0, 1.0),
size: Vec2::new(width, height),
color,
}
}
fn matrix(&self) -> Mat3 {
let translation = Mat3::from_translation(self.pos);
let rotation = Mat3::from_angle(self.rotation);
let scale = Mat3::from_scale(self.scale);
translation * rotation * scale
}
}
fn draw_triangle(draw: &mut Draw, size: Vec2, offset: f32) {
let a = (size.x * 0.5, size.y * 0.2);
let b = (size.x * 0.2, size.y * 0.8);
let c = (size.x * 0.8, size.y * 0.8);
let rotation = offset * 360.0 * 0.5;
draw.triangle(a, b, c)
.alpha(0.7)
.rotate_degrees_from((size.x * 0.5, size.y * 0.5), rotation)
.color_vertex(Color::RED, Color::GREEN, Color::BLUE);
}