Startseite  Inhaltsverzeichnis  <<  >>  

Kapitel 6 - Animationen

6.1 Grundlagen

Avalon nutzt bei der Anzeige von Animationen stärker die vorhandene Hardware. Animationen können direkt mit Eigenschaften verbunden werden wie z.B. Füllmuster. Die benötigten Typen befinden sich im Namespace System.Windows.Media.Animation. Um eigene Klassen Animationsfähig zu machen, implementieren diese das Interfase IAnimatable.

Def.Eine Animation in Avalon verändert eine bestimmte Eigenschaft eines Kontrollelements innerhalb eines Wertebereichs und eines Zeitintervalls. Je nach Eigenschaftstyp kommen unterschiedliche Animationstypen zur Anwendung.

Im folgenden Beispiel wird ein farbiges Rechteck angezeigt, dessen Breite sich innerhalb von 5 Sekunden zwischen 100 und 200 Pixeln verändert. Die Schrittweite wird durch diese Angaben automatisch berechnet. Durch die Angabe AutoReverse="true" wird danach die Breite wieder von 200 nach 100 Pixeln verändert.  Ansonsten würde die Animation wieder mit der Breite von 100 beginnen.

Beispiel: Animation1.xaml
<FlowPanel xmlns="http://schemas.microsoft.com/2003/xaml">
<Rectangle Width="100" Height="100" Fill="LightBlue" Margin="20, 20">
<Rectangle.Width>
<LengthAnimation From="100" To="200" Duration="5" RepeatDuration="Indefinite"
AutoReverse="true" />
</Rectangle.Width>
</Rectangle>
</FlowPanel>
Und als C#-Code
...
using System.Windows.Media.Animation;
using System.Drawing.Printing;
...
FlowPanel fp = new FlowPanel();
Rectangle rect = new Rectangle();
rect.Width = new Length(100);
rect.Height = new Length(100);
rect.Fill = Brushes.LightBlue;
rect.Margin = new Thickness(10, 10, 10, 10);

LengthAnimation la = new LengthAnimation(new Length(100), new Length(200), new Time(5));
la.RepeatDuration = Time.Indefinite;
la.AutoReverse = true;

rect.GetAnimations(Rectangle.WidthProperty).Add(la);
fp.Children.Add(rect);
this.Content = fp;
Sie können natürlich auch mehrere Eigenschaften animieren. Dazu muss wie bereits erwähnt immer der Eigenschaftstyp beachtet werden. Zu jedem Eigenschaftstyp gibt es zwei Animationstypen. Der einfache Typ verwendet die Attribute From, To und By, um die Schrittweite festzulegen. Der zweite Typ verwendet Key Frames. Dazu können mehrere Zielwerte verwendet werden. Die Berechnung der Zwischenwerte kann ebenfalls gesteuert werden. Der Typ der Werte der Eigenschaften From, To und By hängt vom verwendeten Eigenschaftstyp ab.  Alle Klassen sind indirekt von System.Windows.Media.Animation.AnimationTimeline abgeleitet.

Eigenschaft Animationstyp
Color
ColorAnimation und KeyFrameColorAnimation
Double DoubleAnimation und KeyFrameDoubleAnimation
Length LengthAnimation und KeyFrameLengthAnimation
PointPointAnimation und KeyFramePointAnimation
StringStringAnimation und KeyFrameStringAnimation

Im einfachsten Fall verwenden Sie nur die Angaben To und Duration. Der Startwert wird aus dem aktuellen Wert der entsprechenden Eigenschaft abgeleitet. Umgekehrt können Sie auch From und Duration angeben. Der Endwert ist in diesem Fall der aktuelle Wert der Eigenschaft. Über By geben Sie an, um wieviel sich der Wert der Eigenschaft innerhalb der durch Duration gesetzten Zeit verändern soll. Sie können die Attribute From, To und By in den folgenden Kombinationen einsetzen:

Eigenschaft Animationstyp
By
läuft vom aktuellen Wert bis (aktuellen Wert + By)
From läuft von From bis zum aktuellen Wert
From By läuft von From bis (From + By)
From Toläuft von From bis To
Toläuft vom aktuellen Wert bis To

Die Zeitdauer vom Erreichen des Anfangs- bis zum Endwert wird in Sekunden angegeben. Der Wert kann in XAML als Double-Wert angegeben werden, so dass auch Zeiten wie 3.34 möglich sind. Das Beispiel Animation2.xaml verwendet verschiedene Kombinationen der Attribute From, By und To.

Beispiel: Animation2.xaml

<Grid xmlns="http://schemas.microsoft.com/2003/xaml">
  <Rectangle Grid.Left="10" Grid.Top="10" Width="100" Height="100" Fill="LightBlue">
    <Rectangle.Width>
      <LengthAnimation From="100" To="200" Duration="5" RepeatDuration="Indefinite"
AutoReverse="true" />
    </Rectangle.Width>
  </Rectangle>
  <Rectangle Grid.Left="10" Grid.Top="160" Width="100" Height="100" Fill="LightGreen">
    <Rectangle.Width>
      <LengthAnimation To="200" Duration="5" RepeatDuration="Indefinite" AutoReverse="true" />
    </Rectangle.Width>
  </Rectangle>
  <Rectangle Grid.Left="10" Grid.Top="310" Width="100" Height="100" Fill="Yellow">
    <Rectangle.Width>
      <LengthAnimation From="50" Duration="5" RepeatDuration="Indefinite" AutoReverse="true" />
    </Rectangle.Width>
  </Rectangle>
  <Rectangle Grid.Left="10" Grid.Top="460" Width="100" Height="100" Fill="Orange">
    <Rectangle.Width>
      <LengthAnimation By="50" Duration="3.34" RepeatDuration="Indefinite" AutoReverse="true" />
    </Rectangle.Width>
  </Rectangle>
</Grid>

Eigenschaft Animationstyp
AccelerationRatio läuft vom aktuellen Wert bis (aktuellen Wert + By)
Begin Legt die Zeitdauer in Sekunden fest, nach der die Animation nach dem Laden gestartet wird. Wurde die Eigenschaft RepeatDuration gesetzt, hat Begin keine Auswirkung auf die Startzeit, nachdem eine Anwendung ersteinmal geladen wurde.
RepeatBehavior >> ToDo <<
RepeatCount
Legt die Anzahl der Wiederholungen fest (AutoReverse muss true sein). Ein Refresh des Browsers o.a. hat nach dem einmaligen Start keine Auswirkungen.
RepeatDurationLegt die Gesamtlaufzeit der Animation fest. Der Wert von Indefinite bewirkt eine unendlich lange Ausführung. Werden die Eigenschaften RepeatCount und RepeatDuration beide gesetzt, läuft die Animation die längere von beiden Zeiten.
Speed
>> ToDo <<

6.2 Anwendung der Animationstypen

Beispiel: Animation3.xaml

Farb-Animationen

Sie können über Farbveränderungen Farben von Stiften/Linien und Füllmustern ändern. Bei letzteren müssen Sie (wie bei der Eigenschaft Fill) die Farbe des Füllmusters auswählen. Dies erfolgt über das Elemente SolidColorBrush und dessen Eigenschaft Color.

  <Rectangle Grid.Left="10" Grid.Top="10" Width="100" Height="100" Fill="LightBlue">
    <Rectangle.Fill>
      <SolidColorBrush>
        <SolidColorBrush.Color>
          <ColorAnimation From="#222222" To="#FFFFFF" Duration="5" RepeatDuration="Indefinite"
AutoReverse="true" />
        </SolidColorBrush.Color>
      </SolidColorBrush>
    </Rectangle.Fill>
  </Rectangle>

Double-Animationen

Ein Double-Wert ist beispielsweise die Eigenschaft Opacity - welche die Transparenz eines Objekts zwischen den Werten 1 und 0 (durchsichtig) steuert. Dazu wird im Beispiel ein kleines grünes Rechteck hinter einen blauen größeren Rechteck angezeigt. Wenn die Transparenz des größeren Rechtecks den Wert 1 besitzt, ist das dahinterliegende grüne Rechteck nicht zu sehen.

  <Rectangle Grid.Left="35" Grid.Top="335" Width="50" Height="50" Fill="Green" />

  <Rectangle Grid.Left="10" Grid.Top="310" Width="100" Height="100" Fill="LightSteelBlue">
    <Rectangle.Opacity>
            <DoubleAnimation From="1" To="0.3" Duration="5" RepeatDuration="Indefinite"
AutoReverse="true" />
    </Rectangle.Opacity>
  </Rectangle>

Längen-Animationen

Dies wurde bereits beschrieben.
  <Rectangle Grid.Left="10" Grid.Top="160" Width="100" Height="100" Fill="LightGreen">
    <Rectangle.Width>
      <LengthAnimation To="200" Duration="5" RepeatDuration="Indefinite" AutoReverse="true" />
    </Rectangle.Width>
  </Rectangle>

Punkt-Animationen

Geometrieobjekte können in bestimmten Eigenschaften über Punkte beschrieben werden. Im Beispiel ist dies der Mittelpunkt einer Ellipse. Der Pfad (Path) eines Geometrieobjekts kann aus vordefinierten Objekten festgelegt werden. Im folgenden wird also eine Ellipse vertikal verschoben, in dem Ihr Mittelpunkt zwischen den Punkten 100, 450 und 100, 550 verschoben wird.

  <Path Fill="LightBlue" Stroke="Black" StrokeThickness="2">
    <Path.Data>
      <EllipseGeometry Center="100,450" RadiusX="25" RadiusY="25">
        <EllipseGeometry.Center>
          <PointAnimation From="100,450" To="100,550" Duration="5" AutoReverse="true"
RepeatDuration="Indefinite" />
        </EllipseGeometry.Center>
      </EllipseGeometry>
    </Path.Data>
  </Path>

String-Animationen

- in WinFX in dieser Version noch implementiert -

6.3 Fortgeschrittene Animationen

Mehrere Animationen für ein Element

Mehrere Animationen lassen sich für ein Element angeben, in dem Sie die Compound-Schreibweise der Eigenschaften für jede Animation verwenden. Im Beispiel wird die Breite, Höhe und Füllfarbe eines Rechtecks verändert. Die dazu verwendeten Zeiten sind z.T. unterschiedlich gewählt.

Beispiel: Animation4.xaml

<Rectangle Grid.Left="10" Grid.Top="10" Width="100" Height="100" Fill="LightBlue">
  <Rectangle.Fill>
    <SolidColorBrush>
      <SolidColorBrush.Color>
        <ColorAnimation From="#62527A" To="#AFF3FF" Duration="5" RepeatDuration="Indefinite"
AutoReverse="true" />
      </SolidColorBrush.Color>
    </SolidColorBrush>
  </Rectangle.Fill>
  <Rectangle.Width>
    <LengthAnimation From="200" To="300" Duration="5" RepeatDuration="Indefinite"
AutoReverse="true" />
  </Rectangle.Width>
  <Rectangle.Height>
    <LengthAnimation From="200" To="400" Duration="15" RepeatDuration="Indefinite"
AutoReverse="true" />
  </Rectangle.Height>
</Rectangle>

Mehrere Animationen für ein Attribut

Definieren Sie ein Timeline-Element und fügen Sie die Animationen hintereinander ein. Diese werden dann nacheinander ausgeführt.
<Rectangle.Height>
  <Timeline>
    <LengthAnimation From="100" To="200" Duration="5" />
    <LengthAnimation To="400" Duration="15" />
    <LengthAnimation To="400" Duration="15" Begin="2" />
  </Timeline>
</Rectangle.Height>

Key-Frame-Animationen

In diesem Animationstyp können Sie die aktuellen Positionen besser bestimmen. Dazu werden die korrespondieren <KeyFrameXXXAnimation>-Elemente verwendet. Innerhalb des Rahmenelements geben Sie die Gesamtdauer der Animation an. Darunter wird ein Kindelement <KeyFrameXXXAnimation.KeyFrames> angegeben. Dieses Element enthält dann die einzelnen Frames. Diese Frames besitzen ein Attribut Value für den Wert und ein Attribut KeyTime für die Zeit, die innerhalb der gesamten Animation verstrichen ist.

Um ein Rechteck rotieren zu lassen, werden vier Positionen benötigt, die alle 2 Sekunden eingenommen werden sollen. Anhaltspunkt ist die linke obere Ecke des Rechtecks. Nach 4 Sekunden befindet sich das Rechteck also auf der gegenüberliegenden Position des Startpunkt. Damit sich das Rechteckt gleichmäßig/linear von einer Position zu der folgenden begibt, wird das Element <LinearLengthKeyFrame> verwendet. Da als Duration 10 Sekunden abgegeben wird, verharrt das Rechteck am Ende eines Zyklus 2 Sekunden an der Position, bevor es eine neue Runde startet. Die Werte von KeyTime können in Sekunden oder Prozentual angegeben werden. Dabei ist zu beachten, dass die Werte immer bei 0 beginnen und bei der iner Zeit kleiner oder gleich von Duration bzw. 100% enden.

<KeyFrameLengthAnimation Duration="10" RepeatDuration="Indefinite">
  <LinearLengthKeyFrame Value="100" KeyTime="3" />
  <LinearLengthKeyFrame Value="100" KeyTime="6" />
</KeyFrameLengthAnimation>

<KeyFrameLengthAnimation Duration="10" RepeatDuration="Indefinite">
  <LinearLengthKeyFrame Value="100" KeyTime="30%" />
  <LinearLengthKeyFrame Value="100" KeyTime="60%" />
</KeyFrameLengthAnimation>




Beispiel: Animation5.xaml

<Rectangle RectangleLeft="100" RectangleTop="100" RectangleWidth="100"  
RectangleHeight="100" Fill="LightBlue">
  <Rectangle.RectangleLeft>
    <KeyFrameLengthAnimation Duration="10" RepeatDuration="Indefinite">
      <LinearLengthKeyFrame Value="100" KeyTime="0" />
      <LinearLengthKeyFrame Value="100" KeyTime="2" />
      <LinearLengthKeyFrame Value="300" KeyTime="4" />
      <LinearLengthKeyFrame Value="300" KeyTime="6" />
      <LinearLengthKeyFrame Value="100" KeyTime="8" />
    </KeyFrameLengthAnimation>
  </Rectangle.RectangleLeft>
  <Rectangle.RectangleTop>
    <KeyFrameLengthAnimation Duration="10" RepeatDuration="Indefinite">
     <LinearLengthKeyFrame Value="100" KeyTime="0" />
      <LinearLengthKeyFrame Value="300" KeyTime="2" />
      <LinearLengthKeyFrame Value="300" KeyTime="4" />
      <LinearLengthKeyFrame Value="100" KeyTime="6" />
      <LinearLengthKeyFrame Value="100" KeyTime="8" />
    </KeyFrameLengthAnimation>
  </Rectangle.RectangleTop>
</Rectangle>
Möchten Sie das Rechteck in einem Zug von einer Position auf die nächste bewegen, verwenden Sie stattdessen das Element <DiscreteLengthKeyFrame>.
 <Rectangle.RectangleLeft>
   <KeyFrameLengthAnimation Duration="10" RepeatDuration="Indefinite">
    <DiscreteLengthKeyFrame Value="400" KeyTime="0" />
    <DiscreteLengthKeyFrame Value="400" KeyTime="2" />
    <DiscreteLengthKeyFrame Value="600" KeyTime="4" />
    <DiscreteLengthKeyFrame Value="600" KeyTime="6" />
    <DiscreteLengthKeyFrame Value="400" KeyTime="8" />
  </KeyFrameLengthAnimation>
</Rectangle.RectangleLeft>
Über eine Spline-Interpolation können Sie zwei Stützüunkte für die Verarbeitung eines KeyFrames definieren. Dazu verwenden Sie innerhalb des Elements <SplineLengthKeyFrame> das Attribut KeySpline. Jeweils zwei Werte eines Stützpunktes werden durch Komma getrennt. Sie können über Splines z.B. das Anhalten eines Fahrzeugs besser grafisch simulieren, da die Bewegung anfang schneller abnimmt als gegen Ende.
<Rectangle.RectangleTop>
 <KeyFrameLengthAnimation Duration="10" RepeatDuration="Indefinite">
    <SplineLengthKeyFrame Value="400" KeyTime="0" KeySpline="0.08,0.2 0.55,1" />
   <SplineLengthKeyFrame Value="600" KeyTime="2" KeySpline="0.08,0.2 0.55,1" />
    <SplineLengthKeyFrame Value="600" KeyTime="4" KeySpline="0.08,0.2 0.55,1" />
    <SplineLengthKeyFrame Value="400" KeyTime="6" KeySpline="0.08,0.2 0.55,1" />
    <SplineLengthKeyFrame Value="400" KeyTime="8" KeySpline="0.08,0.2 0.55,1" />
  </KeyFrameLengthAnimation>
</Rectangle.RectangleTop>

Für den Wert von KeyFrame gibt es noch zwei Konstanten Uniform und Paced. Uniform vergibt für jeden KeyFrame prozentual die gleiche Zeit. Die Verwendung von Paced verteilt die Zeitdauer nicht anhand der Anzahl der KeyFrames sondern anhand des prozentualen Anteils der Werte in der Eigenschaft Value.
<KeyFrameLengthAnimation Duration="10" RepeatDuration="Indefinite">
  <LinearLengthKeyFrame Value="100" KeyTime="Uniform" />
  <LinearLengthKeyFrame Value="100" KeyTime="Uniform" />
</KeyFrameLengthAnimation>

<KeyFrameLengthAnimation Duration="10" RepeatDuration="Indefinite">
  <LinearLengthKeyFrame Value="100" KeyTime="Paced" />
  <LinearLengthKeyFrame Value="100" KeyTime="Paced" />
</KeyFrameLengthAnimation>