turtle_svg/
turtle.rs

1use crate::{
2    draw::{
3        pen::{
4            Pen,
5            PenPos
6        },
7        drawing::Drawing
8    },
9    color::Color,
10    angle::Angle,
11    position::Distance
12};
13
14/// Composing SVG with turtle graphics operations with a cursor
15pub struct TurtleSvg {
16    drawing: Drawing,
17    pen: Pen,
18}
19
20impl Default for TurtleSvg {
21    fn default() -> Self {
22        Self {
23            drawing: Drawing::default(),
24            pen: Pen::default(),
25        }
26    }
27}
28
29impl TurtleSvg {
30    pub fn new() -> Self {
31        Self::default()
32    }
33
34    /// Reutnr a mutable referece of Drawing
35    pub fn drawing_mut(&mut self) -> &mut Drawing {
36        &mut self.drawing
37    }
38
39    /// Return a mutable reference of Pen
40    pub fn pen_mut(&mut self) -> &mut Pen {
41        &mut self.pen
42    }
43
44    /// Move forward by `distance`
45    pub fn forward(&mut self, distance: Distance) {
46        if self.pen.is_down() == false {
47            return
48        }
49
50        let mut pen = self.pen;
51
52        self.drawing.forward(&mut pen, distance);
53
54        self.pen = pen;
55    }
56
57    /// Move backward by `distance`
58    pub fn backward(&mut self, distance: Distance) {
59        if self.pen.is_down() == false {
60            return
61        }
62
63        let mut pen = self.pen;
64
65        self.drawing.backward(&mut pen, distance);
66
67        self.pen = pen;
68    }
69
70    /// Turn on the left by `angle`
71    pub fn left<A: Into<Angle>>(&mut self, angle: A) {
72        let angle = self.pen.angle.degrees() - angle.into().degrees();
73
74        self.pen_mut().angle.set_degrees(angle);
75    }
76
77    /// Turn on the right by `angle`
78    pub fn right<A: Into<Angle>>(&mut self, angle: A) {
79        let angle = self.pen.angle.degrees() + angle.into().degrees();
80        
81        self.pen_mut().angle.set_degrees(angle);
82    }
83
84    /// Disable pen
85    pub fn pen_up(&mut self) {
86        self.pen_mut().up();
87    }
88
89    /// Enable pen
90    pub fn pen_down(&mut self) {
91        self.pen_mut().down();
92    }
93
94    /// Change pen line color
95    pub fn set_pen_color<C: Into<Color>>(&mut self, color: C) {
96        self.pen_mut().color = color.into();
97    }
98
99    /// Change the pen line size
100    pub fn set_pen_size(&mut self, thickness: f64) {
101        self.pen_mut().thickness = thickness;
102    }
103
104    /// Return a copy of the current angle
105    pub fn heading(&self) -> Angle {
106        self.pen.angle
107    }
108
109    /// Change the current angle
110    pub fn set_heading<A: Into<Angle>>(&mut self, angle: A) {
111        self.pen_mut().angle = angle.into();
112    }
113
114    /// Change the background color
115    pub fn set_background_color<C: Into<Color>>(&mut self, color: C) {
116        self.drawing_mut().set_background_color(color);
117    }
118
119    /// Replacing the struct
120    pub fn reset(&mut self) {
121        *self = Self::default()
122    }
123
124    /// Move the pen to `position`
125    pub fn go_to<P: Into<PenPos>>(&mut self, position: P) {
126        self.pen_mut().position = position.into();
127    }
128
129    /// Return the pen position on the drawing
130    pub fn position(&mut self) -> PenPos {
131        self.pen.position
132    }
133}