Анимация WPF

Каждая анимация в WPF работает на основе отдельного свойства зависимости. Для того, что бы анимировать свойство, требуется класс
анимации, который поддерживает тип данных свойства. Например, для анимации свойства Height типа Double следует использовать класс DoubleAnimation Стандартная частота анимации — 60 кадров в секунду.

Типы анимации

  • Линейная интерполяция – последовательное изменения значения свойства (такие классы называются по принципу <ИмяТипа>Animation, например, ColorAnimation, DoubleAnimation)
  • Анимация ключевого кадра – изменения свойств в определенный моментвремени (такие классы называются <ИмяТипа>AnimationUsingKeyFrames, например, DoubleAnimationUsingKeyFrames)
  • Анимация на основе пути – изменения значения свойства на основе фигуры, описанной в объекте PathGeometry

Свойства объектов анимации

  • From – начальное значение, с которого начнется анимация.
  • To – значение анимированного свойства, до которого будет работать анимация.
  • By – для создания анимации, которая изменяет значение свойства на определенную величину.
  • Duration – продолжительность анимации. Задается с помощью объекта Duration

Свойства TimeLine

TimeLine – базовый класс для всех объектов анимации.

  • BeginTime – задержка перед запуском анимации.
  • Duration – продолжительность
  • SpeedRatio – изначально равно 1. Чем больше значение, тем быстрее проиграется видео, например, если значение 2, то видео закончится в два раза быстрее.
  • AccelerationRatio и DecelerationRatio – Делает скорость воспроизведения анимации не линейной. Ускорение и замедление при анимации. Значения от 0 до 1.
  • AutoRevers – анимация будет запущена в обратном порядке, как только завершится.
  • FillBehavior – определяет, что случится по завершению анимации. Оставить значения свойств зафиксированными HoldEnd или вернуть к исходным Stop.
  • RepeatBehavior – позволяет повторить анимацию заданное количество раз, в течении указанного интервала времени.

Анимация ключевого кадра

Анимация ключевого кадра состоит из множества коротких сегментов.

  • LinerPointKeyFrame – линейный ключевой кадр, при переходе от ключа к ключу выполняется линейная интерполяция для анимируемых свойств.
  • DiscretePointKeyFrame – при переходе между кадрами дискретного ключа интерполяция не производится.

Пример простой анимации.

DoubleAnimation animation = new DoubleAnimation();
            
            animation.From = 100;
            animation.To = 250;
            animation.Duration = TimeSpan.FromSeconds(2);

            Rect.BeginAnimation(Rectangle.HeightProperty, animation);

 

Пример Xaml анимации

<Window x:Class="XAMLAnimation.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Настройки анимации в XAML разметке" Height="350" Width="525">
    <Button Padding="10"  
            Height="40" Width="160"
            HorizontalAlignment="Center" VerticalAlignment="Center">
        
        <Button.Triggers>
            <!--Триггер сработает на событие-->
            <EventTrigger RoutedEvent="Button.Click">
                <EventTrigger.Actions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetProperty="Width"
                                             To="200"
                                             Duration="0:0:1">
                            </DoubleAnimation>
                          
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger.Actions>
            </EventTrigger>
        </Button.Triggers>
        
        <Button.Content>
            Кнопка
        </Button.Content>
    </Button>
</Window>

 

Пример анимации в Style Xaml разметке

<Window x:Class="AnimationInStyle.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="nookery.ru Анимация в стиле" Height="350" Width="525">
    <Window.Resources>
        <Style x:Key="GrowButtonStyle">

            <Style.Triggers>

                <Trigger Property="Button.IsPressed" Value="True">

                    <!--EnterActions - действие при включении триггера-->
                    <Trigger.EnterActions>
                        <BeginStoryboard>
                            <Storyboard AccelerationRatio="1">
                                <DoubleAnimation 
                                    Storyboard.TargetProperty="Height"
                                    To="250" 
                                    Duration="0:0:1"></DoubleAnimation>
                            </Storyboard>
                        </BeginStoryboard>
                    </Trigger.EnterActions>

                    <!--ExitActions - действие при завершении триггера-->
                    <Trigger.ExitActions>
                        <BeginStoryboard>
                            <Storyboard DecelerationRatio="1">
                                <DoubleAnimation 
                                    Storyboard.TargetProperty="Height"
                                    To="100" 
                                    Duration="0:0:1"></DoubleAnimation>
                            </Storyboard>
                        </BeginStoryboard>
                    </Trigger.ExitActions>

                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>

    <Button Padding="10" Name="cmdGrow" Height="50" Width="150" Style="{StaticResource GrowButtonStyle}"
          HorizontalAlignment="Center" VerticalAlignment="Center">
        Нажать на кнопку
    </Button>
</Window>


 

Пример, анимации смены дня и ночи на картинке, используем только Xaml

<Window x:Class="WipePlayer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="nookery.ru" Height="350" Width="525">
    <Grid>
        
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>
        
        <Grid>
            
            <Image Source="night.jpg"></Image>
            <Image Source="day.jpg" >
                <Image.OpacityMask>
                    <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                        <GradientStop Offset="0" Color="Transparent" x:Name="transparentStop" />
                        <GradientStop Offset="0" Color="Black" x:Name="visibleStop" />
                    </LinearGradientBrush>
                </Image.OpacityMask>
            </Image>
            
        </Grid>

        <Button  Grid.Row="1" Padding="5" Margin="5">
            Start
            
            <Button.Triggers>
                <EventTrigger RoutedEvent="Button.Click">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation
                                Storyboard.TargetName="visibleStop"
                                Storyboard.TargetProperty="Offset"
                                From="0" To="1.5" Duration="0:0:1.5" ></DoubleAnimation>
                            
                            <DoubleAnimation
                                Storyboard.TargetName="transparentStop"
                                Storyboard.TargetProperty="Offset" BeginTime="0:0:0.5" 
                                From="0" To="1" Duration="0:0:1" ></DoubleAnimation>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Button.Triggers>
        </Button>
    </Grid>
</Window>

 

Пример анимационной трансформации вращения кнопок.

<Window x:Class="RotateAnimation.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="nookery.ru Анимация трансформации" Height="350" Width="525">
    <Window.Resources>

        <Style TargetType="{x:Type Button}">
            
            <Setter Property="HorizontalAlignment" Value="Center"></Setter>
            <Setter Property="RenderTransformOrigin" Value="0.5,0.5"></Setter>
            <Setter Property="Padding" Value="20,15"></Setter>
            <Setter Property="Margin" Value="2"></Setter>
            <Setter Property="RenderTransform">
                <Setter.Value>
                    <RotateTransform></RotateTransform>
                </Setter.Value>
            </Setter>
            
            <Style.Triggers>
                
                <EventTrigger RoutedEvent="Button.MouseEnter">
                    <EventTrigger.Actions>
                        <BeginStoryboard Name="rotateStoryboardBegin">
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle"
                                                 To="360" Duration="0:0:0.8"
                                                 RepeatBehavior="Forever">
                                </DoubleAnimation>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
                
                <EventTrigger RoutedEvent="Button.MouseLeave">
                    <EventTrigger.Actions>
                         <!--<RemoveStoryboard BeginStoryboardName="rotateStoryboardBegin"></RemoveStoryboard>--> 
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle"
                                                 Duration="0:0:0.2">
                                </DoubleAnimation>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
                
            </Style.Triggers>
        </Style>

    </Window.Resources>
    <StackPanel Margin="5">
        <Button>One</Button>
        <Button>Two</Button>
        <Button>Three</Button>
        <Button>Four</Button>
    </StackPanel>
</Window>

 

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

Пример анимации перемещения изображения по созданному пути.

<Window.Resources>
    <PathGeometry x:Key="path" >
        <PathFigure IsClosed="True">
            <ArcSegment Point="100,200" Size="15,10" SweepDirection="Clockwise"></ArcSegment>
            <ArcSegment Point="400,50" Size="5,5" ></ArcSegment>
        </PathFigure>
    </PathGeometry>
</Window.Resources>

<Window.Triggers>
    <EventTrigger RoutedEvent="Window.Loaded">

        <EventTrigger.Actions>
            <BeginStoryboard>
                <Storyboard>
                    <!--Анимация с использованием пути-->
                    <DoubleAnimationUsingPath Storyboard.TargetName="image"
                                              Storyboard.TargetProperty="(Canvas.Left)"
                                              PathGeometry="{StaticResource path}"
                                              Source="X"
                                              Duration="0:0:5" RepeatBehavior="Forever"  />

                    <DoubleAnimationUsingPath Storyboard.TargetName="image"
                                              Storyboard.TargetProperty="(Canvas.Top)"
                                              PathGeometry="{StaticResource path}"
                                              Duration="0:0:5" RepeatBehavior="Forever" Source="Y" />
               </Storyboard>
            </BeginStoryboard>
        </EventTrigger.Actions>

    </EventTrigger>
</Window.Triggers>

<Canvas Margin="10">

    <Path StrokeThickness="1" Data="{StaticResource path}" Canvas.Top="10" Canvas.Left="10" Stroke="Transparent">
    </Path>

    <Image Name="image">
        <Image.Source>
            <DrawingImage>
                <DrawingImage.Drawing>
                    <GeometryDrawing Brush="LightSteelBlue">

                        <GeometryDrawing.Geometry>
                            <GeometryGroup>
                                <EllipseGeometry Center="10,10" RadiusX="9" RadiusY="4" />
                                <EllipseGeometry Center="10,10" RadiusX="4" RadiusY="9" />
                            </GeometryGroup>
                        </GeometryDrawing.Geometry>

                        <GeometryDrawing.Pen>
                            <Pen Thickness="1" Brush="Black" />
                        </GeometryDrawing.Pen>

                    </GeometryDrawing>
                </DrawingImage.Drawing>
            </DrawingImage>
        </Image.Source>
    </Image>
</Canvas>

 

.

Обновлено: 30.04.2021 — 16:47

2 комментария

Оставить комментарий
  1. Дмитрий

    Спасибо за полезности ))

    1. Пожалуйста

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.