@@ -368,6 +368,52 @@ pub fn snap_drag(start: DVec2, current: DVec2, snap_to_axis: bool, axis: Axis, s
368368 document. metadata ( ) . document_to_viewport . transform_vector2 ( offset)
369369}
370370
371+ /// Snaps a dragging event using document-space drag state so PTZ changes do not invalidate the drag anchor.
372+ pub fn snap_drag_from_document ( start : DVec2 , current : DVec2 , snap_to_axis : bool , axis : Axis , snap_data : SnapData , snap_manager : & mut SnapManager , candidates : & [ SnapCandidatePoint ] ) -> DVec2 {
373+ let document = snap_data. document ;
374+ let document_to_viewport = document. metadata ( ) . document_to_viewport ;
375+ let start_viewport = document_to_viewport. transform_point2 ( start) ;
376+ let mouse_position = axis_align_drag ( snap_to_axis, axis, snap_data. input . mouse . position , start_viewport) ;
377+ let aligned_document = document_to_viewport. inverse ( ) . transform_point2 ( mouse_position) ;
378+ let total_mouse_delta_document = aligned_document - start;
379+ let mut offset = aligned_document - current;
380+ let mut best_snap = SnappedPoint :: infinite_snap ( aligned_document) ;
381+
382+ let bbox = Rect :: point_iter ( candidates. iter ( ) . map ( |candidate| candidate. document_point + total_mouse_delta_document) ) ;
383+
384+ for ( index, point) in candidates. iter ( ) . enumerate ( ) {
385+ let config = SnapTypeConfiguration {
386+ bbox,
387+ accept_distribution : true ,
388+ use_existing_candidates : index != 0 ,
389+ ..Default :: default ( )
390+ } ;
391+
392+ let mut point = point. clone ( ) ;
393+ point. document_point += total_mouse_delta_document;
394+
395+ let constrained_along_axis = snap_to_axis || axis. is_constraint ( ) ;
396+ let snapped = if constrained_along_axis {
397+ let constraint = SnapConstraint :: Line {
398+ origin : point. document_point ,
399+ direction : total_mouse_delta_document. try_normalize ( ) . unwrap_or ( DVec2 :: X ) ,
400+ } ;
401+ snap_manager. constrained_snap ( & snap_data, & point, constraint, config)
402+ } else {
403+ snap_manager. free_snap ( & snap_data, & point, config)
404+ } ;
405+
406+ if best_snap. other_snap_better ( & snapped) {
407+ offset = snapped. snapped_point_document - point. document_point + ( aligned_document - current) ;
408+ best_snap = snapped;
409+ }
410+ }
411+
412+ snap_manager. update_indicator ( best_snap) ;
413+
414+ offset
415+ }
416+
371417/// Contains info on the overlays for the bounding box and transform handles
372418#[ derive( Clone , Debug , Default ) ]
373419pub struct BoundingBoxManager {
@@ -379,10 +425,12 @@ pub struct BoundingBoxManager {
379425 pub transform_tampered : bool ,
380426 /// The transform to viewport space for the bounds co-ordinates when the transformation was started.
381427 pub original_bound_transform : DAffine2 ,
428+ pub original_bounds_to_document : DAffine2 ,
382429 pub selected_edges : Option < SelectedEdges > ,
383430 pub original_transforms : OriginalTransforms ,
384431 pub opposite_pivot : DVec2 ,
385432 pub center_of_transformation : DVec2 ,
433+ pub center_of_transformation_doc : DVec2 ,
386434}
387435
388436impl BoundingBoxManager {
0 commit comments