Keyframeanimationen und Animationen für Beschleunigungsfunktionen

Lineare Keyframe-Animationen, Keyframe-Animationen mit einem KeySpline-Wert oder Beschleunigungsfunktionen sind drei verschiedene Techniken für ungefähr dasselbe Szenario: Erstellen einer komplexeren Storyboard-Animation, die ein nichtlineares Animationsverhalten ab einem bestimmten Startzustand bis zu einem Endzustand verwendet.

Voraussetzungen

Lesen Sie vorher unbedingt das Thema Storyboardanimationen. Dieses Thema basiert auf den Animationskonzepten, die in Storyboardanimationen erläutert wurden, und behandelt diese nicht erneut. In Storyboard-Animationen wird beispielsweise das Anwenden von Animationen auf Ziele, das Verwenden von Storyboards als Ressourcen, die Timeline-Eigenschaftswerte wie z. B. Duration, FillBehavior usw. erläutert.

Animieren mit Keyframe-Animationen

Keyframe-Animationen lassen mehr als einen Zielwert zu, der an einem gewissen Punkt auf der Animationszeitachse erreicht wird. Mit anderen Worten, jeder Schlüsselrahmen kann einen anderen Zwischenwert angeben, und der letzte erreichte Schlüsselrahmen ist der endgültige Animationswert. Durch Angabe mehrerer Animationswerte können Sie komplexere Animationen erstellen. Keyframe-Animationen ermöglichen auch verschiedene Interpolationslogiken, die pro Animationstyp als unterschiedliche KeyFrame-Unterklassen implementiert werden. Insbesondere hat jeder Keyframe-Animationstyp eine Discrete-, Linear-, Spline- und Easing-Variation seiner KeyFrame-Klasse für die Angabe der Keyframes. Zum Festlegen einer Animation mit Keyframes für Double können Sie z. B. Keyframes mit DiscreteDoubleKeyFrame, LinearDoubleKeyFrame, SplineDoubleKeyFrame und EasingDoubleKeyFrame deklarieren. Sie können all diese Typen beliebig in einer einzelnen KeyFrames-Sammlung verwenden, um die Interpolation bei jedem Erreichen eines neuen Keyframes zu ändern.

Für das Interpolationsverhalten steuert jeder Keyframe die Interpolation, bis die KeyTime-Zeit erreicht ist. Value wird zum selben Zeitpunkt erreicht. Folgen weitere Keyframes, wird der Wert anschließend zum Startwert für den nächsten Keyframe in einer Sequenz.

Wenn beim Start der Animation kein Keyframe mit der KeyTime 0:0:0 vorhanden ist, ist der nicht animierte Wert der Eigenschaft der Startwert. Dies ähnelt der Vorgehensweise einer From/To/By-Animation , wenn kein From vorhanden ist.

Die Dauer einer Keyframe-Animation entspricht implizit der Dauer des höchsten KeyTime-Werts, der in einem ihrer Keyframes festgelegt ist. Sie können eine explizite Duration festlegen. Achten Sie dabei jedoch darauf, dass sie nicht kürzer als eine KeyTime in ihren eigenen Keyframes ist, andernfalls wird ein Teil der Animation abgeschnitten.

Neben der Duration können Sie alle Timeline-basierten Eigenschaften in einer Keyframe-Animation festlegen (genau wie bei einer From/To/By-Animation) da die Keyframe-Animationsklassen ebenfalls von der Timeline abgeleitet werden. Diese lauten wie folgt:

  • AutoReverse: Sobald der letzte Keyframe erreicht ist, werden die Frames vom anderen Ende ausgehend in umgekehrter Reihenfolge wiederholt. So wird die scheinbare Dauer der Animation verdoppelt.
  • BeginTime: verzögert den Start der Animation. Die Zeitachse für die KeyTime-Werte in den Frames beginnt erst nach Erreichen der BeginTime mit der Zählung, damit kein Risiko besteht, dass Frames abgeschnitten werden.
  • FillBehavior: Steuert die Ereignisse nach dem Erreichen des letzten Keyframes. FillBehavior hat keine Auswirkungen auf Zwischenkeyframes.
  • RepeatBehavior:
    • Bei Festlegung auf Forever werden die Keyframes und die dazugehörige Zeitachse unendlich wiederholt.
    • Bei Festlegung auf eine bestimmte Iterationsanzahl wird die Zeitachse entsprechend oft wiederholt.
    • Bei Festlegung auf eine Duration wird die Zeitachse bis zum Erreichen dieser Zeit wiederholt. Dadurch wird die Animation u. U. mitten in der Keyframe-Sequenz abgeschnitten, wenn sie keinen ganzzahligen Teiler der impliziten Dauer der Zeitachse darstellt.
  • SpeedRatio (selten verwendet)

Lineare Keyframes

Lineare Keyframes führen zu einer einfachen linearen Interpolation des Werts, bis die KeyTime des Frames erreicht ist. Dieses Interpolationsverhalten ähnelt den einfacheren Animationen von "From/To/By" , die im Thema Storyboardanimationen beschrieben werden.

Im Folgenden erfahren Sie, wie die Renderhöhe eines Rechtecks mithilfe von linearen Keyframes skaliert wird. In diesem Beispiel wird eine Animation ausgeführt, bei der die Höhe des Rechtecks in den ersten vier Sekunden leicht und linear ansteigt und in der letzten Sekunde schnell skaliert wird, bis das Rechteck im Vergleich zum Start die doppelte Höhe erreicht hat.

<StackPanel>
    <StackPanel.Resources>
        <Storyboard x:Name="myStoryboard">
            <DoubleAnimationUsingKeyFrames
              Storyboard.TargetName="myRectangle"
              Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)">
                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:0"/>
                <LinearDoubleKeyFrame Value="1.2" KeyTime="0:0:4"/>
                <LinearDoubleKeyFrame Value="2" KeyTime="0:0:5"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </StackPanel.Resources>
</StackPanel>

Diskrete Keyframes

Diskrete Keyframes verwenden überhaupt keine Interpolation. Beim Erreichen einer KeyTime wird einfach der neue Value angewendet. Je nach der animierten UI-Eigenschaft führt dies häufig dazu, dass die Animation zu „springen“ scheint. Stellen Sie sicher, dass dieses ästhetische Verhalten gewünscht ist. Sie können die scheinbaren Sprünge reduzieren, indem Sie die Anzahl der deklarierten Keyframes erhöhen. Möchten Sie jedoch eine flüssige Animation erzielen, sollten Sie stattdessen lineare Keyframes oder Spline-Keyframes verwenden.

Hinweis

Diskrete Keyframes sind die einzige Möglichkeit, einen Wert, der nicht vom Typ Double, Point und Color ist, mit einem DiscreteObjectKeyFrame zu animieren. Dies wird später in diesem Thema ausführlich erläutert.

Spline-Keyframes

Ein Spline-Schlüsselrahmen erstellt einen Variablenübergang zwischen Werten gemäß dem Wert der KeySpline-Eigenschaft . Diese Eigenschaft gibt den ersten und zweiten Kontrollpunkt einer Bézierkurve an, mit der die Beschleunigung einer Animation beschrieben wird. Im Grunde definiert ein KeySpline eine Funktion-über-Zeit-Beziehung, bei der das Funktions-Zeit-Diagramm die Form dieser Bézier-Kurve darstellt. In der Regel geben Sie einen KeySpline-Wert in einer XAML-Attributzeichenfolge mit vier Double-Werten an, die durch Leerzeichen oder Kommas getrennt sind. Diese Werte sind „X,Y“-Paare für zwei Kontrollpunkte der Bézierkurve. „X“ ist die Zeit, und „Y“ ist der Funktionsmodifizierer für den Wert. Jeder Wert sollte sich immer zwischen 0 und einschließlich 1 bewegen. Ohne Kontrollpunktänderung an einer KeySpline stellt die gerade Linie von 0,0 bis 1,1 eine Funktion der Zeit für eine lineare Interpolation dar. Ihre Kontrollpunkte ändern die Form der Kurve und somit das Verhalten der Funktion der Zeit für die Spline-Animation. Dies wird am besten visuell als Graph dargestellt. Sie können das Beispiel für die Silverlight Keyspline-Schnellansicht in einem Browser ausführen, um zu sehen, wie die Kontrollpunkte die Kurve ändern, und wie eine Beispielanimation ausgeführt wird, wenn sie als KeySpline-Wert verwendet wird.

Im nächsten Beispiel wird die Anwendung von drei verschiedenen Keyframes auf eine Animation gezeigt, wobei der letzte eine Keyspline-Animation für einen Double-Wert (SplineDoubleKeyFrame) ist. Beachten Sie die Anwendung der Zeichenfolge „0.6,0.0 0.9,0.00“ für KeySpline. Dadurch entsteht eine Kurve, bei der die Animation zuerst scheinbar langsam ausgeführt wird, dann jedoch schnell den Wert erreicht, bevor die KeyTime erreicht ist.

<Storyboard x:Name="myStoryboard">
    <!-- Animate the TranslateTransform's X property
        from 0 to 350, then 50,
        then 200 over 10 seconds. -->
    <DoubleAnimationUsingKeyFrames
        Storyboard.TargetName="MyAnimatedTranslateTransform"
        Storyboard.TargetProperty="X"
        Duration="0:0:10" EnableDependentAnimation="True">

        <!-- Using a LinearDoubleKeyFrame, the rectangle moves 
            steadily from its starting position to 500 over 
            the first 3 seconds.  -->
        <LinearDoubleKeyFrame Value="500" KeyTime="0:0:3"/>

        <!-- Using a DiscreteDoubleKeyFrame, the rectangle suddenly 
            appears at 400 after the fourth second of the animation. -->
        <DiscreteDoubleKeyFrame Value="400" KeyTime="0:0:4"/>

        <!-- Using a SplineDoubleKeyFrame, the rectangle moves 
            back to its starting point. The
            animation starts out slowly at first and then speeds up. 
            This KeyFrame ends after the 6th second. -->
        <SplineDoubleKeyFrame KeySpline="0.6,0.0 0.9,0.00" Value="0" KeyTime="0:0:6"/>
    </DoubleAnimationUsingKeyFrames>
</Storyboard>

Beschleunigungskeyframes

Ein Beschleunigungsschlüsselrahmen ist ein Schlüsselrahmen, in dem interpoliert wird, und die Funktion im Laufe der Interpolation wird von mehreren vordefinierten mathematischen Formeln gesteuert. Sie können mit einem Spline-Keyframe tatsächlich das gleiche Ergebnis erzielen wie mit einigen der Beschleunigungsfunktionstypen, aber es gibt auch einige Beschleunigungsfunktionen, z. B . BackEase, die Sie nicht mit einem Spline reproduzieren können.

Um eine Beschleunigungsfunktion auf einen Beschleunigungskeyframe anzuwenden, legen Sie die EasingFunction-Eigenschaft als Eigenschaftselement in XAML für diesen Keyframe fest. Geben Sie als Wert ein Objektelement für einen der Beschleunigungsfunktionstypen an.

In diesem Beispiel werden eine CubicEase und dann eine BounceEase als aufeinander folgende Keyframes auf eine DoubleAnimation angewendet, um einen Sprungeffekt zu erzielen.

<Storyboard x:Name="myStoryboard">
    <DoubleAnimationUsingKeyFrames Duration="0:0:10"
        Storyboard.TargetProperty="Height"
        Storyboard.TargetName="myEllipse">

        <!-- This keyframe animates the ellipse up to the crest 
            where it slows down and stops. -->
        <EasingDoubleKeyFrame Value="-300" KeyTime="00:00:02">
            <EasingDoubleKeyFrame.EasingFunction>
                <CubicEase/>
            </EasingDoubleKeyFrame.EasingFunction>
        </EasingDoubleKeyFrame>

        <!-- This keyframe animates the ellipse back down and makes
            it bounce. -->
        <EasingDoubleKeyFrame Value="0" KeyTime="00:00:06">
            <EasingDoubleKeyFrame.EasingFunction>
                <BounceEase Bounces="5"/>
            </EasingDoubleKeyFrame.EasingFunction>
        </EasingDoubleKeyFrame>
    </DoubleAnimationUsingKeyFrames>
</Storyboard>

Dies ist jedoch nur ein Beispiel für Beschleunigungsfunktionen. Weitere Beispiele werden im nächsten Abschnitt behandelt.

Beschleunigungsfunktionen

Mit Beschleunigungsfunktionen können Sie benutzerdefinierte mathematische Formeln auf Animationen anwenden. Mathematische Vorgänge eignen sich oft zum Erstellen von Animationen, die ein reales physikalisches Modell in einem 2 D-Koordinatensystem simulieren. Beispielsweise sollte Ihr Objekt realistisch springen oder sich so verhalten, als ob es sich auf einer Feder befinden würde. Sie könnten Keyframe- oder sogar From/To/By-Animationen verwenden, um diese Effekte anzunähern, aber dies würde einen erheblichen Aufwand kosten, und die Animation wäre weniger genau als die Verwendung einer mathematischen Formel.

Beschleunigungsfunktionen können auf drei verschiedene Arten auf Animationen angewendet werden:

Nachfolgend finden Sie eine Liste der Beschleunigungsfunktionen:

  • BackEase: zieht die Bewegung einer Animation vor ihrer Ausführung in dem angegebenen Pfad etwas zurück.
  • BounceEase: erstellt einen Sprungeffekt.
  • CircleEase: Erstellt eine Animation, die anhand einer Winkelfunktion beschleunigt oder verzögert wird.
  • CubicEase: Erstellt eine Animation, die anhand der Formel f(t) = t3 beschleunigt oder verzögert wird.
  • ElasticEase: Erstellt eine Animation ähnlich einer Sprungfeder, die auf und ab federt und schließlich zur Ruhe kommt.
  • ExponentialEase: Erstellt eine Animation, die anhand einer Exponentialfunktion beschleunigt oder verzögert wird.
  • PowerEase: Erstellt eine Animation, die anhand der Formel f(t) = tp beschleunigt oder verzögert wird, wobei p der Eigenschaft Power entspricht.
  • QuadraticEase: Erstellt eine Animation, die anhand der Formel f(t) = t2 beschleunigt oder verzögert wird.
  • QuarticEase: Erstellt eine Animation, die anhand der Formel f(t) = t4 beschleunigt oder verzögert wird.
  • QuinticEase: Erstellt eine Animation, die anhand der Formel f(t) = t5 beschleunigt oder verzögert wird.
  • SineEase: erstellt eine Animation, die anhand einer Sinusfunktion beschleunigt oder verzögert wird.

Einige der Beschleunigungsfunktionen verfügen über eigene Eigenschaften. Beispielsweise verfügt BounceEase über die beiden Eigenschaften Bounces und Bounciness, die das Funktion-über-Zeit-Verhalten dieser bestimmten BounceEase ändern. Andere Beschleunigungsfunktionen wie z. B. CubicEase haben keine weiteren Eigenschaften außer der Eigenschaft EasingMode, die von allen Beschleunigungsfunktionen gemeinsam verwendet wird, und erzeugen immer dasselbe Funktion-über-Zeit-Verhalten.

Einige dieser Beschleunigungsfunktionen überschneiden sich geringfügig, je nach Einstellung der Einstellung der Eigenschaften für die Beschleunigungsfunktionen, die über Eigenschaften verfügen. QuadraticEase ist z. B. identisch mit einer PowerEase, wobei Power 2 entspricht. Und CircleEase ist im Grunde ein Standardwert ExponentialEase.

Die BackEase-Beschleunigungsfunktion ist eindeutig, da sie den Wert außerhalb des normalen Bereichs ändern kann, wie er durch Von/bis oder Werte von Keyframes festgelegt wird. Die Animation wird gestartet, indem der Wert in entgegengesetzter Richtung geändert wird, wie es von einem normalen From/To-Verhalten erwartet wird, zurück zum Wert Von oder start, und dann wird die Animation wie gewohnt ausgeführt.

Das Deklarieren einer Beschleunigungsfunktion für eine Keyframe-Animation wurde in einem vorhergehenden Beispiel gezeigt. In diesem nächsten Beispiel wird eine Beschleunigungsfunktion auf eine From/To/By-Animation angewendet.

<StackPanel x:Name="LayoutRoot" Background="White">
    <StackPanel.Resources>
        <Storyboard x:Name="myStoryboard">
            <DoubleAnimation From="30" To="200" Duration="00:00:3" 
                Storyboard.TargetName="myRectangle" 
                Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)">
                <DoubleAnimation.EasingFunction>
                    <BounceEase Bounces="2" EasingMode="EaseOut" 
                                Bounciness="2"/>
                </DoubleAnimation.EasingFunction>
            </DoubleAnimation>
        </Storyboard>
    </StackPanel.Resources>
    <Rectangle x:Name="myRectangle" Fill="Blue" Width="200" Height="30"/>
</StackPanel>

Wenn eine Beschleunigungsfunktion auf eine From/To/By-Animation angewendet wird, ändert sie im Laufe der Zeit die Funktionsmerkmale der Interpolation zwischen den Werten From und To über die Dauer der Animation. Ohne Beschleunigungsfunktion läge eine lineare Interpolation vor.

Animationen für diskrete Objektwerte

Ein Animationstyp sollte besonders hervorgehoben werden, da er die einzige Methode darstellt, einen animierten Wert auf Eigenschaften von einem anderen Typ als Double, Point oder Color anzuwenden. Hierbei handelt es sich um die Keyframe-Animation ObjectAnimationUsingKeyFrames. Es besteht ein Unterschied zum Animieren mithilfe von Object-Werten, da es keine Möglichkeit zur Interpolation der Werte zwischen den Frames gibt. Beim Erreichen der KeyTime des Frames wird der animierte Wert sofort auf den Wert festgelegt, der im Value des Keyframes angegeben ist. Da es keine Interpolation gibt, gibt es nur einen Keyframe, den Sie in der Keyframe-Auflistung ObjectAnimationUsingKeyFrames verwenden: DiscreteObjectKeyFrame.

Der Value eines DiscreteObjectKeyFrame wird oft mithilfe der Eigenschaftselementsyntax festgelegt, da der festzulegende Objektwert häufig nicht als Zeichenfolge zum Ausfüllen des Value in einer Attributsyntax ausgedrückt werden kann. Sie können weiterhin Attributsyntax verwenden, wenn Sie einen Verweis wie StaticResource verwenden.

Die Verwendung von ObjectAnimationUsingKeyFrames in den Standardvorlagen erfolgt bei einem Verweis auf eine Brush-Ressource durch eine Vorlageneigenschaft. Bei diesen Ressourcen handelt es sich um SolidColorBrush-Objekte, nicht nur um einen Color-Wert. Außerdem werden Ressourcen verwendet, die als Systemthemen (ThemeDictionaries) definiert sind. Sie können direkt einem Wert mit Brush-Typ wie TextBlock.Foreground zugeordnet werden; eine indirekte Zielauswahl ist nicht erforderlich. Da SolidColorBrush jedoch nicht Double, Point oder Color ist, müssen Sie ObjectAnimationUsingKeyFrames verwenden, um die Ressource zu nutzen.

<Style x:Key="TextButtonStyle" TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid Background="Transparent">
                    <TextBlock x:Name="Text"
                        Text="{TemplateBinding Content}"/>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="PointerOver">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPointerOverForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPressedForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
...
                       </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Sie haben auch die Möglichkeit, ObjectAnimationUsingKeyFrames zu verwenden, um Eigenschaften mit einem Enumerationswert zu animieren. Im Folgenden finden Sie ein weiteres Beispiel einer benannten Formatvorlage, die aus den Standardvorlagen der Windows-Runtime stammt. Beachten Sie die Festlegung der Visibility-Eigenschaft, die eine Visibility-Enumerationskonstante akzeptiert. In diesem Fall können Sie den Wert mithilfe der Attributsyntax festlegen. Sie benötigen lediglich den nicht qualifizierten Konstantennamen aus einer Enumeration zum Festlegen einer Eigenschaft mit einem Enumerationswert, z. B. „Collapsed“.

<Style x:Key="BackButtonStyle" TargetType="Button">
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="Button">
          <Grid x:Name="RootGrid">
            <VisualStateManager.VisualStateGroups>
              <VisualStateGroup x:Name="CommonStates">
              <VisualState x:Name="Normal"/>
...           <VisualState x:Name="Disabled">
                <Storyboard>
                  <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Visibility">
                    <DiscreteObjectKeyFrame Value="Collapsed" KeyTime="0"/>
                  </ObjectAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
            </VisualStateGroup>
...
          </VisualStateManager.VisualStateGroups>
        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

Sie können mehrere DiscreteObjectKeyFrame-Elemente für einen ObjectAnimationUsingKeyFrames-Framesatz verwenden. Dies ist eine interessante Erstellungsmethode für eine Diashow-Animation durch Animieren des Werts von Image.Source und ein Beispiel für ein Szenario, in dem mehrere Objektwerte hilfreich sind.