node.rsannotatednode.rssource80 lines · 2.1 KB · raw
1//! The drawing as data: rectangles on the app's grid, grouped, with the motion each group
2//! has. Nothing here draws; `svg.rs` and `css.rs` turn it into markup.
3
4use crate::motion::Motion;
5
6/// An sRGB colour.
7#[derive(Clone, Copy, Debug, PartialEq, Eq)]
8pub struct Color(pub u8, pub u8, pub u8);
9
10impl Color {
11    pub const fn hex(rgb: u32) -> Self {
12        Color((rgb >> 16) as u8, (rgb >> 8) as u8, rgb as u8)
13    }
14
15    pub fn css(self) -> String {
16        format!("#{:02x}{:02x}{:02x}", self.0, self.1, self.2)
17    }
18}
19
20/// A rectangle in grid units.
21#[derive(Clone, Copy, Debug, PartialEq)]
22pub struct Rect {
23    pub x: f32,
24    pub y: f32,
25    pub w: f32,
26    pub h: f32,
27    pub color: Color,
28    pub alpha: f32,
29}
30
31/// Where eyes look.
32#[derive(Clone, Copy, Debug, PartialEq)]
33pub enum Look {
34    /// Towards the pointer (the page) or the scripted gaze (a video frame).
35    Follow,
36    /// Fixed, in gaze units (each axis -1..1), as the app holds them while thinking.
37    Fixed(f32, f32),
38}
39
40#[derive(Clone, Copy, Debug, PartialEq)]
41pub enum Role {
42    Plain,
43    /// The pupils: shifted by the gaze, snapped to half a grid unit as the app snaps them.
44    Eyes(Look),
45}
46
47#[derive(Clone, Debug, PartialEq)]
48pub struct Group {
49    pub motion: Motion,
50    /// The point `motion` scales and turns about, in grid units.
51    pub origin: (f32, f32),
52    pub role: Role,
53    pub children: Vec<Node>,
54}
55
56#[derive(Clone, Debug, PartialEq)]
57pub enum Node {
58    Rect(Rect),
59    Group(Group),
60}
61
62/// A solid rectangle.
63pub fn r(x: f32, y: f32, w: f32, h: f32, color: Color) -> Node {
64    ra(x, y, w, h, color, 1.0)
65}
66
67/// A rectangle with an opacity.
68pub fn ra(x: f32, y: f32, w: f32, h: f32, color: Color, alpha: f32) -> Node {
69    Node::Rect(Rect { x, y, w, h, color, alpha })
70}
71
72/// Children moving together.
73pub fn moving(motion: Motion, origin: (f32, f32), children: Vec<Node>) -> Node {
74    Node::Group(Group { motion, origin, role: Role::Plain, children })
75}
76
77/// The pupils.
78pub fn eyes(look: Look, children: Vec<Node>) -> Node {
79    Node::Group(Group { motion: Motion::Still, origin: (0.0, 0.0), role: Role::Eyes(look), children })
80}