Skip to content

Commit b09ecc6

Browse files
committed
Added notes and cleaned up code
1 parent 24391ac commit b09ecc6

File tree

2 files changed

+116
-80
lines changed

2 files changed

+116
-80
lines changed

Microsoft.Toolkit.Uwp.UI.Controls.Media/ImageCropper/ImageCropper.Logic.cs

Lines changed: 86 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,23 @@ private void InitImageLayout(bool animate = false)
2828
_restrictedCropRect = new Rect(0, 0, Source.PixelWidth, Source.PixelHeight);
2929
if (IsValidRect(_restrictedCropRect))
3030
{
31-
_currentCroppedRect = KeepAspectRatio ? GetUniformRect(_restrictedCropRect, UsedAspectRatio) : _restrictedCropRect;
31+
_currentCroppedRect = KeepAspectRatio ? GetUniformRect(_restrictedCropRect, ActualAspectRatio) : _restrictedCropRect;
3232
UpdateImageLayout(animate);
3333
}
3434
}
3535

3636
UpdateThumbsVisibility();
3737
}
3838

39+
private bool ShouldUpdateImageLayout => Source != null && IsValidRect(CanvasRect);
40+
3941
/// <summary>
4042
/// Update image source transform.
4143
/// </summary>
4244
/// <param name="animate">Whether animation is enabled.</param>
4345
private void UpdateImageLayout(bool animate = false)
4446
{
45-
if (Source != null && IsValidRect(CanvasRect))
47+
if (ShouldUpdateImageLayout)
4648
{
4749
var uniformSelectedRect = GetUniformRect(CanvasRect, _currentCroppedRect.Width / _currentCroppedRect.Height);
4850
UpdateImageLayoutWithViewport(uniformSelectedRect, _currentCroppedRect, animate);
@@ -105,7 +107,7 @@ private void UpdateCroppedRect(ThumbPosition position, Point diffPos)
105107
double radian = 0d, diffPointRadian = 0d;
106108
if (KeepAspectRatio)
107109
{
108-
radian = Math.Atan(UsedAspectRatio);
110+
radian = Math.Atan(ActualAspectRatio);
109111
diffPointRadian = Math.Atan(diffPos.X / diffPos.Y);
110112
}
111113

@@ -117,8 +119,8 @@ private void UpdateCroppedRect(ThumbPosition position, Point diffPos)
117119
case ThumbPosition.Top:
118120
if (KeepAspectRatio)
119121
{
120-
var originSizeChange = new Point(-diffPos.Y * UsedAspectRatio, -diffPos.Y);
121-
var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, UsedAspectRatio);
122+
var originSizeChange = new Point(-diffPos.Y * ActualAspectRatio, -diffPos.Y);
123+
var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, ActualAspectRatio);
122124
startPoint.X += -safeChange.X / 2;
123125
endPoint.X += safeChange.X / 2;
124126
startPoint.Y += -safeChange.Y;
@@ -132,8 +134,8 @@ private void UpdateCroppedRect(ThumbPosition position, Point diffPos)
132134
case ThumbPosition.Bottom:
133135
if (KeepAspectRatio)
134136
{
135-
var originSizeChange = new Point(diffPos.Y * UsedAspectRatio, diffPos.Y);
136-
var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, UsedAspectRatio);
137+
var originSizeChange = new Point(diffPos.Y * ActualAspectRatio, diffPos.Y);
138+
var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, ActualAspectRatio);
137139
startPoint.X += -safeChange.X / 2;
138140
endPoint.X += safeChange.X / 2;
139141
endPoint.Y += safeChange.Y;
@@ -147,8 +149,8 @@ private void UpdateCroppedRect(ThumbPosition position, Point diffPos)
147149
case ThumbPosition.Left:
148150
if (KeepAspectRatio)
149151
{
150-
var originSizeChange = new Point(-diffPos.X, -diffPos.X / UsedAspectRatio);
151-
var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, UsedAspectRatio);
152+
var originSizeChange = new Point(-diffPos.X, -diffPos.X / ActualAspectRatio);
153+
var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, ActualAspectRatio);
152154
startPoint.Y += -safeChange.Y / 2;
153155
endPoint.Y += safeChange.Y / 2;
154156
startPoint.X += -safeChange.X;
@@ -162,8 +164,8 @@ private void UpdateCroppedRect(ThumbPosition position, Point diffPos)
162164
case ThumbPosition.Right:
163165
if (KeepAspectRatio)
164166
{
165-
var originSizeChange = new Point(diffPos.X, diffPos.X / UsedAspectRatio);
166-
var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, UsedAspectRatio);
167+
var originSizeChange = new Point(diffPos.X, diffPos.X / ActualAspectRatio);
168+
var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, ActualAspectRatio);
167169
startPoint.Y += -safeChange.Y / 2;
168170
endPoint.Y += safeChange.Y / 2;
169171
endPoint.X += safeChange.X;
@@ -179,7 +181,7 @@ private void UpdateCroppedRect(ThumbPosition position, Point diffPos)
179181
{
180182
var effectiveLength = diffPos.Y / Math.Cos(diffPointRadian) * Math.Cos(diffPointRadian - radian);
181183
var originSizeChange = new Point(-effectiveLength * Math.Sin(radian), -effectiveLength * Math.Cos(radian));
182-
var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, UsedAspectRatio);
184+
var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, ActualAspectRatio);
183185
diffPos.X = -safeChange.X;
184186
diffPos.Y = -safeChange.Y;
185187
}
@@ -193,7 +195,7 @@ private void UpdateCroppedRect(ThumbPosition position, Point diffPos)
193195
diffPointRadian = -diffPointRadian;
194196
var effectiveLength = diffPos.Y / Math.Cos(diffPointRadian) * Math.Cos(diffPointRadian - radian);
195197
var originSizeChange = new Point(-effectiveLength * Math.Sin(radian), -effectiveLength * Math.Cos(radian));
196-
var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, UsedAspectRatio);
198+
var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, ActualAspectRatio);
197199
diffPos.X = safeChange.X;
198200
diffPos.Y = -safeChange.Y;
199201
}
@@ -207,7 +209,7 @@ private void UpdateCroppedRect(ThumbPosition position, Point diffPos)
207209
diffPointRadian = -diffPointRadian;
208210
var effectiveLength = diffPos.Y / Math.Cos(diffPointRadian) * Math.Cos(diffPointRadian - radian);
209211
var originSizeChange = new Point(effectiveLength * Math.Sin(radian), effectiveLength * Math.Cos(radian));
210-
var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, UsedAspectRatio);
212+
var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, ActualAspectRatio);
211213
diffPos.X = -safeChange.X;
212214
diffPos.Y = safeChange.Y;
213215
}
@@ -220,7 +222,7 @@ private void UpdateCroppedRect(ThumbPosition position, Point diffPos)
220222
{
221223
var effectiveLength = diffPos.Y / Math.Cos(diffPointRadian) * Math.Cos(diffPointRadian - radian);
222224
var originSizeChange = new Point(effectiveLength * Math.Sin(radian), effectiveLength * Math.Cos(radian));
223-
var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, UsedAspectRatio);
225+
var safeChange = GetSafeSizeChangeWhenKeepAspectRatio(_restrictedSelectRect, position, currentSelectedRect, originSizeChange, ActualAspectRatio);
224226
diffPos.X = safeChange.X;
225227
diffPos.Y = safeChange.Y;
226228
}
@@ -293,8 +295,8 @@ private void UpdateSelectedRect(Point startPoint, Point endPoint, bool animate =
293295
_startY = startPoint.Y;
294296
_endX = endPoint.X;
295297
_endY = endPoint.Y;
296-
var centerX = ((_endX - _startX) / 2) + _startX;
297-
var centerY = ((_endY - _startY) / 2) + _startY;
298+
var center = SelectionAreaCenter;
299+
298300
Storyboard storyboard = null;
299301
if (animate)
300302
{
@@ -305,12 +307,12 @@ private void UpdateSelectedRect(Point startPoint, Point endPoint, bool animate =
305307
{
306308
if (animate)
307309
{
308-
storyboard.Children.Add(CreateDoubleAnimation(centerX, _animationDuration, _topThumb, nameof(ImageCropperThumb.X), true));
310+
storyboard.Children.Add(CreateDoubleAnimation(center.X, _animationDuration, _topThumb, nameof(ImageCropperThumb.X), true));
309311
storyboard.Children.Add(CreateDoubleAnimation(_startY, _animationDuration, _topThumb, nameof(ImageCropperThumb.Y), true));
310312
}
311313
else
312314
{
313-
_topThumb.X = centerX;
315+
_topThumb.X = center.X;
314316
_topThumb.Y = _startY;
315317
}
316318
}
@@ -319,12 +321,12 @@ private void UpdateSelectedRect(Point startPoint, Point endPoint, bool animate =
319321
{
320322
if (animate)
321323
{
322-
storyboard.Children.Add(CreateDoubleAnimation(centerX, _animationDuration, _bottomThumb, nameof(ImageCropperThumb.X), true));
324+
storyboard.Children.Add(CreateDoubleAnimation(center.X, _animationDuration, _bottomThumb, nameof(ImageCropperThumb.X), true));
323325
storyboard.Children.Add(CreateDoubleAnimation(_endY, _animationDuration, _bottomThumb, nameof(ImageCropperThumb.Y), true));
324326
}
325327
else
326328
{
327-
_bottomThumb.X = centerX;
329+
_bottomThumb.X = center.X;
328330
_bottomThumb.Y = _endY;
329331
}
330332
}
@@ -334,12 +336,12 @@ private void UpdateSelectedRect(Point startPoint, Point endPoint, bool animate =
334336
if (animate)
335337
{
336338
storyboard.Children.Add(CreateDoubleAnimation(_startX, _animationDuration, _leftThumb, nameof(ImageCropperThumb.X), true));
337-
storyboard.Children.Add(CreateDoubleAnimation(centerY, _animationDuration, _leftThumb, nameof(ImageCropperThumb.Y), true));
339+
storyboard.Children.Add(CreateDoubleAnimation(center.Y, _animationDuration, _leftThumb, nameof(ImageCropperThumb.Y), true));
338340
}
339341
else
340342
{
341343
_leftThumb.X = _startX;
342-
_leftThumb.Y = centerY;
344+
_leftThumb.Y = center.Y;
343345
}
344346
}
345347

@@ -348,12 +350,12 @@ private void UpdateSelectedRect(Point startPoint, Point endPoint, bool animate =
348350
if (animate)
349351
{
350352
storyboard.Children.Add(CreateDoubleAnimation(_endX, _animationDuration, _rightThumb, nameof(ImageCropperThumb.X), true));
351-
storyboard.Children.Add(CreateDoubleAnimation(centerY, _animationDuration, _rightThumb, nameof(ImageCropperThumb.Y), true));
353+
storyboard.Children.Add(CreateDoubleAnimation(center.Y, _animationDuration, _rightThumb, nameof(ImageCropperThumb.Y), true));
352354
}
353355
else
354356
{
355357
_rightThumb.X = _endX;
356-
_rightThumb.Y = centerY;
358+
_rightThumb.Y = center.Y;
357359
}
358360
}
359361

@@ -504,61 +506,74 @@ private void UpdateMaskArea(bool animate = false)
504506
};
505507
}
506508

509+
private bool ShouldUpdateAspectRatio => KeepAspectRatio && Source != null && IsValidRect(_restrictedSelectRect);
510+
507511
/// <summary>
508512
/// Update image aspect ratio.
509513
/// </summary>
510514
private void UpdateAspectRatio(bool animate = false)
511515
{
512-
if (KeepAspectRatio && Source != null && IsValidRect(_restrictedSelectRect))
513-
{
514-
var centerX = ((_endX - _startX) / 2) + _startX;
515-
var centerY = ((_endY - _startY) / 2) + _startY;
516-
var restrictedMinLength = MinCroppedPixelLength * _imageTransform.ScaleX;
517-
var maxSelectedLength = Math.Max(_endX - _startX, _endY - _startY);
518-
var viewRect = new Rect(centerX - (maxSelectedLength / 2), centerY - (maxSelectedLength / 2), maxSelectedLength, maxSelectedLength);
519-
var uniformSelectedRect = GetUniformRect(viewRect, UsedAspectRatio);
520-
if (uniformSelectedRect.Width > _restrictedSelectRect.Width || uniformSelectedRect.Height > _restrictedSelectRect.Height)
521-
{
522-
uniformSelectedRect = GetUniformRect(_restrictedSelectRect, UsedAspectRatio);
523-
}
516+
if (!ShouldUpdateAspectRatio)
517+
{
518+
return;
519+
}
524520

525-
if (uniformSelectedRect.Width < restrictedMinLength || uniformSelectedRect.Height < restrictedMinLength)
526-
{
527-
var scale = restrictedMinLength / Math.Min(uniformSelectedRect.Width, uniformSelectedRect.Height);
528-
uniformSelectedRect.Width *= scale;
529-
uniformSelectedRect.Height *= scale;
530-
if (uniformSelectedRect.Width > _restrictedSelectRect.Width || uniformSelectedRect.Height > _restrictedSelectRect.Height)
531-
{
532-
AspectRatio = -1;
533-
return;
534-
}
535-
}
521+
var center = SelectionAreaCenter;
522+
var restrictedMinLength = MinCroppedPixelLength * _imageTransform.ScaleX;
523+
var maxSelectedLength = Math.Max(_endX - _startX, _endY - _startY);
524+
var viewRect = new Rect(center.X - (maxSelectedLength / 2), center.Y - (maxSelectedLength / 2), maxSelectedLength, maxSelectedLength);
536525

537-
if (_restrictedSelectRect.X > uniformSelectedRect.X)
538-
{
539-
uniformSelectedRect.X += _restrictedSelectRect.X - uniformSelectedRect.X;
540-
}
526+
var uniformSelectedRect = GetUniformRect(viewRect, ActualAspectRatio);
527+
if (uniformSelectedRect.Width > _restrictedSelectRect.Width || uniformSelectedRect.Height > _restrictedSelectRect.Height)
528+
{
529+
uniformSelectedRect = GetUniformRect(_restrictedSelectRect, ActualAspectRatio);
530+
}
541531

542-
if (_restrictedSelectRect.Y > uniformSelectedRect.Y)
543-
{
544-
uniformSelectedRect.Y += _restrictedSelectRect.Y - uniformSelectedRect.Y;
545-
}
532+
// If selection area is smaller than allowed.
533+
if (uniformSelectedRect.Width < restrictedMinLength || uniformSelectedRect.Height < restrictedMinLength)
534+
{
535+
// Scale selection area to fit.
536+
var scale = restrictedMinLength / Math.Min(uniformSelectedRect.Width, uniformSelectedRect.Height);
537+
uniformSelectedRect.Width *= scale;
538+
uniformSelectedRect.Height *= scale;
546539

547-
if ((_restrictedSelectRect.X + _restrictedSelectRect.Width) < (uniformSelectedRect.X + uniformSelectedRect.Width))
540+
// If selection area is larger than allowed.
541+
if (uniformSelectedRect.Width > _restrictedSelectRect.Width || uniformSelectedRect.Height > _restrictedSelectRect.Height)
548542
{
549-
uniformSelectedRect.X += (_restrictedSelectRect.X + _restrictedSelectRect.Width) - (uniformSelectedRect.X + uniformSelectedRect.Width);
543+
// Sentinal value. Equivelant to setting KeepAspectRatio to false. Causes AspectRatio to be recalculated.
544+
AspectRatio = -1;
545+
return;
550546
}
547+
}
551548

552-
if ((_restrictedSelectRect.Y + _restrictedSelectRect.Height) < (uniformSelectedRect.Y + uniformSelectedRect.Height))
553-
{
554-
uniformSelectedRect.Y += (_restrictedSelectRect.Y + _restrictedSelectRect.Height) - (uniformSelectedRect.Y + uniformSelectedRect.Height);
555-
}
549+
// Fix positioning
550+
if (_restrictedSelectRect.X > uniformSelectedRect.X)
551+
{
552+
uniformSelectedRect.X += _restrictedSelectRect.X - uniformSelectedRect.X;
553+
}
556554

557-
var croppedRect = _inverseImageTransform.TransformBounds(uniformSelectedRect);
558-
croppedRect.Intersect(_restrictedCropRect);
559-
_currentCroppedRect = croppedRect;
560-
UpdateImageLayout(animate);
555+
if (_restrictedSelectRect.Y > uniformSelectedRect.Y)
556+
{
557+
uniformSelectedRect.Y += _restrictedSelectRect.Y - uniformSelectedRect.Y;
561558
}
559+
560+
// Fix size
561+
if ((_restrictedSelectRect.X + _restrictedSelectRect.Width) < (uniformSelectedRect.X + uniformSelectedRect.Width))
562+
{
563+
uniformSelectedRect.X += (_restrictedSelectRect.X + _restrictedSelectRect.Width) - (uniformSelectedRect.X + uniformSelectedRect.Width);
564+
}
565+
566+
if ((_restrictedSelectRect.Y + _restrictedSelectRect.Height) < (uniformSelectedRect.Y + uniformSelectedRect.Height))
567+
{
568+
uniformSelectedRect.Y += (_restrictedSelectRect.Y + _restrictedSelectRect.Height) - (uniformSelectedRect.Y + uniformSelectedRect.Height);
569+
}
570+
571+
// Apply transformation
572+
var croppedRect = _inverseImageTransform.TransformBounds(uniformSelectedRect);
573+
croppedRect.Intersect(_restrictedCropRect);
574+
_currentCroppedRect = croppedRect;
575+
576+
UpdateImageLayout(animate);
562577
}
563578

564579
/// <summary>
@@ -632,5 +647,10 @@ private void UpdateThumbsVisibility()
632647
_lowerRigthThumb.Visibility = cornerThumbsVisibility;
633648
}
634649
}
650+
651+
/// <summary>
652+
/// Gets a value that indicates the center of the visible selection rectangle.
653+
/// </summary>
654+
private Point SelectionAreaCenter => new Point(((_endX - _startX) / 2) + _startX, ((_endY - _startY) / 2) + _startY);
635655
}
636656
}

0 commit comments

Comments
 (0)