turtle_svg/draw/
drawing.rs1use svg::{node::element::{Rectangle, Line}, Document};
2
3use crate::{
4 color::{Color, ColorSvg},
5 size::Size,
6 draw::pen::Pen,
7 position::{Distance, Pos}
8};
9
10struct DrawingLine {
11 color: Color,
12 thickness: f64,
13 x1: f64,
14 y1: f64,
15 x2: f64,
16 y2: f64
17}
18
19pub type DrawingPos = Pos<f64>;
21
22pub struct Drawing {
24 size: Size,
25 bg: Color,
26 lines: Vec<DrawingLine>,
27 center: DrawingPos
28}
29
30impl Default for Drawing {
31 fn default() -> Self {
32 Self {
33 size: (800., 600.).into(),
34 bg: Color::default(),
35 lines: Vec::new(),
36 center: (0., 0.).into()
37 }
38 }
39}
40
41impl Drawing {
42 pub fn new() -> Self {
43 Self::default()
44 }
45
46 fn go(
48 &mut self,
49 pen: &mut Pen,
50 distance: Distance,
51 f: &dyn Fn(&mut Pen, Distance)
52 ) {
53 let (x1, y1) = pen.position.into();
54
55 f(pen, distance);
56
57 let (x2, y2) = pen.position.into();
58 let line = DrawingLine {
59 color: pen.color,
60 thickness: pen.thickness,
61 x1,
62 y1,
63 x2,
64 y2,
65 };
66
67 self.lines.push(line);
69 }
70
71 pub fn forward(&mut self, pen: &mut Pen, distance: Distance) {
73 self.go(pen, distance, &Pen::forward)
74 }
75
76 pub fn backward(&mut self, pen: &mut Pen, distance: Distance) {
78 self.go(pen, distance, &Pen::backward)
79 }
80
81 pub fn set_background_color<C: Into<Color>>(&mut self, color: C) {
83 self.bg = color.into();
84 }
85
86 pub fn set_size<S: Into<Size>>(&mut self, size: S) {
88 self.size = size.into();
89 }
90
91 pub fn set_center<P: Into<DrawingPos>>(&mut self, positon: P) {
93 self.center = positon.into();
94 }
95
96 pub fn save_svg(&mut self, path: &str) {
98 let background_color: ColorSvg = self.bg.into();
100 let background = Rectangle::new()
101 .set("fill", background_color)
102 .set("height", "100%")
103 .set("width", "100%");
104
105 let viewbox = (0, 0, self.size.w, self.size.h);
107
108 let mut document = Document::new()
109 .set("viewBox", viewbox)
110 .add(background);
111
112 let dx = (self.size.w / 2.) - self.center.0;
114 let dy = (self.size.h / 2.) - self.center.1;
115
116 for line in &self.lines {
117 let color: ColorSvg = line.color.into();
118 let node = Line::new()
119 .set("stroke", color)
120 .set("stroke-width", line.thickness)
121 .set("x1", line.x1 + dx)
122 .set("y1", line.y1 + dy)
123 .set("x2", line.x2 + dx)
124 .set("y2", line.y2 + dy);
125
126 document = document.add(node);
127 }
128
129 svg::save(path, &document).unwrap();
131 }
132}