feat: 实现曲线功能

This commit is contained in:
2026-02-28 16:17:17 +08:00
parent a9243c498f
commit 25c906278c
2 changed files with 110 additions and 5 deletions

View File

@@ -207,16 +207,23 @@ struct PaintApp {
canvas: MSCanvas,
// 是否正在绘制
/// 是否正在绘制
is_drawing: bool,
/// pencil brush line curve rectangle
begin_point: Point,
/// curve
end_point: Point,
// 用于显示的图像句柄缓存
// 每次像素变化后需要重新生成
/// 贝塞尔曲线控制
is_controlling: bool,
control_points: Vec<Point>,
/// 用于显示的图像句柄缓存
/// 每次像素变化后需要重新生成
image_handle: image::Handle,
// 标记像素是否被修改,用于优化图像句柄的生成
/// 标记像素是否被修改,用于优化图像句柄的生成
dirty: bool,
config: Config,
@@ -239,6 +246,9 @@ impl PaintApp {
canvas,
is_drawing: false,
begin_point: Point::ORIGIN,
end_point: Point::ORIGIN,
is_controlling: false,
control_points: Vec::with_capacity(2),
image_handle: image::Handle::from_rgba(width as u32, height as u32, pixels),
dirty: false,
config,
@@ -392,6 +402,9 @@ impl PaintApp {
Tool::Line => {
self.update_with_line(message);
}
Tool::Curve => {
self.update_with_curve(message);
}
Tool::Rectangle => {
self.update_with_rectangle(message);
}
@@ -471,7 +484,7 @@ impl PaintApp {
_ => None,
});
let tick = time::every(milliseconds(50)).map(Message::Tick);
return Subscription::batch(vec![ev, tick]);
Subscription::batch(vec![ev, tick])
}
// endregion
@@ -629,6 +642,54 @@ impl PaintApp {
}
}
pub fn update_with_curve(&mut self, message: Message) {
match message {
Message::MousePressed(pos) => {
if self.is_controlling {
if self.control_points.len() == 0 {
self.canvas.restore_pixels();
self.canvas
.quadratic_bezier(self.begin_point, self.end_point, pos);
self.control_points.push(pos);
} else {
self.canvas.restore_pixels();
self.canvas.cubic_bezier(
self.begin_point,
self.end_point,
self.control_points[0],
pos,
);
self.control_points.push(pos);
}
self.dirty = true;
} else {
self.is_drawing = true;
self.canvas.save_pixels();
self.begin_point = pos;
}
}
Message::MouseReleased(pos) => {
if self.control_points.len() == 0 {
self.is_drawing = false;
self.end_point = pos;
self.is_controlling = true;
} else if self.control_points.len() == 2 {
self.control_points.clear();
self.is_controlling = false;
}
}
Message::MouseMoved(pos) => {
if self.is_drawing {
self.canvas.restore_pixels();
self.canvas
.draw_line_with_circle_brush(self.begin_point, pos);
self.dirty = true;
}
}
_ => {}
}
}
pub fn update_with_rectangle(&mut self, message: Message) {
match message {
Message::MousePressed(pos) => {