Skip to content

Commit 9387f23

Browse files
committed
Reduce along-path snap influence near colinear anchor point
1 parent 471a5c6 commit 9387f23

2 files changed

Lines changed: 32 additions & 2 deletions

File tree

editor/src/consts.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ pub const SEGMENT_INSERTION_DISTANCE: f64 = 5.;
117117
pub const SEGMENT_OVERLAY_SIZE: f64 = 10.;
118118
pub const SEGMENT_SELECTED_THICKNESS: f64 = 3.;
119119
pub const HANDLE_LENGTH_FACTOR: f64 = 0.5;
120+
pub const SNAP_DAMPENING_START_MULTIPLIER: f64 = 0.3;
120121

121122
// GRADIENT TOOL
122123
pub const GRADIENT_MIDPOINT_DIAMOND_RADIUS: f64 = 4.;

editor/src/messages/tool/tool_messages/path_tool.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use super::tool_prelude::*;
33
use crate::consts::{
44
COLOR_OVERLAY_BLUE, COLOR_OVERLAY_BLUE_05, COLOR_OVERLAY_GRAY, COLOR_OVERLAY_GREEN, COLOR_OVERLAY_GREEN_25, COLOR_OVERLAY_RED, COLOR_OVERLAY_RED_25, DEFAULT_STROKE_WIDTH,
55
DOUBLE_CLICK_MILLISECONDS, DRAG_DIRECTION_MODE_DETERMINATION_THRESHOLD, DRAG_THRESHOLD, DRILL_THROUGH_THRESHOLD, HANDLE_ROTATE_SNAP_ANGLE, SEGMENT_INSERTION_DISTANCE, SEGMENT_OVERLAY_SIZE,
6-
SELECTION_THRESHOLD, SELECTION_TOLERANCE,
6+
SELECTION_THRESHOLD, SELECTION_TOLERANCE, SNAP_DAMPENING_START_MULTIPLIER,
77
};
88
use crate::messages::clipboard::utility_types::ClipboardContent;
99
use crate::messages::input_mapper::utility_types::macros::action_shortcut_manual;
@@ -13,6 +13,7 @@ use crate::messages::portfolio::document::overlays::utility_functions::{path_ove
1313
use crate::messages::portfolio::document::overlays::utility_types::{DrawHandles, OverlayContext};
1414
use crate::messages::portfolio::document::utility_types::clipboards::Clipboard;
1515
use crate::messages::portfolio::document::utility_types::document_metadata::{DocumentMetadata, LayerNodeIdentifier};
16+
use crate::messages::portfolio::document::utility_types::misc::{PathSnapTarget, SnapTarget};
1617
use crate::messages::portfolio::document::utility_types::network_interface::NodeNetworkInterface;
1718
use crate::messages::portfolio::document::utility_types::transformation::Axis;
1819
use crate::messages::preferences::SelectionMode;
@@ -22,7 +23,7 @@ use crate::messages::tool::common_functionality::pivot::{PivotGizmo, PivotGizmoT
2223
use crate::messages::tool::common_functionality::shape_editor::{
2324
ClosestSegment, ManipulatorAngle, OpposingHandleLengths, SelectedLayerState, SelectedPointsInfo, SelectionChange, SelectionShape, SelectionShapeType, ShapeState,
2425
};
25-
use crate::messages::tool::common_functionality::snapping::{SnapCache, SnapCandidatePoint, SnapConstraint, SnapData, SnapManager};
26+
use crate::messages::tool::common_functionality::snapping::{SnapCache, SnapCandidatePoint, SnapConstraint, SnapData, SnapManager, SnappedPoint};
2627
use crate::messages::tool::common_functionality::utility_functions::{calculate_segment_angle, find_two_param_best_approximate, make_path_editable_is_allowed};
2728
use graphene_std::Color;
2829
use graphene_std::renderer::Quad;
@@ -1152,9 +1153,37 @@ impl PathToolData {
11521153

11531154
self.snap_manager.update_indicator(snap_result.clone());
11541155

1156+
let snap_result = self.reduce_snap_weight(snap_result, new_handle_position, anchor_position);
1157+
11551158
document.metadata().document_to_viewport.transform_vector2(snap_result.snapped_point_document - handle_position)
11561159
}
11571160

1161+
fn reduce_snap_weight(&mut self, mut snap_result: SnappedPoint, new_handle_position: DVec2, anchor_position: DVec2) -> SnappedPoint {
1162+
if !matches!(snap_result.target, SnapTarget::Path(PathSnapTarget::AlongPath)) {
1163+
return snap_result;
1164+
}
1165+
1166+
let selection_status = &self.selection_status;
1167+
if selection_status.angle() != Some(ManipulatorAngle::Colinear) {
1168+
return snap_result;
1169+
}
1170+
1171+
let anchor_distance = snap_result.snapped_point_document.distance(anchor_position);
1172+
let dampening_start = snap_result.tolerance * SNAP_DAMPENING_START_MULTIPLIER;
1173+
if anchor_distance >= dampening_start {
1174+
return snap_result;
1175+
}
1176+
1177+
// 1 -> full snap; 0 -> no snap
1178+
let t: f64 = (anchor_distance / dampening_start).clamp(0.0, 1.0);
1179+
// smoothstep function: 3 * t ^ 2 - 2 * t ^ 3
1180+
let weight = t * t * (3.0 - 2.0 * t);
1181+
//linear interpolation
1182+
snap_result.snapped_point_document = new_handle_position.lerp(snap_result.snapped_point_document, weight);
1183+
1184+
snap_result
1185+
}
1186+
11581187
fn start_snap_along_axis(&mut self, shape_editor: &mut ShapeState, document: &DocumentMessageHandler, input: &InputPreprocessorMessageHandler, responses: &mut VecDeque<Message>) {
11591188
// Find the negative delta to take the point to the drag start position
11601189
let current_mouse = input.mouse.position;

0 commit comments

Comments
 (0)