Анимации по ключевым кадрам и на основе функций для реалистичной анимацииKey-frame animations and easing function animations

Линейные анимации по ключевым кадрам, анимации по ключевым кадрам со значением KeySpline или функции для реалистичной анимации – это три различных методики реализации приблизительно одного и того же сценария: создания анимации раскадровки, которая является немного более сложной и использует поведение нелинейной анимации из начального состояния в конечное состояние.Linear key-frame animations, key-frame animations with a KeySpline value, or easing functions are three different techniques for approximately the same scenario: creating a storyboarded animation that's a bit more complex, and that uses a nonlinear animation behavior from a starting state to an end state.

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

Обязательно ознакомьтесь с разделом Анимации раскадровки.Make sure you've read the Storyboarded animations topic. Данный раздел основан на понятиях анимации, которые объясняются в разделе Анимации раскадровки и не будут описаны здесь.This topic builds on the animation concepts that were explained in Storyboarded animations and won't go over them again. Например, в разделе Анимации раскадровки приводится описание нацеливания на анимации, раскадровок как ресурсов, значений свойства Timeline, например Duration, FillBehavior и т. д.For example, Storyboarded animations describes how to target animations, storyboards as resources, the Timeline property values such as Duration, FillBehavior, and so on.

Анимация по ключевым кадрамAnimating using key-frame animations

Анимации по ключевым кадрам допускают несколько целевых значений, которые достигаются в определенный момент по временной шкале анимации.Key-frame animations permit more than one target value that is reached at a point along the animation timeline. Другими словами, каждый ключевой кадр может указывать различное промежуточное значение, последний достигнутый ключевой кадр является конечным значением анимации.In other words, each key frame can specify a different intermediate value, and the last key frame reached is the final animation value. Указав несколько значений для анимирования, вы можете создавать более сложные анимации.By specifying multiple values to animate, you can make more complex animations. Кроме того, анимации по ключевым кадрам включают различную логику интерполяции, каждая из которых реализуется как отдельный подкласс KeyFrame в каждом типе анимации.Key-frame animations also enable different interpolation logic, which are each implemented as a different KeyFrame subclass per animation type. В частности, каждый тип анимации по ключевым кадрам имеет вариант Discrete, Linear, Spline и Easing класса KeyFrame для указания ключевых кадров.Specifically, each key-frame animation type has a Discrete, Linear, Spline and Easing variation of its KeyFrame class for specifying its key frames. Например, чтобы указать анимацию, которая нацеливается на Double и использует ключевые кадры, можно объявить ключевые кадры с помощью DiscreteDoubleKeyFrame, LinearDoubleKeyFrame, SplineDoubleKeyFrame и EasingDoubleKeyFrame.For example, to specify an animation that targets a Double and uses key frames, you could declare key frames with DiscreteDoubleKeyFrame, LinearDoubleKeyFrame, SplineDoubleKeyFrame, and EasingDoubleKeyFrame. Вы можете использовать один или все эти типы в одной коллекции KeyFrames, чтобы изменять интерполяцию при каждом достижении нового ключевого кадра.You can use any and all of these types within a single KeyFrames collection, to change the interpolation each time a new key frame is reached.

В поведении интерполяции каждый ключевой кадр управляет интерполяцией, пока не достигается время KeyTime.For interpolation behavior, each key frame controls the interpolation until its KeyTime time is reached. Также в это время достигается значение Value.Its Value is reached at that time also. Если существуют дополнительные ключевые кадры, то это значение становится начальным значением следующего ключевого кадра в последовательности.If there are more key frames beyond, the value then becomes the starting value for the next key frame in a sequence.

В момент начала анимации, если не существует ключевого кадра со значением KeyTime, равным "0:0:0", начальным значением является неанимированное значение свойства.At the start of the animation, if no key frame with KeyTime of "0:0:0" exists, the starting value is whatever the non-animated value of the property is. Это похоже на то, как From / To / работает анимация From-by, если нет. FromThis is similar to how a From/To/By animation acts if there is no From.

Продолжительность анимации по ключевым кадрам неявно равна самому высокому значению KeyTime, заданному в любом из ее ключевых кадров.The duration of a key-frame animation is implicitly the duration equal to the highest KeyTime value set in any of its key frames. Если требуется, вы можете задать явное значение Duration, но следите за тем, чтобы оно не было меньше значения KeyTime в собственных ключевых кадрах; в противном случае вы обрежете часть анимации.You can set an explicit Duration if you want, but be careful it's not shorter than a KeyTime in your own key frames or you'll cut off part of the animation.

Помимо Duration, в анимации по ключевым кадрам можно задать все свойства, основанные на Timeline, как в случае анимации From/To/By, поскольку классы анимации по ключевым кадрам также наследуются от Timeline.In addition to Duration, you can set all the Timeline based properties on a key-frame animation, like you can with a From/To/By animation, because the key-frame animation classes also derive from Timeline. А именно:These are:

  • AutoReverse: по достижении последнего ключевого кадра воспроизведение кадров повторяется в обратном порядке, начиная с конца.AutoReverse: once the last key frame is reached, the frames are repeated in reverse order from the end. Это удваивает кажущуюся продолжительность анимации.This doubles the apparent duration of the animation.
  • BeginTime: задерживает запуск анимации.BeginTime: delays the start of the animation. Отсчет временной шкалы для значений KeyTime в кадрах не начинается, пока не будет достигнуто значение BeginTime, что исключает риск обрезания кадров.The timeline for the KeyTime values in the frames doesn't start counting until BeginTime is reached, so there's no risk of cutting off frames
  • FillBehavior: определение дальнейших действий по достижении последнего ключевого кадра.FillBehavior: controls what happens when the last key frame is reached. FillBehavior не влияет на какие-либо промежуточные ключевые кадры.FillBehavior has no effect on any intermediate key frames.
  • RepeatBehavior:RepeatBehavior:
    • Если задано значение Forever, ключевые кадры и их временная шкала повторяются бесконечно.If set to Forever, then the key frames and their timeline repeat infinitely.
    • Если задан счетчик итерации, временная шкала повторяется указанное количество раз.If set to an iteration count, the timeline repeats that many times.
    • Если задано значение Duration, временная шкала повторяется, пока не будет достигнуто это значение времени.If set to a Duration, the timeline repeats until that time is reached. Это может привести к усечению анимации во время последовательности ключевых кадров, если значение не является целым множителем значения неявной продолжительности временной шкалы.This might truncate the animation part way through the key frame sequence, if it's not an integer factor of the timeline's implicit duration.
  • SpeedRatio (не является широко используемым)SpeedRatio (not commonly used)

Линейные ключевые кадрыLinear key frames

Линейные ключевые кадры приводят к простой линейной интерполяции значения, пока не будет достигнуто значение KeyTime кадра.Linear key frames result in a simple linear interpolation of the value until the frame's KeyTime is reached. Такое поведение интерполяции наиболее похоже на то, что проще , чем с / To / помощью анимации, описанной в разделе раскадровая анимация .This interpolation behavior is the most similar to the simpler From/To/By animations described in the Storyboarded animations topic.

Ниже приводится описание использования анимации по ключевым кадрам для масштабирования отображаемой высоты прямоугольника с помощью линейных ключевых кадров.Here's how to use a key-frame animation to scale the render height of a rectangle, using linear key frames. В этом примере выполняется анимация, в которой высота прямоугольника немного увеличивается линейно в течение первых 4 секунд, а затем быстро масштабируется в течение последней секунды, пока высота прямоугольника не увеличится в два раза по сравнению с начальной высотой.This example runs an animation where the height of the rectangle increases slightly and linearly for the first 4 seconds, then scales rapidly for the last second until the rectangle is double the starting height.

<StackPanel>
    <StackPanel.Resources>
        <Storyboard x:Name="myStoryboard">
            <DoubleAnimationUsingKeyFrames
              Storyboard.TargetName="myRectangle"
              Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)">
                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:0"/>
                <LinearDoubleKeyFrame Value="1.2" KeyTime="0:0:4"/>
                <LinearDoubleKeyFrame Value="2" KeyTime="0:0:5"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </StackPanel.Resources>
</StackPanel>

Дискретные ключевые кадрыDiscrete key frames

Дискретные ключевые кадры не используют интерполяцию вовсе.Discrete key frames don't use any interpolation at all. По достижении значения KeyTime просто применяется новое значение Value.When a KeyTime is reached, the new Value is simply applied. В зависимости от того, какое свойство пользовательского интерфейса анимируется, это часто приводит к тому, что кажется, будто анимация "прыгает".Depending on which UI property is being animated, this often produces an animation that appears to "jump". Убедитесь, что это именно то поведение, которое вам нужно.Be certain that this is the aesthetic behavior that you really want. Вы можете свести к минимуму видимые прыжки, увеличив количество объявляемых ключевых кадров, но если вам требуется плавная анимация, рекомендуется использовать линейные или сплайновые ключевые кадры.You can minimize the apparent jumps by increasing the number of key frames you declare, but if a smooth animation is your goal, you might be better off using linear or spline key frames instead.

Примечание

Дискретные ключевые кадры — это единственный способ анимировать значение, которое не относится к типам Double, Point и Color, с помощью DiscreteObjectKeyFrame.Discrete key frames are the only way to animate a value that isn't of type Double, Point, and Color, with a DiscreteObjectKeyFrame. Более подробное описание процесса приводится далее в этом разделе.We'll discuss this in more detail later in this topic.

Сплайновые ключевые кадрыSpline key frames

Сплайновый ключевой кадр создает изменяемый переход между значениями в соответствии со значением свойства KeySpline.A spline key frame creates a variable transition between values according to the value of the KeySpline property. Это свойство указывает первую и вторую контрольные точки кривой Безье, которая описывает ускорение анимации.This property specifies the first and second control points of a Bezier curve, which describes the acceleration of the animation. По сути, KeySpline определяет отношение функции и времени, где график зависимости функции от времени является формой этой кривой Безье.Basically, a KeySpline defines a function-over-time relationship where the function-time graph is the shape of that Bezier curve. Обычно указывается значение KeySpline в строке собирательного атрибута XAML, содержащей четыре значения Double, разделенные пробелами или запятыми.You typically specify a KeySpline value in a XAML shorthand attribute string that has four Double values separated by spaces or commas. Эти значения являются парами "X,Y" двух контрольных точек кривой Безье.These values are "X,Y" pairs for two control points of the Bezier curve. "X" – это время, а "Y" – модификатор функции в зависимости от значения."X" is time and "Y" is the function modifier to the value. Каждое значение всегда должно находиться в диапазоне от 0 до 1 включительно.Each value should always be between 0 and 1 inclusive. Без модификации контрольной точки в соответствии со значением KeySpline прямая линия в диапазоне от (0;0) до (1;1) является представлением функции во времени для линейной интерполяции.Without control point modification to a KeySpline, the straight line from 0,0 to 1,1 is the representation of a function over time for a linear interpolation. Контрольные точки изменяют форму этой кривой и, следовательно, поведение функции во времени для сплайновой анимации.Your control points change the shape of that curve and thus the behavior of the function over time for the spline animation. Возможно, визуально это лучше рассматривать как график.It's probably best to see this visually as a graph. Вы можете выполнить образец визуализатора ключ-сплайн Silverlight в браузере, чтобы просмотреть, как контрольные точки изменяют кривую и как выполняется анимация примера при использовании его в качестве значения KeySpline.You can run the Silverlight key-spline visualizer sample in a browser to see how the control points modify the curve and how a sample animation runs when using it as a KeySpline value.

В следующем примере показано три различных ключевых кадра, применяемых к анимации, которая является ключевой сплайновой анимацией для значения Double (SplineDoubleKeyFrame).This next example shows three different key frames applied to an animation, with the last one being a key spline animation for a Double value (SplineDoubleKeyFrame). Обратите внимание на строку "0.6,0.0 0.9,0.00", применяемую к KeySpline.Note the string "0.6,0.0 0.9,0.00" applied for KeySpline. В результате создается кривая, в которой анимация сначала выполняется медленно, а затем быстро достигает этого значения незадолго до достижения KeyTime.This produces a curve where the animation appears to run slowly at first but then rapidly reaches the value just before the KeyTime is reached.

<Storyboard x:Name="myStoryboard">
    <!-- Animate the TranslateTransform's X property
        from 0 to 350, then 50,
        then 200 over 10 seconds. -->
    <DoubleAnimationUsingKeyFrames
        Storyboard.TargetName="MyAnimatedTranslateTransform"
        Storyboard.TargetProperty="X"
        Duration="0:0:10" EnableDependentAnimation="True">

        <!-- Using a LinearDoubleKeyFrame, the rectangle moves 
            steadily from its starting position to 500 over 
            the first 3 seconds.  -->
        <LinearDoubleKeyFrame Value="500" KeyTime="0:0:3"/>

        <!-- Using a DiscreteDoubleKeyFrame, the rectangle suddenly 
            appears at 400 after the fourth second of the animation. -->
        <DiscreteDoubleKeyFrame Value="400" KeyTime="0:0:4"/>

        <!-- Using a SplineDoubleKeyFrame, the rectangle moves 
            back to its starting point. The
            animation starts out slowly at first and then speeds up. 
            This KeyFrame ends after the 6th second. -->
        <SplineDoubleKeyFrame KeySpline="0.6,0.0 0.9,0.00" Value="0" KeyTime="0:0:6"/>
    </DoubleAnimationUsingKeyFrames>
</Storyboard>

Ключевые кадры для реалистичной анимацииEasing key frames

Ключевой кадр для реалистичной анимации — это ключевой кадр, в котором применяется интерполяция, а управление зависимостью функции от времени интерполяции осуществляется с помощью нескольких предопределенных математических формул.An easing key frame is a key frame where interpolation is being applied, and the function over time of the interpolation is controlled by several pre-defined mathematical formulas. Фактически, используя типы функции для реалистичной анимации, вы можете получить почти такой же результат, что и при использовании сплайнового ключевого кадра, однако существуют некоторые функции для реалистичной анимации, например BackEase, которые невозможно воспроизвести с помощью сплайна.You can actually produce much the same result with a spline key frame as you can with some of the easing function types, but there are also some easing functions, such as BackEase, that you can't reproduce with a spline.

Чтобы применить функцию для реалистичной анимации к ключевому кадру для реалистичной анимации, установите свойство EasingFunction в качестве элемента свойства в XAML для данного ключевого кадра.To apply an easing function to an easing key frame, you set the EasingFunction property as a property element in XAML for that key frame. В качестве значения укажите элемент объекта для одного из типов функции для реалистичной анимации.For the value, specify an object element for one of the easing function types.

В этом примере CubicEase, а затем BounceEase применяются в качестве последовательных ключевых кадров к DoubleAnimation для создания эффекта отскакивания.This example applies a CubicEase and then a BounceEase as successive key frames to a DoubleAnimation to create a bouncing effect.

<Storyboard x:Name="myStoryboard">
    <DoubleAnimationUsingKeyFrames Duration="0:0:10"
        Storyboard.TargetProperty="Height"
        Storyboard.TargetName="myEllipse">

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

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

Это всего лишь один из примеров функции для реалистичной анимации.This is just one easing function example. Подробнее о них вы узнаете в следующем разделе.We'll cover more in the next section.

Функции для реалистичной анимацииEasing functions

Функции плавности позволяют применять к анимациям настраиваемые математические формулы.Easing functions allow you to apply custom mathematical formulas to your animations. Математические операции часто полезны для создания анимаций, которые имитируют реальную физику в двухмерной системе координат.Mathematical operations are often useful to produce animations that simulate real-world physics in a 2-D coordinate system. Например, требуется реалистичный отскок объекта или его поведение так, словно он подвешен на пружине.For example, you may want an object to realistically bounce or behave as though it were on a spring. Можно использовать ключевой кадр или даже в / To / анимации для приближения этих эффектов , но это займет значительный объем работы, и анимация будет менее точной, чем использование математической формулы.You could use key frame or even From/To/By animations to approximate these effects but it would take a significant amount of work and the animation would be less accurate than using a mathematical formula.

Функции для реалистичной анимации можно применять к анимациям тремя способами.Easing functions can be applied to animations in three ways:

Ниже представлен список функций для реалистичной анимации.Here is a list of the easing functions:

  • BackEase: объект немного отводится в противоположную сторону, прежде чем начинает двигаться по заданному пути.BackEase: Retracts the motion of an animation slightly before it begins to animate in the path indicated.
  • BounceEase: создается эффект отскакивания.BounceEase: Creates a bouncing effect.
  • CircleEase: создается анимация, которая ускоряется или замедляется на основании круговой функции.CircleEase: Creates an animation that accelerates or decelerates using a circular function.
  • CubicEase: создается анимация, которая ускоряется или замедляется на основании формулы f(t) = t3.CubicEase: Creates an animation that accelerates or decelerates using the formula f(t) = t3.
  • ElasticEase: создается анимация, напоминающая колебания пружины взад и вперед до полной остановки.ElasticEase: Creates an animation that resembles a spring oscillating back and forth until it comes to rest.
  • ExponentialEase: создается анимация, которая ускоряется или замедляется на основании экспоненциальной формулы.ExponentialEase: Creates an animation that accelerates or decelerates using an exponential formula.
  • PowerEase: создается анимация, которая ускоряется или замедляется на основании формулы f(t) = tp, где p равно свойству Power.PowerEase: Creates an animation that accelerates or decelerates using the formula f(t) = tp where p is equal to the Power property.
  • QuadraticEase: создается анимация, которая ускоряется или замедляется на основании формулы f(t) = t2.QuadraticEase: Creates an animation that accelerates or decelerates using the formula f(t) = t2.
  • QuarticEase: создается анимация, которая ускоряется или замедляется на основании формулы f(t) = t4.QuarticEase: Creates an animation that accelerates or decelerates using the formula f(t) = t4.
  • QuinticEase: создается анимация, которая ускоряется или замедляется на основании формулы f(t) = t5.QuinticEase: Create an animation that accelerates or decelerates using the formula f(t) = t5.
  • SineEase: создается анимация, которая ускоряется или замедляется на основании синусоидальной функции.SineEase: Creates an animation that accelerates or decelerates using a sine formula.

Некоторые из функций для реалистичной анимации имеют собственные свойства.Some of the easing functions have their own properties. Например, BounceEase имеет два свойства Bounces и Bounciness, которые изменяют поведение функции во времени данной конкретной функции BounceEase.For example, BounceEase has two properties Bounces and Bounciness that modify the function-over-time behavior of that particular BounceEase. Другие функции для реалистичной анимации, такие как CubicEase, не имеют иных свойств, кроме свойства EasingMode, общего для всех функций для реалистичной анимации, и всегда создают одинаковое поведение функции во времени.Other easing functions such as CubicEase don't have properties other than the EasingMode property that all easing functions share, and always produce the same function-over-time behavior.

Некоторые из этих функций для реалистичной анимации немного перекрываются в зависимости от настроек свойств функций для реалистичной анимации, имеющих их.Some of these easing functions have a bit of overlap, depending on how you set properties on the easing functions that have properties. Например, QuadraticEase абсолютно совпадает с PowerEase со значением Power, равным 2.For example, QuadraticEase is exactly the same as a PowerEase with Power equal to 2. Кроме того, CircleEase обычно является значением по умолчанию ExponentialEase.And CircleEase is basically a default-value ExponentialEase.

Функция для реалистичной анимации BackEase уникальна, поскольку она может изменять значение за пределами обычного диапазона, заданного с помощью From/To или значений ключевых кадров.The BackEase easing function is unique because it can change the value outside of the normal range as set by From/To or values of key frames. Он запускает анимацию, изменяя значение в противоположном направлении, как ожидалось от нормального / до поведения, возвращается к значению from или Start и затем запускает анимацию в обычном режиме.It starts the animation by changing the value in the opposite direction as would be expected from a normal From/To behavior, goes back to the From or starting value again, and then runs the animation as normal.

В предыдущем примере мы показали, как объявить функцию для реалистичной анимации в случае анимации по ключевым кадрам.In an earlier example, we showed how to declare an easing function for a key-frame animation. В следующем примере функция плавности применяется к анимации из / в / By .This next sample applies an easing function to a From/To/By animation.

<StackPanel x:Name="LayoutRoot" Background="White">
    <StackPanel.Resources>
        <Storyboard x:Name="myStoryboard">
            <DoubleAnimation From="30" To="200" Duration="00:00:3" 
                Storyboard.TargetName="myRectangle" 
                Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)">
                <DoubleAnimation.EasingFunction>
                    <BounceEase Bounces="2" EasingMode="EaseOut" 
                                Bounciness="2"/>
                </DoubleAnimation.EasingFunction>
            </DoubleAnimation>
        </Storyboard>
    </StackPanel.Resources>
    <Rectangle x:Name="myRectangle" Fill="Blue" Width="200" Height="30"/>
</StackPanel>

Если функция плавности применяется к анимации from / to / by , она изменяет характеристики, с которым происходит интерполяция значения между значениями от до и до времени анимации. DurationWhen an easing function is applied to a From/To/By animation, it's changing the function- over-time characteristics of how the value interpolates between the From and To values over the Duration of the animation. Без функции для реалистичной анимации это была бы линейная интерполяция.Without an easing function, that would be a linear interpolation.

Анимация значений дискретных объектовDiscrete object value animations

Один тип анимации заслуживает особого внимания, поскольку это единственный способ применения анимированного значения к свойствам, не принадлежащим к типу Double, Point или Color.One type of animation deserves special mention because it's the only way you can apply an animated value to properties that aren't of type Double, Point, or Color. Это анимация по ключевым кадрам ObjectAnimationUsingKeyFrames.This is the key-frame animation ObjectAnimationUsingKeyFrames. Анимирование с помощью значений Object отличается, поскольку возможность интерполяции значений между кадрами отсутствует.Animating using Object values is different because there's no possibility of interpolating the values between the frames. По достижении значения KeyTime кадра анимированное значение незамедлительно становится равным значению, указанному в Value ключевого кадра.When the frame's KeyTime is reached, the animated value is immediately set to the value specified in the key frame's Value. Поскольку интерполяции нет, существует только один ключевой кадр, который можно использовать в коллекции ключевых кадров ObjectAnimationUsingKeyFrames: DiscreteObjectKeyFrame.Because there's no interpolation, there's only one key frame you use in the ObjectAnimationUsingKeyFrames key frames collection: DiscreteObjectKeyFrame.

Значение ValueDiscreteObjectKeyFrame часто задается с помощью синтаксиса элемента свойства, поскольку значение объекта, которое вы пытаетесь задать, часто не может быть выражено в качестве строки для заполнения Value в синтаксисе атрибута.The Value of a DiscreteObjectKeyFrame is often set using property element syntax, because the object value you are trying to set often is not expressible as a string to fill Value in attribute syntax. Вы по-прежнему можете использовать синтаксис атрибута, если используется образец, например StaticResource.You can still use attribute syntax if you use a reference such as StaticResource.

Одним из случаев, когда можно увидеть ObjectAnimationUsingKeyFrames, используемый в шаблонах по умолчанию, является ситуация, когда свойство шаблона ссылается на ресурс Brush.One place you'll see an ObjectAnimationUsingKeyFrames used in the default templates is when a template property references a Brush resource. Эти ресурсы являются объектами SolidColorBrush, а не только значением Color, и используют ресурсы, определенные как системные темы (ThemeDictionaries).These resources are SolidColorBrush objects, not just a Color value, and they use resources that are defined as system themes (ThemeDictionaries). Их можно назначить непосредственно значению типа Brush, такому как TextBlock.Foreground; непрямое нацеливание использовать не требуется.They can be assigned directly to a Brush-type value such as TextBlock.Foreground and don't need to use indirect targeting. Но поскольку SolidColorBrush не является Double, Point или Color, необходимо применить ObjectAnimationUsingKeyFrames для использования ресурса.But because a SolidColorBrush is not Double, Point, or Color, you have to use a ObjectAnimationUsingKeyFrames to use the resource.

<Style x:Key="TextButtonStyle" TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid Background="Transparent">
                    <TextBlock x:Name="Text"
                        Text="{TemplateBinding Content}"/>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="PointerOver">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPointerOverForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPressedForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
...
                       </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Также возможно использование ObjectAnimationUsingKeyFrames для анимирования свойств, использующих значение перечисления.You also might use ObjectAnimationUsingKeyFrames to animate properties that use an enumeration value. Вот другой пример из именованного стиля, построенного по шаблонам среды выполнения Windows по умолчанию.Here's another example from a named style that comes from the Windows Runtime default templates. Обратите внимание на то, как задается свойство Visibility, которое принимает константу перечисления Visibility.Note how it sets the Visibility property that takes a Visibility enumeration constant. В этом случае можно задать значение, используя синтаксис атрибута.In this case you can set the value using attribute syntax. Вам потребуется только неполное имя константы из перечисления для задания свойства со значением перечисления, например "Collapsed".You only need the unqualified constant name from an enumeration for setting a property with an enumeration value, for example "Collapsed".

<Style x:Key="BackButtonStyle" TargetType="Button">
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="Button">
          <Grid x:Name="RootGrid">
            <VisualStateManager.VisualStateGroups>
              <VisualStateGroup x:Name="CommonStates">
              <VisualState x:Name="Normal"/>
...           <VisualState x:Name="Disabled">
                <Storyboard>
                  <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Visibility">
                    <DiscreteObjectKeyFrame Value="Collapsed" KeyTime="0"/>
                  </ObjectAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
            </VisualStateGroup>
...
          </VisualStateManager.VisualStateGroups>
        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

Можно использовать несколько DiscreteObjectKeyFrame для набора кадров ObjectAnimationUsingKeyFrames.You can use more than one DiscreteObjectKeyFrame for an ObjectAnimationUsingKeyFrames frame set. Анимирование значения Image.Source может быть интересным способом создания анимации слайд-шоу, поскольку пример сценария с несколькими значениями объекта может оказаться полезен.This might be an interesting way to create a "slide show" animation by animating the value of Image.Source, as an example scenario for where multiple object values might be useful.