Browse Source

Scaling to center works

flabbet 8 months ago
parent
commit
63683f27ad

+ 47 - 17
src/PixiEditor/ViewModels/Document/TransformOverlays/DocumentTransformViewModel.cs

@@ -19,10 +19,11 @@ namespace PixiEditor.ViewModels.Document.TransformOverlays;
 internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
 internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
 {
 {
     private DocumentViewModel document;
     private DocumentViewModel document;
-    
+
     private TransformOverlayUndoStack<(ShapeCorners, TransformState)>? undoStack = null;
     private TransformOverlayUndoStack<(ShapeCorners, TransformState)>? undoStack = null;
 
 
     private TransformState internalState;
     private TransformState internalState;
+
     public TransformState InternalState
     public TransformState InternalState
     {
     {
         get => internalState;
         get => internalState;
@@ -30,6 +31,7 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
     }
     }
 
 
     private TransformCornerFreedom cornerFreedom;
     private TransformCornerFreedom cornerFreedom;
+
     public TransformCornerFreedom CornerFreedom
     public TransformCornerFreedom CornerFreedom
     {
     {
         get => cornerFreedom;
         get => cornerFreedom;
@@ -37,13 +39,23 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
     }
     }
 
 
     private TransformSideFreedom sideFreedom;
     private TransformSideFreedom sideFreedom;
+
     public TransformSideFreedom SideFreedom
     public TransformSideFreedom SideFreedom
     {
     {
         get => sideFreedom;
         get => sideFreedom;
         set => SetProperty(ref sideFreedom, value);
         set => SetProperty(ref sideFreedom, value);
     }
     }
 
 
+    private bool scaleFromCenter;
+
+    public bool ScaleFromCenter
+    {
+        get => scaleFromCenter;
+        set => SetProperty(ref scaleFromCenter, value);
+    }
+
     private bool lockRotation;
     private bool lockRotation;
+
     public bool LockRotation
     public bool LockRotation
     {
     {
         get => lockRotation;
         get => lockRotation;
@@ -51,6 +63,7 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
     }
     }
 
 
     private bool snapToAngles;
     private bool snapToAngles;
+
     public bool SnapToAngles
     public bool SnapToAngles
     {
     {
         get => snapToAngles;
         get => snapToAngles;
@@ -58,6 +71,7 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
     }
     }
 
 
     private bool transformActive;
     private bool transformActive;
+
     public bool TransformActive
     public bool TransformActive
     {
     {
         get => transformActive;
         get => transformActive;
@@ -70,7 +84,8 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
 
 
             if (value)
             if (value)
             {
             {
-                document.ActionDisplays[nameof(DocumentTransformViewModel)] = new LocalizedString($"TRANSFORM_ACTION_DISPLAY_{activeTransformMode.GetDescription()}");
+                document.ActionDisplays[nameof(DocumentTransformViewModel)] =
+                    new LocalizedString($"TRANSFORM_ACTION_DISPLAY_{activeTransformMode.GetDescription()}");
             }
             }
             else
             else
             {
             {
@@ -80,6 +95,7 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
     }
     }
 
 
     private bool showTransformControls;
     private bool showTransformControls;
+
     public bool ShowTransformControls
     public bool ShowTransformControls
     {
     {
         get => showTransformControls;
         get => showTransformControls;
@@ -89,6 +105,7 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
     public event Action<MouseOnCanvasEventArgs>? PassthroughPointerPressed;
     public event Action<MouseOnCanvasEventArgs>? PassthroughPointerPressed;
 
 
     private bool coverWholeScreen;
     private bool coverWholeScreen;
+
     public bool CoverWholeScreen
     public bool CoverWholeScreen
     {
     {
         get => coverWholeScreen;
         get => coverWholeScreen;
@@ -96,6 +113,7 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
     }
     }
 
 
     private ShapeCorners corners;
     private ShapeCorners corners;
+
     public ShapeCorners Corners
     public ShapeCorners Corners
     {
     {
         get => corners;
         get => corners;
@@ -112,25 +130,27 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
     {
     {
         get => showHandles;
         get => showHandles;
         set => SetProperty(ref showHandles, value);
         set => SetProperty(ref showHandles, value);
-    } 
-    
+    }
+
     private bool isSizeBoxEnabled;
     private bool isSizeBoxEnabled;
 
 
     public bool IsSizeBoxEnabled
     public bool IsSizeBoxEnabled
     {
     {
         get => isSizeBoxEnabled;
         get => isSizeBoxEnabled;
         set => SetProperty(ref isSizeBoxEnabled, value);
         set => SetProperty(ref isSizeBoxEnabled, value);
-    } 
+    }
 
 
     private bool enableSnapping = true;
     private bool enableSnapping = true;
+
     public bool EnableSnapping
     public bool EnableSnapping
     {
     {
         get => enableSnapping;
         get => enableSnapping;
         set => SetProperty(ref enableSnapping, value);
         set => SetProperty(ref enableSnapping, value);
     }
     }
-    
-    
+
+
     private ExecutionTrigger<ShapeCorners> requestedCornersExecutor;
     private ExecutionTrigger<ShapeCorners> requestedCornersExecutor;
+
     public ExecutionTrigger<ShapeCorners> RequestCornersExecutor
     public ExecutionTrigger<ShapeCorners> RequestCornersExecutor
     {
     {
         get => requestedCornersExecutor;
         get => requestedCornersExecutor;
@@ -138,18 +158,21 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
     }
     }
 
 
     private ICommand? actionCompletedCommand = null;
     private ICommand? actionCompletedCommand = null;
+
     public ICommand? ActionCompletedCommand
     public ICommand? ActionCompletedCommand
     {
     {
         get => actionCompletedCommand;
         get => actionCompletedCommand;
         set => SetProperty(ref actionCompletedCommand, value);
         set => SetProperty(ref actionCompletedCommand, value);
     }
     }
 
 
-    private RelayCommand<MouseOnCanvasEventArgs>? passThroughPointerPressedCommand; 
+    private RelayCommand<MouseOnCanvasEventArgs>? passThroughPointerPressedCommand;
+
     public RelayCommand<MouseOnCanvasEventArgs> PassThroughPointerPressedCommand
     public RelayCommand<MouseOnCanvasEventArgs> PassThroughPointerPressedCommand
     {
     {
         get
         get
         {
         {
-            return passThroughPointerPressedCommand ??= new RelayCommand<MouseOnCanvasEventArgs>(x => PassthroughPointerPressed?.Invoke(x));
+            return passThroughPointerPressedCommand ??=
+                new RelayCommand<MouseOnCanvasEventArgs>(x => PassthroughPointerPressed?.Invoke(x));
         }
         }
     }
     }
 
 
@@ -166,7 +189,8 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
                 return;
                 return;
 
 
             var lastState = undoStack.PeekCurrent();
             var lastState = undoStack.PeekCurrent();
-            if (lastState is not null && lastState.Value.Item1.AlmostEquals(Corners) && lastState.Value.Item2.AlmostEquals(InternalState))
+            if (lastState is not null && lastState.Value.Item1.AlmostEquals(Corners) &&
+                lastState.Value.Item2.AlmostEquals(InternalState))
                 return;
                 return;
 
 
             undoStack.AddState((Corners, InternalState), TransformOverlayStateType.Move);
             undoStack.AddState((Corners, InternalState), TransformOverlayStateType.Move);
@@ -208,7 +232,7 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
         return true;
         return true;
     }
     }
 
 
-    public bool HasUndo => undoStack is not null && undoStack.UndoCount > 0; 
+    public bool HasUndo => undoStack is not null && undoStack.UndoCount > 0;
     public bool HasRedo => undoStack is not null && undoStack.RedoCount > 0;
     public bool HasRedo => undoStack is not null && undoStack.RedoCount > 0;
 
 
     public void HideTransform()
     public void HideTransform()
@@ -221,7 +245,8 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
         ShowTransformControls = false;
         ShowTransformControls = false;
     }
     }
 
 
-    public void ShowTransform(DocumentTransformMode mode, bool coverWholeScreen, ShapeCorners initPos, bool showApplyButton)
+    public void ShowTransform(DocumentTransformMode mode, bool coverWholeScreen, ShapeCorners initPos,
+        bool showApplyButton)
     {
     {
         if (undoStack is not null || initPos.IsPartiallyDegenerate)
         if (undoStack is not null || initPos.IsPartiallyDegenerate)
             return;
             return;
@@ -253,21 +278,24 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
             requestedCornerFreedom = TransformCornerFreedom.ScaleProportionally;
             requestedCornerFreedom = TransformCornerFreedom.ScaleProportionally;
             requestedSideFreedom = TransformSideFreedom.ScaleProportionally;
             requestedSideFreedom = TransformSideFreedom.ScaleProportionally;
         }
         }
-        else if (isCtrlDown)
+        else if (isAltDown)
         {
         {
             requestedCornerFreedom = TransformCornerFreedom.Free;
             requestedCornerFreedom = TransformCornerFreedom.Free;
             requestedSideFreedom = TransformSideFreedom.Free;
             requestedSideFreedom = TransformSideFreedom.Free;
         }
         }
-        else if (isAltDown)
+        /*else if (isAltDown)
         {
         {
+        TODO: Add shear to the transform overlay
             requestedSideFreedom = TransformSideFreedom.Shear;
             requestedSideFreedom = TransformSideFreedom.Shear;
-        }
+        }*/
         else
         else
         {
         {
             requestedCornerFreedom = TransformCornerFreedom.Scale;
             requestedCornerFreedom = TransformCornerFreedom.Scale;
             requestedSideFreedom = TransformSideFreedom.Stretch;
             requestedSideFreedom = TransformSideFreedom.Stretch;
         }
         }
 
 
+        ScaleFromCenter = isCtrlDown;
+
         switch (activeTransformMode)
         switch (activeTransformMode)
         {
         {
             case DocumentTransformMode.Scale_Rotate_Shear_Perspective:
             case DocumentTransformMode.Scale_Rotate_Shear_Perspective:
@@ -290,6 +318,8 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
                 break;
                 break;
         }
         }
     }
     }
-    
-    public override string ToString() => !TransformActive ? "Not active" : $"Transform Mode: {activeTransformMode}; Corner Freedom: {CornerFreedom}; Side Freedom: {SideFreedom}";
+
+    public override string ToString() => !TransformActive
+        ? "Not active"
+        : $"Transform Mode: {activeTransformMode}; Corner Freedom: {CornerFreedom}; Side Freedom: {SideFreedom}";
 }
 }

+ 6 - 0
src/PixiEditor/Views/Main/ViewportControls/ViewportOverlays.cs

@@ -326,6 +326,11 @@ internal class ViewportOverlays
         };
         };
 
 
         Binding zoomboxAngleBinding = new() { Source = Viewport, Path = "Zoombox.Angle", Mode = BindingMode.OneWay };
         Binding zoomboxAngleBinding = new() { Source = Viewport, Path = "Zoombox.Angle", Mode = BindingMode.OneWay };
+        
+        Binding scaleFromCenterBinding = new()
+        {
+            Source = Viewport, Path = "Document.TransformViewModel.ScaleFromCenter", Mode = BindingMode.OneWay
+        };
 
 
         transformOverlay.Bind(Visual.IsVisibleProperty, isVisibleBinding);
         transformOverlay.Bind(Visual.IsVisibleProperty, isVisibleBinding);
         transformOverlay.Bind(TransformOverlay.ActionCompletedProperty, actionCompletedBinding);
         transformOverlay.Bind(TransformOverlay.ActionCompletedProperty, actionCompletedBinding);
@@ -342,6 +347,7 @@ internal class ViewportOverlays
         transformOverlay.Bind(TransformOverlay.ZoomboxAngleProperty, zoomboxAngleBinding);
         transformOverlay.Bind(TransformOverlay.ZoomboxAngleProperty, zoomboxAngleBinding);
         transformOverlay.Bind(TransformOverlay.ShowHandlesProperty, showHandlesBinding);
         transformOverlay.Bind(TransformOverlay.ShowHandlesProperty, showHandlesBinding);
         transformOverlay.Bind(TransformOverlay.IsSizeBoxEnabledProperty, isSizeBoxEnabledBinding);
         transformOverlay.Bind(TransformOverlay.IsSizeBoxEnabledProperty, isSizeBoxEnabledBinding);
+        transformOverlay.Bind(TransformOverlay.ScaleFromCenterProperty, scaleFromCenterBinding);
     }
     }
     
     
     private void BindVectorPathOverlay()
     private void BindVectorPathOverlay()

+ 13 - 1
src/PixiEditor/Views/Overlays/TransformOverlay/TransformOverlay.cs

@@ -160,6 +160,15 @@ internal class TransformOverlay : Overlay
         set => SetValue(IsSizeBoxEnabledProperty, value);
         set => SetValue(IsSizeBoxEnabledProperty, value);
     }
     }
 
 
+    public static readonly StyledProperty<bool> ScaleFromCenterProperty = AvaloniaProperty.Register<TransformOverlay, bool>(
+        nameof(ScaleFromCenter));
+
+    public bool ScaleFromCenter
+    {
+        get => GetValue(ScaleFromCenterProperty);
+        set => SetValue(ScaleFromCenterProperty, value);
+    }
+
     static TransformOverlay()
     static TransformOverlay()
     {
     {
         AffectsRender<TransformOverlay>(CornersProperty, ZoomScaleProperty, SideFreedomProperty, CornerFreedomProperty,
         AffectsRender<TransformOverlay>(CornersProperty, ZoomScaleProperty, SideFreedomProperty, CornerFreedomProperty,
@@ -754,7 +763,9 @@ internal class TransformOverlay : Overlay
 
 
             ShapeCorners? newCorners = TransformUpdateHelper.UpdateShapeFromCorner
             ShapeCorners? newCorners = TransformUpdateHelper.UpdateShapeFromCorner
             ((Anchor)capturedAnchor, CornerFreedom, InternalState.ProportionalAngle1,
             ((Anchor)capturedAnchor, CornerFreedom, InternalState.ProportionalAngle1,
-                InternalState.ProportionalAngle2, cornersOnStartAnchorDrag, targetPos, SnappingController,
+                InternalState.ProportionalAngle2, cornersOnStartAnchorDrag, targetPos,
+                ScaleFromCenter,
+                SnappingController,
                 out string snapX, out string snapY);
                 out string snapX, out string snapY);
 
 
             HighlightSnappedAxis(snapX, snapY);
             HighlightSnappedAxis(snapX, snapY);
@@ -836,6 +847,7 @@ internal class TransformOverlay : Overlay
             ShapeCorners? newCorners = TransformUpdateHelper.UpdateShapeFromSide
             ShapeCorners? newCorners = TransformUpdateHelper.UpdateShapeFromSide
             ((Anchor)capturedAnchor, SideFreedom, InternalState.ProportionalAngle1,
             ((Anchor)capturedAnchor, SideFreedom, InternalState.ProportionalAngle1,
                 InternalState.ProportionalAngle2, cornersOnStartAnchorDrag, targetPos + snapped.Delta,
                 InternalState.ProportionalAngle2, cornersOnStartAnchorDrag, targetPos + snapped.Delta,
+                ScaleFromCenter,
                 SnappingController, out string snapX, out string snapY);
                 SnappingController, out string snapX, out string snapY);
 
 
             string finalSnapX = snapped.SnapAxisXName ?? snapX;
             string finalSnapX = snapped.SnapAxisXName ?? snapX;

+ 57 - 7
src/PixiEditor/Views/Overlays/TransformOverlay/TransformUpdateHelper.cs

@@ -11,7 +11,7 @@ internal static class TransformUpdateHelper
 
 
     public static ShapeCorners? UpdateShapeFromCorner
     public static ShapeCorners? UpdateShapeFromCorner
     (Anchor targetCorner, TransformCornerFreedom freedom, double propAngle1, double propAngle2, ShapeCorners corners,
     (Anchor targetCorner, TransformCornerFreedom freedom, double propAngle1, double propAngle2, ShapeCorners corners,
-        VecD desiredPos,
+        VecD desiredPos, bool scaleFromCenter,
         SnappingController? snappingController, out string snapX, out string snapY)
         SnappingController? snappingController, out string snapX, out string snapY)
     {
     {
         if (!TransformHelper.IsCorner(targetCorner))
         if (!TransformHelper.IsCorner(targetCorner))
@@ -79,6 +79,7 @@ internal static class TransformUpdateHelper
             // find by how much move each corner
             // find by how much move each corner
             VecD delta = (desiredPos - targetPos).Rotate(-angle);
             VecD delta = (desiredPos - targetPos).Rotate(-angle);
             VecD leftNeighDelta, rightNeighDelta;
             VecD leftNeighDelta, rightNeighDelta;
+
             if (corners.IsPartiallyDegenerate)
             if (corners.IsPartiallyDegenerate)
             {
             {
                 // handle cases where we'd need to scale by infinity
                 // handle cases where we'd need to scale by infinity
@@ -97,6 +98,24 @@ internal static class TransformUpdateHelper
                 rightNeighDelta = newRightPos.Value - rightNeighTrans;
                 rightNeighDelta = newRightPos.Value - rightNeighTrans;
             }
             }
 
 
+            VecD oppositeDelta = VecD.Zero;
+            if (scaleFromCenter)
+            {
+                oppositeDelta = -delta;
+                bool swapped = leftNeighbor is Anchor.TopLeft or Anchor.BottomRight;
+
+                if (swapped)
+                {
+                    leftNeighDelta += new VecD(0, oppositeDelta.Y);
+                    rightNeighDelta += new VecD(oppositeDelta.X, 0);
+                }
+                else
+                {
+                    leftNeighDelta += new VecD(oppositeDelta.X, 0);
+                    rightNeighDelta += new VecD(0, oppositeDelta.Y);
+                }
+            }
+
             // handle cases where the transform overlay is squished into a line or a single point
             // handle cases where the transform overlay is squished into a line or a single point
             bool squishedWithLeft = leftNeighTrans.TaxicabLength < epsilon;
             bool squishedWithLeft = leftNeighTrans.TaxicabLength < epsilon;
             bool squishedWithRight = rightNeighTrans.TaxicabLength < epsilon;
             bool squishedWithRight = rightNeighTrans.TaxicabLength < epsilon;
@@ -121,6 +140,8 @@ internal static class TransformUpdateHelper
                 (leftNeighTrans + leftNeighDelta).Rotate(angle) + oppositePos);
                 (leftNeighTrans + leftNeighDelta).Rotate(angle) + oppositePos);
             corners = TransformHelper.UpdateCorner(corners, rightNeighbor,
             corners = TransformHelper.UpdateCorner(corners, rightNeighbor,
                 (rightNeighTrans + rightNeighDelta).Rotate(angle) + oppositePos);
                 (rightNeighTrans + rightNeighDelta).Rotate(angle) + oppositePos);
+            corners = TransformHelper.UpdateCorner(corners, opposite,
+                (oppositeDelta).Rotate(angle) + oppositePos);
 
 
             if (!corners.IsLegal)
             if (!corners.IsLegal)
                 return null;
                 return null;
@@ -151,7 +172,7 @@ internal static class TransformUpdateHelper
 
 
     public static ShapeCorners? UpdateShapeFromSide
     public static ShapeCorners? UpdateShapeFromSide
     (Anchor targetSide, TransformSideFreedom freedom, double propAngle1, double propAngle2, ShapeCorners corners,
     (Anchor targetSide, TransformSideFreedom freedom, double propAngle1, double propAngle2, ShapeCorners corners,
-        VecD desiredPos, SnappingController? snappingController, out string snapX, out string snapY)
+        VecD desiredPos, bool scaleFromCenter, SnappingController? snappingController, out string snapX, out string snapY)
     {
     {
         if (!TransformHelper.IsSide(targetSide))
         if (!TransformHelper.IsSide(targetSide))
             throw new ArgumentException($"{targetSide} is not a side");
             throw new ArgumentException($"{targetSide} is not a side");
@@ -171,7 +192,7 @@ internal static class TransformUpdateHelper
 
 
             VecD direction = targetPos - oppositePos;
             VecD direction = targetPos - oppositePos;
             direction = VecD.FromAngleAndLength(direction.Angle, 1 / direction.Length);
             direction = VecD.FromAngleAndLength(direction.Angle, 1 / direction.Length);
-            
+
             if (snappingController is not null)
             if (snappingController is not null)
             {
             {
                 desiredPos = snappingController.GetSnapPoint(desiredPos, direction, out snapX, out snapY);
                 desiredPos = snappingController.GetSnapPoint(desiredPos, direction, out snapX, out snapY);
@@ -203,10 +224,24 @@ internal static class TransformUpdateHelper
                     center + VecD.FromAngleAndLength(leftAngle, 1));
                     center + VecD.FromAngleAndLength(leftAngle, 1));
                 var updRightCorn = TransformHelper.TwoLineIntersection(leftCornPos + delta, rightCornPos + delta,
                 var updRightCorn = TransformHelper.TwoLineIntersection(leftCornPos + delta, rightCornPos + delta,
                     center, center + VecD.FromAngleAndLength(rightAngle, 1));
                     center, center + VecD.FromAngleAndLength(rightAngle, 1));
-                var updLeftOppCorn = TransformHelper.TwoLineIntersection(leftOppCornPos, rightOppCornPos, center,
-                    center + VecD.FromAngleAndLength(rightAngle, 1));
-                var updRightOppCorn = TransformHelper.TwoLineIntersection(leftOppCornPos, rightOppCornPos, center,
-                    center + VecD.FromAngleAndLength(leftAngle, 1));
+
+                VecD? updLeftOppCorn = null, updRightOppCorn = null;
+                if (!scaleFromCenter)
+                {
+                    updLeftOppCorn = TransformHelper.TwoLineIntersection(leftOppCornPos, rightOppCornPos, center,
+                        center + VecD.FromAngleAndLength(rightAngle, 1));
+                    updRightOppCorn = TransformHelper.TwoLineIntersection(leftOppCornPos, rightOppCornPos, center,
+                        center + VecD.FromAngleAndLength(leftAngle, 1));
+                }
+                else if(updLeftCorn is not null && updRightCorn is not null)
+                {
+                    // Mirror the corners across the center
+                    VecD mirrorLeftOppCorn = 2 * center - ((VecD)updRightCorn + delta);
+                    VecD mirrorRightOppCorn = 2 * center - ((VecD)updLeftCorn + delta);
+
+                    updLeftOppCorn = mirrorLeftOppCorn;
+                    updRightOppCorn = mirrorRightOppCorn; 
+                }
 
 
                 if (updLeftCorn is null || updRightCorn is null || updLeftOppCorn is null || updRightOppCorn is null)
                 if (updLeftCorn is null || updRightCorn is null || updLeftOppCorn is null || updRightOppCorn is null)
                     goto fallback;
                     goto fallback;
@@ -260,9 +295,24 @@ internal static class TransformUpdateHelper
             }
             }
 
 
             var delta = desiredPos - targetPos;
             var delta = desiredPos - targetPos;
+            
             var newCorners = TransformHelper.UpdateCorner(corners, leftCorner, leftCornerPos + delta);
             var newCorners = TransformHelper.UpdateCorner(corners, leftCorner, leftCornerPos + delta);
             newCorners = TransformHelper.UpdateCorner(newCorners, rightCorner, rightCornerPos + delta);
             newCorners = TransformHelper.UpdateCorner(newCorners, rightCorner, rightCornerPos + delta);
 
 
+            if (scaleFromCenter)
+            {
+                VecD oppositeDelta = -delta;
+                Anchor leftCornerOpp = TransformHelper.GetOpposite(leftCorner);
+                Anchor rightCornerOpp = TransformHelper.GetOpposite(rightCorner);
+                
+                var leftCornerOppPos = TransformHelper.GetAnchorPosition(corners, leftCornerOpp);
+                var rightCornerOppPos = TransformHelper.GetAnchorPosition(corners, rightCornerOpp);
+                
+                newCorners = TransformHelper.UpdateCorner(newCorners, leftCornerOpp, leftCornerOppPos + oppositeDelta);
+                newCorners = TransformHelper.UpdateCorner(newCorners, rightCornerOpp, rightCornerOppPos + oppositeDelta);
+            }
+
+
             return newCorners.IsLegal ? newCorners : null;
             return newCorners.IsLegal ? newCorners : null;
         }
         }