Поделиться через


Общие сведения о методах анимации свойств

В данном разделе описываются различные подходы к анимации свойств: раскадровки, локальные анимации, часы и покадровая анимация.

Предварительные требования

Чтобы разобраться в этом разделе, необходимо ознакомиться с базовыми средствами анимации, описанными в Общие сведения об эффектах анимации.

Различные способы анимации

Поскольку существует множество различных скриптов для анимации свойств, WPF предоставляет несколько подходов к анимации свойств.

В следующей таблице показывает для каждого подхода, можно ли использовать его с каждым экземпляром, в стилях, шаблонах элементов управления или шаблонах данных; может ли он использоваться в XAML и позволяет ли подход интерактивно управлять анимацией. "Для каждого экземпляра" относится к способу применения анимации или раскадровки непосредственно к экземплярам объекта, а не к стилю, шаблону элемента управления или шаблону данных.

Метод анимации

Сценарии

Поддерживает XAML

Интерактивно управляемый

Анимация с помощью Storyboard

"Для каждого экземпляра", Style, ControlTemplate, DataTemplate

Да

Да

Локальная анимация

"Для каждого экземпляра"

Нет

Нет

Анимация часов

"Для каждого экземпляра"

Нет

Да

Покадровая анимация

"Для каждого экземпляра"

Нет

Неприменимо

Анимации с помощью Storyboard

Используйте Storyboard, если требуется определить и применить анимацию в XAML, управлять анимациями в интерактивном режиме после запуска, создать сложные деревья анимаций или создать анимации в Style, ControlTemplate или DataTemplate. Объект, анимируемый с помощью Storyboard, должен быть FrameworkElement или FrameworkContentElement, или он должен использоваться для задания FrameworkElement или FrameworkContentElement. Дополнительные сведения см. в разделе Общие сведения о Storyboard.

Storyboard представляет собой особый тип контейнера Timeline, предоставляющий сведения о содержащихся в нем анимациях. Для анимации с помощью Storyboard необходимо выполнить следующие три действия.

  1. Объявите Storyboard и одну или несколько анимаций.

  2. Используйте вложенные свойства TargetName и TargetProperty для указания конечного объекта и свойства каждой анимации.

  3. (Только код) Определите NameScope элемента FrameworkElement или FrameworkContentElement. Зарегистрируйте имена объектов анимации с помощью FrameworkElement или FrameworkContentElement.

  4. Запустите Storyboard.

Запуск Storyboard применяет анимации к анимируемым свойствам и запускает их. Существует два способа запуска Storyboard: можно использовать метод Begin, предоставленный классом Storyboard, или использовать действие BeginStoryboard. Единственным способом анимации в XAML является использование действия BeginStoryboard. Действие BeginStoryboard можно использовать в триггере EventTrigger, триггере Trigger свойства или в триггере DataTrigger.

В следующей таблице приведены различные способы запуска Storyboard: для каждого экземпляра, стиля, шаблона элемента управления и шаблона данных.

Запуск раскадровки при помощи…

"Для каждого экземпляра"

Стиль

Шаблон элемента управления

Шаблон данных

Пример

BeginStoryboard и EventTrigger

Да

Да

Да

Да

Практическое руководство. Анимирование свойства с помощью раскадровки (класс Storyboard)

BeginStoryboard и свойство Trigger

Нет

Да

Да

Да

Практическое руководство. Запуск анимации при изменении значения свойства

BeginStoryboard и DataTrigger

Нет

Да

Да

Да

Практическое руководство. Запуск анимации при изменении данных

Метод Begin

Да

Нет

Нет

Нет

Практическое руководство. Анимирование свойства с помощью раскадровки (класс Storyboard)

Дополнительные сведения об объектах Storyboard содержатся в разделе Общие сведения о Storyboard.

Локальные анимации

Локальные анимации предоставляют удобный способ анимации свойства зависимостей любого объекта Animatable. Используйте локальную анимацию, когда необходимо применить одну анимацию к свойству и нет необходимости в управлении анимацией в интерактивном режиме после запуска. В отличие от анимации Storyboard локальная анимации может анимировать объект, не связанный с FrameworkElement или FrameworkContentElement. Кроме того, нет необходимости определять NameScope для данного типа анимации.

Локальные анимации могут использоваться только в коде и не могут определяться в стилях, шаблонах элементов управления и шаблонах данных. После запуска локальной анимацией нельзя управлять в интерактивном режиме.

Для анимации с помощью локальной анимации необходимо выполнить следующие действия.

  1. Создайте объект AnimationTimeline.

  2. Используйте метод BeginAnimation объекта, который требуется анимировать, чтобы применить к указанному свойству AnimationTimeline.

В следующем примере показана анимация ширины и цвета фона Button.

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''This sample demonstrates how to apply non-storyboard animations to a property.
'''To animate in markup, you must use storyboards.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Imports System
Imports System.Windows
Imports System.Windows.Navigation
Imports System.Windows.Media
Imports System.Windows.Media.Animation
Imports System.Windows.Shapes
Imports System.Windows.Controls

Namespace Microsoft.Samples.Animation.LocalAnimations

    ' Create the demonstration.
    Public Class LocalAnimationExample
        Inherits Page

        Public Sub New()

            WindowTitle = "Animate Property Example"
            Dim myStackPanel As New StackPanel()
            myStackPanel.Margin = New Thickness(20)

            ' Create and set the Button.
            Dim aButton As New Button()
            aButton.Content = "A Button"

            ' Animate the Button's Width.
            Dim myDoubleAnimation As New DoubleAnimation()
            myDoubleAnimation.From = 75
            myDoubleAnimation.To = 300
            myDoubleAnimation.Duration = New Duration(TimeSpan.FromSeconds(5))
            myDoubleAnimation.AutoReverse = True
            myDoubleAnimation.RepeatBehavior = RepeatBehavior.Forever

            ' Apply the animation to the button's Width property.
            aButton.BeginAnimation(Button.WidthProperty, myDoubleAnimation)

            ' Create and animate a Brush to set the button's Background.
            Dim myBrush As New SolidColorBrush()
            myBrush.Color = Colors.Blue

            Dim myColorAnimation As New ColorAnimation()
            myColorAnimation.From = Colors.Blue
            myColorAnimation.To = Colors.Red
            myColorAnimation.Duration = New Duration(TimeSpan.FromMilliseconds(7000))
            myColorAnimation.AutoReverse = True
            myColorAnimation.RepeatBehavior = RepeatBehavior.Forever

            ' Apply the animation to the brush's Color property.
            myBrush.BeginAnimation(SolidColorBrush.ColorProperty, myColorAnimation)
            aButton.Background = myBrush

            ' Add the Button to the panel.
            myStackPanel.Children.Add(aButton)
            Me.Content = myStackPanel
        End Sub
    End Class
End Namespace
/*

   This sample demonstrates how to apply non-storyboard animations to a property.
   To animate in markup, you must use storyboards.

*/

using System;
using System.Windows;
using System.Windows.Navigation;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Controls;

namespace Microsoft.Samples.Animation.LocalAnimations
{

    // Create the demonstration.
    public class LocalAnimationExample : Page 
    {




        public LocalAnimationExample()
        {


            WindowTitle = "Local Animation Example";
            StackPanel myStackPanel = new StackPanel();
            myStackPanel.Margin = new Thickness(20);                     


            // Create and set the Button.
            Button aButton = new Button();
            aButton.Content = "A Button";

            // Animate the Button's Width.
            DoubleAnimation myDoubleAnimation = new DoubleAnimation();
            myDoubleAnimation.From = 75;
            myDoubleAnimation.To = 300;
            myDoubleAnimation.Duration =  new Duration(TimeSpan.FromSeconds(5));
            myDoubleAnimation.AutoReverse = true;
            myDoubleAnimation.RepeatBehavior = RepeatBehavior.Forever;

            // Apply the animation to the button's Width property.
            aButton.BeginAnimation(Button.WidthProperty, myDoubleAnimation);       

            // Create and animate a Brush to set the button's Background.
            SolidColorBrush myBrush = new SolidColorBrush();
            myBrush.Color = Colors.Blue;            

            ColorAnimation myColorAnimation = new ColorAnimation();
            myColorAnimation.From = Colors.Blue;
            myColorAnimation.To = Colors.Red;
            myColorAnimation.Duration =  new Duration(TimeSpan.FromMilliseconds(7000));
            myColorAnimation.AutoReverse = true;
            myColorAnimation.RepeatBehavior = RepeatBehavior.Forever;

            // Apply the animation to the brush's Color property.
            myBrush.BeginAnimation(SolidColorBrush.ColorProperty, myColorAnimation);           
            aButton.Background = myBrush;

            // Add the Button to the panel.
            myStackPanel.Children.Add(aButton);
            this.Content = myStackPanel;
        }
    }

}
/*

   This sample demonstrates how to apply non-storyboard animations to a property.
   To animate in markup, you must use storyboards.

*/

using namespace System;
using namespace System::Windows;
using namespace System::Windows::Navigation;
using namespace System::Windows::Media;
using namespace System::Windows::Media::Animation;
using namespace System::Windows::Shapes;
using namespace System::Windows::Controls;


namespace Microsoft {
   namespace Samples {
      namespace Animation {
         namespace LocalAnimations {
            // Create the demonstration.
            public ref class LocalAnimationExample : Page {

            public: 
               LocalAnimationExample ()
               {
                  WindowTitle = "Local Animation Example";
                  StackPanel^ myStackPanel = gcnew StackPanel();
                  myStackPanel->Margin = Thickness(20);

                  // Create and set the Button.
                  Button^ aButton = gcnew Button();
                  aButton->Content = "A Button";

                  // Animate the Button's Width.
                  DoubleAnimation^ myDoubleAnimation = gcnew DoubleAnimation();
                  myDoubleAnimation->From = 75;
                  myDoubleAnimation->To = 300;
                  myDoubleAnimation->Duration = Duration(TimeSpan::FromSeconds(5));
                  myDoubleAnimation->AutoReverse = true;
                  myDoubleAnimation->RepeatBehavior = RepeatBehavior::Forever;

                  // Apply the animation to the button's Width property.
                  aButton->BeginAnimation(Button::WidthProperty, myDoubleAnimation);

                  // Create and animate a Brush to set the button's Background.
                  SolidColorBrush^ myBrush = gcnew SolidColorBrush();
                  myBrush->Color = Colors::Blue;

                  ColorAnimation^ myColorAnimation = gcnew ColorAnimation();
                  myColorAnimation->From = Colors::Blue;
                  myColorAnimation->To = Colors::Red;
                  myColorAnimation->Duration = Duration(TimeSpan::FromMilliseconds(7000));
                  myColorAnimation->AutoReverse = true;
                  myColorAnimation->RepeatBehavior = RepeatBehavior::Forever;

                  // Apply the animation to the brush's Color property.
                  myBrush->BeginAnimation(SolidColorBrush::ColorProperty, myColorAnimation);
                  aButton->Background = myBrush;

                  // Add the Button to the panel.
                  myStackPanel->Children->Add(aButton);
                  this->Content = myStackPanel;
               };
            };
         }
      }
   }
}

Анимации часов

Используйте объекты Clock, когда требуется выполнять анимацию без использования Storyboard и создавать сложные временные деревья или управлять анимациями в интерактивном режиме после их запуска. Можно использовать объекты Clock для анимации свойства зависимостей любого объекта Animatable.

Объекты Clock нельзя использовать непосредственно для анимации в стилях, шаблонах элементов управления или шаблонах данных. (Анимация и система расчета времени фактически используют объекты Clock для анимации в стилях, шаблонах элементов управления и шаблонах данных, но необходимо создать эти объекты Clock с помощью Storyboard. Дополнительные сведения об отношении между объектами Storyboard и Clock см. в разделе Общие сведения об анимации и системе управления временем)

Чтобы применить один элемент Clock к свойству, выполните следующие действия.

  1. Создайте объект AnimationTimeline.

  2. Используйте метод CreateClock элемента AnimationTimeline для создания AnimationClock.

  3. Используйте метод ApplyAnimationClock объекта, который требуется анимировать, чтобы применить к указанному свойству AnimationClock.

В следующем примере показано создание AnimationClock и применение его к двум аналогичным свойствам.

'
'    This example shows how to create and apply
'    an AnimationClock.
'


Imports System
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Media
Imports System.Windows.Shapes
Imports System.Windows.Media.Animation


Namespace Microsoft.Samples.Animation.TimingBehaviors
    Public Class AnimationClockExample
        Inherits Page

        Private myScaleTransform As ScaleTransform

        Public Sub New()

            Me.WindowTitle = "Opacity Animation Example"
            Me.Background = Brushes.White
            Dim myStackPanel As New StackPanel()
            myStackPanel.Margin = New Thickness(20)

            ' Create a button that with a ScaleTransform.
            ' The ScaleTransform will animate when the
            ' button is clicked.
            Dim myButton As New Button()
            myButton.Margin = New Thickness(50)
            myButton.HorizontalAlignment = HorizontalAlignment.Left
            myButton.Content = "Click Me"
            myScaleTransform = New ScaleTransform(1,1)
            myButton.RenderTransform = myScaleTransform


            ' Associate an event handler with the
            ' button's Click event.
            AddHandler myButton.Click, AddressOf myButton_Clicked

            myStackPanel.Children.Add(myButton)
            Me.Content = myStackPanel
        End Sub

        ' Create and apply and animation when the button is clicked.
        Private Sub myButton_Clicked(ByVal sender As Object, ByVal e As RoutedEventArgs)

            ' Create a DoubleAnimation to animate the
            ' ScaleTransform.
            Dim myAnimation As New DoubleAnimation(1, 5, New Duration(TimeSpan.FromSeconds(5))) ' "To" value -  "From" value
            myAnimation.AutoReverse = True

            ' Create a clock the for the animation.
            Dim myClock As AnimationClock = myAnimation.CreateClock()

            ' Associate the clock the ScaleX and
            ' ScaleY properties of the button's
            ' ScaleTransform.
            myScaleTransform.ApplyAnimationClock(ScaleTransform.ScaleXProperty, myClock)
            myScaleTransform.ApplyAnimationClock(ScaleTransform.ScaleYProperty, myClock)
        End Sub
    End Class
End Namespace
/*
    This example shows how to create and apply
    an AnimationClock.
*/

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Media.Animation;


namespace Microsoft.Samples.Animation.TimingBehaviors
{
    public class AnimationClockExample : Page
    {

        ScaleTransform myScaleTransform;

        public AnimationClockExample()
        {

            this.WindowTitle = "Opacity Animation Example";
            this.Background = Brushes.White;
            StackPanel myStackPanel = new StackPanel();
            myStackPanel.Margin = new Thickness(20);

            // Create a button that with a ScaleTransform.
            // The ScaleTransform will animate when the
            // button is clicked.
            Button myButton = new Button();
            myButton.Margin = new Thickness(50);
            myButton.HorizontalAlignment = HorizontalAlignment.Left;
            myButton.Content = "Click Me";           
            myScaleTransform = new ScaleTransform(1,1);
            myButton.RenderTransform = myScaleTransform;


            // Associate an event handler with the
            // button's Click event.
            myButton.Click += new RoutedEventHandler(myButton_Clicked);

            myStackPanel.Children.Add(myButton);
            this.Content = myStackPanel;
        }

        // Create and apply and animation when the button is clicked.
        private void myButton_Clicked(object sender, RoutedEventArgs e)
        {

            // Create a DoubleAnimation to animate the
            // ScaleTransform.
            DoubleAnimation myAnimation = 
                new DoubleAnimation(
                    1, // "From" value
                    5, // "To" value 
                    new Duration(TimeSpan.FromSeconds(5))
                );
            myAnimation.AutoReverse = true;

            // Create a clock the for the animation.
            AnimationClock myClock = myAnimation.CreateClock();            

            // Associate the clock the ScaleX and
            // ScaleY properties of the button's
            // ScaleTransform.
            myScaleTransform.ApplyAnimationClock(
                ScaleTransform.ScaleXProperty, myClock);
            myScaleTransform.ApplyAnimationClock(
                ScaleTransform.ScaleYProperty, myClock);
        }
    }
}

Чтобы создать дерево времени и использовать его для анимации свойств, выполните следующие действия.

  1. Используйте объекты ParallelTimeline и AnimationTimeline для создания дерева времени.

  2. Используйте CreateClock элемента ParallelTimeline для создания ClockGroup.

  3. Пройдите по Children элемента ClockGroup и примените его дочерние объекты Clock. Для каждого дочернего объекта AnimationClock используйте метод ApplyAnimationClock объекта, который требуется анимировать, чтобы применить AnimationClock к указанному свойству.

Дополнительные сведения об объектах Clock см. в разделе Общие сведения об анимации и системе управления временем.

Покадровая анимация: обход анимации и системы управления временем

Этот подход следует использовать, если требуется полностью обойти систему анимации WPF. Одним скриптом при таком подходе является анимация физики, при которой на каждом шаге анимации требуется пересчитывать объекты на основе последних результатов взаимодействия между объектами.

Покадровые анимации не могут быть определены внутри стилей, шаблонов элементов управления и шаблонов данных.

Для анимации "кадр-за-кадром" производится регистрация события Rendering объекта, содержащего объекты, которые требуется анимировать. Этот метод обработчика событий вызывается один раз за кадр. Каждый раз, когда WPF маршалирует сохраненные данные отрисовки в визуальном дереве через дерево композиции, вызывается метод обработчика событий.

В обработчике событий могут выполняться любые вычисления, необходимые для эффекта анимации, и задаваться свойства объектов, которые требуется анимировать с этими значениями.

Чтобы определить продолжительность текущего кадра, EventArgs, связанные с этим событием, могут быть приведены к RenderingEventArgs, предоставляющим свойство RenderingTime, которое можно использовать для получения времени отображения текущего кадра.

Дополнительные сведения см. на странице Rendering).

См. также

Основные понятия

Общие сведения об эффектах анимации

Общие сведения о Storyboard

Общие сведения об анимации и системе управления временем

Общие сведения о свойствах зависимости