Ich muss in meiner WPF-App ein wackelig aussehendes Textobjekt erstellen, und ich nahm tatsächlich an, dass es eine Art "Biegung entlang eines Pfades" geben würde, aber in Blend sehe ich überhaupt keine.
Ich habe ein Tutorial gefunden, das besagt, dass Sie Ihren Text Buchstaben für Buchstaben in einen Pfad umwandeln müssen, um ihn dann zu drehen, aber das ist meiner Meinung nach absolut schrecklich, viel Platz für Fehler und nicht genug Flexibilität.
Ich möchte im Wesentlichen, dass ein Satz einen animierten Welleneffekt hat, wie kann ich das erreichen?
Danke allen Markiere
Vielleicht möchten Sie sich den MSDN-Artikel von Charles Petzold Text auf einem Pfad mit WPF rendern ansehen ( archivierte Version hier ).
Ich habe diesen Artikel sehr nützlich gefunden und er stellt auch ein Beispiel zur Verfügung, wo er Animation verwendet.
Was Sie suchen, ist effektiv eine nichtlineare Transformation. Die Eigenschaft Transform in Visual kann nur lineare Transformationen ausführen. Glücklicherweise kommen die 3D-Funktionen von WPF zu Ihrer Rettung. Sie können einfach das erreichen, wonach Sie suchen, indem Sie ein einfaches benutzerdefiniertes Steuerelement erstellen, das wie folgt verwendet wird:
%Vor%So geht's:
Erstellen Sie zuerst das benutzerdefinierte Steuerelement "DisplayOnPath".
Geometry
(verwenden Sie wpfdp snippet) Geometry3D
(verwenden Sie wpfdpro snippet) PropertyChangedCallback
für Pfad hinzu, um eine "ComputeDisplayMesh" -Methode aufzurufen, um den Pfad in eine Geometry3D zu konvertieren, und setzen Sie DisplayMesh darauf Es sieht ungefähr so aus:
%Vor% Erstellen Sie als Nächstes die Stil- und Steuerelementvorlage in Themes/Generic.xaml
(oder einem ResourceDictionary
davon) wie für jedes benutzerdefinierte Steuerelement. Die Vorlage wird folgenden Inhalt haben:
Dies bedeutet, dass ein 3D-Modell angezeigt wird, das ein DisplayMesh als Speicherort verwendet und den Inhalt des Steuerelements als Pinselmaterial verwendet.
Beachten Sie, dass Sie möglicherweise andere Eigenschaften für Viewport3DVisual und VisualBrush festlegen müssen, damit das Layout so funktioniert, wie Sie möchten, und dass das Content-Visual entsprechend erweitert wird.
Nur noch die Funktion "ComputeDisplayMesh". Dies ist ein triviales Mapping, wenn Sie möchten, dass der Anfang des Inhalts (die angezeigten Wörter) eine bestimmte Entfernung vom Pfad entfernt sind. Natürlich gibt es andere Algorithmen, die Sie stattdessen wählen könnten, z. B. um einen parallelen Pfad zu erstellen und den prozentualen Abstand zu verwenden.
In jedem Fall ist der grundlegende Algorithmus der gleiche:
PathGeometry
mit PathGeometry.CreateFromGeometry
Positions
-Werte für alle Ecken der Rechtecke. Es gibt n + 1 Ecken an der Spitze und n + 1 Ecken an der Unterseite. Jede untere Ecke kann durch Aufruf von PathGeometry.GetPointAtFractionOfLength
gefunden werden. Dies gibt auch eine Tangente zurück, so dass es leicht ist, auch die obere Ecke zu finden. TriangleIndices
. Das ist trivial. Jedes Rechteck besteht aus zwei Dreiecken, also gibt es sechs Indizes pro Rechteck. TextureCoordinates
. Dies ist noch trivialer, weil sie alle 0, 1 oder i / n sind (wobei i der Rechteckindex ist). Beachten Sie, dass, wenn Sie einen festen Wert von n verwenden, das einzige, was Sie jemals neu berechnen müssen, wenn sich der Pfad ändert, das Posisions
-Array ist. Alles andere ist behoben.
Hier sehen Sie, wie der Hauptteil dieser Methode aussieht:
%Vor%Das ist es. Der Großteil des Codes ist oben geschrieben. Ich überlasse es Ihnen, den Rest auszufüllen.
Übrigens, beachten Sie, dass Sie durch die Kreativität mit dem Z-Wert wirklich beeindruckende Effekte erzielen können.
Aktualisieren
Mark hat den Code dafür implementiert und drei Probleme festgestellt. Hier sind die Probleme und die Lösungen für sie:
Ich habe einen Fehler in meiner TriangleIndices-Bestellung für Dreieck # 1 gemacht. Es ist oben korrigiert. Ich hatte diese Indizes ursprünglich oben links - unten links - oben rechts. Indem wir das Dreieck gegen den Uhrzeigersinn umhergingen, sahen wir tatsächlich die Rückseite des Dreiecks, so dass nichts gemalt wurde. Indem wir einfach die Reihenfolge der Indizes ändern, gehen wir im Uhrzeigersinn herum, so dass das Dreieck sichtbar ist.
Die Bindung für das GeometryModel3D war ursprünglich ein TemplateBinding
. Dies hat nicht funktioniert, da TemplateBinding Aktualisierungen nicht auf die gleiche Weise behandelt. Das Ändern in eine reguläre Bindung hat das Problem behoben.
Das Koordinatensystem für 3D ist + Y ist aufwärts, während für 2D + Y unten ist, so dass der Pfad auf dem Kopf steht. Dies kann entweder durch Negieren von Y im Code oder durch Hinzufügen von RenderTransform
auf ViewPort3DVisual
gelöst werden. Ich persönlich bevorzuge die RenderTransform, weil sie den ComputeDisplayMesh-Code lesbarer macht.
Hier ist ein Schnappschuss von Marks Code, der eine Stimmung belebt, die wir alle teilen:
>Ich dachte, ich würde tatsächlich die Details meiner Fortschritte veröffentlichen, damit wir aus den Kommentaren herauskommen können (die nicht so schön formatieren:))
Hier ist mein Hauptfenster:
%Vor%Dann habe ich die eigentliche Benutzerkontrolle:
%Vor%Im Moment wie es ist, macht dies nichts anderes als den Pfad.
ABER wenn Sie die Mesh-Details von wave1
erhalten, nachdem das Fenster geladen wurde, ersetzen Sie die Bindung durch fest codierte Werte. Sie erhalten dies: Ссылка
Was zwei Hauptprobleme hat: