Главная » Silverlight » Время жизни анимации

0

Все анимации Silverlight вносят лишь временные изменения. Это означает, что они фактически не изменяют значение нижележащего свойства. Когда анимация актив­на, она переопределяет значение свойства. Зависимые свойства получают значения от многих провайдеров (см. главу 4). Непонимание этой тонкости часто приводит к тяже­ло исправимым ошибкам.

Односторонняя анимация (например, расширение кнопки) остается активной и по­сле завершения. Она должна удерживать кнопку в расширенном состоянии. Это мо­жет привести к необычным проблемам. Например, если попытаться с помощью кода изменить значение ширины кнопки после завершения анимации, код не повлияет на кнопку. Код присвоит ширине новое локальное значение, но приоритет анимационного значения будет выше, чем локального.

Решить эту проблему можно несколькими способами, в зависимости от того, какой эффект необходимо реализовать.

В первых трех способах изменяется поведение анимации. Так или иначе, анимированное свойство возвращается в исходное значение. Если это нежелательно, примените последний способ.

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

storyboard.Completed += storyboard_Completed;

При возникновении события Completed можно извлечь объект раскадровки, управ­ляющий анимацией, и остановить его.

private void storyboard_Completed(object sender,

EventArgs e)

{

Storyboard storyboard = (Storyboard)sender; storyboard.Stop ();

)

При вызове метода Storyboard. Stop () свойству возвращается значение, которое оно имело до запуска анимации. Если это нежелательно, можно сохранить текущее зна­чение, установленное анимацией, удалить анимацию, а затем присвоить сохраненное значение изменяемому свойству.

double currentWidth = cmdGrow.Width;

storyboard.Stop ();

cmdGrow.Width = currentWidth;

Учитывайте, что при этом изменяется локальное значение свойства. Это может повлиять на поведение других анимаций. Например, если кнопка анимирована без установки свойства From, новое значение используется в качестве начальной точки. В большинстве случаев это то, что нужно.

Свойство RepeatBehavior

Свойство RepeatBehavior управляет повторением анимации. Если нужно повто­рить ее фиксированное количество раз, то в качестве значения свойства введите число с суффиксом х. Например, приведенная ниже анимация повторяется дважды.

<DoubleAnimation Storyboard.TargetName="cmdGrow" RepeatBehavior="2x" Storyboard.TargetProperty="Width" To="300" Duration="0:0:5"></DoubleAnimation>

В коде C# количество повторений можно передать конструктору объекта

RepeatBehavior.

widthAnimation.RepeatBehavior = new RepeatBehavior(2);

При выполнении анимации ширина кнопки будет плавно увеличиваться на протя­жении 5 секунд, затем мгновенно установится исходная ширина, после чего ширина опять будет плавно увеличиваться. Если присвоить свойству AutoReverse значение True, поведение анимации немного изменится: ширина кнопки будет плавно увеличи­ваться и уменьшаться два раза подряд.

В свойстве RepeatBehavior можно задать не только количество повторений, но и ин­тервал времени, на протяжении которого выполняются повторения. Например, приве­денная ниже анимация повторяется на протяжении 13 секунд.

<DoubleAnimation Storyboard.TargetName="cmdGrow" RepeatBehavior="0:0:13" Storyboard.TargetProperty="Width" To="300" Duration="0:0:5"></DoubleAnimation>

Того же эффекта можно достичь, задав интервал повторения в конструкторе объек­та RepeatBehavior.

widthAnimation.RepeatBehavior =

new RepeatBehavior(TimeSpan.FromSeconds(13));

В данном примере свойство Duration задает продолжительность анимации равной 5 секундам. Интервал повторения равен 13 секундам. Следовательно, анимация будет повторена два раза полностью, а при третьем повторении будет остановлена на полпути.

Совет. Свойство RepeatBehavior можно использовать для выполнения части анимации. Для этого введите количество повторений в интервале от 0 до 1 (оно может быть дробным) или задайте интервал повторения меньше продолжительности анимации.

И наконец, с помощью значения RepeatBehavior. Forever можно задать бесконеч­ное повторение анимации.

<DoubleAnimation Storyboard.TargetName="cmdGrow" RepeatBehavior="Forever" Storyboard.TargetProperty="Width" To="300" Duration="0:0:5"></DoubleAnimation>

Одновременное выполнение нескольких анимаций

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

В приведенную ниже раскадровку вложено две анимации. Одна изменяет свойство Width кнопки, а другая — свойство Height. Анимации сгруппированы в одной раска­дровке, поэтому они изменяют размеры кнопки в унисон.

<Storyboard x:Name="storyboard" Storyboard.TargetName="cmdGrow">

<DoubleAnimation Storyboard.TargetProperty="Width" To="300" Duration="0:0:5"></DoubleAnimation> <DoubleAnimation Storyboard.TargetProperty="Height" To="300" Duration="0:0:5"></DoubleAnimation>

</Storyboard>

Свойство Storyboard.TargetName перемещено из DoubleAnimation в Storyboard. Делать так не обязательно, однако это позволяет избежать установки свойства дважды: по одному разу для каждого объекта анимации. Если же объекты анимации управляют разными элементами, применить этот трюк не удастся.

В данном примере объектам анимации присвоена одинаковая продолжительность, однако это не обязательно. Когда значения продолжительности разные, нужно лишь позаботиться о свойстве FillBehavior. Если свойству FillBehavior присвоено зна­чение HoldEnd (установлено по умолчанию), значение удерживается, пока все анима­ции раскадровки не будут завершены. В этот момент времени вступает в игру свойство FillBehavior: оно либо продолжает удерживать значения обеих анимаций (при значе­ниях HoldEnd), либо присваивает им исходные значения (при значениях Stop). С другой стороны, если в раскадровке определено несколько анимаций и в одной из них свойству FillBehavior присвоено значение Stop, анимируемое свойство переключается в исхо­дное состояние при завершении анимации, даже если другие анимации раскадровки все еще выполняются.

При одновременном выполнении нескольких анимаций полезны свойства BeginTime и SpeedRatio. Они устанавливают задержку (тип TimeSpan), добавляемую перед запуском анимации. Задержка добавляется к общему времени, а не включается в него, поэтому при задержке в 5 секунд анимация длительностью 5 секунд выполняется 10 секунд. Свойство BeginTime полезно для синхронизации разных анимаций, которые запускаются в один и тот же момент времени, но должны создавать эффекты одна после другой. Свойство SpeedRatio увеличивает или уменьшает скорость анимации. Обычно оно равно единице. Если увеличить его, анимация выполняется быстрее (например, при значении 5 она завершается в 5 раз быстрее). Если уменьшить, анимация замедляет­ся (например, при значении 0.5 анимация длится в два раза дольше). Эффект тот же, что и при изменении свойства Duration, однако с помощью свойства SpeedRatio легче управлять взаимодействием одновременных анимаций.

Управление воспроизведением

Вы уже знаете, как запустить анимацию с помощью метода Storyboard. Begin (). Класс Storyboard предоставляет еще несколько методов, позволяющих управлять воспроизведе­нием анимации. В следующем примере вы увидите их в действии (рис. 10.2). На данной странице с помощью элемента Grid размещены два элемента Image в одной и той же об­ласти. В исходном состоянии видно верхнее изображение — телевышка города Торонто днем. При запуске анимации прозрачность изображения увеличивается, и сквозь него на­чинает просматриваться ночной пейзаж. Создается впечатление плавного перехода от дня к ночи, как при выводе последовательности фотографий, сделанных с одной точки.

Рис. 10.2. Управляемая анимация

Ниже приведена разметка контейнера Grid, содержащего два изображения.

<Grid>

<Image Source="night. jpg"></Image> <Image Source="day. jpg" x:Name="imgDay"></Image> </Grid>

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

<Storyboard х:Name="fadeStoryboard"> <DoubleAnimation x: Name="fadeAnimation" Storyboard.TargetName="imgDay"

Storyboard.TargetProperty="Opacity" From="l" To="0" Duration="0:0:10"> </DoubleAnimation> </Storyboard>

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

Storyboard.

private void cmdStart_Click(object sender, RoutedEventArgs e)

fadeStoryboard. Begin ();

private void cmdPause_Click(object sender, RoutedEventArgs e)

fadeStoryboard.Pause();

private void cmdResume_Click(object sender, RoutedEventArgs e)

fadeStoryboard.Resume();

private void cmdStop_Click(object sender, RoutedEventArgs e) fadeStoryboard.Stop();

private void cmdMiddle_Click(object sender, RoutedEventArgs e)

{

// Запуск анимации, если она не активна fadeStoryboard.Begin();

// Переход к позиции, представляющей середину // интервала времени fadeStoryboard.Seek( TimeSpan.FromSeconds( fadeAnimation.Duration.TimeSpan.TotalSeconds/2));

}

Примечание. Остановка анимации не эквивалентна ее завершению (если только свойству FillBehavior не присвоено значение stop). Это объясняется тем, что когда анимация достигает конечного значения, оно остается действующим. Аналогично при паузе продолжает применяться текущее значение. Однако когда анимация остановлена, она больше не применяет никакое значение и анимируемое свойство возвращается в исходное состояние.

При перемещении ползунка Slider запускается обработчик его события Slider. ValueChanged, который запускает еще один обработчик, который, в свою очередь, извле­кает значение ползунка (в диапазоне от 0 до 3) и присваивает его свойству SpeedRatio.

private void sldSpeed_ValueChanged(object sender,

RoutedEventArgs e)

// Возврат, если страница еще инициализируется if (sldSpeed == null) return;

// Изменение скорости анимации fadeStoryboard.SpeedRatio = sldSpeed.Value; lblSpeed.Text = sldSpeed.Value.ToString ("0.0");

}

В отличие от WPF, встроенный в Silverlight класс Storyboard не предоставляет со­бытия, позволяющие отслеживать анимацию. Например, в Silverlight нет события CurrentTimelnvalidated, сообщающего о продвижении анимации на один шаг.

Источник: Мак-Дональд, Мэтью. Silverlight 3 с примерами на С# для профессионалов. : Пер. с англ. —- М. : ООО «И.Д. Вильяме», 2010. — 656 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии