对象旋转后,对象比例无法正常工作:UWP

时间:2019-12-11 13:39:40

标签: c# .net .net-core uwp uwp-xaml

我有一个无法解决的问题。我有一个用户控制刻度并旋转。 比例尺工作正常,但是当我旋转对象时,比例尺无法正常工作。 enter image description here

enter image description here

这是XAML

    <Border Name="rectangle1" Background="Blue"
         Width="200" Height="200" RenderTransformOrigin="0.5,0.5">
        <Border.RenderTransform>
            <RotateTransform x:Name="image_rotate"/>
        </Border.RenderTransform>  
    </Border>
</Canvas>

这是C#

public MainPage()
    {
        InitializeComponent();
    }

    private enum HitType
    {
        None, Body, UL, UR, LR, LL, L, R, T, B
    };

    // True if a drag is in progress.
    private bool DragInProgress = false;

    // The drag's last point.
    private Point LastPoint;

    // The part of the rectangle under the mouse.
    HitType MouseHitType = HitType.None;
    private bool isRotate = false;

    // Return a HitType value to indicate what is at the point.
    private HitType SetHitType(Border rect, Point point)
    {
        double left = Canvas.GetLeft(rect);
        double top = Canvas.GetTop(rect);
        double right = left + rect.Width;
        double bottom = top + rect.Height;
        if (point.X < left) return HitType.None;
        if (point.X > right) return HitType.None;
        if (point.Y < top) return HitType.None;
        if (point.Y > bottom) return HitType.None;

        const double GAP = 10;
        if (point.X - left < GAP)
        {
            // Left edge.
            if (point.Y - top < GAP) return HitType.UL;
            if (bottom - point.Y < GAP) return HitType.LL;
            return HitType.L;
        }
        if (right - point.X < GAP)
        {
            // Right edge.
            if (point.Y - top < GAP) return HitType.UR;
            if (bottom - point.Y < GAP) return HitType.LR;
            return HitType.R;
        }
        if (point.Y - top < GAP) return HitType.T;
        if (bottom - point.Y < GAP) return HitType.B;
        return HitType.Body;
    }

    // Set a mouse cursor appropriate for the current hit type.
    private void SetMouseCursor()
    {
        // See what cursor we should display.
        Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.Arrow, 0);
        switch (MouseHitType)
        {
            case HitType.None:
                Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.Arrow, 0);
                break;
            case HitType.Body:
                Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.Hand, 0);
                break;
            case HitType.UL:
            case HitType.LR:
                Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.SizeNorthwestSoutheast, 0);
                break;
            case HitType.LL:
            case HitType.UR:
                Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.SizeNortheastSouthwest, 0);
                break;
            case HitType.T:
            case HitType.B:
                Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.SizeNorthSouth, 0);
                break;
            case HitType.L:
            case HitType.R:
                Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.SizeWestEast, 0);
                break;
        }
    }

    // Start dragging.
    private void canvas1_MouseDown(object sender, PointerRoutedEventArgs e)
    {
        isRotate = false;
        var position = e.GetCurrentPoint(canvas1);
        MouseHitType = SetHitType(rectangle1, position.Position);
        SetMouseCursor();
        DragInProgress = true;
        if (MouseHitType == HitType.None)
        {
            //var Pos = e.GetCurrentPoint(canvas1);   
            //double dx = Pos.Position.X - ImageCenter.X;
            //double dy = Pos.Position.Y - ImageCenter.Y;
            isRotate = true;
            //StartAngle = (float)Math.Atan2(dy, dx);
            //return;

        }
        var lastPos = e.GetCurrentPoint(canvas1);
        LastPoint = lastPos.Position;

    }



    // If a drag is in progress, continue the drag.
    // Otherwise display the correct cursor.
    private void canvas1_MouseMove(object sender, PointerRoutedEventArgs e)
    {
        var position = e.GetCurrentPoint(canvas1);
        if (!DragInProgress)
        {
            MouseHitType = SetHitType(rectangle1, position.Position);
            SetMouseCursor();

        }
        else
        {
            // See how much the mouse has moved.
            Point point = position.Position;
            double offset_x = point.X - LastPoint.X;
            double offset_y = point.Y - LastPoint.Y;

            // Get the rectangle's current position.
            double new_x = Canvas.GetLeft(rectangle1);
            double new_y = Canvas.GetTop(rectangle1);
            double new_width = rectangle1.Width;
            double new_height = rectangle1.Height;

            // Update the rectangle.
            switch (MouseHitType)
            {
                case HitType.Body:
                    new_x += offset_x;
                    new_y += offset_y;
                    break;
                case HitType.UL:
                    new_x += offset_x;
                    new_y += offset_y;
                    new_width -= offset_x;
                    new_height -= offset_y;
                    break;
                case HitType.UR:
                    new_y += offset_y;
                    new_width += offset_x;
                    new_height -= offset_y;
                    break;
                case HitType.LR:
                    new_width += offset_x;
                    new_height += offset_y;
                    break;
                case HitType.LL:
                    new_x += offset_x;
                    new_width -= offset_x;
                    new_height += offset_y;
                    break;
                case HitType.L:
                    new_x += offset_x;
                    new_width -= offset_x;
                    break;
                case HitType.R:
                    new_width += offset_x;
                    break;
                case HitType.B:
                    new_height += offset_y;
                    break;
                case HitType.T:
                    new_y += offset_y;
                    new_height -= offset_y;
                    break;
            }

            // Don't use negative width or height.
            if ((new_width > 0) && (new_height > 0))
            {
                // Update the rectangle.
                Canvas.SetLeft(rectangle1, new_x);
                Canvas.SetTop(rectangle1, new_y);
                rectangle1.Width = new_width;
                rectangle1.Height = new_height;

                // Save the mouse's new location.
                LastPoint = point;
            }
        }
    }

    // Stop dragging.
    private void canvas1_MouseUp(object sender, PointerRoutedEventArgs e)
    {
        isRotate = false;
        DragInProgress = false;
    }

    private void canvas1_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
    {
        if (isRotate)
        {
            image_rotate.Angle += e.Delta.Translation.X;
        }
    }
}

如图所示,当对象未旋转时,光标位于缩放的正确位置,但是当我旋转对象时,缩放的光标位置未更改,而是从两侧缩放。 如果您有任何建议,请告诉我。 谢谢!!!

1 个答案:

答案 0 :(得分:1)

问题是转换的起源。

旋转时,矩形的中心已更改,如下所示:

Imgur

更新

执行RenderTransform时,对元素的影响只是视觉上的。不会影响元素的实际位置。

在旋转的情况下,您的SetHitType方法无法确定倾斜的边缘。

计算斜边非常困难,我的建议是可以添加9个辅助点:

Imgur

仅当指针移至相应点时才会触发更改,这可以简化我们遇到的问题。

最诚挚的问候。