diff --git a/editor/src/messages/tool/tool_messages/path_tool.rs b/editor/src/messages/tool/tool_messages/path_tool.rs index ab10565fda0..c1bc03510a0 100644 --- a/editor/src/messages/tool/tool_messages/path_tool.rs +++ b/editor/src/messages/tool/tool_messages/path_tool.rs @@ -620,6 +620,7 @@ struct PathToolData { temporary_colinear_handles: bool, molding_info: Option<(DVec2, DVec2)>, molding_segment: bool, + molding_snap_origin: Option, temporary_adjacent_handles_while_molding: Option<[Option; 2]>, frontier_handles_info: Option>>>, adjacent_anchor_offset: Option, @@ -2001,7 +2002,7 @@ impl Fsm for PathToolFsmState { // Draw the snapping axis lines through where the point under the pointer began if let Some(axis) = tool_data.snapping_axis { let slide_start = tool_data.slide.as_ref().map(|slide| document.metadata().document_to_viewport.transform_point2(slide.start)); - let origin = slide_start.unwrap_or(tool_data.drag_start_pos); + let origin = tool_data.molding_snap_origin.or(slide_start).unwrap_or(tool_data.drag_start_pos); let viewport_diagonal = viewport.size().into_dvec2().length(); match axis { @@ -2138,16 +2139,38 @@ impl Fsm for PathToolFsmState { } let break_molding = input.keyboard.get(break_colinear_molding as usize); + let snap_angle_state = input.keyboard.get(snap_angle as usize); // Logic for molding segment if let Some(segment) = &mut tool_data.segment && let Some(molding_segment_handles) = tool_data.molding_info { + let mouse_position = if snap_angle_state { + let transform = document.metadata().transform_to_viewport_if_feeds(segment.layer(), &document.network_interface); + let parametric_bezier_mid = point_to_dvec2(segment.pathseg().eval(0.5)); + let mid = transform.transform_point2(parametric_bezier_mid); + + tool_data.molding_snap_origin = Some(mid); + let drag_start = tool_data.drag_start_pos; + + let delta = input.mouse.position - drag_start; + tool_data.snapping_axis = Some(if delta.x.abs() >= delta.y.abs() { Axis::X } else { Axis::Y }); + match tool_data.snapping_axis { + Some(Axis::X) => DVec2::new(input.mouse.position.x, drag_start.y), + Some(Axis::Y) => DVec2::new(drag_start.x, input.mouse.position.y), + _ => input.mouse.position, + } + } else { + tool_data.snapping_axis = None; + tool_data.molding_snap_origin = None; + input.mouse.position + }; + tool_data.temporary_adjacent_handles_while_molding = segment.mold_handle_positions( document, responses, molding_segment_handles, - input.mouse.position, + mouse_position, break_molding, tool_data.temporary_adjacent_handles_while_molding, ); @@ -2188,7 +2211,6 @@ impl Fsm for PathToolFsmState { let toggle_colinear_state = input.keyboard.get(toggle_colinear as usize); let equidistant_state = input.keyboard.get(equidistant as usize); let lock_angle_state = input.keyboard.get(lock_angle as usize); - let snap_angle_state = input.keyboard.get(snap_angle as usize); if !lock_angle_state { tool_data.angle_locked = false; @@ -2406,6 +2428,8 @@ impl Fsm for PathToolFsmState { } tool_data.molding_info = None; tool_data.molding_segment = false; + tool_data.molding_snap_origin = None; + tool_data.snapping_axis = None; tool_data.temporary_adjacent_handles_while_molding = None; tool_data.angle_locked = false; responses.add(DocumentMessage::AbortTransaction); @@ -2660,6 +2684,7 @@ impl Fsm for PathToolFsmState { } tool_data.sliding_point_info = None; + tool_data.snapping_axis = None; if drag_occurred || extend_selection { responses.add(DocumentMessage::EndTransaction);