rive_rs/shapes/
ellipse.rs
1use std::rc::Rc;
6
7use crate::component::Component;
8use crate::component_dirt::ComponentDirt;
9use crate::core::{Core, Object, ObjectRef, OnAdded};
10use crate::math;
11use crate::shapes::{CubicDetachedVertex, CubicVertex, ParametricPath, Path, PathVertex};
12
13#[derive(Debug)]
14pub struct Ellipse {
15 parametric_path: ParametricPath,
16 vertex1: Rc<CubicDetachedVertex>,
17 vertex2: Rc<CubicDetachedVertex>,
18 vertex3: Rc<CubicDetachedVertex>,
19 vertex4: Rc<CubicDetachedVertex>,
20}
21
22impl ObjectRef<'_, Ellipse> {
23 pub fn update(&self, value: ComponentDirt) {
24 let parametric_path = self.cast::<ParametricPath>();
25
26 if Component::value_has_dirt(value, ComponentDirt::PATH) {
27 let radius_x = parametric_path.width() / 2.0;
28 let radius_y = parametric_path.height() / 2.0;
29
30 let o_x = -parametric_path.origin_x() * parametric_path.width() + radius_x;
31 let o_y = -parametric_path.origin_y() * parametric_path.height() + radius_y;
32
33 fn vertex_ref(vertex: &Rc<CubicDetachedVertex>) -> ObjectRef<'_, CubicDetachedVertex> {
34 ObjectRef::from(&**vertex)
35 }
36
37 let v1 = vertex_ref(&self.vertex1);
38 let v2 = vertex_ref(&self.vertex2);
39 let v3 = vertex_ref(&self.vertex3);
40 let v4 = vertex_ref(&self.vertex4);
41
42 v1.cast::<PathVertex>().set_x(o_x);
43 v1.cast::<PathVertex>().set_y(o_y - radius_y);
44 v1.cast::<CubicVertex>().set_in_point(math::Vec::new(
45 o_x - radius_x * math::CIRCLE_CONSTANT,
46 o_y - radius_y,
47 ));
48 v1.cast::<CubicVertex>().set_out_point(math::Vec::new(
49 o_x + radius_x * math::CIRCLE_CONSTANT,
50 o_y - radius_y,
51 ));
52
53 v2.cast::<PathVertex>().set_x(o_x + radius_x);
54 v2.cast::<PathVertex>().set_y(o_y);
55 v2.cast::<CubicVertex>().set_in_point(math::Vec::new(
56 o_x + radius_x,
57 o_y - radius_y * math::CIRCLE_CONSTANT,
58 ));
59 v2.cast::<CubicVertex>().set_out_point(math::Vec::new(
60 o_x + radius_x,
61 o_y + radius_y * math::CIRCLE_CONSTANT,
62 ));
63
64 v3.cast::<PathVertex>().set_x(o_x);
65 v3.cast::<PathVertex>().set_y(o_y + radius_y);
66 v3.cast::<CubicVertex>().set_in_point(math::Vec::new(
67 o_x + radius_x * math::CIRCLE_CONSTANT,
68 o_y + radius_y,
69 ));
70 v3.cast::<CubicVertex>().set_out_point(math::Vec::new(
71 o_x - radius_x * math::CIRCLE_CONSTANT,
72 o_y + radius_y,
73 ));
74
75 v4.cast::<PathVertex>().set_x(o_x - radius_x);
76 v4.cast::<PathVertex>().set_y(o_y);
77 v4.cast::<CubicVertex>().set_in_point(math::Vec::new(
78 o_x - radius_x,
79 o_y + radius_y * math::CIRCLE_CONSTANT,
80 ));
81 v4.cast::<CubicVertex>().set_out_point(math::Vec::new(
82 o_x - radius_x,
83 o_y - radius_y * math::CIRCLE_CONSTANT,
84 ));
85 }
86
87 self.cast::<Path>().update(value);
88 }
89}
90
91impl Core for Ellipse {
92 parent_types![(parametric_path, ParametricPath)];
93
94 properties!(parametric_path);
95}
96
97impl OnAdded for ObjectRef<'_, Ellipse> {
98 on_added!(ParametricPath);
99}
100
101impl Default for Ellipse {
102 fn default() -> Self {
103 let ellipse = Self {
104 parametric_path: ParametricPath::default(),
105 vertex1: Rc::new(CubicDetachedVertex::default()),
106 vertex2: Rc::new(CubicDetachedVertex::default()),
107 vertex3: Rc::new(CubicDetachedVertex::default()),
108 vertex4: Rc::new(CubicDetachedVertex::default()),
109 };
110
111 let ellipse_ref = ObjectRef::from(&ellipse);
112 let path = ellipse_ref.cast::<Path>();
113
114 let v1 = ellipse.vertex1.clone() as Rc<dyn Core>;
115 let v2 = ellipse.vertex2.clone() as Rc<dyn Core>;
116 let v3 = ellipse.vertex3.clone() as Rc<dyn Core>;
117 let v4 = ellipse.vertex4.clone() as Rc<dyn Core>;
118
119 path.push_vertex(Object::new(&v1));
120 path.push_vertex(Object::new(&v2));
121 path.push_vertex(Object::new(&v3));
122 path.push_vertex(Object::new(&v4));
123
124 ellipse
125 }
126}