Freigeben über


Keyframeanimationen und Animationen für Beschleunigungsfunktionen

Lineare Keyframeanimationen, Keyframeanimationen mit einem KeySpline-Wert oder Beschleunigungsfunktionen sind drei verschiedene Techniken für ungefähr dasselbe Szenario: Erstellen einer Storyboardanimation, die etwas komplexer ist und ein nichtlineares Animationsverhalten von einem Anfangszustand bis zu einem Endzustand verwendet.

Voraussetzungen

Stellen Sie sicher, dass Sie das Thema "Storyboardanimationen" gelesen haben. Dieses Thema baut auf den Animationskonzepten auf, die in Storyboardanimationen erläutert wurden und sie nicht erneut übergehen. Storyboardanimationen beschreiben z. B. das Ausrichten von Animationen, Storyboards als Ressourcen, die Zeitachsen-Eigenschaftswerte wie "Duration", "FillBehavior" usw.

Animieren mithilfe von Keyframeanimationen

Keyframeanimationen ermöglichen mehr als einen Zielwert, der an einem Punkt entlang der Animationszeitachse erreicht wird. Mit anderen Worten, jeder Keyframe kann einen anderen Zwischenwert angeben, und der letzte erreichte Keyframe ist der endgültige Animationswert. Indem Sie mehrere zu animierende Werte angeben, können Sie komplexere Animationen erstellen. Keyframeanimationen ermöglichen auch unterschiedliche Interpolationslogik, die jeweils als unterschiedliche Keyframe-Unterklasse pro Animationstyp implementiert werden. Insbesondere verfügt jeder Keyframeanimationstyp über eine diskrete, lineare, Spline - und Beschleunigungsvariation der Keyframeklasse zur Angabe seiner Keyframes. Um beispielsweise eine Animation anzugeben, die auf ein Double ausgerichtet ist und Keyframes verwendet, können Sie Keyframes mit DiscreteDoubleKeyFrame, LinearDoubleKeyFrame, SplineDoubleKeyFrame und EasingDoubleKeyFrame deklarieren. Sie können alle diese Typen innerhalb einer einzelnen Keyframes-Auflistung verwenden, um die Interpolation jedes Mal zu ändern, wenn ein neuer Keyframe erreicht wird.

Bei interpolationsverhalten steuert jeder Keyframe die Interpolation, bis die KeyTime-Zeit erreicht ist. Der Wert wird zu diesem Zeitpunkt ebenfalls erreicht. Wenn weitere Keyframes vorhanden sind, wird der Wert in einer Sequenz zum Startwert für den nächsten Keyframe.

Wenn am Anfang der Animation kein Keyframe mit KeyTime von "0:0:0" vorhanden ist, ist der Startwert unabhängig vom nicht animierten Wert der Eigenschaft. Dies ähnelt der Funktionsweise einer From/To/By-Animation, wenn kein From vorhanden ist.

Die Dauer einer Keyframeanimation ist implizit die Dauer, die dem höchsten KeyTime-Wert entspricht, der in einem seiner Keyframes festgelegt ist. Sie können eine explizite Dauer festlegen, wenn Sie möchten, aber achten Sie darauf, dass es nicht kürzer als eine KeyTime in Ihren eigenen Keyframes ist, oder Sie werden einen Teil der Animation abschneiden.

Zusätzlich zu "Dauer" können Sie alle zeitachsenbasierten Eigenschaften für eine Keyframeanimation festlegen, z. B. mit einer From-By-Animation//, da die Keyframeanimationsklassen ebenfalls von der Zeitachse abgeleitet sind. Dies sind:

  • AutoReverse: Sobald der letzte Keyframe erreicht wurde, werden die Frames von Ende an in umgekehrter Reihenfolge wiederholt. Dadurch 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 nicht, bis BeginTime erreicht ist, sodass keine Gefahr besteht, Frames abzuschneiden.
  • FillBehavior: Steuert, was passiert, wenn der letzte Keyframe erreicht wird. FillBehavior wirkt sich nicht auf zwischengeschaltete Keyframes aus.
  • RepeatBehavior:
    • Wenn dieser Wert auf "Forever" festgelegt ist, wiederholen sich die Keyframes und deren Zeitachse unendlich.
    • Bei Festlegung auf eine Iterationsanzahl wiederholt sich die Zeitachse so oft.
    • Bei Festlegung auf eine Dauer wiederholt sich die Zeitachse, bis diese Zeit erreicht ist. Dadurch wird die Animation möglicherweise durch die Keyframesequenz abgeschnitten, wenn es sich nicht um einen ganzzahligen Faktor der impliziten Dauer der Zeitachse handelt.
  • SpeedRatio (nicht häufig verwendet)

Lineare Keyframes

Lineare Keyframes führen zu einer einfachen linearen Interpolation des Werts, bis die KeyTime des Frames erreicht ist. Dieses Interpolationsverhalten ähnelt dem einfacheren "Von/zu/"-Animationen" im Thema "Storyboardanimationen".

Hier erfahren Sie, wie Sie mithilfe einer Keyframeanimation die Renderhöhe eines Rechtecks mithilfe linearer Keyframes skalieren. In diesem Beispiel wird eine Animation ausgeführt, bei der die Höhe des Rechtecks für die ersten 4 Sekunden leicht und linear zunimmt und dann schnell für die letzte Sekunde skaliert wird, bis das Rechteck doppelt so hoch ist wie die Anfangshöhe.

<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. Wenn eine KeyTime erreicht ist, wird einfach der neue Wert angewendet. Je nachdem, welche UI-Eigenschaft animiert wird, erzeugt dies häufig eine Animation, die als "Springen" angezeigt wird. Seien Sie sicher, dass dies das ästhetische Verhalten ist, das Sie wirklich wollen. Sie können die scheinbaren Sprünge minimieren, indem Sie die Anzahl der deklarierten Keyframes erhöhen, aber wenn eine reibungslose Animation Ihr Ziel ist, sollten Sie stattdessen lineare oder Spline-Keyframes verwenden.

Hinweis

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

Spline-Keyframes

Ein Spline-Keyframe erstellt einen variablen Übergang zwischen Werten gemäß dem Wert der KeySpline-Eigenschaft . Diese Eigenschaft gibt die ersten und zweiten Kontrollpunkte einer Bézierkurve an, die die Beschleunigung der Animation beschreibt. Im Grunde definiert eine KeySpline eine Funktionsüberzeitbeziehung, bei der das Funktionszeitdiagramm die Form dieser Bézierkurve ist. In der Regel geben Sie einen KeySpline-Wert in einer XAML-Kurzhand-Attributzeichenfolge an, die vier Double-Werte durch Leerzeichen oder Kommas getrennt hat. Diese Werte sind "X,Y"-Paare für zwei Kontrollpunkte der Bézierkurve. "X" ist Zeit und "Y" ist der Funktionsmodifizierer für den Wert. Jeder Wert sollte immer zwischen 0 und einschließlich 1 liegen. Ohne Änderung des Kontrollpunkts an eine KeySpline ist die gerade Linie von 0,0 bis 1,1 die Darstellung einer Funktion im Laufe der Zeit für eine lineare Interpolation. Ihre Kontrollpunkte ändern die Form dieser Kurve und damit das Verhalten der Funktion im Laufe der Zeit für die Splineanimation. Es ist wahrscheinlich am besten, dies visuell als Diagramm zu sehen. Sie können das Silverlight-Beispiel für die Schlüssel-Splineschnellansicht 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.

Dieses nächste Beispiel zeigt drei verschiedene Keyframes, die auf eine Animation angewendet werden, wobei es sich bei der letzten um eine Schlüsselsplineanimation für einen Double-Wert (SplineDoubleKeyFrame) handelt. Beachten Sie die Zeichenfolge "0.6,0.0 0.9,0.00", die für KeySpline angewendet wurde. Dies erzeugt eine Kurve, bei der die Animation zunächst langsam ausgeführt wird, dann aber schnell den Wert erreicht, bevor die KeyTime erreicht wird.

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

Beschleunigungs-Keyframes

Ein Beschleunigungstastenframe ist ein Keyframe, in dem Interpolation angewendet wird, und die Funktion im Laufe der Zeit der Interpolation wird von mehreren vordefinierten mathematischen Formeln gesteuert. Sie können tatsächlich dasselbe Ergebnis mit einem Spline-Keyframe erzeugen, wie sie mit einigen der Beschleunigungsfunktionstypen möglich sind, aber es gibt auch einige Beschleunigungsfunktionen, z . B. BackEase, die Sie nicht mit einem Spline reproduzieren können.

Wenn Sie eine Beschleunigungsfunktion auf einen Beschleunigungsschlüsselframe anwenden möchten, legen Sie die EasingFunction-Eigenschaft als Eigenschaftselement in XAML für diesen Keyframe fest. Geben Sie für den Wert ein Objektelement für einen der Beschleunigungsfunktionstypen an.

This example applies a CubicEase and then a BounceEase as successive key frames to a DoubleAnimation to create a bouncing effect.

<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 nur ein Beispiel für beschleunigungsfunktion. Weitere Informationen finden Sie im nächsten Abschnitt.

Beschleunigungsfunktionen

Mit Beschleunigungsfunktionen können Sie benutzerdefinierte mathematische Formeln auf Animationen anwenden. Mathematische Vorgänge sind häufig hilfreich, um Animationen zu erzeugen, die reale Physik in einem 2D-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 es würde eine erhebliche Menge an Arbeit in Anspruch nehmen, und die Animation wäre weniger genau als die Verwendung einer mathematischen Formel.

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

Hier ist eine Liste der Beschleunigungsfunktionen:

  • BackEase: Zieht die Bewegung einer Animation etwas zurück, bevor sie im angegebenen Pfad animiert wird.
  • BounceEase: Erstellt einen Springeffekt.
  • CircleEase: Erstellt eine Animation, die mithilfe einer Kreisfunktion beschleunigt oder verzögert wird.
  • CubicEase: Erstellt eine Animation, die mithilfe der Formel f(t) = t3 beschleunigt oder verzögert wird.
  • ElasticEase: Erstellt eine Animation, die einer Feder ähnelt, die hin und her schwingt, bis sie zum Ruhezustand kommt.
  • ExponentialEase: Erstellt eine Animation, die mithilfe einer exponentiellen Formel beschleunigt oder verzögert wird.
  • PowerEase: Erstellt eine Animation, die mithilfe der Formel f(t) = tp beschleunigt oder verzögert wird, wobei p der Power-Eigenschaft entspricht.
  • QuadraticEase: Erstellt eine Animation, die mithilfe der Formel f(t) = t2 beschleunigt oder verzögert wird.
  • QuarticEase: Erstellt eine Animation, die mithilfe der Formel f(t) = t4 beschleunigt oder verzögert wird.
  • QuinticEase: Erstellen Sie eine Animation, die mithilfe der Formel f(t) = t5 beschleunigt oder verzögert wird.
  • SineEase: Erstellt eine Animation, die mithilfe einer Sinusformel beschleunigt oder verzögert wird.

Einige der Beschleunigungsfunktionen verfügen über eigene Eigenschaften. Beispielsweise verfügt BounceEase über zwei Eigenschaften "Bounces" und "Bounciness", die das Funktion-Over-Time-Verhalten dieses bestimmten BounceEase ändern. Andere Beschleunigungsfunktionen wie CubicEase verfügen nicht über andere Eigenschaften als die EasingMode-Eigenschaft, die alle Beschleunigungsfunktionen gemeinsam nutzen, und erzeugen immer dasselbe Funktionsüberlaufzeitverhalten.

Einige dieser Beschleunigungsfunktionen haben eine gewisse Überlappung, je nachdem, wie Sie Eigenschaften für die Beschleunigungsfunktionen mit Eigenschaften festlegen. QuadraticEase ist z. B. identisch mit einer PowerEase mit PowerEase gleich 2. 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 durch "Von/" oder "Werte von Keyframes" festgelegt. Sie startet die Animation, indem Sie den Wert in der entgegengesetzten Richtung ändern, wie es von einem normalen Von-To-Verhalten/ erwartet wird, zurück zum From- oder Startwert zurückgeht und dann die Animation normal ausführt.

In einem früheren Beispiel wurde gezeigt, wie eine Beschleunigungsfunktion für eine Keyframeanimation deklariert wird. 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, wird die Funktion im Laufe der Zeit geändert, wie der Wert zwischen dem From- und to-Wert über die Dauer der Animation interpoliert. Ohne Beschleunigungsfunktion wäre dies eine lineare Interpolation.

Animationen für diskrete Objektwerte

Eine Art von Animation verdient besondere Erwähnung, da sie die einzige Möglichkeit ist, einen animierten Wert auf Eigenschaften anzuwenden, die nicht vom Typ "Double", "Point" oder "Color" sind. Dies ist die KeyframeanimationUsingKeyFrames.This is the key-frame animation ObjectAnimationUsingKeyFrames. Das Animieren von Objektwerten unterscheidet sich, da es keine Möglichkeit gibt, die Werte zwischen den Frames zu interpolieren. Wenn die KeyTime des Frames erreicht ist, wird der animierte Wert sofort auf den Wert festgelegt, der im Wert des Keyframes angegeben ist. Da keine Interpolation vorhanden ist, gibt es nur einen Keyframe, den Sie in der Keyframesammlung ObjectAnimationUsingKeyFrames verwenden: DiscreteObjectKeyFrame.

Der Wert eines DiscreteObjectKeyFrame wird häufig mithilfe der Eigenschaftselementsyntax festgelegt, da der objektwert, den Sie festlegen möchten, häufig nicht als Zeichenfolge zum Ausfüllen von Value in Attributsyntax ausgedrückt werden kann. Sie können die Attributsyntax weiterhin verwenden, wenn Sie einen Verweis wie StaticResource verwenden.

Eine Stelle, an der ein ObjectAnimationUsingKeyFrames in den Standardvorlagen verwendet wird, ist, wenn eine Vorlageneigenschaft auf eine Brush-Ressource verweist. Diese Ressourcen sind SolidColorBrush-Objekte, nicht nur ein Farbwert, und sie verwenden Ressourcen, die als Systemdesigns (ThemeDictionaries) definiert sind. Sie können direkt einem Pinseltypwert wie "TextBlock.Foreground" zugewiesen werden und müssen keine indirekte Zielbestimmung verwenden. Da ein SolidColorBrush jedoch nicht Double, Point oder Color ist, müssen Sie eine ObjectAnimationUsingKeyFrames verwenden, um die Ressource zu verwenden.

<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 können auch ObjectAnimationUsingKeyFrames verwenden, um Eigenschaften zu animieren, die einen Enumerationswert verwenden. Hier sehen Sie ein weiteres Beispiel aus einer benannten Formatvorlage, die aus den Windows-Runtime Standardvorlagen stammt. Beachten Sie, wie die Visibility-Eigenschaft festgelegt wird, die eine Visibility-Enumerationskonstante verwendet. In diesem Fall können Sie den Wert mithilfe der Attributsyntax festlegen. Sie benötigen nur den nicht qualifizierten Konstantennamen aus einer Aufzählung, um eine Eigenschaft mit einem Enumerationswert festzulegen, 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 mehr als ein DiscreteObjectKeyFrame für einen ObjectAnimationUsingKeyFrames-Framesatz verwenden. Dies kann eine interessante Möglichkeit sein, eine "Bildschirmpräsentationsanimation" zu erstellen, indem Sie den Wert von Image.Source animieren, als Beispielszenario, in dem mehrere Objektwerte nützlich sein können.