Crates.io | svg-path-parser |
lib.rs | svg-path-parser |
version | 0.1.1 |
source | src |
created_at | 2023-03-07 17:35:46.784823 |
updated_at | 2023-04-05 22:26:16.932095 |
description | Generate a list of points from SVG path strings |
homepage | |
repository | https://github.com/UnicodingUnicorn/svg-path-parser |
max_upload_size | |
id | 803791 |
size | 20,013 |
A really un-opinionated library for reading SVG paths. So un-opinionated, in fact, that you're just returned lists of points and whether the path is closed or not. If the path is closed, just assume there's a line between the last point and the first point.
First of all, extract the path string from the d
tag. I dunno, use regex or something, it's a free world. Next, feed it into the parser:
let paths = svg_path_parser::parse(&path).collect::<Vec<(bool, Vec<(f64, f64)>)>>();
The bool
indicates whether the path is closed and the Vec
is a vector of all the points. Treat it as a continuous connect the dots thing.
By default, curves are rendered as 64 different line segments spaced at equal angles from each other. In order to change this, use:
let resolution = 32;
let paths = svg_path_parser::parse_with_resolution(&path, resolution).collect::<Vec<(bool, Vec<(f64, f64)>)>>();
I get that a list of points is not very helpful.
struct Line {
start: (f64, f64),
end: (f64, f64),
}
impl Line {
pub fn new(start:(f64, f64), end:(f64, f64)) -> Self {
Self { start, end, }
}
}
fn to_lines((close, path):(bool, Vec<(f64, f64)>)) -> Vec<Line> {
let mut lines = path.iter()
.zip(path.iter().skip(1))
.map(|(start, end)| Line::new(*start, *end))
.collect::<Vec<Line>>();
if close && lines.len() > 0 {
let &end = lines[lines.len() - 1];
let &start = lines[0]
if start.start != end.end {
lines.push(Line::new(end.end, start.start));
}
}
lines
}