diff --git a/Microsoft.Toolkit.Uwp.UI.Controls.Media/ImageCropper/ImageCropper.Events.cs b/Microsoft.Toolkit.Uwp.UI.Controls.Media/ImageCropper/ImageCropper.Events.cs
index a8a7109c735..cb0e4b1af39 100644
--- a/Microsoft.Toolkit.Uwp.UI.Controls.Media/ImageCropper/ImageCropper.Events.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Controls.Media/ImageCropper/ImageCropper.Events.cs
@@ -106,7 +106,11 @@ private void ImageCropperThumb_KeyUp(object sender, KeyRoutedEventArgs e)
_currentCroppedRect = croppedRect;
}
- UpdateImageLayout(true);
+ if (TryUpdateImageLayout(true))
+ {
+ UpdateSelectionThumbs(true);
+ UpdateMaskArea(true);
+ }
}
private void ImageCropperThumb_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
@@ -119,7 +123,11 @@ private void ImageCropperThumb_ManipulationCompleted(object sender, Manipulation
_currentCroppedRect = croppedRect;
}
- UpdateImageLayout(true);
+ if (TryUpdateImageLayout(true))
+ {
+ UpdateSelectionThumbs(true);
+ UpdateMaskArea(true);
+ }
}
private void ImageCropperThumb_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
@@ -161,7 +169,12 @@ private void SourceImage_ManipulationDelta(object sender, ManipulationDeltaRoute
var croppedRect = _inverseImageTransform.TransformBounds(selectedRect);
croppedRect.Intersect(_restrictedCropRect);
_currentCroppedRect = croppedRect;
- UpdateImageLayout();
+
+ if (TryUpdateImageLayout())
+ {
+ UpdateSelectionThumbs();
+ UpdateMaskArea();
+ }
}
private void ImageCanvas_SizeChanged(object sender, SizeChangedEventArgs e)
@@ -171,8 +184,16 @@ private void ImageCanvas_SizeChanged(object sender, SizeChangedEventArgs e)
return;
}
- UpdateImageLayout();
- UpdateMaskArea();
+ if (TryUpdateImageLayout())
+ {
+ UpdateSelectionThumbs();
+ }
+
+ if (TryUpdateAspectRatio())
+ {
+ UpdateSelectionThumbs();
+ UpdateMaskArea();
+ }
}
}
}
\ No newline at end of file
diff --git a/Microsoft.Toolkit.Uwp.UI.Controls.Media/ImageCropper/ImageCropper.Logic.cs b/Microsoft.Toolkit.Uwp.UI.Controls.Media/ImageCropper/ImageCropper.Logic.cs
index 47f87baed84..368d9f17a9b 100644
--- a/Microsoft.Toolkit.Uwp.UI.Controls.Media/ImageCropper/ImageCropper.Logic.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Controls.Media/ImageCropper/ImageCropper.Logic.cs
@@ -28,8 +28,13 @@ private void InitImageLayout(bool animate = false)
_restrictedCropRect = new Rect(0, 0, Source.PixelWidth, Source.PixelHeight);
if (IsValidRect(_restrictedCropRect))
{
- _currentCroppedRect = KeepAspectRatio ? GetUniformRect(_restrictedCropRect, UsedAspectRatio) : _restrictedCropRect;
- UpdateImageLayout(animate);
+ _currentCroppedRect = KeepAspectRatio ? GetUniformRect(_restrictedCropRect, ActualAspectRatio) : _restrictedCropRect;
+
+ if (TryUpdateImageLayout(animate))
+ {
+ UpdateSelectionThumbs(animate);
+ UpdateMaskArea(animate);
+ }
}
}
@@ -40,13 +45,16 @@ private void InitImageLayout(bool animate = false)
/// Update image source transform.
///
/// Whether animation is enabled.
- private void UpdateImageLayout(bool animate = false)
+ private bool TryUpdateImageLayout(bool animate = false)
{
if (Source != null && IsValidRect(CanvasRect))
{
var uniformSelectedRect = GetUniformRect(CanvasRect, _currentCroppedRect.Width / _currentCroppedRect.Height);
- UpdateImageLayoutWithViewport(uniformSelectedRect, _currentCroppedRect, animate);
+
+ return TryUpdateImageLayoutWithViewport(uniformSelectedRect, _currentCroppedRect, animate);
}
+
+ return false;
}
///
@@ -55,11 +63,11 @@ private void UpdateImageLayout(bool animate = false)
/// Viewport
/// The real image area of viewport.
/// Whether animation is enabled.
- private void UpdateImageLayoutWithViewport(Rect viewport, Rect viewportImageRect, bool animate = false)
+ private bool TryUpdateImageLayoutWithViewport(Rect viewport, Rect viewportImageRect, bool animate = false)
{
if (!IsValidRect(viewport) || !IsValidRect(viewportImageRect))
{
- return;
+ return false;
}
var imageScale = viewport.Width / viewportImageRect.Width;
@@ -69,12 +77,8 @@ private void UpdateImageLayoutWithViewport(Rect viewport, Rect viewportImageRect
_inverseImageTransform.ScaleX = _inverseImageTransform.ScaleY = 1 / imageScale;
_inverseImageTransform.TranslateX = -_imageTransform.TranslateX / imageScale;
_inverseImageTransform.TranslateY = -_imageTransform.TranslateY / imageScale;
- var selectedRect = _imageTransform.TransformBounds(_currentCroppedRect);
_restrictedSelectRect = _imageTransform.TransformBounds(_restrictedCropRect);
- var startPoint = GetSafePoint(_restrictedSelectRect, new Point(selectedRect.X, selectedRect.Y));
- var endPoint = GetSafePoint(_restrictedSelectRect, new Point(
- selectedRect.X + selectedRect.Width,
- selectedRect.Y + selectedRect.Height));
+
if (animate)
{
AnimateUIElementOffset(new Point(_imageTransform.TranslateX, _imageTransform.TranslateY), _animationDuration, _sourceImage);
@@ -87,7 +91,7 @@ private void UpdateImageLayoutWithViewport(Rect viewport, Rect viewportImageRect
targetVisual.Scale = new Vector3((float)imageScale);
}
- UpdateSelectedRect(startPoint, endPoint, animate);
+ return true;
}
///
@@ -105,7 +109,7 @@ private void UpdateCroppedRect(ThumbPosition position, Point diffPos)
double radian = 0d, diffPointRadian = 0d;
if (KeepAspectRatio)
{
- radian = Math.Atan(UsedAspectRatio);
+ radian = Math.Atan(ActualAspectRatio);
diffPointRadian = Math.Atan(diffPos.X / diffPos.Y);
}
@@ -117,8 +121,8 @@ private void UpdateCroppedRect(ThumbPosition position, Point diffPos)
case ThumbPosition.Top:
if (KeepAspectRatio)
{
- var originSizeChange = new Point(-diffPos.Y * UsedAspectRatio, -diffPos.Y);
- var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, UsedAspectRatio);
+ var originSizeChange = new Point(-diffPos.Y * ActualAspectRatio, -diffPos.Y);
+ var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, ActualAspectRatio);
startPoint.X += -safeChange.X / 2;
endPoint.X += safeChange.X / 2;
startPoint.Y += -safeChange.Y;
@@ -132,8 +136,8 @@ private void UpdateCroppedRect(ThumbPosition position, Point diffPos)
case ThumbPosition.Bottom:
if (KeepAspectRatio)
{
- var originSizeChange = new Point(diffPos.Y * UsedAspectRatio, diffPos.Y);
- var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, UsedAspectRatio);
+ var originSizeChange = new Point(diffPos.Y * ActualAspectRatio, diffPos.Y);
+ var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, ActualAspectRatio);
startPoint.X += -safeChange.X / 2;
endPoint.X += safeChange.X / 2;
endPoint.Y += safeChange.Y;
@@ -147,8 +151,8 @@ private void UpdateCroppedRect(ThumbPosition position, Point diffPos)
case ThumbPosition.Left:
if (KeepAspectRatio)
{
- var originSizeChange = new Point(-diffPos.X, -diffPos.X / UsedAspectRatio);
- var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, UsedAspectRatio);
+ var originSizeChange = new Point(-diffPos.X, -diffPos.X / ActualAspectRatio);
+ var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, ActualAspectRatio);
startPoint.Y += -safeChange.Y / 2;
endPoint.Y += safeChange.Y / 2;
startPoint.X += -safeChange.X;
@@ -162,8 +166,8 @@ private void UpdateCroppedRect(ThumbPosition position, Point diffPos)
case ThumbPosition.Right:
if (KeepAspectRatio)
{
- var originSizeChange = new Point(diffPos.X, diffPos.X / UsedAspectRatio);
- var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, UsedAspectRatio);
+ var originSizeChange = new Point(diffPos.X, diffPos.X / ActualAspectRatio);
+ var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, ActualAspectRatio);
startPoint.Y += -safeChange.Y / 2;
endPoint.Y += safeChange.Y / 2;
endPoint.X += safeChange.X;
@@ -179,7 +183,7 @@ private void UpdateCroppedRect(ThumbPosition position, Point diffPos)
{
var effectiveLength = diffPos.Y / Math.Cos(diffPointRadian) * Math.Cos(diffPointRadian - radian);
var originSizeChange = new Point(-effectiveLength * Math.Sin(radian), -effectiveLength * Math.Cos(radian));
- var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, UsedAspectRatio);
+ var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, ActualAspectRatio);
diffPos.X = -safeChange.X;
diffPos.Y = -safeChange.Y;
}
@@ -193,7 +197,7 @@ private void UpdateCroppedRect(ThumbPosition position, Point diffPos)
diffPointRadian = -diffPointRadian;
var effectiveLength = diffPos.Y / Math.Cos(diffPointRadian) * Math.Cos(diffPointRadian - radian);
var originSizeChange = new Point(-effectiveLength * Math.Sin(radian), -effectiveLength * Math.Cos(radian));
- var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, UsedAspectRatio);
+ var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, ActualAspectRatio);
diffPos.X = safeChange.X;
diffPos.Y = -safeChange.Y;
}
@@ -207,7 +211,7 @@ private void UpdateCroppedRect(ThumbPosition position, Point diffPos)
diffPointRadian = -diffPointRadian;
var effectiveLength = diffPos.Y / Math.Cos(diffPointRadian) * Math.Cos(diffPointRadian - radian);
var originSizeChange = new Point(effectiveLength * Math.Sin(radian), effectiveLength * Math.Cos(radian));
- var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, UsedAspectRatio);
+ var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, ActualAspectRatio);
diffPos.X = -safeChange.X;
diffPos.Y = safeChange.Y;
}
@@ -220,7 +224,7 @@ private void UpdateCroppedRect(ThumbPosition position, Point diffPos)
{
var effectiveLength = diffPos.Y / Math.Cos(diffPointRadian) * Math.Cos(diffPointRadian - radian);
var originSizeChange = new Point(effectiveLength * Math.Sin(radian), effectiveLength * Math.Cos(radian));
- var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, UsedAspectRatio);
+ var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, ActualAspectRatio);
diffPos.X = safeChange.X;
diffPos.Y = safeChange.Y;
}
@@ -273,28 +277,43 @@ private void UpdateCroppedRect(ThumbPosition position, Point diffPos)
_currentCroppedRect = croppedRect;
var viewportRect = GetUniformRect(CanvasRect, selectedRect.Width / selectedRect.Height);
var viewportImgRect = _inverseImageTransform.TransformBounds(selectedRect);
- UpdateImageLayoutWithViewport(viewportRect, viewportImgRect);
+
+ if (TryUpdateImageLayoutWithViewport(viewportRect, viewportImgRect))
+ {
+ UpdateSelectionThumbs();
+ UpdateMaskArea();
+ }
}
else
{
- UpdateSelectedRect(startPoint, endPoint);
+ UpdateSelectionThumbs(startPoint, endPoint);
+ UpdateMaskArea();
}
}
+ private void UpdateSelectionThumbs(bool animate = false)
+ {
+ var selectedRect = _imageTransform.TransformBounds(_currentCroppedRect);
+ var startPoint = GetSafePoint(_restrictedSelectRect, new Point(selectedRect.X, selectedRect.Y));
+ var endPoint = GetSafePoint(_restrictedSelectRect, new Point(selectedRect.X + selectedRect.Width, selectedRect.Y + selectedRect.Height));
+
+ UpdateSelectionThumbs(startPoint, endPoint, animate);
+ }
+
///
- /// Update selection area.
+ /// Positions the thumbs for the selection rectangle.
///
/// The point on the upper left corner.
/// The point on the lower right corner.
/// Whether animation is enabled.
- private void UpdateSelectedRect(Point startPoint, Point endPoint, bool animate = false)
+ private void UpdateSelectionThumbs(Point startPoint, Point endPoint, bool animate = false)
{
_startX = startPoint.X;
_startY = startPoint.Y;
_endX = endPoint.X;
_endY = endPoint.Y;
- var centerX = ((_endX - _startX) / 2) + _startX;
- var centerY = ((_endY - _startY) / 2) + _startY;
+ var center = SelectionAreaCenter;
+
Storyboard storyboard = null;
if (animate)
{
@@ -305,12 +324,12 @@ private void UpdateSelectedRect(Point startPoint, Point endPoint, bool animate =
{
if (animate)
{
- storyboard.Children.Add(CreateDoubleAnimation(centerX, _animationDuration, _topThumb, nameof(ImageCropperThumb.X), true));
+ storyboard.Children.Add(CreateDoubleAnimation(center.X, _animationDuration, _topThumb, nameof(ImageCropperThumb.X), true));
storyboard.Children.Add(CreateDoubleAnimation(_startY, _animationDuration, _topThumb, nameof(ImageCropperThumb.Y), true));
}
else
{
- _topThumb.X = centerX;
+ _topThumb.X = center.X;
_topThumb.Y = _startY;
}
}
@@ -319,12 +338,12 @@ private void UpdateSelectedRect(Point startPoint, Point endPoint, bool animate =
{
if (animate)
{
- storyboard.Children.Add(CreateDoubleAnimation(centerX, _animationDuration, _bottomThumb, nameof(ImageCropperThumb.X), true));
+ storyboard.Children.Add(CreateDoubleAnimation(center.X, _animationDuration, _bottomThumb, nameof(ImageCropperThumb.X), true));
storyboard.Children.Add(CreateDoubleAnimation(_endY, _animationDuration, _bottomThumb, nameof(ImageCropperThumb.Y), true));
}
else
{
- _bottomThumb.X = centerX;
+ _bottomThumb.X = center.X;
_bottomThumb.Y = _endY;
}
}
@@ -334,12 +353,12 @@ private void UpdateSelectedRect(Point startPoint, Point endPoint, bool animate =
if (animate)
{
storyboard.Children.Add(CreateDoubleAnimation(_startX, _animationDuration, _leftThumb, nameof(ImageCropperThumb.X), true));
- storyboard.Children.Add(CreateDoubleAnimation(centerY, _animationDuration, _leftThumb, nameof(ImageCropperThumb.Y), true));
+ storyboard.Children.Add(CreateDoubleAnimation(center.Y, _animationDuration, _leftThumb, nameof(ImageCropperThumb.Y), true));
}
else
{
_leftThumb.X = _startX;
- _leftThumb.Y = centerY;
+ _leftThumb.Y = center.Y;
}
}
@@ -348,12 +367,12 @@ private void UpdateSelectedRect(Point startPoint, Point endPoint, bool animate =
if (animate)
{
storyboard.Children.Add(CreateDoubleAnimation(_endX, _animationDuration, _rightThumb, nameof(ImageCropperThumb.X), true));
- storyboard.Children.Add(CreateDoubleAnimation(centerY, _animationDuration, _rightThumb, nameof(ImageCropperThumb.Y), true));
+ storyboard.Children.Add(CreateDoubleAnimation(center.Y, _animationDuration, _rightThumb, nameof(ImageCropperThumb.Y), true));
}
else
{
_rightThumb.X = _endX;
- _rightThumb.Y = centerY;
+ _rightThumb.Y = center.Y;
}
}
@@ -417,8 +436,6 @@ private void UpdateSelectedRect(Point startPoint, Point endPoint, bool animate =
{
storyboard.Begin();
}
-
- UpdateMaskArea(animate);
}
///
@@ -507,58 +524,69 @@ private void UpdateMaskArea(bool animate = false)
///
/// Update image aspect ratio.
///
- private void UpdateAspectRatio(bool animate = false)
+ private bool TryUpdateAspectRatio()
{
- if (KeepAspectRatio && Source != null && IsValidRect(_restrictedSelectRect))
- {
- var centerX = ((_endX - _startX) / 2) + _startX;
- var centerY = ((_endY - _startY) / 2) + _startY;
- var restrictedMinLength = MinCroppedPixelLength * _imageTransform.ScaleX;
- var maxSelectedLength = Math.Max(_endX - _startX, _endY - _startY);
- var viewRect = new Rect(centerX - (maxSelectedLength / 2), centerY - (maxSelectedLength / 2), maxSelectedLength, maxSelectedLength);
- var uniformSelectedRect = GetUniformRect(viewRect, UsedAspectRatio);
- if (uniformSelectedRect.Width > _restrictedSelectRect.Width || uniformSelectedRect.Height > _restrictedSelectRect.Height)
- {
- uniformSelectedRect = GetUniformRect(_restrictedSelectRect, UsedAspectRatio);
- }
+ if (KeepAspectRatio is false || Source is null || IsValidRect(_restrictedSelectRect) is false)
+ {
+ return false;
+ }
- if (uniformSelectedRect.Width < restrictedMinLength || uniformSelectedRect.Height < restrictedMinLength)
- {
- var scale = restrictedMinLength / Math.Min(uniformSelectedRect.Width, uniformSelectedRect.Height);
- uniformSelectedRect.Width *= scale;
- uniformSelectedRect.Height *= scale;
- if (uniformSelectedRect.Width > _restrictedSelectRect.Width || uniformSelectedRect.Height > _restrictedSelectRect.Height)
- {
- AspectRatio = -1;
- return;
- }
- }
+ var center = SelectionAreaCenter;
+ var restrictedMinLength = MinCroppedPixelLength * _imageTransform.ScaleX;
+ var maxSelectedLength = Math.Max(_endX - _startX, _endY - _startY);
+ var viewRect = new Rect(center.X - (maxSelectedLength / 2), center.Y - (maxSelectedLength / 2), maxSelectedLength, maxSelectedLength);
- if (_restrictedSelectRect.X > uniformSelectedRect.X)
- {
- uniformSelectedRect.X += _restrictedSelectRect.X - uniformSelectedRect.X;
- }
+ var uniformSelectedRect = GetUniformRect(viewRect, ActualAspectRatio);
+ if (uniformSelectedRect.Width > _restrictedSelectRect.Width || uniformSelectedRect.Height > _restrictedSelectRect.Height)
+ {
+ uniformSelectedRect = GetUniformRect(_restrictedSelectRect, ActualAspectRatio);
+ }
- if (_restrictedSelectRect.Y > uniformSelectedRect.Y)
- {
- uniformSelectedRect.Y += _restrictedSelectRect.Y - uniformSelectedRect.Y;
- }
+ // If selection area is smaller than allowed.
+ if (uniformSelectedRect.Width < restrictedMinLength || uniformSelectedRect.Height < restrictedMinLength)
+ {
+ // Scale selection area to fit.
+ var scale = restrictedMinLength / Math.Min(uniformSelectedRect.Width, uniformSelectedRect.Height);
+ uniformSelectedRect.Width *= scale;
+ uniformSelectedRect.Height *= scale;
- if ((_restrictedSelectRect.X + _restrictedSelectRect.Width) < (uniformSelectedRect.X + uniformSelectedRect.Width))
+ // If selection area is larger than allowed.
+ if (uniformSelectedRect.Width > _restrictedSelectRect.Width || uniformSelectedRect.Height > _restrictedSelectRect.Height)
{
- uniformSelectedRect.X += (_restrictedSelectRect.X + _restrictedSelectRect.Width) - (uniformSelectedRect.X + uniformSelectedRect.Width);
+ // Sentinal value. Equivelant to setting KeepAspectRatio to false. Causes AspectRatio to be recalculated.
+ AspectRatio = -1;
+ return false;
}
+ }
- if ((_restrictedSelectRect.Y + _restrictedSelectRect.Height) < (uniformSelectedRect.Y + uniformSelectedRect.Height))
- {
- uniformSelectedRect.Y += (_restrictedSelectRect.Y + _restrictedSelectRect.Height) - (uniformSelectedRect.Y + uniformSelectedRect.Height);
- }
+ // Fix positioning
+ if (_restrictedSelectRect.X > uniformSelectedRect.X)
+ {
+ uniformSelectedRect.X += _restrictedSelectRect.X - uniformSelectedRect.X;
+ }
- var croppedRect = _inverseImageTransform.TransformBounds(uniformSelectedRect);
- croppedRect.Intersect(_restrictedCropRect);
- _currentCroppedRect = croppedRect;
- UpdateImageLayout(animate);
+ if (_restrictedSelectRect.Y > uniformSelectedRect.Y)
+ {
+ uniformSelectedRect.Y += _restrictedSelectRect.Y - uniformSelectedRect.Y;
+ }
+
+ // Fix size
+ if ((_restrictedSelectRect.X + _restrictedSelectRect.Width) < (uniformSelectedRect.X + uniformSelectedRect.Width))
+ {
+ uniformSelectedRect.X += (_restrictedSelectRect.X + _restrictedSelectRect.Width) - (uniformSelectedRect.X + uniformSelectedRect.Width);
+ }
+
+ if ((_restrictedSelectRect.Y + _restrictedSelectRect.Height) < (uniformSelectedRect.Y + uniformSelectedRect.Height))
+ {
+ uniformSelectedRect.Y += (_restrictedSelectRect.Y + _restrictedSelectRect.Height) - (uniformSelectedRect.Y + uniformSelectedRect.Height);
}
+
+ // Apply transformation
+ var croppedRect = _inverseImageTransform.TransformBounds(uniformSelectedRect);
+ croppedRect.Intersect(_restrictedCropRect);
+ _currentCroppedRect = croppedRect;
+
+ return true;
}
///
@@ -632,5 +660,10 @@ private void UpdateThumbsVisibility()
_lowerRigthThumb.Visibility = cornerThumbsVisibility;
}
}
+
+ ///
+ /// Gets a value that indicates the center of the visible selection rectangle.
+ ///
+ private Point SelectionAreaCenter => new Point(((_endX - _startX) / 2) + _startX, ((_endY - _startY) / 2) + _startY);
}
}
\ No newline at end of file
diff --git a/Microsoft.Toolkit.Uwp.UI.Controls.Media/ImageCropper/ImageCropper.Properties.cs b/Microsoft.Toolkit.Uwp.UI.Controls.Media/ImageCropper/ImageCropper.Properties.cs
index f0640486f23..97eaf0567b6 100644
--- a/Microsoft.Toolkit.Uwp.UI.Controls.Media/ImageCropper/ImageCropper.Properties.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Controls.Media/ImageCropper/ImageCropper.Properties.cs
@@ -51,7 +51,15 @@ private static void OnAspectRatioChanged(
DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var target = (ImageCropper)d;
- target.UpdateAspectRatio(true);
+
+ if (target.TryUpdateAspectRatio())
+ {
+ if (target.TryUpdateImageLayout(true))
+ {
+ target.UpdateSelectionThumbs(true);
+ target.UpdateMaskArea(true);
+ }
+ }
}
private static void OnCropShapeChanged(
@@ -60,7 +68,15 @@ private static void OnCropShapeChanged(
var target = (ImageCropper)d;
target.UpdateCropShape();
target.UpdateThumbsVisibility();
- target.UpdateAspectRatio();
+
+ if (target.TryUpdateAspectRatio())
+ {
+ if (target.TryUpdateImageLayout())
+ {
+ target.UpdateSelectionThumbs();
+ }
+ }
+
target.UpdateMaskArea();
}
diff --git a/Microsoft.Toolkit.Uwp.UI.Controls.Media/ImageCropper/ImageCropper.cs b/Microsoft.Toolkit.Uwp.UI.Controls.Media/ImageCropper/ImageCropper.cs
index 60ed065fbdd..260ef1a0172 100644
--- a/Microsoft.Toolkit.Uwp.UI.Controls.Media/ImageCropper/ImageCropper.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Controls.Media/ImageCropper/ImageCropper.cs
@@ -49,10 +49,13 @@ public partial class ImageCropper : Control
private ImageCropperThumb _upperRightThumb;
private ImageCropperThumb _lowerLeftThumb;
private ImageCropperThumb _lowerRigthThumb;
+
+ // Selection area
private double _startX;
private double _startY;
private double _endX;
private double _endY;
+
private Rect _currentCroppedRect = Rect.Empty;
private Rect _restrictedCropRect = Rect.Empty;
private Rect _restrictedSelectRect = Rect.Empty;
@@ -70,23 +73,36 @@ public ImageCropper()
private Rect CanvasRect => new Rect(0, 0, _imageCanvas?.ActualWidth ?? 0, _imageCanvas?.ActualHeight ?? 0);
- private bool KeepAspectRatio => UsedAspectRatio > 0;
+ ///
+ /// Gets a value indicating whether the user-provided is valid and should be kept during manipulation of the image cropper.
+ ///
+ private bool KeepAspectRatio => ActualAspectRatio > 0;
- private double UsedAspectRatio
+ ///
+ /// Gets the internally used aspect ratio, rather than the user-provided value. Adjusted to handle crop shape and invalid values.
+ ///
+ private double ActualAspectRatio
{
get
{
- var aspectRatio = AspectRatio;
- switch (CropShape)
+ var aspectRatio = CropShape switch
{
- case CropShape.Rectangular:
- break;
- case CropShape.Circular:
- aspectRatio = 1;
- break;
- }
+ CropShape.Rectangular => AspectRatio,
+ CropShape.Circular => 1,
+ _ => AspectRatio,
+ };
- return aspectRatio != null && aspectRatio > 0 ? aspectRatio.Value : -1;
+ if (aspectRatio is not null && aspectRatio > 0)
+ {
+ // When not null or 0.
+ return aspectRatio.Value;
+ }
+ else
+ {
+ // Fallback to sentinal value.
+ // Used to indicate aspect ratio should be discarded and reset during manipulation of the image cropper.
+ return -1;
+ }
}
}
@@ -97,7 +113,7 @@ private Size MinCropSize
{
get
{
- var aspectRatio = KeepAspectRatio ? UsedAspectRatio : 1;
+ var aspectRatio = KeepAspectRatio ? ActualAspectRatio : 1;
var size = new Size(MinCroppedPixelLength, MinCroppedPixelLength);
if (aspectRatio >= 1)
{
@@ -123,7 +139,7 @@ private Size MinSelectSize
var minLength = Math.Min(realMinSelectSize.Width, realMinSelectSize.Height);
if (minLength < MinSelectedLength)
{
- var aspectRatio = KeepAspectRatio ? UsedAspectRatio : 1;
+ var aspectRatio = KeepAspectRatio ? ActualAspectRatio : 1;
var minSelectSize = new Size(MinSelectedLength, MinSelectedLength);
if (aspectRatio >= 1)
{
@@ -433,13 +449,18 @@ public bool TrySetCroppedRegion(Rect rect)
// If an aspect ratio is set, reject regions that don't respect it
// If cropping a circle, reject regions where the aspect ratio is not 1
- if (KeepAspectRatio && UsedAspectRatio != rect.Width / rect.Height)
+ if (KeepAspectRatio && ActualAspectRatio != rect.Width / rect.Height)
{
return false;
}
_currentCroppedRect = rect;
- UpdateImageLayout(true);
+ if (TryUpdateImageLayout(true))
+ {
+ UpdateSelectionThumbs(true);
+ UpdateMaskArea(true);
+ }
+
return true;
}
}