|
@@ -227,7 +227,9 @@ internal class TransformOverlay : Overlay
|
|
|
private bool rotationCursorActive = false;
|
|
|
|
|
|
private VecD lastPointerPos;
|
|
|
-
|
|
|
+ private InfoBox infoBox;
|
|
|
+ private VecD lastSize;
|
|
|
+
|
|
|
public TransformOverlay()
|
|
|
{
|
|
|
topLeftHandle = new AnchorHandle(this);
|
|
@@ -286,7 +288,7 @@ internal class TransformOverlay : Overlay
|
|
|
|
|
|
public override void RenderOverlay(Canvas drawingContext, RectD canvasBounds)
|
|
|
{
|
|
|
- DrawOverlay(drawingContext, new(Bounds.Width, Bounds.Height), Corners, InternalState.Origin, (float)ZoomScale);
|
|
|
+ DrawOverlay(drawingContext, canvasBounds.Size, Corners, InternalState.Origin, (float)ZoomScale);
|
|
|
|
|
|
if (capturedAnchor is null)
|
|
|
UpdateRotationCursor(lastPointerPos);
|
|
@@ -318,6 +320,7 @@ internal class TransformOverlay : Overlay
|
|
|
private void DrawOverlay
|
|
|
(Canvas context, VecD size, ShapeCorners corners, VecD origin, float zoomboxScale)
|
|
|
{
|
|
|
+ lastSize = size;
|
|
|
// draw transparent background to enable mouse input
|
|
|
DrawMouseInputArea(context, size);
|
|
|
|
|
@@ -685,6 +688,11 @@ internal class TransformOverlay : Overlay
|
|
|
VecD targetPos = originalAnchorPos + pos - mousePosOnStartAnchorDrag;
|
|
|
|
|
|
VecD projected = targetPos.ProjectOntoLine(originalAnchorPos, InternalState.Origin);
|
|
|
+ if (projected.IsNaNOrInfinity())
|
|
|
+ {
|
|
|
+ projected = targetPos;
|
|
|
+ }
|
|
|
+
|
|
|
VecD anchorRelativeDelta = projected - originalAnchorPos;
|
|
|
|
|
|
var adjacentAnchors = TransformHelper.GetAdjacentAnchors((Anchor)capturedAnchor);
|
|
@@ -709,12 +717,26 @@ internal class TransformOverlay : Overlay
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- snapped = FindProjectedAnchorSnap(projected);
|
|
|
- if (snapped.Delta == VecI.Zero)
|
|
|
+ // If rotation is almost cardinal, projecting snapping points result in extreme values when perpendicular to the axis
|
|
|
+ if (!TransformHelper.RotationIsAlmostCardinal(cornersOnStartAnchorDrag.RectRotation))
|
|
|
+ {
|
|
|
+ snapped = FindProjectedAnchorSnap(projected);
|
|
|
+ if (snapped.Delta == VecI.Zero)
|
|
|
+ {
|
|
|
+ snapped = FindAdjacentCornersSnap(adjacentAnchors, anchorRelativeDelta);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
{
|
|
|
- snapped = FindAdjacentCornersSnap(adjacentAnchors, anchorRelativeDelta);
|
|
|
+ snapped = TrySnapAnchor(targetPos);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ VecD potentialPos = targetPos + snapped.Delta;
|
|
|
+ if(potentialPos.X < 0 || potentialPos.Y < 0 || potentialPos.X > lastSize.X || potentialPos.Y > lastSize.Y)
|
|
|
+ {
|
|
|
+ snapped = new SnapData();
|
|
|
+ }
|
|
|
|
|
|
ShapeCorners? newCorners = TransformUpdateHelper.UpdateShapeFromSide
|
|
|
((Anchor)capturedAnchor, SideFreedom, InternalState.ProportionalAngle1,
|
|
@@ -754,7 +776,13 @@ internal class TransformOverlay : Overlay
|
|
|
|
|
|
VecD snapOrigin = TransformHelper.GetAnchorPosition(cornersOnStartAnchorDrag, adjacent) + anchorRelativeDelta;
|
|
|
var snapped = TrySnapAnchorAlongLine(adjacentAnchorPos, snapOrigin);
|
|
|
-
|
|
|
+ double maxDistance = GetSizeToOppositeSide(cornersOnStartAnchorDrag, capturedAnchor.Value) / 8f;
|
|
|
+
|
|
|
+ if(snapped.Delta.Length > maxDistance)
|
|
|
+ {
|
|
|
+ snapped = new SnapData();
|
|
|
+ }
|
|
|
+
|
|
|
if (snapped.Delta == VecI.Zero)
|
|
|
{
|
|
|
adjacentAnchorPos = TransformHelper.GetAnchorPosition(cornersOnStartAnchorDrag, adjacentAnchors.Item2) +
|
|
@@ -764,10 +792,22 @@ internal class TransformOverlay : Overlay
|
|
|
snapOrigin = TransformHelper.GetAnchorPosition(cornersOnStartAnchorDrag, adjacent) + anchorRelativeDelta;
|
|
|
|
|
|
snapped = TrySnapAnchorAlongLine(adjacentAnchorPos, snapOrigin);
|
|
|
+ if(snapped.Delta.Length > maxDistance)
|
|
|
+ {
|
|
|
+ snapped = new SnapData();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return snapped;
|
|
|
}
|
|
|
+
|
|
|
+ private double GetSizeToOppositeSide(ShapeCorners corners, Anchor anchor1)
|
|
|
+ {
|
|
|
+ Anchor opposite = TransformHelper.GetOppositeAnchor(anchor1);
|
|
|
+ VecD oppositePos = TransformHelper.GetAnchorPosition(corners, opposite);
|
|
|
+ VecD anchorPos = TransformHelper.GetAnchorPosition(corners, anchor1);
|
|
|
+ return (oppositePos - anchorPos).Length;
|
|
|
+ }
|
|
|
|
|
|
private SnapData FindProjectedAnchorSnap(VecD projected)
|
|
|
{
|