2017-02-24 9 views
0

Ich möchte, dass ein Benutzersteuerelement durch Gesten bewegt/skaliert/gedreht wird, und ich möchte, dass die Drehung und Skalierung ihren Mittelpunkt in der Mitte der Geste hat (z. B. wenn zwei Finger verwendet werden) drehen, der Punkt zwischen den Fingern sollte das Zentrum der Rotation sein).Drehen/Skalieren um Punkt der Geste

Wenn ich nicht versuche, einen Mittelpunkt für Rotation/Skalierung festzulegen oder einen statischen Punkt festzulegen, funktioniert alles wie erwartet. Wenn Sie CompositeTransform.CenterX/Y auf die Werte von ManipulationDeltaRoutedEventArgs.Position setzen, rotiert das Benutzersteuerelement mit Mittelpunktspunkten, die bei jeder Geste falscher werden und gelegentlich schneller werden.

Ich bin mit einer CompositeTransform als die Kontrolle über meinen Benutzer verwandeln machen und ich habe wie so an dem Manipulation-Ereignis angeschlossen:

private void UserControl_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e) 
    { 
     //this.transform is my composite transform 
     //which is set to be the render transform of the user control 
     this.transform.CenterX = e.Position.X; 
     this.transform.CenterY = e.Position.Y; 
     this.transform.ScaleX *= e.Delta.Scale; 
     this.transform.ScaleY *= e.Delta.Scale; 
     this.transform.Rotation += e.Delta.Rotation; 
     this.transform.TranslateX += e.Delta.Translation.X; 
     this.transform.TranslateY += e.Delta.Translation.Y; 
    } 

Es scheint, dass e.Position mich nicht geben was ich will, und leider ist die Dokumentation sehr kurz, nur unter Angabe Gets the point from which the manipulation originated. Von meinen Debug-Drucke scheint es, dass sowohl CompositeTransform.CenterX/Y und ManipulationDeltaRoutedEventArgs.Position im Koordinatensystem des Benutzersteuerelements sind.

Antwort

1

Das Problem stellte sich heraus, dass CompositeTransform nur einen Mittelpunkt verarbeiten kann. Wenn sich der Mittelpunkt änderte, änderte er sich daher rückwirkend auch für alle vorherigen Transformationen. Die Lösung besteht darin, eine TransformGroup zu verwenden und individuelle Transformationen mit ihren eigenen Mittelpunkten zu erstellen:

private void UserControl_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e) 
    { 
     var localCoords = e.Position; 
     var relativeTransform = this.TransformToVisual(this.Container); 
     Point parentContainerCoords = relativeTransform.TransformPoint(localCoords); 
     var center = parentContainerCoords; 

     RotateTransform rotation = new RotateTransform(); 
     rotation.CenterX = center.X; 
     rotation.CenterY = center.Y; 
     rotation.Angle = e.Delta.Rotation; 
     this.transformGroup.Children.Add(rotation); 

     ScaleTransform scaling = new ScaleTransform(); 
     scaling.CenterX = center.X; 
     scaling.CenterY = center.Y; 
     scaling.ScaleX = e.Delta.Scale; 
     scaling.ScaleY = e.Delta.Scale; 
     this.transformGroup.Children.Add(scaling); 

     TranslateTransform translation = new TranslateTransform(); 
     translation.X = e.Delta.Translation.X; 
     translation.Y = e.Delta.Translation.Y; 
     this.transformGroup.Children.Add(translation); 
    }