@@ -3,7 +3,7 @@ use super::tool_prelude::*;
33use 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} ;
88use crate :: messages:: clipboard:: utility_types:: ClipboardContent ;
99use crate :: messages:: input_mapper:: utility_types:: macros:: action_shortcut_manual;
@@ -13,6 +13,7 @@ use crate::messages::portfolio::document::overlays::utility_functions::{path_ove
1313use crate :: messages:: portfolio:: document:: overlays:: utility_types:: { DrawHandles , OverlayContext } ;
1414use crate :: messages:: portfolio:: document:: utility_types:: clipboards:: Clipboard ;
1515use crate :: messages:: portfolio:: document:: utility_types:: document_metadata:: { DocumentMetadata , LayerNodeIdentifier } ;
16+ use crate :: messages:: portfolio:: document:: utility_types:: misc:: { PathSnapTarget , SnapTarget } ;
1617use crate :: messages:: portfolio:: document:: utility_types:: network_interface:: NodeNetworkInterface ;
1718use crate :: messages:: portfolio:: document:: utility_types:: transformation:: Axis ;
1819use crate :: messages:: preferences:: SelectionMode ;
@@ -22,7 +23,7 @@ use crate::messages::tool::common_functionality::pivot::{PivotGizmo, PivotGizmoT
2223use 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 } ;
2627use crate :: messages:: tool:: common_functionality:: utility_functions:: { calculate_segment_angle, find_two_param_best_approximate, make_path_editable_is_allowed} ;
2728use graphene_std:: Color ;
2829use 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