Функции плавности

Функции плавности позволяют применять к анимациям настраиваемые математические формулы. Например, требуется реалистичный отскок объекта или его поведение так, словно он подвешен на пружине. Для приблизительного воспроизведения этих эффектов можно использовать анимацию по ключевым кадрам или даже анимацию From/To/By, но это потребует значительного объема работы, и анимация будет менее точна, чем при использовании математических формул.

Кроме создания собственной функции плавности путем наследования от EasingFunctionBase, можно использовать одну из функций плавности, предоставляемых средой выполнения для создания распространенных эффектов.

  • BackEase: Объект немного отводится в противоположную сторону, прежде чем начинает двигаться по заданному пути.

  • BounceEase: Создается эффект отскакивания.

  • CircleEase: Создается анимация, которая ускоряется и/или замедляется на основании круговой функции.

  • CubicEase: создается анимация, которая ускоряется или замедляется на основании формулы f(t) = t3.

  • ElasticEase: создается анимация, напоминающая колебания пружины взад и вперед до полной остановки.

  • ExponentialEase: создается анимация, которая ускоряется и/или замедляется на основании экспоненциальной формулы.

  • PowerEase: представляет функцию для реалистичной анимации, которая создает анимацию, ускоряющуюся и/или замедляющуюся по формуле f(t) = tp, где p равно значению свойства Power.

  • QuadraticEase: создается анимация, которая ускоряется и/или замедляется на основании формулы f(t) = t2.

  • QuarticEase: создается анимация, которая ускоряется и/или замедляется на основании формулы f(t) = t4.

  • QuinticEase: создается анимация, которая ускоряется и/или замедляется на основании формулы f(t) = t5.

  • SineEase: создается анимация, которая ускоряется и/или замедляется на основании синусоидальной функции.

Для применения функции плавности к анимации нужно использовать свойство EasingFunction анимации для указания функции плавности. В следующем примере функция плавности BounceEase применяется к DoubleAnimation для создания эффекта отскакивания.

<Rectangle Name="myRectangle" Width="200" Height="30" Fill="Blue">
    <Rectangle.Triggers>
        <EventTrigger RoutedEvent="Rectangle.MouseDown">
            <BeginStoryboard>
                <Storyboard>
                    <Storyboard x:Name="myStoryboard">
                        <DoubleAnimation From="30" To="200" Duration="00:00:3" 
                         Storyboard.TargetName="myRectangle" 
                         Storyboard.TargetProperty="Height">
                            <DoubleAnimation.EasingFunction>
                                <BounceEase Bounces="2" EasingMode="EaseOut" 
                                 Bounciness="2" />
                            </DoubleAnimation.EasingFunction>
                        </DoubleAnimation>
                    </Storyboard>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Rectangle.Triggers>
</Rectangle>

В предыдущем примере функция плавности применялась к анимации From/To/By. Эти функции плавности можно применять и к анимации по ключевым кадрам. В следующем примере показано, как использовать ключевые кадры с функциями плавности для создания анимации прямоугольника, который сокращается вверх, замедляется вниз, затем расширяется вниз (как будто падает), а затем подпрыгивает до остановки.

<Rectangle Name="myRectangle" Width="200" Height="200" Fill="Blue">
    <Rectangle.Triggers>
        <EventTrigger RoutedEvent="Rectangle.MouseDown">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimationUsingKeyFrames
                     Storyboard.TargetProperty="Height"
                     Storyboard.TargetName="myRectangle">

                        <!-- This keyframe animates the ellipse up to the crest 
                             where it slows down and stops. -->
                        <EasingDoubleKeyFrame Value="30" KeyTime="00:00:02">
                            <EasingDoubleKeyFrame.EasingFunction>
                                <CubicEase EasingMode="EaseOut"/>
                            </EasingDoubleKeyFrame.EasingFunction>
                        </EasingDoubleKeyFrame>

                        <!-- This keyframe animates the ellipse back down and makes
                             it bounce. -->
                        <EasingDoubleKeyFrame Value="200" KeyTime="00:00:06">
                            <EasingDoubleKeyFrame.EasingFunction>
                                <BounceEase Bounces="5" EasingMode="EaseOut"/>
                            </EasingDoubleKeyFrame.EasingFunction>
                        </EasingDoubleKeyFrame>

                    </DoubleAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Rectangle.Triggers>

</Rectangle>

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

  • EaseIn: Интерполяция производится по математической формуле, связанной с функцией плавности.

  • EaseOut: Интерполяция соответствует 100% интерполяции минус результат формулы, связанной с функцией плавности.

  • EaseInOut: Интерполяция использует EaseIn для первой половины анимации и EaseOut для второй половины.

На следующих диаграммах показаны различные значения свойства EasingMode, гдеf(x) обозначает ход анимации, а t — время.

BackEase

BackEase EasingMode graphs.

BounceEase

BounceEase EasingMode graphs.

CircleEase

CircleEase EasingMode graphs.

CubicEase

CubicEase EasingMode graphs.

ElasticEase

ElasticEase with graphs of different easingmodes.

ExponentialEase

ExponentialEase graphs of different easingmodes.

PowerEase

QuarticEase with graphs of different easingmodes.

QuadraticEase

QuadraticEase with graphs of different easingmodes

QuarticEase

QuarticEase with graphs of different easingmodes.

QuinticEase

QuinticEase with graphs of different easingmodes.

SineEase

SineEase for different EasingMode values

Примечание.

Можно использовать PowerEase для создания того же поведения, что и CubicEase, QuadraticEase, QuarticEase и QuinticEase с помощью свойства Power. Например, если вы хотите использовать PowerEase для замены CubicEase, укажите для Power значение 3.

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

namespace CustomEasingFunction
{
    public class CustomSeventhPowerEasingFunction : EasingFunctionBase
    {
        public CustomSeventhPowerEasingFunction()
            : base()
        {
        }

        // Specify your own logic for the easing function by overriding
        // the EaseInCore method. Note that this logic applies to the "EaseIn"
        // mode of interpolation.
        protected override double EaseInCore(double normalizedTime)
        {
            // applies the formula of time to the seventh power.
            return Math.Pow(normalizedTime, 7);
        }

        // Typical implementation of CreateInstanceCore
        protected override Freezable CreateInstanceCore()
        {

            return new CustomSeventhPowerEasingFunction();
        }
    }
}
Namespace CustomEasingFunction
    Public Class CustomSeventhPowerEasingFunction
        Inherits EasingFunctionBase
        Public Sub New()
            MyBase.New()
        End Sub

        ' Specify your own logic for the easing function by overriding
        ' the EaseInCore method. Note that this logic applies to the "EaseIn"
        ' mode of interpolation. 
        Protected Overrides Function EaseInCore(ByVal normalizedTime As Double) As Double
            ' applies the formula of time to the seventh power.
            Return Math.Pow(normalizedTime, 7)
        End Function

        ' Typical implementation of CreateInstanceCore
        Protected Overrides Function CreateInstanceCore() As Freezable

            Return New CustomSeventhPowerEasingFunction()
        End Function

    End Class
End Namespace
<Window x:Class="CustomEasingFunction.Window1"
        xmlns:CustomEase="clr-namespace:CustomEasingFunction"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="500" Width="300">
    <StackPanel>
        <TextBlock Margin="10" TextWrapping="Wrap">Click on the rectangle to start the animation</TextBlock>
        <StackPanel x:Name="LayoutRoot" Background="White">

            <Rectangle Name="myRectangle" Width="200" Height="30" Fill="Blue">
                <Rectangle.Triggers>
                    <EventTrigger RoutedEvent="Rectangle.MouseDown">
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation From="30" To="300" Duration="00:00:3" 
                                 Storyboard.TargetName="myRectangle" 
                                 Storyboard.TargetProperty="Height">
                                    <DoubleAnimation.EasingFunction>

                                        <!-- You get the EasingMode property for free on your custom
                                             easing function.-->
                                        <CustomEase:CustomSeventhPowerEasingFunction EasingMode="EaseIn"/>
                                    </DoubleAnimation.EasingFunction>
                                </DoubleAnimation>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </Rectangle.Triggers>

            </Rectangle>

        </StackPanel>
    </StackPanel>

</Window>