2016-07-04 5 views
0

In einem Test-UWP-Formular habe ich einen grundlegenden Manipulationstest, Code unten. Er zeichnet 3 Kreise auf einem CanvasControl und richtet Manipulationen für die Übersetzung und Skalierung ein.Reagieren auf Manipulationsdelta - merkwürdiger Effekt und Überlauf

Wenn ich dies auf einem Touchscreen teste, mache ich grundsätzlich das, was ich erwarte, indem ich die Kreise basierend auf der Position von 2 Fingern auf dem Bildschirm übersetze und zoome. Wenn ich jedoch einen bestimmten Punkt abschneide, beginnt das Bild sehr schnell zwischen 2 Extents zu oszillieren und wird sehr schnell dazu führen, dass der Code mit einem Überlauf stoppt.

Ich legte die Canvas-Steuerelement in ein Raster und versuchte, die Manipulation auf der Leinwand Steuerung aus dem Raster-Steuerelement, und es leidet nicht an dem gleichen Problem, obwohl die Auswirkungen von Zoom und Schwenken scheint nicht korrekt.

So sieht der Effekt meines Codes aus, wie es ist, ist eine Iteration, wo eine Manipulation, die eine Rendertransformationsänderung verursacht, eine andere Manipulation verursachen kann und in Kreisen verläuft, bis sie sich einstellt - oder wenn ein Genauigkeitsproblem vorliegt , vielleicht weil der Abstand zwischen den Berührungspunkten zu klein wird, divergiert die Iteration bis zum Überlauf.

Wird das erwartet? Was ist der richtige Weg, dies zu tun?

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 

Antwort

0

Der gemeinsame Weg in UWP ist CompositeTransform zu verwenden, unterstützt es Maßstab, Skew, Drehen und Übersetzen.

Bitte beachten Sie die BasicInput Probe, insbesondere the forth scenario

Für die Zoom-Ausgabe, können Sie es mithilfe der folgenden Art und Weise vermeiden:

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 

Screenshot: Gif

0

einige nützliche Informationen darin fand ich in der Zwischenzeit eine ordentliche Lösung, die CanvasControl im Raster zu belassen und die Manipulation zu übernehmen Ereignisse aus dem Grid und ändern Sie die Rendertransform des Canvas-Steuerelements, auf diese Weise gibt es keine Rekursion. Es bedeutet auch, dass die natürliche Übersetzung nicht korrekt ist - aber das ist leicht zu beheben, indem man sie mit der kumulativen Skala multipliziert, d. Der vollständige Manipulationscode lautet:

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