gpui: Add more shapes for PathBuilder
(#30904)
- Add `arc` for drawing elliptical arc. - Add `polygon` support. <img width="1136" alt="image" src="https://github.com/user-attachments/assets/97032b02-e6ff-4985-a587-3689500bfd56" /> Release Notes: - N/A
This commit is contained in:
parent
e42cf21703
commit
c73af0a52f
2 changed files with 110 additions and 5 deletions
|
@ -27,10 +27,15 @@ impl PaintingViewer {
|
||||||
|
|
||||||
// draw a lightening bolt ⚡
|
// draw a lightening bolt ⚡
|
||||||
let mut builder = PathBuilder::fill();
|
let mut builder = PathBuilder::fill();
|
||||||
builder.move_to(point(px(150.), px(200.)));
|
builder.add_polygon(
|
||||||
builder.line_to(point(px(200.), px(125.)));
|
&[
|
||||||
builder.line_to(point(px(200.), px(175.)));
|
point(px(150.), px(200.)),
|
||||||
builder.line_to(point(px(250.), px(100.)));
|
point(px(200.), px(125.)),
|
||||||
|
point(px(200.), px(175.)),
|
||||||
|
point(px(250.), px(100.)),
|
||||||
|
],
|
||||||
|
false,
|
||||||
|
);
|
||||||
let path = builder.build().unwrap();
|
let path = builder.build().unwrap();
|
||||||
lines.push((path, rgb(0x1d4ed8).into()));
|
lines.push((path, rgb(0x1d4ed8).into()));
|
||||||
|
|
||||||
|
@ -58,6 +63,7 @@ impl PaintingViewer {
|
||||||
.color_space(ColorSpace::Oklab),
|
.color_space(ColorSpace::Oklab),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
// draw linear gradient
|
||||||
let square_bounds = Bounds {
|
let square_bounds = Bounds {
|
||||||
origin: point(px(450.), px(100.)),
|
origin: point(px(450.), px(100.)),
|
||||||
size: size(px(200.), px(80.)),
|
size: size(px(200.), px(80.)),
|
||||||
|
@ -87,6 +93,47 @@ impl PaintingViewer {
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
// draw a pie chart
|
||||||
|
let center = point(px(96.), px(96.));
|
||||||
|
let pie_center = point(px(775.), px(155.));
|
||||||
|
let segments = [
|
||||||
|
(
|
||||||
|
point(px(871.), px(155.)),
|
||||||
|
point(px(747.), px(63.)),
|
||||||
|
rgb(0x1374e9),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
point(px(747.), px(63.)),
|
||||||
|
point(px(679.), px(163.)),
|
||||||
|
rgb(0xe13527),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
point(px(679.), px(163.)),
|
||||||
|
point(px(754.), px(249.)),
|
||||||
|
rgb(0x0751ce),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
point(px(754.), px(249.)),
|
||||||
|
point(px(854.), px(210.)),
|
||||||
|
rgb(0x209742),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
point(px(854.), px(210.)),
|
||||||
|
point(px(871.), px(155.)),
|
||||||
|
rgb(0xfbc10a),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (start, end, color) in segments {
|
||||||
|
let mut builder = PathBuilder::fill();
|
||||||
|
builder.move_to(start);
|
||||||
|
builder.arc_to(center, px(0.), false, false, end);
|
||||||
|
builder.line_to(pie_center);
|
||||||
|
builder.close();
|
||||||
|
let path = builder.build().unwrap();
|
||||||
|
lines.push((path, color.into()));
|
||||||
|
}
|
||||||
|
|
||||||
// draw a wave
|
// draw a wave
|
||||||
let options = StrokeOptions::default()
|
let options = StrokeOptions::default()
|
||||||
.with_line_width(1.)
|
.with_line_width(1.)
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use etagere::euclid::Vector2D;
|
use etagere::euclid::{Point2D, Vector2D};
|
||||||
use lyon::geom::Angle;
|
use lyon::geom::Angle;
|
||||||
|
use lyon::math::{Vector, vector};
|
||||||
|
use lyon::path::traits::SvgPathBuilder;
|
||||||
|
use lyon::path::{ArcFlags, Polygon};
|
||||||
use lyon::tessellation::{
|
use lyon::tessellation::{
|
||||||
BuffersBuilder, FillTessellator, FillVertex, StrokeTessellator, StrokeVertex, VertexBuffers,
|
BuffersBuilder, FillTessellator, FillVertex, StrokeTessellator, StrokeVertex, VertexBuffers,
|
||||||
};
|
};
|
||||||
|
@ -56,6 +59,18 @@ impl From<Point<Pixels>> for lyon::math::Point {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Point<Pixels>> for Vector {
|
||||||
|
fn from(p: Point<Pixels>) -> Self {
|
||||||
|
vector(p.x.0, p.y.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Point<Pixels>> for Point2D<f32, Pixels> {
|
||||||
|
fn from(p: Point<Pixels>) -> Self {
|
||||||
|
Point2D::new(p.x.0, p.y.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for PathBuilder {
|
impl Default for PathBuilder {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -116,6 +131,49 @@ impl PathBuilder {
|
||||||
.cubic_bezier_to(control_a.into(), control_b.into(), to.into());
|
.cubic_bezier_to(control_a.into(), control_b.into(), to.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds an elliptical arc.
|
||||||
|
pub fn arc_to(
|
||||||
|
&mut self,
|
||||||
|
radii: Point<Pixels>,
|
||||||
|
x_rotation: Pixels,
|
||||||
|
large_arc: bool,
|
||||||
|
sweep: bool,
|
||||||
|
to: Point<Pixels>,
|
||||||
|
) {
|
||||||
|
self.raw.arc_to(
|
||||||
|
radii.into(),
|
||||||
|
Angle::degrees(x_rotation.into()),
|
||||||
|
ArcFlags { large_arc, sweep },
|
||||||
|
to.into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Equivalent to `arc_to` in relative coordinates.
|
||||||
|
pub fn relative_arc_to(
|
||||||
|
&mut self,
|
||||||
|
radii: Point<Pixels>,
|
||||||
|
x_rotation: Pixels,
|
||||||
|
large_arc: bool,
|
||||||
|
sweep: bool,
|
||||||
|
to: Point<Pixels>,
|
||||||
|
) {
|
||||||
|
self.raw.relative_arc_to(
|
||||||
|
radii.into(),
|
||||||
|
Angle::degrees(x_rotation.into()),
|
||||||
|
ArcFlags { large_arc, sweep },
|
||||||
|
to.into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds a polygon.
|
||||||
|
pub fn add_polygon(&mut self, points: &[Point<Pixels>], closed: bool) {
|
||||||
|
let points = points.iter().copied().map(|p| p.into()).collect::<Vec<_>>();
|
||||||
|
self.raw.add_polygon(Polygon {
|
||||||
|
points: points.as_ref(),
|
||||||
|
closed,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// Close the current sub-path.
|
/// Close the current sub-path.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn close(&mut self) {
|
pub fn close(&mut self) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue