30 приложений для Windows Phone: Пока горит свеча

Вот втором нашем приложении мы сделаем анимированную свечу. Для анимации нам понадобится шестьдесят отдельных изображений, которые будут сменяться со скоростью 20 кадров в секунду. Картинки были взяты с Wikipedia.

Анимацию можно сделать разными способами. Например, использовать таймер, как это мы делали в предыдущем приложении. Другой метод заключается в использовании раскадровки (storyboard). Мы можем создать раскадровку двуамя методами: через XAML или программно. Для нашего примера мы сделаем анимацию программным способом, а потом покажем способ через XAML.

Настройка интерфейса

Добавим на страницу элемент Image с именем CandleImage и установим следующие свойства.

  • Margin: Clear (Сбросим все настройки)
  • Horizontal и Vertical Alignment: Stretch

Создание раскадровки

К сожалению, Expression Blend не поддерживет тип DiscreteObjectKeyFrame, который нам нужен для приложения. Поэтому нам придется самостоятельно написать код в XAML или реализовать раскодровку в коде программно.

В событии Loaded создадим новые объекты Storyboard и ObjectAnimationUsingKeyFrames. Для Storyboard установим поведение RepeatBehavior в Forever (постоянная анимация) и укажем для изображения пути ко всем 60 картинкам через свойство Source.

Затем в цикле пройдемся по всем изображениям анимации и создадим из них отдельные кадры, которые буут сменяться каждые 50 миллисекунд и укажем точный путь к картинке для каждого кадра.

Затем добавим раскадровку в ресурсы страницы и запустим аниманию.

public partial class MainPage
{
    public MainPage()
    {
        InitializeComponent();
 
        Loaded += OnLoaded;
    }
 
    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        var storyboard = 
		    new Storyboard {RepeatBehavior = RepeatBehavior.Forever};
 
        var animation = new ObjectAnimationUsingKeyFrames();
 
        Storyboard.SetTarget(animation, CandleImage);
        Storyboard.SetTargetProperty(animation, new PropertyPath("Source"));
 
        storyboard.Children.Add(animation);
 
        for(int i = 1; i <= 60; i++)
        {
            var keyframe = new DiscreteObjectKeyFrame
           {
               KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(50 * i)),
               Value = String.Format("/Images/candle_{0:D2}.jpg", i)
           };
 
           animation.KeyFrames.Add(keyframe);
        }
 
       Resources.Add("CandleStoryboard", storyboard);
 
       storyboard.Begin();
    }
}

Если вы хотите построить раскадровку через XAML, то вам придется повторять одни и те же строчки, что довольно утомительно.

<Storyboard x:Key="CandleStoryboardXaml" RepeatBehavior="Forever">
 <ObjectAnimationUsingKeyFrames Storyboard.TargetName="CandleImage" Storyboard.TargetProperty="Source">
 <DiscreteObjectKeyFrame KeyTime="0:0:0.50" Value="/images/candle_01.jpg" />
 <DiscreteObjectKeyFrame KeyTime="0:0:0.100" Value="/images/candle_02.jpg" />
 <DiscreteObjectKeyFrame KeyTime="0:0:0.150" Value="/images/candle_03.jpg" />
 <DiscreteObjectKeyFrame KeyTime="0:0:0.200" Value="/images/candle_04.jpg" />
 <DiscreteObjectKeyFrame KeyTime="0:0:0.250" Value="/images/candle_05.jpg" />
 ...
 </ObjectAnimationUsingKeyFrames>
</Storyboard>

Код приведен с сокращениями, но программно проще создать такой же эффект. Выбирайте сами.

Свеча
Реклама