/// <summary>
        /// Update cropped area.
        /// </summary>
        /// <param name="dragPosition">The control point</param>
        /// <param name="diffPos">Position offset</param>
        private void UpdateCroppedRectWithAspectRatio(DragPosition dragPosition, Point diffPos)
        {
            if (diffPos == default(Point) || !CanvasRect.IsValid())
            {
                return;
            }

            double radian = 0d, diffPointRadian = 0d, effectiveLength = 0d;

            if (KeepAspectRatio)
            {
                radian          = Math.Atan(UsedAspectRatio);
                diffPointRadian = Math.Atan(diffPos.X / diffPos.Y);
            }

            var startPoint          = new Point(_startX, _startY);
            var endPoint            = new Point(_endX, _endY);
            var currentSelectedRect = new Rect(startPoint, endPoint);

            switch (dragPosition)
            {
            case DragPosition.Top:
                if (KeepAspectRatio)
                {
                    var originSizeChange = new Point(-diffPos.Y * UsedAspectRatio, -diffPos.Y);
                    var safeChange       = _restrictedSelectRect.GetSafeSizeChangeWhenKeepAspectRatio(dragPosition, currentSelectedRect, originSizeChange, UsedAspectRatio);
                    startPoint.X += -safeChange.X / 2;
                    endPoint.X   -= -safeChange.X / 2;
                    startPoint.Y += -safeChange.Y;
                }
                else
                {
                    startPoint.Y += diffPos.Y;
                }

                break;

            case DragPosition.Bottom:
                if (KeepAspectRatio)
                {
                    var originSizeChange = new Point(diffPos.Y * UsedAspectRatio, diffPos.Y);
                    var safeChange       = _restrictedSelectRect.GetSafeSizeChangeWhenKeepAspectRatio(dragPosition, currentSelectedRect, originSizeChange, UsedAspectRatio);
                    startPoint.X -= safeChange.X / 2;
                    endPoint.X   += safeChange.X / 2;
                    endPoint.Y   += safeChange.Y;
                }
                else
                {
                    endPoint.Y += diffPos.Y;
                }

                break;

            case DragPosition.Left:
                if (KeepAspectRatio)
                {
                    var originSizeChange = new Point(-diffPos.X, -diffPos.X / UsedAspectRatio);
                    var safeChange       = _restrictedSelectRect.GetSafeSizeChangeWhenKeepAspectRatio(dragPosition, currentSelectedRect, originSizeChange, UsedAspectRatio);
                    startPoint.Y += -safeChange.Y / 2;
                    endPoint.Y   -= -safeChange.Y / 2;
                    startPoint.X += -safeChange.X;
                }
                else
                {
                    startPoint.X += diffPos.X;
                }

                break;

            case DragPosition.Right:
                if (KeepAspectRatio)
                {
                    var originSizeChange = new Point(diffPos.X, diffPos.X / UsedAspectRatio);
                    var safeChange       = _restrictedSelectRect.GetSafeSizeChangeWhenKeepAspectRatio(dragPosition, currentSelectedRect, originSizeChange, UsedAspectRatio);
                    startPoint.Y -= safeChange.Y / 2;
                    endPoint.Y   += safeChange.Y / 2;
                    endPoint.X   += safeChange.X;
                }
                else
                {
                    endPoint.X += diffPos.X;
                }

                break;

            case DragPosition.UpperLeft:
                if (KeepAspectRatio)
                {
                    effectiveLength = diffPos.Y / Math.Cos(diffPointRadian) * Math.Cos(diffPointRadian - radian);
                    var originSizeChange = new Point(-effectiveLength * Math.Sin(radian), -effectiveLength * Math.Cos(radian));
                    var safeChange       = _restrictedSelectRect.GetSafeSizeChangeWhenKeepAspectRatio(dragPosition, currentSelectedRect, originSizeChange, UsedAspectRatio);
                    diffPos.X = -safeChange.X;
                    diffPos.Y = -safeChange.Y;
                }

                startPoint.X += diffPos.X;
                startPoint.Y += diffPos.Y;
                break;

            case DragPosition.UpperRight:
                if (KeepAspectRatio)
                {
                    diffPointRadian = -diffPointRadian;
                    effectiveLength = diffPos.Y / Math.Cos(diffPointRadian) * Math.Cos(diffPointRadian - radian);
                    var originSizeChange = new Point(-effectiveLength * Math.Sin(radian), -effectiveLength * Math.Cos(radian));
                    var safeChange       = _restrictedSelectRect.GetSafeSizeChangeWhenKeepAspectRatio(dragPosition, currentSelectedRect, originSizeChange, UsedAspectRatio);
                    diffPos.X = safeChange.X;
                    diffPos.Y = -safeChange.Y;
                }

                endPoint.X   += diffPos.X;
                startPoint.Y += diffPos.Y;
                break;

            case DragPosition.LowerLeft:
                if (KeepAspectRatio)
                {
                    diffPointRadian = -diffPointRadian;
                    effectiveLength = diffPos.Y / Math.Cos(diffPointRadian) * Math.Cos(diffPointRadian - radian);
                    var originSizeChange = new Point(effectiveLength * Math.Sin(radian), effectiveLength * Math.Cos(radian));
                    var safeChange       = _restrictedSelectRect.GetSafeSizeChangeWhenKeepAspectRatio(dragPosition, currentSelectedRect, originSizeChange, UsedAspectRatio);
                    diffPos.X = -safeChange.X;
                    diffPos.Y = safeChange.Y;
                }

                startPoint.X += diffPos.X;
                endPoint.Y   += diffPos.Y;
                break;

            case DragPosition.LowerRight:
                if (KeepAspectRatio)
                {
                    effectiveLength = diffPos.Y / Math.Cos(diffPointRadian) * Math.Cos(diffPointRadian - radian);
                    var originSizeChange = new Point(effectiveLength * Math.Sin(radian), effectiveLength * Math.Cos(radian));
                    var safeChange       = _restrictedSelectRect.GetSafeSizeChangeWhenKeepAspectRatio(dragPosition, currentSelectedRect, originSizeChange, UsedAspectRatio);
                    diffPos.X = safeChange.X;
                    diffPos.Y = safeChange.Y;
                }

                endPoint.X += diffPos.X;
                endPoint.Y += diffPos.Y;
                break;
            }

            if (!RectExtensions.IsSafeRect(startPoint, endPoint, MinSelectSize))
            {
                if (KeepAspectRatio)
                {
                    if ((endPoint.Y - startPoint.Y) < (_endY - _startY) ||
                        (endPoint.X - startPoint.X) < (_endX - _startX))
                    {
                        return;
                    }
                }
                else
                {
                    var safeRect = RectExtensions.GetSafeRect(startPoint, endPoint, MinSelectSize, dragPosition);
                    safeRect.Intersect(_restrictedSelectRect);
                    startPoint = new Point(safeRect.X, safeRect.Y);
                    endPoint   = new Point(safeRect.X + safeRect.Width, safeRect.Y + safeRect.Height);
                }
            }

            var isEffectiveRegion = _restrictedSelectRect.IsSafePoint(startPoint) &&
                                    _restrictedSelectRect.IsSafePoint(endPoint);
            var selectedRect = new Rect(startPoint, endPoint);

            if (!isEffectiveRegion)
            {
                if (_restrictedSelectRect.GetContainsRect(ref selectedRect))
                {
                    startPoint = new Point(selectedRect.Left, selectedRect.Top);
                    endPoint   = new Point(selectedRect.Right, selectedRect.Bottom);
                }
                else
                {
                    return;
                }
            }
            selectedRect.Union(CanvasRect);
            if (selectedRect != CanvasRect)
            {
                var croppedRect = _inverseImageTransform.TransformBounds(
                    new Rect(startPoint, endPoint));
                croppedRect.Intersect(_restrictedCropRect);
                _currentCroppedRect = croppedRect;
                var viewportRect    = CanvasRect.GetUniformRect(selectedRect.Width / selectedRect.Height);
                var viewportImgRect = _inverseImageTransform.TransformBounds(selectedRect);
                UpdateImageLayoutWithViewport(viewportRect, viewportImgRect);
            }
            else
            {
                UpdateSelectedRect(startPoint, endPoint);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Update cropped area.
        /// </summary>
        /// <param name="dragPosition">The control point</param>
        /// <param name="diffPos">Position offset</param>
        private void UpdateCroppedRectWithAspectRatio(DragPosition dragPosition, Point diffPos)
        {
            double radian = 0d, diffPointRadian = 0d, effectiveLength = 0d;

            if (KeepAspectRatio)
            {
                radian          = Math.Atan(UsedAspectRatio);
                diffPointRadian = Math.Atan(diffPos.X / diffPos.Y);
            }

            var startPoint = new Point(_startX, _startY);
            var endPoint   = new Point(_endX, _endY);

            switch (dragPosition)
            {
            case DragPosition.Top:
                startPoint.Y += diffPos.Y;
                if (KeepAspectRatio)
                {
                    var changeX = diffPos.Y * UsedAspectRatio;
                    startPoint.X += changeX / 2;
                    endPoint.X   -= changeX / 2;
                }

                break;

            case DragPosition.Bottom:
                endPoint.Y += diffPos.Y;
                if (KeepAspectRatio)
                {
                    var changeX = diffPos.Y * UsedAspectRatio;
                    startPoint.X -= changeX / 2;
                    endPoint.X   += changeX / 2;
                }

                break;

            case DragPosition.Left:
                startPoint.X += diffPos.X;
                if (KeepAspectRatio)
                {
                    var changeY = diffPos.X / UsedAspectRatio;
                    startPoint.Y += changeY / 2;
                    endPoint.Y   -= changeY / 2;
                }

                break;

            case DragPosition.Right:
                endPoint.X += diffPos.X;
                if (KeepAspectRatio)
                {
                    var changeY = diffPos.X / UsedAspectRatio;
                    startPoint.Y -= changeY / 2;
                    endPoint.Y   += changeY / 2;
                }

                break;

            case DragPosition.UpperLeft:
                if (KeepAspectRatio)
                {
                    effectiveLength = diffPos.Y / Math.Cos(diffPointRadian) * Math.Cos(diffPointRadian - radian);
                    diffPos.X       = effectiveLength * Math.Sin(radian);
                    diffPos.Y       = effectiveLength * Math.Cos(radian);
                }

                startPoint.X += diffPos.X;
                startPoint.Y += diffPos.Y;
                break;

            case DragPosition.UpperRight:
                if (KeepAspectRatio)
                {
                    diffPointRadian = -diffPointRadian;
                    effectiveLength = diffPos.Y / Math.Cos(diffPointRadian) * Math.Cos(diffPointRadian - radian);
                    diffPos.X       = -effectiveLength *Math.Sin(radian);

                    diffPos.Y = effectiveLength * Math.Cos(radian);
                }

                endPoint.X   += diffPos.X;
                startPoint.Y += diffPos.Y;
                break;

            case DragPosition.LowerLeft:
                if (KeepAspectRatio)
                {
                    diffPointRadian = -diffPointRadian;
                    effectiveLength = diffPos.Y / Math.Cos(diffPointRadian) * Math.Cos(diffPointRadian - radian);
                    diffPos.X       = -effectiveLength *Math.Sin(radian);

                    diffPos.Y = effectiveLength * Math.Cos(radian);
                }

                startPoint.X += diffPos.X;
                endPoint.Y   += diffPos.Y;
                break;

            case DragPosition.LowerRight:
                if (KeepAspectRatio)
                {
                    effectiveLength = diffPos.Y / Math.Cos(diffPointRadian) * Math.Cos(diffPointRadian - radian);
                    diffPos.X       = effectiveLength * Math.Sin(radian);
                    diffPos.Y       = effectiveLength * Math.Cos(radian);
                }

                endPoint.X += diffPos.X;
                endPoint.Y += diffPos.Y;
                break;
            }

            if (!RectExtensions.IsSafeRect(startPoint, endPoint, MinSelectSize))
            {
                if (KeepAspectRatio)
                {
                    if ((endPoint.Y - startPoint.Y) < (_endY - _startY) ||
                        (endPoint.X - startPoint.X) < (_endX - _startX))
                    {
                        return;
                    }
                }
                else
                {
                    var safeRect = RectExtensions.GetSafeRect(startPoint, endPoint, MinSelectSize, dragPosition);
                    safeRect.Intersect(_restrictedSelectRect);
                    startPoint = new Point(safeRect.X, safeRect.Y);
                    endPoint   = new Point(safeRect.X + safeRect.Width, safeRect.Y + safeRect.Height);
                }
            }

            var isEffectiveRegion = _restrictedSelectRect.IsSafePoint(startPoint) &&
                                    _restrictedSelectRect.IsSafePoint(endPoint);

            if (!isEffectiveRegion)
            {
                return;
            }
            var selectedRect = new Rect(startPoint, endPoint);

            selectedRect.Union(CanvasRect);
            if (selectedRect != CanvasRect)
            {
                var inverseImageTransform = _imageTransform.Inverse;
                if (inverseImageTransform == null)
                {
                    return;
                }
                var croppedRect = inverseImageTransform.TransformBounds(
                    new Rect(startPoint, endPoint));
                croppedRect.Intersect(_restrictedCropRect);
                _currentCroppedRect = croppedRect;
                var viewportRect    = CanvasRect.GetUniformRect(selectedRect.Width / selectedRect.Height);
                var viewportImgRect = inverseImageTransform.TransformBounds(selectedRect);
                UpdateImageLayoutWithViewport(viewportRect, viewportImgRect);
            }
            else
            {
                UpdateSelectedRect(startPoint, endPoint);
            }
        }