Раскадровки анимаций
Раскадровки анимации — это не только анимация в визуальном смысле. Раскадровка анимации — это способ изменить значение свойства зависимостей в качестве функции времени. Одной из основных причин, по которым может потребоваться раскадровка анимации, которая не из библиотеки анимации, заключается в определении визуального состояния элемента управления в рамках шаблона элемента управления или определения страницы.
Различия с Silverlight и WPF
Если вы знакомы с Microsoft Silverlight или Windows Presentation Foundation (WPF), ознакомьтесь с этим разделом; в противном случае можно пропустить его.
Как правило, создание раскадровки анимаций в приложении среда выполнения Windows похоже на Silverlight или WPF. Но есть ряд важных различий:
- Раскадровки анимаций — это не единственный способ визуального анимации пользовательского интерфейса, а также это самый простой способ для разработчиков приложений. Вместо использования раскадровки анимаций часто лучше использовать анимацию тем и анимацию перехода. Они могут быстро создавать рекомендуемые анимации пользовательского интерфейса без попадания в хитрые элементы целевого свойства анимации. Дополнительные сведения см. в разделе "Анимация".
- В среда выполнения Windows многие элементы управления XAML включают анимацию тем и анимацию перехода в рамках встроенного поведения. В большинстве случаев элементы управления WPF и Silverlight не имеют поведения анимации по умолчанию.
- Не все пользовательские анимации, создаваемые по умолчанию, могут выполняться в приложении среда выполнения Windows, если система анимации определяет, что анимация может привести к плохой производительности в пользовательском интерфейсе. Анимации, в которых система определяет, может быть влияние на производительность, называются зависимыми анимациями. Это зависит от того, что часы анимации работают непосредственно с потоком пользовательского интерфейса, который также является местом, где активные входные данные пользователя и другие обновления пытаются применить изменения среды выполнения к пользовательскому интерфейсу. Зависимые анимации, которые используют обширные системные ресурсы в потоке пользовательского интерфейса, могут сделать приложение не отвечает в определенных ситуациях. Если анимация приводит к изменению макета или может повлиять на производительность потока пользовательского интерфейса, часто необходимо явно включить анимацию для его выполнения. Вот для чего предназначено свойство EnableDependentAnimation для определенных классов анимации. Дополнительные сведения см . в зависимых и независимых анимациях .
- Пользовательские функции упрощения в настоящее время не поддерживаются в среда выполнения Windows.
Определение раскадровки анимаций
Раскадровка анимации — это способ изменить значение свойства зависимостей в качестве функции времени. Свойство, которое вы анимируете, не всегда является свойством, которое непосредственно влияет на пользовательский интерфейс приложения. Но так как XAML предназначен для определения пользовательского интерфейса для приложения, обычно это свойство, связанное с пользовательским интерфейсом, которое вы анимируете. Например, можно анимировать угол поворотаTransform или цвет фона кнопки.
Одна из основных причин, по которой вы можете определить раскадровку анимации, заключается в том, что вы являетесь автором элемента управления или повторно создаете шаблон элемента управления и определяете визуальные состояния. Дополнительные сведения см. в разделе раскадровки анимаций для визуальных состояний.
Независимо от того, определяете ли вы визуальные состояния или настраиваемую анимацию для приложения, основные понятия и API для раскадровки анимаций, описанных в этом разделе, в основном применяются к обоим.
Чтобы быть анимированным, свойство, предназначенное для раскадровки анимации, должно быть свойством зависимостей. Свойство зависимости является ключевым компонентом реализации среда выполнения Windows XAML. Свойства, доступные для записи наиболее распространенных элементов пользовательского интерфейса, обычно реализуются как свойства зависимостей, чтобы их можно было анимировать, применять значения, связанные с данными, или применять стиль и нацеливать свойство с помощью метода Setter. Дополнительные сведения о работе свойств зависимостей см. в обзоре свойств зависимостей.
Большую часть времени вы определяете раскадровку анимации, написав XAML. Если вы используете такой инструмент, как Microsoft Visual Studio, он создаст xaml для вас. Можно также определить раскадровку анимации с помощью кода, но это менее распространено.
Давайте посмотрим на простой пример. В этом примере XAML свойство Opacity анимируется для определенного объекта Rectangle.
<Page ...>
<Page.Resources>
<!-- Storyboard resource: Animates a rectangle's opacity. -->
<Storyboard x:Name="myStoryboard">
<DoubleAnimation
Storyboard.TargetName="MyAnimatedRectangle"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:1"/>
</Storyboard>
</Page.Resources>
<!--Page root element, UI definition-->
<Grid>
<Rectangle x:Name="MyAnimatedRectangle"
Width="300" Height="200" Fill="Blue"/>
</Grid>
</Page>
Определение объекта для анимации
В предыдущем примере раскадровка анимирует свойство Opacity прямоугольника. Анимации в самом объекте не объявляться. Вместо этого вы делаете это в определении анимации раскадровки. Раскадровки обычно определяются в XAML, который не находится в непосредственной близости от определения пользовательского интерфейса XAML объекта для анимации. Вместо этого они обычно настраиваются как ресурс XAML.
Чтобы подключить анимацию к целевому объекту, вы ссылаетесь на целевой объект, определяя его имя программирования. Атрибут x:Name всегда следует применять в определении пользовательского интерфейса XAML для имени объекта, который требуется анимировать. Затем объект предназначен для анимации, задав Storyboard.TargetName в определении анимации. Для значения Storyboard.TargetName используется строка имени целевого объекта, которая устанавливается ранее и в другом месте с атрибутом x:Name.
Назначение свойства зависимостей для анимации
В анимации задано значение Storyboard.TargetProperty. Это определяет, какое конкретное свойство целевого объекта анимировано.
Иногда необходимо нацелить свойство, которое не является непосредственным свойством целевого объекта, но вложено более глубоко в отношение свойства объекта. Это часто необходимо сделать, чтобы детализировать набор значений объектов и свойств, пока вы не сможете ссылаться на тип свойства, который может быть анимирован (Double, Point, Color). Эта концепция называется косвенным целевым назначением, а синтаксис для назначения свойства таким образом называется путем свойства.
Рассмотрим пример. Одним из распространенных сценариев раскадровки анимации является изменение цвета части пользовательского интерфейса приложения или элемента управления для представления того, что элемент управления находится в определенном состоянии. Предположим, что вы хотите анимировать передний план TextBlock, чтобы он поворачивается от красного к зеленому. Вы бы ожидали, что используется ColorAnimation , и это правильно. Однако ни один из свойств элементов пользовательского интерфейса, влияющих на цвет объекта, фактически не имеет типа Color. Вместо этого они типы Brush. Поэтому для анимации необходимо использовать свойство Color класса SolidColorBrush, которое является типом, производным от кисти, который обычно используется для этих свойств пользовательского интерфейса, связанных с цветом. И вот как это выглядит с точки зрения формирования пути свойства для целевого свойства анимации:
<Storyboard x:Name="myStoryboard">
<ColorAnimation
Storyboard.TargetName="tb1"
Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
From="Red" To="Green"/>
</Storyboard>
Вот как подумать об этом синтаксисе с точки зрения его частей:
- Каждый набор скобок () заключает имя свойства.
- В имени свойства есть точка, и эта точка отделяет имя типа и имя свойства, чтобы определяемое свойство было однозначно.
- Точка в середине, та, которая не находится внутри круглых скобок, является шагом. Это интерпретируется синтаксисом, чтобы означать, принимать значение первого свойства (который является объектом), шагом в объектную модель и нацеливать конкретное под свойство значения первого свойства.
Ниже приведен список сценариев, предназначенных для анимации, в которых вы, вероятно, будете использовать непрямое назначение свойств, а также некоторые строки пути к свойству, приблизительные к синтаксису, который будет использоваться:
- Анимация значения X переводаTransform, применяемого к RenderTransform:
(UIElement.RenderTransform).(TranslateTransform.X)
- Анимация цвета в GradientStop линейногоgradientBrush, как применено к заливки:
(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)
- Анимация значения X переводаTransform, которое составляет 1 из 4 преобразований в transformGroup, как применяется к RenderTransform:
(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)
Некоторые из этих примеров используют квадратные скобки вокруг чисел. Это индексатор. Он указывает, что имя свойства, предшествующее ему, имеет коллекцию в качестве значения, и что требуется элемент (как определено отсчитываемым от нуля индексом) из этой коллекции.
Кроме того, можно анимировать присоединенные свойства XAML. Всегда заключайте полное имя присоединенного свойства в скобки, например (Canvas.Left)
. Дополнительные сведения см. в разделе "Анимация присоединенных свойств XAML".
Дополнительные сведения о том, как использовать путь к свойству для косвенного назначения свойства для анимации, см. в разделе "Синтаксис пути свойства" или присоединенное свойство Storyboard.TargetProperty.
Типы анимации
Система анимации среда выполнения Windows имеет три конкретных типа, к которым могут применяться раскадровки анимации:
- Double, можно анимировать с помощью любой doubleAnimation
- Point, можно анимировать с помощью любой PointAnimation
- Цвет, можно анимировать с помощью любой colorAnimation
Существует также обобщенный тип анимации объекта для ссылочных значений объектов, которые мы обсудим позже.
Указание анимированных значений
До сих пор мы показали, как нацелить объект и свойство на анимацию, но еще не описали, что анимация делает со значением свойства при выполнении.
Описанные типы анимации иногда называются анимациями from/By./ Это означает, что анимация изменяет значение свойства со временем, используя один или несколько этих входных данных, поступающих из определения анимации:
- Значение начинается со значения From . Если вы не указываете значение From , начальное значение является любым значением анимированного свойства в то время перед запуском анимации. Это может быть значение по умолчанию, значение из стиля или шаблона или значения, конкретно применяемого определением пользовательского интерфейса XAML или кодом приложения.
- В конце анимации значение — значение To .
- Или, чтобы указать конечное значение относительно начального значения, задайте свойство By . Вы задали это вместо свойства To .
- Если значение to или by не задано, конечное значение является любым значением анимированного свойства в то время перед запуском анимации. В этом случае лучше иметь значение From , так как в противном случае анимация не изменит значение вообще; его начальные и конечные значения совпадают.
- Анимация обычно имеет по крайней мере один из от, by или To, но никогда не все три.
Давайте вернемся к предыдущему примеру XAML и снова рассмотрим значения from и To , а также длительность. В примере выполняется анимация свойства Opacity, а тип свойства Opacity — Double. Поэтому анимация, используемая здесь, — DoubleAnimation.
From="1.0" To="0.0"
указывает, что при выполнении анимации свойство Opacity начинается со значения 1 и анимирует значение 0. Другими словами, с точки зрения того, что эти двойные значения означают для свойства Opacity, эта анимация приведет к тому, что объект начнет непрозрачный, а затем исчезает.
...
<Storyboard x:Name="myStoryboard">
<DoubleAnimation
Storyboard.TargetName="MyAnimatedRectangle"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:1"/>
</Storyboard>
...
Duration="0:0:1"
указывает, сколько времени длится анимация, т. е. насколько быстро прямоугольник исчезает. Свойство Duration указывается в виде часов:минут:секунд. Длительность времени в этом примере составляет одну секунду.
Дополнительные сведения о значениях длительности и синтаксисе XAML см. в разделе "Длительность".
Примечание.
В примере, который мы показали, если вы уверены, что начальное состояние анимируемого объекта всегда равно 1( по умолчанию или явному набору), можно пропустить значение From, анимация будет использовать неявное начальное значение, а результат будет таким же.
Значение
Ранее упоминалось, что можно опустить значения from, To или By и таким образом использовать текущие неанимированные значения в качестве замены отсутствующих значений. Свойства анимации от, "To" или "По " не являются типом, который можно угадать. Например, тип свойства DoubleAnimation.To не является двойным. Вместо этого это значение NULL для Double. Значение по умолчанию равно null, а не 0. Это значение NULL заключается в том, как система анимации отличается от того, что вы не задали специальное значение для свойства From, To или By . Расширения компонентов Visual C++ (C++/CX) не имеют типа NULL, поэтому вместо этого используется IReference.
Другие свойства анимации
Следующие свойства, описанные в этом разделе, являются необязательными в том, что они имеют значения по умолчанию для большинства анимаций.
AutoReverse
Если в анимации не указан параметр AutoReverse или RepeatBehavior , анимация будет выполняться один раз и выполняться в течение указанного времени в качестве длительности.
Свойство AutoReverse указывает, воспроизводится ли временная шкала в обратном направлении после окончания его длительности. Если задано значение true, анимация изменится после окончания объявленной длительности, изменив значение с конечного значения (To) обратно на начальное значение (From). Это означает, что анимация эффективно выполняется в два раза больше времени его длительности.
RepeatBehavior
Свойство RepeatBehavior указывает, сколько раз воспроизводится временная шкала или более большая длительность, в которую должна повторяться временная шкала. По умолчанию временная шкала имеет количество итераций "1x", что означает, что он воспроизводится один раз в течение его длительности и не повторяется.
Анимация может привести к выполнению нескольких итераций. Например, значение "3x" приводит к тому, что анимация выполняется три раза. Кроме того, можно указать другую длительность для RepeatBehavior. Эта длительность должна быть длиннее, чем длительность самой анимации, чтобы быть эффективной. Например, если указать RepeatBehavior "0:0:10", для анимации с длительностью "0:0:2", анимация повторяется пять раз. Если они не разделяются равномерно, анимация будет усечена в то время, когда достигнуто время RepeatBehavior , которое может быть частью. Наконец, можно указать специальное значение "Forever", которое приводит к бесконечному выполнению анимации, пока она не будет намеренно остановлена.
Дополнительные сведения о значениях RepeatBehavior и синтаксисе XAML см. в разделе RepeatBehavior.
FillBehavior="Stop"
По умолчанию, когда анимация заканчивается, анимация оставляет значение свойства в качестве окончательного значения To или By-modified даже после превышения его длительности. Однако если для свойства FillBehavior задано значение FillBehavior.Stop, значение анимированного значения возвращается к значению, заданному до применения анимации, или точнее к текущему эффективному значению, определенному системой свойств зависимостей (дополнительные сведения об этом различии см. в обзоре свойств зависимостей).
BeginTime
По умолчанию время начала анимации — "0:0:0", поэтому начинается сразу после запуска раскадровки. Это может измениться, если раскадровка содержит несколько анимаций, и вы хотите ошеломить время начала других и начальную анимацию или создать преднамеренную короткую задержку.
SpeedRatio
Если в раскадровке есть несколько анимаций, можно изменить частоту времени одного или нескольких анимаций относительно раскадровки. Это родительская раскадровка, которая в конечном счете определяет, как время длительности истекает во время выполнения анимаций. Это свойство не используется очень часто. Дополнительные сведения см. в разделе SpeedRatio.
Определение нескольких анимаций в раскадровке
Содержимое раскадровки может быть несколькими определениями анимации. При применении связанных анимаций к двум свойствам одного целевого объекта может потребоваться несколько анимаций. Например, можно изменить свойства TranslateX и TranslateY, используемые в качестве объекта RenderTransform элемента пользовательского интерфейса. Это приведет к переводу элемента по диагонали. Для этого требуется два разных анимации, но вам может потребоваться, чтобы анимации были частью одной раскадровки , так как вы всегда хотите, чтобы эти два анимации выполнялись вместе.
Анимации не должны быть одинаковыми типами или целевыми объектами. Они могут иметь разные длительности и не должны совместно использовать значения свойств.
При запуске родительской раскадровки каждая из анимаций в ней будет выполняться тоже.
Класс Раскадровки на самом деле имеет много одинаковых свойств анимации, что и типы анимации, так как оба используют базовый класс Временной шкалы. Таким образом, раскадровка может иметь RepeatBehavior или BeginTime. Обычно они не задаются на раскадровке, если только не требуется, чтобы все содержащиеся анимации имели такое поведение. Как правило, любое свойство Временной шкалы, заданное на раскадровке, применяется ко всем дочерним анимациям. Если разрешить отмену настройки, раскадровка имеет неявную длительность, вычисляемую из самого длинного значения длительности содержащихся анимаций. Явно заданная длительность в раскадровке , которая короче одной из его дочерних анимаций, приведет к тому, что анимация будет отрезана, что обычно не желательно.
Раскадровка не может содержать две анимации, которые пытаются нацелить и анимировать одно и то же свойство в одном объекте. При попытке вы получите ошибку среды выполнения при попытке запустить раскадровку. Это ограничение применяется, даже если анимации не перекрываются во времени из-за намеренно разных значений и длительности BeginTime . Если вы действительно хотите применить более сложную временную шкалу анимации к тому же свойству в одной раскадровки, способ сделать это — использовать анимацию ключевых кадров. См . анимацию ключевых кадров и анимацию функций с упрощением.
Система анимации может применять несколько анимаций к значению свойства, если эти входные данные приходят из нескольких раскадровки. Использование этого поведения намеренно для одновременного запуска раскадровки не распространено. Однако возможно, что определяемая приложением анимация, применяемая к свойству элемента управления, будет изменять значение HoldEnd анимации, которая ранее выполнялась в рамках модели визуального состояния элемента управления.
Определение раскадровки в качестве ресурса
Раскадровка — это контейнер, в который вы помещаете объекты анимации. Обычно раскадровка определяется как ресурс, доступный объекту, который требуется анимировать, в ресурсах уровня страницы или Application.Resources.
В следующем примере показано, как предыдущий пример Раскадровки будет содержаться в определении ресурсов на уровне страницы, где раскадровка является ключевым ресурсом корневой страницы. Обратите внимание на атрибут x:Name. Этот атрибут определяет имя переменной для раскадровки, чтобы другие элементы в XAML, а также код могли ссылаться на раскадровку позже.
<Page ...>
<Page.Resources>
<!-- Storyboard resource: Animates a rectangle's opacity. -->
<Storyboard x:Name="myStoryboard">
<DoubleAnimation
Storyboard.TargetName="MyAnimatedRectangle"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:1"/>
</Storyboard>
</Page.Resources>
<!--Page root element, UI definition-->
<Grid>
<Rectangle x:Name="MyAnimatedRectangle"
Width="300" Height="200" Fill="Blue"/>
</Grid>
</Page>
Определение ресурсов в корневом каталоге XAML-файла, например page.xaml или app.xaml, является распространенной практикой организации ключевых ресурсов в XAML. Вы также можете учитывать ресурсы в отдельные файлы и объединять их в приложения или страницы. Дополнительные сведения см. в справочниках по ресурсам ResourceDictionary и XAML.
Примечание.
среда выполнения Windows XAML поддерживает определение ресурсов с помощью атрибута x:Key или атрибута x:Name. Использование атрибута x:Name более распространено для раскадровки, так как вы хотите ссылаться на него по имени переменной в конечном итоге, чтобы можно было вызвать метод Begin и запустить анимацию. Если вы используете атрибут x:Key, необходимо использовать методы ResourceDictionary, такие как индексатор Item, чтобы получить его в качестве ключа ресурса, а затем привести полученный объект к раскадровке для использования методов Раскадровки.
Раскадровки для визуальных состояний
Вы также помещаете анимацию в блок раскадровки при объявлении анимаций визуального состояния элемента управления. В этом случае элементы раскадровки, которые вы определяете, переходят в контейнер VisualState, вложенный более глубоко в стиль (это стиль, который является ключом ресурса). В этом случае вам не нужен ключ или имя раскадровки, так как это VisualState с целевым именем, который Может вызвать VisualStateManager. Стили элементов управления часто учитываются в отдельных файлах ResourceDictionary XAML, а не в коллекции ресурсов страницы или приложения. Дополнительные сведения см. в разделе раскадровки анимаций для визуальных состояний.
Зависимые и независимые анимации
На этом этапе мы должны ввести некоторые важные моменты о том, как работает система анимации. В частности, анимация в основном взаимодействует с тем, как приложение среда выполнения Windows отрисовывается на экране и как эта отрисовка использует потоки обработки. Приложение среда выполнения Windows всегда имеет основной поток пользовательского интерфейса, и этот поток отвечает за обновление экрана с текущей информацией. Кроме того, приложение среда выполнения Windows имеет поток композиции, который используется для предварительного вычисления макетов непосредственно перед отображением. При анимации пользовательского интерфейса может потребоваться много работы для потока пользовательского интерфейса. Система должна перераскрыть большие области экрана, используя довольно короткие интервалы времени между каждым обновлением. Это необходимо для записи последнего значения свойства анимированного свойства. Если вы не осторожны, есть риск того, что анимация может сделать пользовательский интерфейс менее адаптивным или повлиять на производительность других функций приложения, которые также находятся в одном потоке пользовательского интерфейса.
Разнообразие анимации, которая определяется, имеет некоторый риск замедления потока пользовательского интерфейса называется зависимой анимацией. Анимация, не подверженная этому риску, является независимой анимацией. Различие между зависимыми и независимыми анимациями не только определяется типами анимации (DoubleAnimation и т. д.), как описано ранее. Вместо этого определяется, какие определенные свойства вы анимируете, а также другие факторы, такие как наследование и композиция элементов управления. Существуют ситуации, когда даже если анимация изменяет пользовательский интерфейс, анимация может оказать минимальное влияние на поток пользовательского интерфейса и вместо этого может обрабатываться потоком композиции как независимая анимация.
Анимация является независимой, если она имеет какие-либо из следующих характеристик:
- Длительность анимации составляет 0 секунд (см. предупреждение)
- Анимация предназначена для UIElement.Opacity
- Анимация предназначена для значения вложенных свойств UIElement: Transform3D, RenderTransform, Проекция, Клип
- Анимация предназначена для Canvas.Left или Canvas.Top
- Анимация предназначена для значения кисти и использует SolidColorBrush, анимируя его цвет
- Анимация — objectAnimationUsingKeyFrames
Предупреждение
Чтобы анимация рассматривалась как независимая, необходимо явно задать Duration="0"
. Например, при удалении Duration="0"
из этого XAML анимация рассматривается как зависимое, даже если ключевое время кадра равно "0:0:0".
<Storyboard>
<DoubleAnimationUsingKeyFrames
Duration="0"
Storyboard.TargetName="Button2"
Storyboard.TargetProperty="Width">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="200"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
Если анимация не соответствует этим критериям, это, вероятно, зависимый анимация. По умолчанию система анимации не будет запускать зависимые анимации. Таким образом, во время разработки и тестирования вы даже не увидите, что анимация выполняется. Вы по-прежнему можете использовать эту анимацию, но необходимо специально включить каждую зависимые анимации. Чтобы включить анимацию, задайте для свойства EnableDependentAnimation объекта анимации значение true. (Каждый из них Подкласс временной шкалы , представляющий анимацию, имеет другую реализацию свойства, но все они называются EnableDependentAnimation
.)
Требование включения зависимых анимаций, падающих на разработчик приложения, является сознательным аспектом разработки системы анимации и опыта разработки. Мы хотим, чтобы разработчики знали, что анимации имеют затраты на производительность для реагирования пользовательского интерфейса. Плохое выполнение анимаций трудно изолировать и отлаживать в полномасштабном приложении. Поэтому лучше включить только зависимые анимации, которые вам действительно нужны для пользовательского интерфейса вашего приложения. Мы не хотели, чтобы сделать его слишком простым, чтобы скомпрометировать производительность вашего приложения из-за декоративных анимаций, которые используют много циклов. Дополнительные сведения о советах по производительности анимации см. в разделе "Оптимизация анимации" и мультимедиа.
Разработчик приложений также может применять параметр на уровне приложения, который всегда отключает зависимые анимации, даже те, где EnableDependentAnimation имеет значение true. См. раздел "Временная шкала.AllowDependentAnimations".
Совет
Если вы используете область анимации в Blend для Visual Studio 2019 года, при попытке применить зависимые анимации к свойству визуального состояния предупреждения будут отображаться в конструкторе.
Предупреждения не отображаются в выходных данных сборки или списке ошибок.
Если вы редактируют XAML вручную, конструктор не будет отображать предупреждение.
Во время выполнения при отладке выходные данные области вывода отображают предупреждение о том, что анимация не является независимой и будет пропущена.
Запуск и управление анимацией
Все, что мы показали вам до сих пор, не приводит к выполнению анимации или применению! Пока анимация не будет запущена и запущена, значение изменится, что анимация объявляется в XAML, является скрытой и еще не произойдет. Необходимо явно запустить анимацию каким-то образом, связанную с временем существования приложения или взаимодействием с пользователем. На самом простом уровне анимация запускается путем вызова метода Begin на раскадровке, который является родительским для этой анимации. Вы не можете вызывать методы из XAML напрямую, поэтому все, что вы делаете, чтобы включить анимацию, вы будете делать это из кода. Это будет либо код позади страниц или компонентов приложения, либо логика элемента управления, если вы определяете пользовательский класс элемента управления.
Как правило, вы вызовете Begin и просто позволите анимации выполняться до его завершения длительности. Однако вы также можете использовать методы приостановки, возобновления и остановки для управления раскадровки во время выполнения, а также других API, которые используются для более сложных сценариев управления анимацией.
При вызове Begin на раскадровке, содержащей анимацию, которая повторяется бесконечно (RepeatBehavior="Forever"
), эта анимация выполняется до тех пор, пока страница, содержащая ее, не выгружается или вызывается специально приостанавливать или остановить.
Запуск анимации из кода приложения
Вы можете автоматически запускать анимации или реагировать на действия пользователя. В автоматическом случае обычно используется событие времени существования объекта, например Loaded , чтобы выступать в качестве триггера анимации. Загруженное событие является хорошим событием для этого, так как на этом этапе пользовательский интерфейс готов к взаимодействию, и анимация не будет отрезана в начале, так как другая часть пользовательского интерфейса по-прежнему загружается.
В этом примере событие PointerPressed присоединено к прямоугольнику, чтобы, когда пользователь щелкнул прямоугольник, начинается анимация.
<Rectangle PointerPressed="Rectangle_Tapped"
x:Name="MyAnimatedRectangle"
Width="300" Height="200" Fill="Blue"/>
Обработчик событий запускает раскадровку (анимацию) с помощью метода Begin раскадровки.
myStoryboard.Begin();
myStoryboard().Begin();
myStoryboard->Begin();
myStoryBoard.Begin()
Вы можете обработать событие Completed , если вы хотите выполнить другую логику после завершения применения значений анимации. Кроме того, для устранения неполадок взаимодействия системы свойств и анимации метод GetAnimationBaseValue может быть полезным.
Совет
При написании кода для сценария приложения, когда вы запускаете анимацию из кода приложения, может потребоваться проверить, существует ли анимация или переход уже существует в библиотеке анимации для вашего сценария пользовательского интерфейса. Анимации библиотеки обеспечивают более согласованный интерфейс пользовательского интерфейса во всех среда выполнения Windows приложениях и упрощают использование.
Анимация для визуальных состояний
Поведение выполнения для раскадровки, используемой для определения визуального состояния элемента управления, отличается от того, как приложение может запускать раскадровки напрямую. Как применяется к определению визуального состояния в XAML, раскадровка является элементом содержащего VisualState, и состояние в целом управляется с помощью API VisualStateManager. Все анимации в пределах будут выполняться в соответствии со своими значениями анимации и свойствами временной шкалы при использовании элемента управления, содержащего VisualState. Дополнительные сведения см. в разделе "Раскадровки" для визуальных состояний. Для визуальных состояний видимый FillBehavior отличается. Если визуальное состояние изменяется на другое состояние, все изменения свойств, примененные предыдущим визуальным состоянием и его анимацией, отменяются, даже если новое визуальное состояние не применяет новую анимацию к свойству.
Раскадровка и EventTrigger
Существует один из способов запуска анимации, которая может быть объявлена полностью в XAML. Однако этот метод больше не используется. Это устаревший синтаксис из WPF и ранних версий Silverlight до поддержки VisualStateManager. Этот синтаксис EventTrigger по-прежнему работает в среда выполнения Windows XAML по причинам импорта и совместимости, но работает только для поведения триггера на основе события FrameworkElement.Loaded; попытка активировать другие события вызовет исключения или не выполняет компиляцию. Дополнительные сведения см. в разделе EventTrigger или BeginStoryboard.
Анимация присоединенных свойств XAML
Это не распространенный сценарий, но вы можете применить анимированное значение к присоединенному свойству XAML. Дополнительные сведения о присоединенных свойствах и их работе см. в обзоре присоединенных свойств. Для присоединенного свойства требуется синтаксис пути свойства, который заключает имя свойства в скобки. Встроенные свойства, такие как Canvas.ZIndex, можно анимировать с помощью объекта ObjectAnimationUsingKeyFrames, который применяет дискретные целые значения. Однако существующее ограничение реализации среда выполнения Windows XAML заключается в том, что нельзя анимировать пользовательское присоединенное свойство.
Дополнительные типы анимации и дальнейшие действия по изучению анимации пользовательского интерфейса
До сих пор мы отображали пользовательские анимации, которые анимируются между двумя значениями, а затем линейно интерполяции значений при необходимости при выполнении анимации. Они вызываются анимациями from/By./ Но есть другой тип анимации, позволяющий объявлять промежуточные значения, которые падают между началом и окончанием. Это называется анимацией с ключевым кадром. Существует также способ изменить логику интерполяции в анимации from/By/ или анимации с помощью ключевого кадра. Это включает применение функции упрощения. Дополнительные сведения об этих понятиях см. в разделе "Ключевые кадры" и анимации функций с упрощенной функцией.
См. также
- Синтаксис пути к свойству
- Общие сведения о свойствах зависимостей
- Анимации ключевых кадров и анимаций с упрощенной функцией
- Раскадровки анимаций для визуальных состояний
- Шаблоны элементов управления
- Раскадровка
- Раскадровка.TargetProperty
Ранее упоминалось, что можно опустить значения from, To или By и таким образом использовать текущие неанимированные значения в качестве замены отсутствующих значений. Свойства анимации от, "To" или "По " не являются типом, который можно угадать. Например, тип свойства DoubleAnimation.To не является двойным. Вместо этого это значение NULL для Double. Значение по умолчанию равно null, а не 0. Это значение NULL заключается в том, как система анимации отличается от того, что вы не задали специальное значение для свойства From, To или By . Расширения компонентов Visual C++ (C++/CX) не имеют типа NULL, поэтому вместо этого используется IReference.
Другие свойства анимации
Следующие свойства, описанные в этом разделе, являются необязательными в том, что они имеют значения по умолчанию для большинства анимаций.
AutoReverse
Если в анимации не указан параметр AutoReverse или RepeatBehavior , анимация будет выполняться один раз и выполняться в течение указанного времени в качестве длительности.
Свойство AutoReverse указывает, воспроизводится ли временная шкала в обратном направлении после окончания его длительности. Если задано значение true, анимация изменится после окончания объявленной длительности, изменив значение с конечного значения (To) обратно на начальное значение (From). Это означает, что анимация эффективно выполняется в два раза больше времени его длительности.
RepeatBehavior
Свойство RepeatBehavior указывает, сколько раз воспроизводится временная шкала или более большая длительность, в которую должна повторяться временная шкала. По умолчанию временная шкала имеет количество итераций "1x", что означает, что он воспроизводится один раз в течение его длительности и не повторяется.
Анимация может привести к выполнению нескольких итераций. Например, значение "3x" приводит к тому, что анимация выполняется три раза. Кроме того, можно указать другую длительность для RepeatBehavior. Эта длительность должна быть длиннее, чем длительность самой анимации, чтобы быть эффективной. Например, если указать RepeatBehavior "0:0:10", для анимации с длительностью "0:0:2", анимация повторяется пять раз. Если они не разделяются равномерно, анимация будет усечена в то время, когда достигнуто время RepeatBehavior , которое может быть частью. Наконец, можно указать специальное значение "Forever", которое приводит к бесконечному выполнению анимации, пока она не будет намеренно остановлена.
Дополнительные сведения о значениях RepeatBehavior и синтаксисе XAML см. в разделе RepeatBehavior.
FillBehavior="Stop"
По умолчанию, когда анимация заканчивается, анимация оставляет значение свойства в качестве окончательного значения To или By-modified даже после превышения его длительности. Однако если для свойства FillBehavior задано значение FillBehavior.Stop, значение анимированного значения возвращается к значению, заданному до применения анимации, или точнее к текущему эффективному значению, определенному системой свойств зависимостей (дополнительные сведения об этом различии см. в обзоре свойств зависимостей).
BeginTime
По умолчанию время начала анимации — "0:0:0", поэтому начинается сразу после запуска раскадровки. Это может измениться, если раскадровка содержит несколько анимаций, и вы хотите ошеломить время начала других и начальную анимацию или создать преднамеренную короткую задержку.
SpeedRatio
Если в раскадровке есть несколько анимаций, можно изменить частоту времени одного или нескольких анимаций относительно раскадровки. Это родительская раскадровка, которая в конечном счете определяет, как время длительности истекает во время выполнения анимаций. Это свойство не используется очень часто. Дополнительные сведения см. в разделе SpeedRatio.
Определение нескольких анимаций в раскадровке
Содержимое раскадровки может быть несколькими определениями анимации. При применении связанных анимаций к двум свойствам одного целевого объекта может потребоваться несколько анимаций. Например, можно изменить свойства TranslateX и TranslateY, используемые в качестве объекта RenderTransform элемента пользовательского интерфейса. Это приведет к переводу элемента по диагонали. Для этого требуется два разных анимации, но вам может потребоваться, чтобы анимации были частью одной раскадровки , так как вы всегда хотите, чтобы эти два анимации выполнялись вместе.
Анимации не должны быть одинаковыми типами или целевыми объектами. Они могут иметь разные длительности и не должны совместно использовать значения свойств.
При запуске родительской раскадровки каждая из анимаций в ней будет выполняться тоже.
Класс Раскадровки на самом деле имеет много одинаковых свойств анимации, что и типы анимации, так как оба используют базовый класс Временной шкалы. Таким образом, раскадровка может иметь RepeatBehavior или BeginTime. Обычно они не задаются на раскадровке, если только не требуется, чтобы все содержащиеся анимации имели такое поведение. Как правило, любое свойство Временной шкалы, заданное на раскадровке, применяется ко всем дочерним анимациям. Если разрешить отмену настройки, раскадровка имеет неявную длительность, вычисляемую из самого длинного значения длительности содержащихся анимаций. Явно заданная длительность в раскадровке , которая короче одной из его дочерних анимаций, приведет к тому, что анимация будет отрезана, что обычно не желательно.
Раскадровка не может содержать две анимации, которые пытаются нацелить и анимировать одно и то же свойство в одном объекте. При попытке вы получите ошибку среды выполнения при попытке запустить раскадровку. Это ограничение применяется, даже если анимации не перекрываются во времени из-за намеренно разных значений и длительности BeginTime . Если вы действительно хотите применить более сложную временную шкалу анимации к тому же свойству в одной раскадровки, способ сделать это — использовать анимацию ключевых кадров. См . анимацию ключевых кадров и анимацию функций с упрощением.
Система анимации может применять несколько анимаций к значению свойства, если эти входные данные приходят из нескольких раскадровки. Использование этого поведения намеренно для одновременного запуска раскадровки не распространено. Однако возможно, что определяемая приложением анимация, применяемая к свойству элемента управления, будет изменять значение HoldEnd анимации, которая ранее выполнялась в рамках модели визуального состояния элемента управления.
Определение раскадровки в качестве ресурса
Раскадровка — это контейнер, в который вы помещаете объекты анимации. Обычно раскадровка определяется как ресурс, доступный объекту, который требуется анимировать, в ресурсах уровня страницы или Application.Resources.
В следующем примере показано, как предыдущий пример Раскадровки будет содержаться в определении ресурсов на уровне страницы, где раскадровка является ключевым ресурсом корневой страницы. Обратите внимание на атрибут x:Name. Этот атрибут определяет имя переменной для раскадровки, чтобы другие элементы в XAML, а также код могли ссылаться на раскадровку позже.
<Page ...>
<Page.Resources>
<!-- Storyboard resource: Animates a rectangle's opacity. -->
<Storyboard x:Name="myStoryboard">
<DoubleAnimation
Storyboard.TargetName="MyAnimatedRectangle"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:1"/>
</Storyboard>
</Page.Resources>
<!--Page root element, UI definition-->
<Grid>
<Rectangle x:Name="MyAnimatedRectangle"
Width="300" Height="200" Fill="Blue"/>
</Grid>
</Page>
Определение ресурсов в корневом каталоге XAML-файла, например page.xaml или app.xaml, является распространенной практикой организации ключевых ресурсов в XAML. Вы также можете учитывать ресурсы в отдельные файлы и объединять их в приложения или страницы. Дополнительные сведения см. в справочниках по ресурсам ResourceDictionary и XAML.
Примечание.
среда выполнения Windows XAML поддерживает определение ресурсов с помощью атрибута x:Key или атрибута x:Name. Использование атрибута x:Name более распространено для раскадровки, так как вы хотите ссылаться на него по имени переменной в конечном итоге, чтобы можно было вызвать метод Begin и запустить анимацию. Если вы используете атрибут x:Key, необходимо использовать методы ResourceDictionary, такие как индексатор Item, чтобы получить его в качестве ключа ресурса, а затем привести полученный объект к раскадровке для использования методов Раскадровки.
Раскадровки для визуальных состояний
Вы также помещаете анимацию в блок раскадровки при объявлении анимаций визуального состояния элемента управления. В этом случае элементы раскадровки, которые вы определяете, переходят в контейнер VisualState, вложенный более глубоко в стиль (это стиль, который является ключом ресурса). В этом случае вам не нужен ключ или имя раскадровки, так как это VisualState с целевым именем, который Может вызвать VisualStateManager. Стили элементов управления часто учитываются в отдельных файлах ResourceDictionary XAML, а не в коллекции ресурсов страницы или приложения. Дополнительные сведения см. в разделе раскадровки анимаций для визуальных состояний.
Зависимые и независимые анимации
На этом этапе мы должны ввести некоторые важные моменты о том, как работает система анимации. В частности, анимация в основном взаимодействует с тем, как приложение среда выполнения Windows отрисовывается на экране и как эта отрисовка использует потоки обработки. Приложение среда выполнения Windows всегда имеет основной поток пользовательского интерфейса, и этот поток отвечает за обновление экрана с текущей информацией. Кроме того, приложение среда выполнения Windows имеет поток композиции, который используется для предварительного вычисления макетов непосредственно перед отображением. При анимации пользовательского интерфейса может потребоваться много работы для потока пользовательского интерфейса. Система должна перераскрыть большие области экрана, используя довольно короткие интервалы времени между каждым обновлением. Это необходимо для записи последнего значения свойства анимированного свойства. Если вы не осторожны, есть риск того, что анимация может сделать пользовательский интерфейс менее адаптивным или повлиять на производительность других функций приложения, которые также находятся в одном потоке пользовательского интерфейса.
Разнообразие анимации, которая определяется, имеет некоторый риск замедления потока пользовательского интерфейса называется зависимой анимацией. Анимация, не подверженная этому риску, является независимой анимацией. Различие между зависимыми и независимыми анимациями не только определяется типами анимации (DoubleAnimation и т. д.), как описано ранее. Вместо этого определяется, какие определенные свойства вы анимируете, а также другие факторы, такие как наследование и композиция элементов управления. Существуют ситуации, когда даже если анимация изменяет пользовательский интерфейс, анимация может оказать минимальное влияние на поток пользовательского интерфейса и вместо этого может обрабатываться потоком композиции как независимая анимация.
Анимация является независимой, если она имеет какие-либо из следующих характеристик:
- Длительность анимации составляет 0 секунд (см. предупреждение)
- Анимация предназначена для UIElement.Opacity
- Анимация предназначена для значения вложенных свойств UIElement: Transform3D, RenderTransform, Проекция, Клип
- Анимация предназначена для Canvas.Left или Canvas.Top
- Анимация предназначена для значения кисти и использует SolidColorBrush, анимируя его цвет
- Анимация — objectAnimationUsingKeyFrames
Предупреждение
Чтобы анимация рассматривалась как независимая, необходимо явно задать Duration="0"
. Например, при удалении Duration="0"
из этого XAML анимация рассматривается как зависимое, даже если ключевое время кадра равно "0:0:0".
<Storyboard>
<DoubleAnimationUsingKeyFrames
Duration="0"
Storyboard.TargetName="Button2"
Storyboard.TargetProperty="Width">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="200"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
Если анимация не соответствует этим критериям, это, вероятно, зависимый анимация. По умолчанию система анимации не будет запускать зависимые анимации. Таким образом, во время разработки и тестирования вы даже не увидите, что анимация выполняется. Вы по-прежнему можете использовать эту анимацию, но необходимо специально включить каждую зависимые анимации. Чтобы включить анимацию, задайте для свойства EnableDependentAnimation объекта анимации значение true. (Каждый из них Подкласс временной шкалы , представляющий анимацию, имеет другую реализацию свойства, но все они называются EnableDependentAnimation
.)
Требование включения зависимых анимаций, падающих на разработчик приложения, является сознательным аспектом разработки системы анимации и опыта разработки. Мы хотим, чтобы разработчики знали, что анимации имеют затраты на производительность для реагирования пользовательского интерфейса. Плохое выполнение анимаций трудно изолировать и отлаживать в полномасштабном приложении. Поэтому лучше включить только зависимые анимации, которые вам действительно нужны для пользовательского интерфейса вашего приложения. Мы не хотели, чтобы сделать его слишком простым, чтобы скомпрометировать производительность вашего приложения из-за декоративных анимаций, которые используют много циклов. Дополнительные сведения о советах по производительности анимации см. в разделе "Оптимизация анимации" и мультимедиа.
Разработчик приложений также может применять параметр на уровне приложения, который всегда отключает зависимые анимации, даже те, где EnableDependentAnimation имеет значение true. См. раздел "Временная шкала.AllowDependentAnimations".
Совет
Если вы используете область анимации в Blend для Visual Studio 2019 года, при попытке применить зависимые анимации к свойству визуального состояния предупреждения будут отображаться в конструкторе. Предупреждения не отображаются в выходных данных сборки или списке ошибок. Если вы редактируют XAML вручную, конструктор не будет отображать предупреждение. Во время выполнения при отладке выходные данные области вывода отображают предупреждение о том, что анимация не является независимой и будет пропущена.
Запуск и управление анимацией
Все, что мы показали вам до сих пор, не приводит к выполнению анимации или применению! Пока анимация не будет запущена и запущена, значение изменится, что анимация объявляется в XAML, является скрытой и еще не произойдет. Необходимо явно запустить анимацию каким-то образом, связанную с временем существования приложения или взаимодействием с пользователем. На самом простом уровне анимация запускается путем вызова метода Begin на раскадровке, который является родительским для этой анимации. Вы не можете вызывать методы из XAML напрямую, поэтому все, что вы делаете, чтобы включить анимацию, вы будете делать это из кода. Это будет либо код позади страниц или компонентов приложения, либо логика элемента управления, если вы определяете пользовательский класс элемента управления.
Как правило, вы вызовете Begin и просто позволите анимации выполняться до его завершения длительности. Однако вы также можете использовать методы приостановки, возобновления и остановки для управления раскадровки во время выполнения, а также других API, которые используются для более сложных сценариев управления анимацией.
При вызове Begin на раскадровке, содержащей анимацию, которая повторяется бесконечно (RepeatBehavior="Forever"
), эта анимация выполняется до тех пор, пока страница, содержащая ее, не выгружается или вызывается специально приостанавливать или остановить.
Запуск анимации из кода приложения
Вы можете автоматически запускать анимации или реагировать на действия пользователя. В автоматическом случае обычно используется событие времени существования объекта, например Loaded , чтобы выступать в качестве триггера анимации. Загруженное событие является хорошим событием для этого, так как на этом этапе пользовательский интерфейс готов к взаимодействию, и анимация не будет отрезана в начале, так как другая часть пользовательского интерфейса по-прежнему загружается.
В этом примере событие PointerPressed присоединено к прямоугольнику, чтобы, когда пользователь щелкнул прямоугольник, начинается анимация.
<Rectangle PointerPressed="Rectangle_Tapped"
x:Name="MyAnimatedRectangle"
Width="300" Height="200" Fill="Blue"/>
Обработчик событий запускает раскадровку (анимацию) с помощью метода Begin раскадровки.
myStoryboard.Begin();
myStoryboard().Begin();
myStoryboard->Begin();
myStoryBoard.Begin()
Вы можете обработать событие Completed , если вы хотите выполнить другую логику после завершения применения значений анимации. Кроме того, для устранения неполадок взаимодействия системы свойств и анимации метод GetAnimationBaseValue может быть полезным.
Совет
При написании кода для сценария приложения, когда вы запускаете анимацию из кода приложения, может потребоваться проверить, существует ли анимация или переход уже существует в библиотеке анимации для вашего сценария пользовательского интерфейса. Анимации библиотеки обеспечивают более согласованный интерфейс пользовательского интерфейса во всех среда выполнения Windows приложениях и упрощают использование.
Анимация для визуальных состояний
Поведение выполнения для раскадровки, используемой для определения визуального состояния элемента управления, отличается от того, как приложение может запускать раскадровки напрямую. Как применяется к определению визуального состояния в XAML, раскадровка является элементом содержащего VisualState, и состояние в целом управляется с помощью API VisualStateManager. Все анимации в пределах будут выполняться в соответствии со своими значениями анимации и свойствами временной шкалы при использовании элемента управления, содержащего VisualState. Дополнительные сведения см. в разделе "Раскадровки" для визуальных состояний. Для визуальных состояний видимый FillBehavior отличается. Если визуальное состояние изменяется на другое состояние, все изменения свойств, примененные предыдущим визуальным состоянием и его анимацией, отменяются, даже если новое визуальное состояние не применяет новую анимацию к свойству.
Раскадровка и EventTrigger
Существует один из способов запуска анимации, которая может быть объявлена полностью в XAML. Однако этот метод больше не используется. Это устаревший синтаксис из WPF и ранних версий Silverlight до поддержки VisualStateManager. Этот синтаксис EventTrigger по-прежнему работает в среда выполнения Windows XAML по причинам импорта и совместимости, но работает только для поведения триггера на основе события FrameworkElement.Loaded; попытка активировать другие события вызовет исключения или не выполняет компиляцию. Дополнительные сведения см. в разделе EventTrigger или BeginStoryboard.
Анимация присоединенных свойств XAML
Это не распространенный сценарий, но вы можете применить анимированное значение к присоединенному свойству XAML. Дополнительные сведения о присоединенных свойствах и их работе см. в обзоре присоединенных свойств. Для присоединенного свойства требуется синтаксис пути свойства, который заключает имя свойства в скобки. Встроенные свойства, такие как Canvas.ZIndex, можно анимировать с помощью объекта ObjectAnimationUsingKeyFrames, который применяет дискретные целые значения. Однако существующее ограничение реализации среда выполнения Windows XAML заключается в том, что нельзя анимировать пользовательское присоединенное свойство.
Дополнительные типы анимации и дальнейшие действия по изучению анимации пользовательского интерфейса
До сих пор мы отображали пользовательские анимации, которые анимируются между двумя значениями, а затем линейно интерполяции значений при необходимости при выполнении анимации. Они вызываются анимациями from/By./ Но есть другой тип анимации, позволяющий объявлять промежуточные значения, которые падают между началом и окончанием. Это называется анимацией с ключевым кадром. Существует также способ изменить логику интерполяции в анимации from/By/ или анимации с помощью ключевого кадра. Это включает применение функции упрощения. Дополнительные сведения об этих понятиях см. в разделе "Ключевые кадры" и анимации функций с упрощенной функцией.
См. также
- Синтаксис пути к свойству
- Общие сведения о свойствах зависимостей
- Анимации ключевых кадров и анимаций с упрощенной функцией
- Раскадровки анимаций для визуальных состояний
- Шаблоны элементов управления
- Раскадровка
- Раскадровка.TargetProperty
Windows developer