rive_rs/shapes/
ellipse.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use 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}