WPF Wie können Sie eine schöne Welle von Buchstaben erstellen?

7

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

    
Mark 23.12.2009, 23:10
quelle

3 Antworten

8

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.

    
Patrick Klug 18.01.2010, 05:31
quelle
36

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".

  1. Erstellen Sie es mit der benutzerdefinierten Steuerelementvorlage von Visual Studio (stellen Sie sicher, dass Ihre Assembly: ThemeInfo-Attribut korrekt festgelegt ist und all das)
  2. Fügen Sie eine Abhängigkeitseigenschaft "Path" vom Typ Geometry (verwenden Sie wpfdp snippet)
  3. hinzu
  4. Fügen Sie eine schreibgeschützte Abhängigkeitseigenschaft "DisplayMesh" vom Typ Geometry3D (verwenden Sie wpfdpro snippet)
  5. hinzu
  6. Fügen Sie eine 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:

%Vor%

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:

  1. Konvertiere in PathGeometry mit PathGeometry.CreateFromGeometry
  2. Wählen Sie eine geeignete Anzahl von Rechtecken in Ihrem Netz, 'n', mit einer Heuristik Ihrer Wahl. Vielleicht beginnen Sie mit der Hartcodierung n = 50.
  3. Berechnen Sie Ihre 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.
  4. Berechne deine TriangleIndices . Das ist trivial. Jedes Rechteck besteht aus zwei Dreiecken, also gibt es sechs Indizes pro Rechteck.
  5. Berechne deine 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:

  1. 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.

  2. 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.

  3. 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:

Momentaufnahme des animierten Textes "StackOverflowIsFun" http://rayburnsresume.com/StackOverflowImages/WavyLetters.png

>     
Ray Burns 24.12.2009 01:02
quelle
0

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:

  1. Die Dreiecke sind alle spitz, daher denke ich, dass die Rechtecke nicht richtig definiert sind
  2. Es ist umgekehrt! Aber ich denke, das hat etwas mit den Tangenten zu tun
Mark 31.12.2009 06:33
quelle

Tags und Links