WPF - 连续动画简单的例子 [英] WPF - sequential animation simple example

查看:153
本文介绍了WPF - 连续动画简单的例子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在学习WPF动画,感到困惑的是如何按顺序使用动画。一个简单的例子,我有四个矩形在一个统一的网格,想改变每一个顺序的颜色。这是我到目前为止有:

 公共部分类窗口1:窗口
{
    矩形blueRect;
    矩形redRect;
    矩形greenRect;
    矩形yellowRect;    公共窗口1()
    {
        的InitializeComponent();
        blueRect =新的Rectangle(){填写= System.Windows.Media.Brushes.Blue,NAME =蓝};
        redRect =新的Rectangle(){填写= System.Windows.Media.Brushes.Red,名称=黄色};
        greenRect =新的Rectangle(){填写= System.Windows.Media.Brushes.Green,名称=绿色};
        yellowRect =新的Rectangle(){填写= System.Windows.Media.Brushes.Yellow,名称=黄色};        UniformGrid1.Children.Add(blueRect);
        UniformGrid1.Children.Add(redRect);
        UniformGrid1.Children.Add(greenRect);
        UniformGrid1.Children.Add(yellowRect);    }    私人无效Window_Loaded(对象发件人,RoutedEventArgs E)
    {
        animateCell(blueRect,Colors.Blue);
        animateCell(redRect,Colors.Red);
    }    私人无效animateCell(矩形矩形,颜色fromColor)
    {
        颜色toColor = Colors.White;
        ColorAnimation ANI =新ColorAnimation(toColor,新的持续时间(TimeSpan.FromMilliseconds(300)));
        ani.AutoReverse = TRUE;        的SolidColorBrush newBrush =新的SolidColorBrush(fromColor);
        ani.BeginTime = TimeSpan.FromSeconds(2);
        rectangle.Fill = newBrush;
        newBrush.BeginAnimation(SolidColorBrush.ColorProperty,ANI);
        //NameScope.GetNameScope(this).RegisterName(rectangle.Name,矩形);
        //故事板板=新的故事板();
        //board.Children.Add(ani);
        //Storyboard.SetTargetName(rectangle,rectangle.Name);
        //Storyboard.SetTargetProperty(ani,新的PropertyPath(SolidColorBrush.ColorProperty));
        //board.Begin();    }

什么是解决这个问题的最简单的方法?在评论中code是我的第一个猜测,但它不能正常工作。


解决方案

应该有一个事件 ani.Completed - 处理该事件,并启动动画的下一阶段,然后开始第一次运行,每个阶段将触发下一个。

  Col​​orAnimation ANI = //无论...ani.Completed + =(S,E)=>
   {
       ColorAnimation ANI2 = //另一个...       // 等等
   };newBrush.BeginAnimation(SolidColorBrush.ColorProperty,ANI);

更新:

 公共部分类窗口1:窗口
{
    矩形blueRect;
    矩形redRect;
    矩形greenRect;
    矩形yellowRect;    公共窗口1()
    {
        的InitializeComponent();
        blueRect =新的Rectangle(){填写= System.Windows.Media.Brushes.Blue,NAME =蓝};
        redRect =新的Rectangle(){填写= System.Windows.Media.Brushes.Red,名称=黄色};
        greenRect =新的Rectangle(){填写= System.Windows.Media.Brushes.Green,名称=绿色};
        yellowRect =新的Rectangle(){填写= System.Windows.Media.Brushes.Yellow,名称=黄色};        UniformGrid1.Children.Add(blueRect);
        UniformGrid1.Children.Add(redRect);
        UniformGrid1.Children.Add(greenRect);
        UniformGrid1.Children.Add(yellowRect);
    }    IEnumerable的<作用<作用>> AnimationSequence()
    {
        对于(;)
        {
            产量返回AnimateCell(blueRect,Colors.Blue);
            产量返回AnimateCell(redRect,Colors.Red);
            产量返回AnimateCell(greenRect,Colors.Green);
            产量返回AnimateCell(yellowRect,Colors.Yellow);
        }
    }    私人的IEnumerator<作用<作用>> _actions;    私人无效RunNextAction()
    {
        如果(_actions.MoveNext())
            _actions.Current(RunNextAction);
    }    私人无效Window_Loaded(对象发件人,RoutedEventArgs E)
    {
        _actions = AnimationSequence()的GetEnumerator()。
        RunNextAction();
    }    民营动作<作用> AnimateCell(矩形矩形,颜色fromColor)
    {
        返回完成= GT;
        {
            颜色toColor = Colors.White;
            ColorAnimation ANI =新ColorAnimation(toColor,
                                    新持续时间(TimeSpan.FromMilliseconds(300)));
            ani.AutoReverse = TRUE;
            ani.Completed + =(S,E)=>完成();            的SolidColorBrush newBrush =新的SolidColorBrush(fromColor);
            ani.BeginTime = TimeSpan.FromSeconds(2);
            rectangle.Fill = newBrush;
            newBrush.BeginAnimation(SolidColorBrush.ColorProperty,ANI);
        };
    }
}

试试上面的粘贴到你的程序。它做你所需要的,但在某种程度上可能会在其他对你有用。它仍然是事件驱动,但它使用一个iterator方法(与收益回报)来创建IM pression,它是连续的编码,阻止而动画是怎么回事。

关于这样做的好处是,你可以玩,在一个非常直观的方式AnimationSequence方法 - 你可以写出来的动画的时间轴中的一系列语句,或使用循环,或任何你想

I'm learning about WPF animation, and am confused about how to apply animations sequentially. As a simple example, I've got four rectangles in a uniform grid, and would like to change the color of each one sequentially. Here's what I have so far:

public partial class Window1 : Window
{
    Rectangle blueRect;
    Rectangle redRect;
    Rectangle greenRect;
    Rectangle yellowRect;

    public Window1()
    {
        InitializeComponent();
        blueRect = new Rectangle() { Fill = System.Windows.Media.Brushes.Blue, Name="Blue"};
        redRect = new Rectangle() { Fill = System.Windows.Media.Brushes.Red, Name="Yellow"};
        greenRect = new Rectangle() { Fill = System.Windows.Media.Brushes.Green, Name="Green" };
        yellowRect = new Rectangle() { Fill = System.Windows.Media.Brushes.Yellow, Name="Yellow" };

        UniformGrid1.Children.Add(blueRect);
        UniformGrid1.Children.Add(redRect);
        UniformGrid1.Children.Add(greenRect);
        UniformGrid1.Children.Add(yellowRect);

    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        animateCell(blueRect, Colors.Blue);
        animateCell(redRect, Colors.Red);
    }

    private void animateCell(Rectangle rectangle, Color fromColor)
    {
        Color toColor = Colors.White;
        ColorAnimation ani = new ColorAnimation(toColor, new Duration(TimeSpan.FromMilliseconds(300)));
        ani.AutoReverse = true;

        SolidColorBrush newBrush = new SolidColorBrush(fromColor);
        ani.BeginTime = TimeSpan.FromSeconds(2);
        rectangle.Fill = newBrush;
        newBrush.BeginAnimation(SolidColorBrush.ColorProperty, ani);
        //NameScope.GetNameScope(this).RegisterName(rectangle.Name, rectangle);
        //Storyboard board = new Storyboard();
        //board.Children.Add(ani);
        //Storyboard.SetTargetName(rectangle, rectangle.Name);
        //Storyboard.SetTargetProperty(ani, new PropertyPath(SolidColorBrush.ColorProperty));
        //board.Begin();

    }

What's the easiest way of accomplishing this? The code in the comments is my first guess, but it's not working correctly.

解决方案

There should be an event ani.Completed - handle that event and start the next phase of the animation, then start the first one running and each phase will trigger the next.

ColorAnimation ani = // whatever...

ani.Completed += (s, e) => 
   {
       ColorAnimation ani2 = // another one...

       // and so on
   };

newBrush.BeginAnimation(SolidColorBrush.ColorProperty, ani);

UPDATE:

public partial class Window1 : Window
{
    Rectangle blueRect;
    Rectangle redRect;
    Rectangle greenRect;
    Rectangle yellowRect;

    public Window1()
    {
        InitializeComponent();
        blueRect = new Rectangle() { Fill = System.Windows.Media.Brushes.Blue, Name = "Blue" };
        redRect = new Rectangle() { Fill = System.Windows.Media.Brushes.Red, Name = "Yellow" };
        greenRect = new Rectangle() { Fill = System.Windows.Media.Brushes.Green, Name = "Green" };
        yellowRect = new Rectangle() { Fill = System.Windows.Media.Brushes.Yellow, Name = "Yellow" };

        UniformGrid1.Children.Add(blueRect);
        UniformGrid1.Children.Add(redRect);
        UniformGrid1.Children.Add(greenRect);
        UniformGrid1.Children.Add(yellowRect);
    }

    IEnumerable<Action<Action>> AnimationSequence()
    {
        for (; ; )
        {
            yield return AnimateCell(blueRect, Colors.Blue);
            yield return AnimateCell(redRect, Colors.Red);
            yield return AnimateCell(greenRect, Colors.Green);
            yield return AnimateCell(yellowRect, Colors.Yellow);
        }
    }

    private IEnumerator<Action<Action>> _actions;

    private void RunNextAction()
    {
        if (_actions.MoveNext())
            _actions.Current(RunNextAction);
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        _actions = AnimationSequence().GetEnumerator();
        RunNextAction();
    }

    private Action<Action> AnimateCell(Rectangle rectangle, Color fromColor)
    {
        return completed =>
        {
            Color toColor = Colors.White;
            ColorAnimation ani = new ColorAnimation(toColor, 
                                    new Duration(TimeSpan.FromMilliseconds(300)));
            ani.AutoReverse = true;
            ani.Completed += (s, e) => completed();

            SolidColorBrush newBrush = new SolidColorBrush(fromColor);
            ani.BeginTime = TimeSpan.FromSeconds(2);
            rectangle.Fill = newBrush;
            newBrush.BeginAnimation(SolidColorBrush.ColorProperty, ani);
        };
    }
}

Try pasting the above into your program. It does what you need, but in a way that may be useful to you in other contexts. It's still event driven, but it uses an "iterator method" (with yield return) to create the impression that it is sequential coding that blocks while the animation is going on.

The nice thing about this is that you can play around with the AnimationSequence method in a very intuitive way - you could write out the timeline of the animation in a series of statements, or use loops, or whatever you want.

这篇关于WPF - 连续动画简单的例子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆