Bezier-rs: Add function to smoothly join bezier curves (#1037)

* Added bezier join

* Stylistic changes per review
This commit is contained in:
Rob Nadal 2023-02-28 18:59:06 -05:00 committed by Keavon Chambers
parent 8d3daeae78
commit 8bc290fde9
3 changed files with 108 additions and 5 deletions

View file

@ -483,6 +483,56 @@ const bezierFeatures = {
},
chooseTVariant: true,
},
join: {
name: "Join",
callback: (bezier: WasmBezierInstance): string => {
const points = JSON.parse(bezier.get_points());
let examplePoints = [];
if (points.length === 2) {
examplePoints = [
[120, 155],
[40, 155],
];
} else if (points.length === 3) {
examplePoints = [
[40, 150],
[95, 195],
[155, 145],
];
} else {
examplePoints = [
[140, 150],
[85, 110],
[65, 180],
[30, 140],
];
}
return bezier.join(examplePoints);
},
demoOptions: {
Linear: {
customPoints: [
[45, 40],
[130, 90],
],
},
Quadratic: {
customPoints: [
[153, 40],
[40, 20],
[75, 85],
],
},
Cubic: {
customPoints: [
[20, 80],
[40, 20],
[90, 100],
[130, 55],
],
},
},
},
};
export type BezierFeatureKey = keyof typeof bezierFeatures;

View file

@ -621,4 +621,44 @@ impl WasmBezier {
.fold(original_curve_svg, |acc, item| format!("{acc}{item}"));
wrap_svg_tag(arcs_svg)
}
pub fn join(&self, js_points: &JsValue) -> String {
let other_bezier: Bezier = match self.0.get_points().count() {
2 => {
let points: [DVec2; 2] = serde_wasm_bindgen::from_value(js_points.into()).unwrap();
Bezier::from_linear_dvec2(points[0], points[1])
}
3 => {
let points: [DVec2; 3] = serde_wasm_bindgen::from_value(js_points.into()).unwrap();
Bezier::from_quadratic_dvec2(points[0], points[1], points[2])
}
4 => {
let points: [DVec2; 4] = serde_wasm_bindgen::from_value(js_points.into()).unwrap();
Bezier::from_cubic_dvec2(points[0], points[1], points[2], points[3])
}
_ => unreachable!(),
};
let mut other_bezier_svg = String::new();
other_bezier.to_svg(
&mut other_bezier_svg,
CURVE_ATTRIBUTES.to_string().replace(BLACK, GRAY),
ANCHOR_ATTRIBUTES.to_string().replace(BLACK, GRAY),
String::new(),
String::new(),
);
let joining_bezier: Bezier = self.0.join(&other_bezier);
let mut joining_bezier_svg = String::new();
joining_bezier.to_svg(
&mut joining_bezier_svg,
CURVE_ATTRIBUTES.to_string().replace(BLACK, RED),
ANCHOR_ATTRIBUTES.to_string().replace(BLACK, RED),
String::new(),
String::new(),
);
let bezier_svg = self.get_bezier_path();
wrap_svg_tag(format!("{bezier_svg}{joining_bezier_svg}{other_bezier_svg}"))
}
}