diff --git a/examples/clock/src/main.rs b/examples/clock/src/main.rs index 25a213cd..0a70709f 100644 --- a/examples/clock/src/main.rs +++ b/examples/clock/src/main.rs @@ -94,14 +94,7 @@ impl canvas::layer::Drawable for LocalTime { let radius = frame.width().min(frame.height()) / 2.0; let offset = Vector::new(center.x, center.y); - let clock = canvas::Path::new(|path| { - path.arc(canvas::path::Arc { - center, - radius, - start_angle: 0.0, - end_angle: 2.0 * std::f32::consts::PI, - }) - }); + let clock = canvas::Path::new(|path| path.circle(center, radius)); frame.fill( &clock, diff --git a/wgpu/src/widget/canvas/path.rs b/wgpu/src/widget/canvas/path.rs index c8ba10e1..8847ea29 100644 --- a/wgpu/src/widget/canvas/path.rs +++ b/wgpu/src/widget/canvas/path.rs @@ -1,4 +1,6 @@ -use iced_native::{Point, Vector}; +use iced_native::{Point, Size, Vector}; + +use lyon::path::builder::{Build, FlatPathBuilder, PathBuilder, SvgBuilder}; #[derive(Debug, Clone)] pub struct Path { @@ -23,13 +25,13 @@ impl Path { #[allow(missing_debug_implementations)] pub struct Builder { - raw: lyon::path::Builder, + raw: lyon::path::builder::SvgPathBuilder, } impl Builder { pub fn new() -> Builder { Builder { - raw: lyon::path::Path::builder(), + raw: lyon::path::Path::builder().with_svg(), } } @@ -48,14 +50,32 @@ impl Builder { self.ellipse(arc.into()); } - #[inline] + pub fn arc_to(&mut self, a: Point, b: Point, radius: f32) { + use lyon::{math, path}; + + let a = math::Point::new(a.x, a.y); + + if self.raw.current_position() != a { + let _ = self.raw.line_to(a); + } + + let _ = self.raw.arc_to( + math::Vector::new(radius, radius), + math::Angle::radians(0.0), + path::ArcFlags::default(), + math::Point::new(b.x, b.y), + ); + } + pub fn ellipse(&mut self, ellipse: Ellipse) { - let arc = lyon::geom::Arc { - center: lyon::math::Point::new(ellipse.center.x, ellipse.center.y), - radii: lyon::math::Vector::new(ellipse.radii.x, ellipse.radii.y), - x_rotation: lyon::math::Angle::radians(ellipse.rotation), - start_angle: lyon::math::Angle::radians(ellipse.start_angle), - sweep_angle: lyon::math::Angle::radians(ellipse.end_angle), + use lyon::{geom, math}; + + let arc = geom::Arc { + center: math::Point::new(ellipse.center.x, ellipse.center.y), + radii: math::Vector::new(ellipse.radii.x, ellipse.radii.y), + x_rotation: math::Angle::radians(ellipse.rotation), + start_angle: math::Angle::radians(ellipse.start_angle), + sweep_angle: math::Angle::radians(ellipse.end_angle), }; let _ = self.raw.move_to(arc.sample(0.0)); @@ -65,6 +85,51 @@ impl Builder { }); } + #[inline] + pub fn bezier_curve_to( + &mut self, + control_a: Point, + control_b: Point, + to: Point, + ) { + use lyon::math; + + let _ = self.raw.cubic_bezier_to( + math::Point::new(control_a.x, control_a.y), + math::Point::new(control_b.x, control_b.y), + math::Point::new(to.x, to.y), + ); + } + + #[inline] + pub fn quadratic_curve_to(&mut self, control: Point, to: Point) { + use lyon::math; + + let _ = self.raw.quadratic_bezier_to( + math::Point::new(control.x, control.y), + math::Point::new(to.x, to.y), + ); + } + + #[inline] + pub fn rectangle(&mut self, p: Point, size: Size) { + self.move_to(p); + self.line_to(Point::new(p.x + size.width, p.y)); + self.line_to(Point::new(p.x + size.width, p.y + size.height)); + self.line_to(Point::new(p.x, p.y + size.height)); + self.close(); + } + + #[inline] + pub fn circle(&mut self, center: Point, radius: f32) { + self.arc(Arc { + center, + radius, + start_angle: 0.0, + end_angle: 2.0 * std::f32::consts::PI, + }); + } + #[inline] pub fn close(&mut self) { self.raw.close()