Sdílet prostřednictvím


Tipy a triky animace

Při práci s animacemi ve WPF existuje řada tipů a triků, které vám můžou usnadnit výkon animací a ušetřit vám frustraci.

Obecné problémy

Animace polohy posuvníku nebo posuvné lišty způsobí jejich zamrznutí.

Pokud animujete pozici posuvníku nebo jezdce pomocí animace, která má hodnotu FillBehaviorHoldEnd (výchozí hodnota), uživatel už nebude moci posuvník nebo jezdec přesunout. Je to proto, že i po skončení animace stále mění základní hodnotu vlastnosti cíle. Pokud chcete zabránit animaci v přepsání aktuální hodnoty vlastnosti, odeberte ji nebo jí dejte hodnotu FillBehaviorStop. Další informace a příklad naleznete v tématu Nastavení vlastnosti po animaci pomocí scénáře.

Animace výstupu animace nemá žádný efekt

Objekt, který je výstupem jiné animace, nemůžete animovat. Pokud například použijete ObjectAnimationUsingKeyFrames k animování FillRectangle z RadialGradientBrush na SolidColorBrush, nemůžete animovat žádné vlastnosti RadialGradientBrush nebo SolidColorBrush.

Po animaci nelze změnit hodnotu vlastnosti.

V některých případech se může zdát, že nemůžete změnit hodnotu vlastnosti po animaci, i když animace skončila. Je to proto, že i když animace skončila, stále přepisuje základní hodnotu vlastnosti. Pokud chcete zabránit animaci v přepsání aktuální hodnoty vlastnosti, odeberte ji nebo jí dejte hodnotu FillBehaviorStop. Další informace a příklad naleznete v tématu Nastavení vlastnosti po animaci pomocí scénáře.

Změna časové osy nemá žádný vliv

Přestože lze většinu vlastností Timeline animovat a lze je vázat na data, změna hodnot vlastností aktivního Timeline nemá žádný vliv. Je to proto, že když je Timeline zahájen, systém časování vytvoří kopii Timeline a použije ji k vytvoření objektu Clock. Úprava originálu nemá žádný vliv na kopii systému.

Timeline Aby se změny projevily, musí se jeho hodiny znovu vygenerovat a použít k nahrazení dříve vytvořených hodin. Hodiny se automaticky nevygenerují. Změny časové osy můžete použít několika způsoby:

  • Pokud časová osa je nebo patří k Storyboard, můžete je aktualizovat, aby odrážela změny, tím, že znovu použijete její scénář pomocí metody BeginStoryboard nebo Begin. To má vedlejší vliv také na restartování animace. V kódu můžete použít metodu Seek pro přechod scénáře zpět na předchozí pozici.

  • Pokud jste použili animaci přímo na vlastnost pomocí BeginAnimation metody, zavolejte metodu BeginAnimation znovu a předejte ji animaci, která byla změněna.

  • Pokud pracujete přímo na úrovni hodin, vytvořte a použijte novou sadu hodin a použijte je k nahrazení předchozí sady vygenerovaných hodin.

Další informace o časových osách a hodinách najdete v přehledu Animace a časovacího systému.

FillBehavior.Stop nepracuje tak, jak bylo očekáváno

Někdy se zdá, že nastavení parametru FillBehavior na Stop nemá žádný vliv, například když jedna animace předá řízení jiné, protože má HandoffBehavior nastavení na SnapshotAndReplace.

Následující příklad vytvoří Canvas, Rectangle a TranslateTransform. Bude TranslateTransform animován k pohybu Rectangle okolo Canvas.

<Canvas Width="600" Height="200">
  <Rectangle 
    Canvas.Top="50" Canvas.Left="0" 
    Width="50" Height="50" Fill="Red">
    <Rectangle.RenderTransform>
      <TranslateTransform 
        x:Name="MyTranslateTransform" 
        X="0" Y="0" />
    </Rectangle.RenderTransform>
  </Rectangle>
</Canvas>

Příklady v této části používají předchozí objekty k předvedení několika případů, kdy FillBehavior se vlastnost nechová podle očekávání.

FillBehavior="Stop" a HandoffBehavior s více animacemi

Někdy se zdá, že animace ignoruje jeho FillBehavior vlastnost, když je nahrazena druhou animací. Podívejte se na následující příklad, který vytvoří dva Storyboard objekty a použije je k animaci stejného TranslateTransform obrázku v předchozím příkladu.

První Storyboard, B1, animuje vlastnost X u TranslateTransform od 0 do 350, což přesune obdélník o 350 pixelů doprava. Když animace dosáhne konce doby trvání a přestane se přehrávat, X vlastnost se vrátí k původní hodnotě 0. V důsledku toho se obdélník přesune doprava o 350 pixelů a pak přeskočí zpět na původní pozici.

<Button Content="Start Storyboard B1">
  <Button.Triggers>
    <EventTrigger RoutedEvent="Button.Click">
      <BeginStoryboard>
        <Storyboard x:Name="B1">
          <DoubleAnimation 
            Storyboard.TargetName="MyTranslateTransform"
            Storyboard.TargetProperty="X"
            From="0" To="350" Duration="0:0:5"
            FillBehavior="Stop"
            />
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Button.Triggers>
</Button>

Druhý Storyboard, B2, také animuje vlastnost X stejného TranslateTransform. Vzhledem k tomu, že je nastavena pouze vlastnost To animace v Storyboard, animace používá aktuální hodnotu vlastnosti, kterou animuje, jako počáteční hodnotu.


<!-- Animates the same object and property as the preceding
     Storyboard. -->
<Button Content="Start Storyboard B2">
  <Button.Triggers>
    <EventTrigger RoutedEvent="Button.Click">
      <BeginStoryboard>
        <Storyboard x:Name="B2">
          <DoubleAnimation 
            Storyboard.TargetName="MyTranslateTransform"
            Storyboard.TargetProperty="X"
            To="500" Duration="0:0:5" 
            FillBehavior="Stop" />
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Button.Triggers>
</Button>

Pokud kliknete na druhé tlačítko, zatímco se přehrává Storyboard spojený s prvním tlačítkem, můžete očekávat následující chování:

  1. První storyboard končí a odesílá obdélník zpět do původní pozice, protože animace má FillBehavior ve tvaru Stop.

  2. Druhý storyboard se projeví a animuje se z aktuální pozice 0 na 500.

Ale to není to, co se stane. Místo toho obdélník nepřeskočí zpět; pokračuje v pohybu doprava. Je to proto, že druhá animace používá aktuální hodnotu první animace jako počáteční hodnotu a animuje z této hodnoty na 500. Když druhá animace nahradí první, protože SnapshotAndReplaceHandoffBehavior se použije, FillBehavior první animace není důležitá.

FillBehavior a dokončená událost

Další příklady ukazují jiný scénář, ve kterém se zdá, že StopFillBehavior nemá žádný vliv. Příklad opět používá Storyboard k animaci X vlastnosti TranslateTransform od 0 do 350. Tentokrát se příklad zaregistruje pro událost Completed.

<Button Content="Start Storyboard C">
  <Button.Triggers>
    <EventTrigger RoutedEvent="Button.Click">
      <BeginStoryboard>
        <Storyboard Completed="StoryboardC_Completed">
          <DoubleAnimation 
            Storyboard.TargetName="MyTranslateTransform"
            Storyboard.TargetProperty="X"
            From="0" To="350" Duration="0:0:5"
            FillBehavior="Stop" />
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Button.Triggers>
</Button>

Obslužná rutina Completed události spustí jinou Storyboard , která animuje stejnou vlastnost z aktuální hodnoty na 500.

private void StoryboardC_Completed(object sender, EventArgs e)
{

    Storyboard translationAnimationStoryboard =
        (Storyboard)this.Resources["TranslationAnimationStoryboardResource"];
    translationAnimationStoryboard.Begin(this);
}
Private Sub StoryboardC_Completed(ByVal sender As Object, ByVal e As EventArgs)

    Dim translationAnimationStoryboard As Storyboard = CType(Me.Resources("TranslationAnimationStoryboardResource"), Storyboard)
    translationAnimationStoryboard.Begin(Me)
End Sub

Následuje značkovací jazyk, který definuje druhý Storyboard jako prostředek.

<Page.Resources>
  <Storyboard x:Key="TranslationAnimationStoryboardResource">
    <DoubleAnimation 
      Storyboard.TargetName="MyTranslateTransform"
      Storyboard.TargetProperty="X"
      To="500" Duration="0:0:5" />
  </Storyboard>
</Page.Resources>

Když spustíte Storyboard, můžete očekávat, že vlastnost X bude animovaná od 0 do 350, potom se po dokončení vrátí na hodnotu 0 (protože má nastavení TranslateTransform na FillBehavior), a následně bude animovaná od 0 do 500. Místo toho se TranslateTransform animuje od 0 do 350 a pak k 500.

Důvodem je pořadí, ve kterém WPF vyvolává události a protože hodnoty vlastností jsou uloženy v mezipaměti a nejsou přepočítány, pokud není vlastnost neplatná. Událost Completed se zpracuje jako první, protože ji aktivovala kořenová časová osa (první Storyboard). V tuto chvíli vlastnost X stále vrací svou animovanou hodnotu, protože ještě nebyla zneplatněna. Druhý Storyboard používá hodnotu uloženou v mezipaměti jako počáteční hodnotu a začne animovat.

Výkon

Animace se budou dál spouštět i po přechodu mimo stránku.

Když přejdete od Page, který obsahuje spuštěné animace, tyto animace se budou nadále přehrávat, dokud Page nebude uvolněna z paměti. V závislosti na navigačním systému, který používáte, může stránka, od které odcházíte, zůstat v paměti po neomezenou dobu, a přitom spotřebovávat prostředky kvůli svým animacím. To je nejvýraznější, když stránka obsahuje neustále běžící ("ambientní") animace.

Z tohoto důvodu je vhodné použít Unloaded událost k odebrání animací, když přejdete mimo stránku.

Animace se dá odebrat různými způsoby. Následující techniky lze použít k odebrání animací, které patří k Storyboard.

Další technika se může použít bez ohledu na to, jak byla animace spuštěna.

Další informace o různých způsobech animace vlastností naleznete v tématu Přehled technik animace vlastností.

Použití nástroje Compose HandoffBehavior spotřebovává systémové prostředky

Pokud použijete Storyboard, AnimationTimeline nebo AnimationClock na vlastnost pomocí ComposeHandoffBehavior, všechny Clock objekty, které byly dříve přidruženy k této vlastnosti, budou nadále spotřebovávat systémové prostředky; systém časování tyto časovače automaticky neodstraní.

Abyste se vyhnuli problémům s výkonem při použití velkého počtu hodin pomocí Compose, měli byste po dokončení odebrat sestavovací hodiny z animované vlastnosti. Hodiny můžete odebrat několika způsoby.

Jedná se především o problém s animacemi na objektech, které mají dlouhou životnost. Když je objekt sesbírán z paměti, jeho časovače budou také odpojeny a sesbírány z paměti.

Další informace o objektech hodin naleznete v tématu Animace a časování systému Přehled.

Viz také

  • Přehled animací