ratatui/widgets/canvas/
circle.rs

1use crate::{
2    style::Color,
3    widgets::canvas::{Painter, Shape},
4};
5
6/// A circle with a given center and radius and with a given color
7#[derive(Debug, Default, Clone, PartialEq)]
8pub struct Circle {
9    /// `x` coordinate of the circle's center
10    pub x: f64,
11    /// `y` coordinate of the circle's center
12    pub y: f64,
13    /// Radius of the circle
14    pub radius: f64,
15    /// Color of the circle
16    pub color: Color,
17}
18
19impl Shape for Circle {
20    fn draw(&self, painter: &mut Painter<'_, '_>) {
21        for angle in 0..360 {
22            let radians = f64::from(angle).to_radians();
23            let circle_x = self.radius.mul_add(radians.cos(), self.x);
24            let circle_y = self.radius.mul_add(radians.sin(), self.y);
25            if let Some((x, y)) = painter.get_point(circle_x, circle_y) {
26                painter.paint(x, y, self.color);
27            }
28        }
29    }
30}
31
32#[cfg(test)]
33mod tests {
34    use crate::{
35        buffer::Buffer,
36        layout::Rect,
37        style::Color,
38        symbols::Marker,
39        widgets::{
40            canvas::{Canvas, Circle},
41            Widget,
42        },
43    };
44
45    #[test]
46    fn test_it_draws_a_circle() {
47        let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 5));
48        let canvas = Canvas::default()
49            .paint(|ctx| {
50                ctx.draw(&Circle {
51                    x: 5.0,
52                    y: 2.0,
53                    radius: 5.0,
54                    color: Color::Reset,
55                });
56            })
57            .marker(Marker::Braille)
58            .x_bounds([-10.0, 10.0])
59            .y_bounds([-10.0, 10.0]);
60        canvas.render(buffer.area, &mut buffer);
61        let expected = Buffer::with_lines([
62            "     ⢀⣠⢤⣀ ",
63            "    ⢰⠋  ⠈⣇",
64            "    ⠘⣆⡀ ⣠⠇",
65            "      ⠉⠉⠁ ",
66            "          ",
67        ]);
68        assert_eq!(buffer, expected);
69    }
70}