ГЛАВНАЯ     АРХИВ     НАПИСАТЬ АДМИНУ     ПОДПИСАТЬСЯ НА RSS     ВОЙТИ      

Поиск

Категории

Облако тегов

acer ado.net amd asp.net c sharp c# cms css exceptions google html ipad iphone it бизнес javascript jquery linq microsoft mysql net nokia nokia lumia samsung seo silverlight sql surface tsql windows 8 windows blue windows phone windows rt xna безопасность библиотека вопросы на собеседовании интересные проекты интернет интернет магазин исключения книга книги компьютерная безопасность компьютерные игры контролы курсы по программированию логированние исключений мобильные приложения монетизация сайтов наушники новости новости it новости microsoft новости интернет новости технологий ноутбук ноутбуки обработка исключений оптимизация острова периферия планшет планшеты поддержка сайтов поисковое продвижение программы продвижение продвижение сайта продвижение сайтов рабство разработка игр разработка сайтов раскрутка сайта рекламные технологии смартфон смартфоны собеседование создание сайтов средства разработки туризм фриланс хостинг яндекс
  << Предыдущий пост       Следующий пост >>  
От: peerAt
26. апреля 2011 02:00

Оригинал статьи взят отсюда: Сервелат, анимация и старый добрый code-behind

Автор (на хабре): ThePretender

Решил немножко покопаться в Silverlight, да смастерить на нём что-нибудь прикольное. Это прикольное, конечно, должно шевелиться, переливаться и плавно подёргиваться, ибо вебдваноль у нас или где? :). И вот тут мне пришлось столкнуться с неплохой, по сути, системой анимаций в WPF/Silverlight. Покурив MSDN, я бодренько приступил к написанию анимаций в XAML. Одну написал, вторую, третью… А потом мне захотелось сделать так, чтобы они шли в определённой последовательности. И вот тут-то я и понял, что XAML, зараза, очень избыточный. Для описания интерфейсов он подходит идеально: сразу видно, что к чему относится и надобность в визуальном редакторе отпадает чуть менее, чем полностью. Но вот когда пытаешься написать в этом XAMLе какую-то логику, начинает проявляться вся его несуразность. Покурив гугл, я был сильно удивлён тем, что большинство людей упорно пытаются впихнуть в XAML абсолютно всё. Ругаются, путаются в коде, плачут, но продолжают писать. Прямо как те мыши с кактусом, чесслово. И тут мне пришла идея аккуратно описать анимации обычным кодом на C#. Мы, так сказать, олдфаги, рисовали интерфейс прямыми вызовами к WinAPI, неужто нас какие-то анимации испугают? :)

В результате получился вот такой портабельный класс AnimationBag. Портабельный он потому, что его безо всяких изменений можно использовать как в WPF, так и в Silverlight.


public class AnimationItem
{
    public event EventHandler Completed;

    private void OnStoryboardComplete(object sender, EventArgs e)
    {
        if (Completed != null)
            Completed(this, EventArgs.Empty);
    }

    private Storyboard storyboard;
    public Storyboard Storyboard
    {
        get { return storyboard; }
        set
        {
            if (storyboard != null)
                storyboard.Completed -= OnStoryboardComplete;

            storyboard = value;
            storyboard.Completed += OnStoryboardComplete;
        }
    }

    public Action BeginAction { get; set; }
    public Action EndAction { get; set; }
}

public class AnimationBag
{
    private readonly Dictionary<string, AnimationItem> storyboards =
             new Dictionary<string, AnimationItem>();

    public void AddAnimation(string name, DependencyObject control,
             string propertyName, Timeline animation, Action beginAction = null, Action endAction = null)
    {
        Storyboard board = new Storyboard();
        AnimationItem item = new AnimationItem { BeginAction = beginAction, EndAction = endAction };

        Storyboard.SetTarget(animation, control);
        Storyboard.SetTargetProperty(animation, new PropertyPath(propertyName));
        board.Children.Add(animation);
        if (endAction != null)
            item.Completed += item_Completed;
        item.Storyboard = board;

        storyboards[name] = item;
    }

    private void item_Completed(object sender, EventArgs e)
    {
        KeyValuePair<string, AnimationItem> pair =
                     storyboards.Where(x => x.Value.Equals(sender)).FirstOrDefault();

        if (pair.Value != null && pair.Value.EndAction != null)
            pair.Value.EndAction.Invoke();
    }

    public void StartAnimation(string name)
    {
        if (!storyboards.ContainsKey(name))
            return;

        if (storyboards[name].BeginAction != null)
            storyboards[name].BeginAction.Invoke();

        storyboards[name].Storyboard.Begin();
    }

    public void StopAnimation(string name)
    {
        if (!storyboards.ContainsKey(name))
            return;

        storyboards[name].Storyboard.Stop();

        if (storyboards[name].EndAction != null)
            storyboards[name].EndAction.Invoke();
    }

    public static DoubleAnimation CreateDoubleAnimation(double? to, long durationMs,
            double? from = null, bool repeat = false)
    {
        DoubleAnimation ret = new DoubleAnimation { To = to, From = from,
                    Duration = new Duration(TimeSpan.FromMilliseconds(durationMs)) };

        if (repeat)
            ret.RepeatBehavior = RepeatBehavior.Forever;

        return ret;
    }
}

Как видно из кода, класс предельно простой. Вот пример использования.

XAML:


<Window
x:Class="Animation.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="350"
Width="525"
>
<Grid>
<Rectangle Height="110" HorizontalAlignment="Left"
Margin="55,71,0,0" Name="rectangle1" Stroke="Black"
VerticalAlignment="Top" Width="181" Fill="#FF9D3434"
/>
<Button Content="Button" Height="36" HorizontalAlignment="Left"
Margin="286,93,0,0" Name="button1" VerticalAlignment="Top"
Width="149" Click="button1_Click"
/>
</Grid>
</Window>

Code-behind:


public partial class MainWindow : Window
{
    private readonly AnimationBag animations = new AnimationBag();

    public MainWindow()
    {
        InitializeComponent();
        InitAnimations();
    }

    private void InitAnimations()
    {
        animations.AddAnimation(
            "fadeOut",
            rectangle1,
            "Opacity",
            AnimationBag.CreateDoubleAnimation(0, 500),
            null,
            () => animations.StartAnimation("fadeIn"));

        animations.AddAnimation(
            "fadeIn",
            rectangle1,
            "Opacity",
            AnimationBag.CreateDoubleAnimation(1, 500));
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        animations.StartAnimation("fadeOut");
    }
}

Сам класс представляет собой что-то вроде словаря с ключами — именами анимаций и значениями — анимациями. В методе InitAnimations в коллекцию добавляются две анимации, при этом указывается имя, контрол, над которым будет производится действо, свойство этого контрола и сам объект анимации. Его можно создавать ручками, а можно добавить статические хэлперы к уже имеющемуся методу для DoubleAnimation. Кроме всего прочего, метод AddAnimation может принимать два делегата, которые будут выполняться до и после самой анимации. Например, здесь после завершения анимации “fadeOut” сразу запускается “fadeIn”.

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

Скачать исходники с тестовыми проектами

Похожие записи


Новый Старый Бойцовский клуб
Если у вас появилось немного свободного времени, то хорошим вариантом будет попробовать свои силы в какой-то онлайн игре. Компьютерные онлайн игры – это всегда залог веселья, новых знакомств и впечатлений. Для тех, кому лень возиться с установкой массивного клиента игры, существуют не менее интересные и захватывающие браузерные игры. И если кто-то д...

Irrlicht - это графический 3D движок с открытым исходным кодом
Оригинал cтатьи взят отсюда: www.irrlicht.ru Irrlicht - это графический 3D движок с открытым исходным кодом и высоким быстродействием, написанный на C++. Он являет собой готовый кросс-платформенный продукт, использующий как D3D, OpenGL так и собственный рендерер. В движке присутствуют все возможности коммерческих продуктов. Движок, за время существования, обрел огро...

Ianprime XNA Engine (IXNAE) - 2D игровой движек под XNA
IXNAE проект - это 2D движок XNA. Он создан, чтобы помочь разработчикам быстро создавать игры под XNA, не беспокоясь о простых, повторяющихся задачах. IXNAE упрощает анимацию спрайтов, а также создание игровых объектов. Области, в которых IXNAE упрощает жизнь разработчика игр: 1. Спрайты (анимация, проигрывание последовательностей, масштабирование, раскрашиван...

Добавить комментарий




biuquote
  • Комментарий
  • Предпросмотр
Loading


  Сохранить комментарий