Skip to main content

ranim_items/vitem/geometry/
ellipse.rs

1use ranim_core::{
2    Extract,
3    color::{AlphaColor, Srgb},
4    core_item::{CoreItem, vitem::DEFAULT_STROKE_WIDTH},
5    glam::{DVec2, DVec3},
6    traits::{Aabb, Discard, FillColor, Opacity, StrokeColor, With},
7};
8
9use crate::vitem::{
10    VItem,
11    geometry::{Circle, EllipticArc},
12};
13
14/// An ellipse centered at the origin in the XY plane.
15#[derive(Clone, Debug, ranim_macros::Interpolatable)]
16pub struct Ellipse {
17    /// Semi-axes in the x and y directions.
18    pub radius: DVec2,
19    /// Stroke rgba.
20    pub stroke_rgba: AlphaColor<Srgb>,
21    /// Stroke width.
22    pub stroke_width: f32,
23    /// Fill rgba.
24    pub fill_rgba: AlphaColor<Srgb>,
25}
26
27impl Ellipse {
28    /// Creates a new ellipse.
29    pub fn new(radius: DVec2) -> Self {
30        Self {
31            radius,
32            stroke_rgba: AlphaColor::WHITE,
33            stroke_width: DEFAULT_STROKE_WIDTH,
34            fill_rgba: AlphaColor::TRANSPARENT,
35        }
36    }
37}
38
39impl From<Circle> for Ellipse {
40    fn from(value: Circle) -> Self {
41        let Circle {
42            radius,
43            stroke_rgba,
44            stroke_width,
45            fill_rgba,
46        } = value;
47        Self {
48            radius: DVec2::splat(radius),
49            stroke_rgba,
50            stroke_width,
51            fill_rgba,
52        }
53    }
54}
55
56impl From<Ellipse> for VItem {
57    fn from(value: Ellipse) -> Self {
58        let fill_rgba = value.fill_rgba;
59        VItem::from(EllipticArc::from(value)).with(|item| item.set_fill_color(fill_rgba).discard())
60    }
61}
62
63impl Aabb for Ellipse {
64    fn aabb(&self) -> [DVec3; 2] {
65        let r = self.radius.extend(0.0);
66        [-r, r].aabb()
67    }
68}
69
70impl StrokeColor for Ellipse {
71    fn stroke_color(&self) -> AlphaColor<Srgb> {
72        self.stroke_rgba
73    }
74
75    fn set_stroke_opacity(&mut self, opacity: f32) -> &mut Self {
76        self.stroke_rgba = self.stroke_rgba.with_alpha(opacity);
77        self
78    }
79
80    fn set_stroke_color(&mut self, color: AlphaColor<Srgb>) -> &mut Self {
81        self.stroke_rgba = color;
82        self
83    }
84}
85
86impl FillColor for Ellipse {
87    fn fill_color(&self) -> AlphaColor<Srgb> {
88        self.fill_rgba
89    }
90
91    fn set_fill_opacity(&mut self, opacity: f32) -> &mut Self {
92        self.fill_rgba = self.fill_rgba.with_alpha(opacity);
93        self
94    }
95
96    fn set_fill_color(&mut self, color: AlphaColor<Srgb>) -> &mut Self {
97        self.fill_rgba = color;
98        self
99    }
100}
101
102impl Opacity for Ellipse {
103    fn set_opacity(&mut self, opacity: f32) -> &mut Self {
104        self.set_fill_opacity(opacity).set_stroke_opacity(opacity);
105        self
106    }
107}
108
109impl Extract for Ellipse {
110    type Target = CoreItem;
111
112    fn extract_into(&self, buf: &mut Vec<Self::Target>) {
113        VItem::from(self.clone()).extract_into(buf);
114    }
115}