mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-07-07 15:55:00 +00:00
Fix 'Morph' node lerping the target paths to its end point instead of start point (#2754)
* fix lerping the target paths to the point at the end of path instead of the start. * comment * append a MoveTo element first if the bezpath is empty --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
parent
02afd08c80
commit
86da69e33f
1 changed files with 19 additions and 10 deletions
|
@ -15,7 +15,7 @@ use crate::vector::{FillId, PointDomain, RegionId};
|
||||||
use crate::{CloneVarArgs, Color, Context, Ctx, ExtractAll, GraphicElement, GraphicGroupTable, OwnedContextImpl};
|
use crate::{CloneVarArgs, Color, Context, Ctx, ExtractAll, GraphicElement, GraphicGroupTable, OwnedContextImpl};
|
||||||
use bezier_rs::{Join, ManipulatorGroup, Subpath};
|
use bezier_rs::{Join, ManipulatorGroup, Subpath};
|
||||||
use glam::{DAffine2, DVec2};
|
use glam::{DAffine2, DVec2};
|
||||||
use kurbo::{Affine, BezPath, DEFAULT_ACCURACY, ParamCurve, PathEl, PathSeg, Point, Shape};
|
use kurbo::{Affine, BezPath, DEFAULT_ACCURACY, ParamCurve, PathEl, PathSeg, Shape};
|
||||||
use rand::{Rng, SeedableRng};
|
use rand::{Rng, SeedableRng};
|
||||||
use std::collections::hash_map::DefaultHasher;
|
use std::collections::hash_map::DefaultHasher;
|
||||||
use std::f64::consts::PI;
|
use std::f64::consts::PI;
|
||||||
|
@ -1591,6 +1591,9 @@ async fn morph(_: impl Ctx, source: VectorDataTable, #[expose] target: VectorDat
|
||||||
}
|
}
|
||||||
|
|
||||||
for segment in new_segments {
|
for segment in new_segments {
|
||||||
|
if bezpath.elements().is_empty() {
|
||||||
|
bezpath.move_to(segment.start())
|
||||||
|
}
|
||||||
bezpath.push(segment.as_path_el());
|
bezpath.push(segment.as_path_el());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1666,7 +1669,10 @@ async fn morph(_: impl Ctx, source: VectorDataTable, #[expose] target: VectorDat
|
||||||
for mut source_path in source_paths {
|
for mut source_path in source_paths {
|
||||||
source_path.apply_affine(Affine::new(source_transform.to_cols_array()));
|
source_path.apply_affine(Affine::new(source_transform.to_cols_array()));
|
||||||
|
|
||||||
let end: Point = source_path.elements().last().and_then(|element| element.end_point()).unwrap_or_default();
|
// Skip if the path has no segments else get the point at the end of the path.
|
||||||
|
let Some(end) = source_path.segments().last().and_then(|element| Some(element.end())) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
for element in source_path.elements_mut() {
|
for element in source_path.elements_mut() {
|
||||||
match element {
|
match element {
|
||||||
|
@ -1690,20 +1696,23 @@ async fn morph(_: impl Ctx, source: VectorDataTable, #[expose] target: VectorDat
|
||||||
for mut target_path in target_paths {
|
for mut target_path in target_paths {
|
||||||
target_path.apply_affine(Affine::new(source_transform.to_cols_array()));
|
target_path.apply_affine(Affine::new(source_transform.to_cols_array()));
|
||||||
|
|
||||||
let end: Point = target_path.elements().last().and_then(|element| element.end_point()).unwrap_or_default();
|
// Skip if the path has no segments else get the point at the start of the path.
|
||||||
|
let Some(start) = target_path.segments().next().and_then(|element| Some(element.start())) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
for element in target_path.elements_mut() {
|
for element in target_path.elements_mut() {
|
||||||
match element {
|
match element {
|
||||||
PathEl::MoveTo(point) => *point = point.lerp(end, time),
|
PathEl::MoveTo(point) => *point = start.lerp(*point, time),
|
||||||
PathEl::LineTo(point) => *point = point.lerp(end, time),
|
PathEl::LineTo(point) => *point = start.lerp(*point, time),
|
||||||
PathEl::QuadTo(point, point1) => {
|
PathEl::QuadTo(point, point1) => {
|
||||||
*point = point.lerp(end, time);
|
*point = start.lerp(*point, time);
|
||||||
*point1 = point1.lerp(end, time);
|
*point1 = start.lerp(*point1, time);
|
||||||
}
|
}
|
||||||
PathEl::CurveTo(point, point1, point2) => {
|
PathEl::CurveTo(point, point1, point2) => {
|
||||||
*point = point.lerp(end, time);
|
*point = start.lerp(*point, time);
|
||||||
*point1 = point1.lerp(end, time);
|
*point1 = start.lerp(*point1, time);
|
||||||
*point2 = point2.lerp(end, time);
|
*point2 = start.lerp(*point2, time);
|
||||||
}
|
}
|
||||||
PathEl::ClosePath => {}
|
PathEl::ClosePath => {}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue