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}