响应操纵三角洲 - 奇怪的效果和溢出

时间:2016-07-04 14:47:23

标签: touch uwp

在测试UWP表单中,我有一个基本的操作测试,代码如下。它在CanvasControl上绘制3个圆圈,并设置平移和缩放操作。

当我在触摸屏上测试它时,它基本上完成了我的预期,根据屏幕上2个手指的位置来平移和缩放圆圈。但是,如果我捏了一下超过某一点,图像开始在两个范围之间非常快地振荡,并且会很快导致代码因溢出而停止。

我将画布控件放在网格中并尝试​​从网格控件对画布控件进行操作,虽然缩放和平移的效果看起来不正确,但它不会遇到同样的问题。

所以看起来像我的代码的效果,是一个迭代,其中导致渲染转换更改的操作可能导致另一个操作,并且它进入圆圈直到它结算 - 或者如果存在精度问题,也许是由于触摸点之间的距离太小,迭代会发散直到溢出。

这是预期的吗?这样做的正确方法是什么?

Private WithEvents Canv As New CanvasControl
Private WithEvents gr As New Grid


Private Sub Canv_Draw(sender As CanvasControl, args As CanvasDrawEventArgs) Handles Canv.Draw
    args.DrawingSession.DrawCircle(50, 50, 25, Windows.UI.Colors.Blue)
    args.DrawingSession.DrawCircle(250, 250, 25, Windows.UI.Colors.Blue)
    args.DrawingSession.DrawCircle(500, 500, 25, Windows.UI.Colors.Blue)
End Sub

Public Sub New()

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.

    Content = gr
    gr.Children.Add(Canv)


    Canv.ManipulationMode = ManipulationModes.Scale Or ManipulationModes.TranslateX Or ManipulationModes.TranslateY

end sub


Private Sub Canv_ManipulationDelta(sender As Object, e As ManipulationDeltaRoutedEventArgs) Handles Canv.ManipulationDelta
    Dim t As New TranslateTransform

    t.X = e.Cumulative.Translation.X
    t.Y = e.Cumulative.Translation.Y


    Dim s As New ScaleTransform
    s.ScaleX = e.Cumulative.Scale
    s.ScaleY = e.Cumulative.Scale
    s.CenterX = e.Position.X
    s.CenterY = e.Position.Y

    Dim g As New TransformGroup
    g.Children.Add(s)
    g.Children.Add(t)

    Canv.RenderTransform = g



End Sub

2 个答案:

答案 0 :(得分:0)

UWP的常用方法是使用CompositeTransform,它支持缩放,偏斜,旋转和翻译

请参阅BasicInput示例,尤其是the forth scenario

对于缩放问题,您可以通过以下方式避免它:

Public NotInheritable Class MainPage
Inherits Page

Private WithEvents Canv As New CanvasControl
Private WithEvents gr As New Grid

Private Sub Canv_Draw(sender As CanvasControl, args As CanvasDrawEventArgs) Handles Canv.Draw
    args.DrawingSession.DrawCircle(50, 50, 25, Windows.UI.Colors.Blue)
    args.DrawingSession.DrawCircle(250, 250, 25, Windows.UI.Colors.Blue)
    args.DrawingSession.DrawCircle(500, 500, 25, Windows.UI.Colors.Blue)
End Sub

Public Sub New()

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.

    Content = gr
    gr.Children.Add(Canv)

    Canv.ManipulationMode = ManipulationModes.Scale Or ManipulationModes.TranslateX Or ManipulationModes.TranslateY

End Sub

Private Sub Canv_ManipulationDelta(sender As Object, e As ManipulationDeltaRoutedEventArgs) Handles Canv.ManipulationDelta
    Dim tran = Transform(sender)
    tran.ScaleX = tran.ScaleX * e.Delta.Scale
    tran.ScaleY = tran.ScaleY * e.Delta.Scale
    'System.Diagnostics.Debug.WriteLine("tran.ScaleX =" + tran.ScaleX.ToString() + " tran.ScaleY =" + tran.ScaleY.ToString())
End Sub

Private Function Transform(sender As Object) As CompositeTransform
    Dim rect = TryCast(sender, CanvasControl)
    rect.RenderTransformOrigin = New Point(0.5, 0.5)
    Dim tran As New CompositeTransform
    If TryCast(rect.RenderTransform, CompositeTransform) IsNot Nothing Then
        tran = DirectCast(rect.RenderTransform, CompositeTransform)
    Else
        rect.RenderTransform = New CompositeTransform()
    End If
    Return tran
End Function

' utility method
Private Function Boundary(value As Double, min As Double, max As Double) As Double
    If value > max Then
        Return max
    ElseIf value < min Then
        Return min
    Else
        Return value
    End If
End Function
End Class

<强>截图: Gif

答案 1 :(得分:0)

其中一些有用的信息,与此同时我发现了一个整洁的解决方案,即将CanvasControl留在网格中,并从网格中获取操作事件并更改Canvas控件的rendertransform,这样就没有了递归。这也意味着自然翻译是不正确的 - 但这很容易通过乘以累积尺度来解决,即。完整的操作代码变为:

Private Sub GerberCanvGrid_ManipulationDelta(sender As Object, e As ManipulationDeltaRoutedEventArgs) Handles GerberCanvGrid.ManipulationDelta
    Dim sf As New ScaleTransform
    sf.ScaleX = e.Cumulative.Scale
    sf.ScaleY = e.Cumulative.Scale
    sf.CenterX = e.Position.X
    sf.CenterY = e.Position.Y

    Dim tt As New TranslateTransform
    tt.X = e.Cumulative.Translation.X * e.Cumulative.Scale
    tt.Y = e.Cumulative.Translation.Y * e.Cumulative.Scale

    ManipulationTransform = New TransformGroup
    ManipulationTransform.Children.Add(sf)
    ManipulationTransform.Children.Add(tt)
    GerberCanv.RenderTransform = ManipulationTransform
End Sub