如何使矩形随时间更快地改变颜色

时间:2017-07-21 20:06:35

标签: c# wpf

我有一个wpf应用程序,其中矩形在10秒内在一秒钟内在红色和黑色之间改变颜色。我想要的是能够在经过毫秒达到6秒(6000毫秒)时更快地改变颜色。

我(大多数情况下)工作,但问题是它在2秒标记后切换太快。我希望它会在接近最后几秒时变得更快。

这是我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Timers;
using System.Diagnostics;

namespace Test
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Grid_Loaded(object sender, RoutedEventArgs e)
        {
            SoftBlink(6000); //6 seconds...
        }

        private async void SoftBlink(short CycleTime_ms)
        {
            Stopwatch sw = new Stopwatch(); sw.Start();

            int interval = 500;

            while (sw.ElapsedMilliseconds < CycleTime_ms)
            {
                await Task.Delay(interval);
                recTest.Fill = Brushes.Red;
                await Task.Delay(interval);
                recTest.Fill = Brushes.Black;

                interval -= (int)(interval * 0.5);
            }
            sw.Stop();
        }
    }
}

有人能看出我做错了吗?

1 个答案:

答案 0 :(得分:0)

这种类型的动画需要用故事板完成;用任务await操纵颜色不会真正给出预期的结果。

这与Storyboard动画相当直接。您将需要使用具有PowerEase功能的ColorAnimation,这将允许您逐渐增加或减少动画速度/过渡。

这是一个简单的例子,点击按钮将改变矩形的填充颜色。它将运行故事板6秒。动画是0.5秒长,但故事板将在代码中反复重复,直到我们达到6秒。在每次迭代中,我们将增加Power属性以加速颜色转换。

操纵powerFactor值以查看效果如何。您也可以使用EasingMode

<强>的Xaml     

        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>

        <Storyboard x:Key="Storyboard1">
            <ColorAnimationUsingKeyFrames x:Name="Animation" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="Flash">
                <EasingColorKeyFrame KeyTime="0" Value="Red"/>
                <EasingColorKeyFrame KeyTime="0:0:0.5" Value="Black">
                    <EasingColorKeyFrame.EasingFunction>
                        <PowerEase EasingMode="EaseInOut"/>
                    </EasingColorKeyFrame.EasingFunction>
                </EasingColorKeyFrame>
            </ColorAnimationUsingKeyFrames>
        </Storyboard>

    </Window.Resources>

    <Grid Background="Gray">
        <Rectangle x:Name="Flash" Height="100" Width="100" Fill="Red">
        </Rectangle>

        <Button x:Name="button" Content="Button" Margin="246,0,196,34.04" VerticalAlignment="Bottom" Click="button_Click"/>
    </Grid>
</Window>

代码

public partial class MainWindow : Window
{

    private Stopwatch timer = new Stopwatch();
    private static readonly double powerFactor = .3;
    private Storyboard storyboard;
    private PowerEase easingFunction;

    public MainWindow()
    {
        InitializeComponent();

        //handle the completed event to re-execute the storyboard
        this.storyboard = this.Resources["Storyboard1"] as Storyboard;
        this.storyboard.Completed += Storyboard_Completed;

        //get the animation to locate our easing function defined in xaml.
        var animation = storyboard.Children[0] as ColorAnimationUsingKeyFrames;

        //find the second keyframe, thats the one that has easing function.
        this.easingFunction = (animation.KeyFrames[1] as EasingColorKeyFrame).EasingFunction as PowerEase;


    }

    private void button_Click(object sender, RoutedEventArgs e)
    {
        this.timer.Reset();
        this.timer.Start();
        this.easingFunction.Power = 0;

        RunStoryboard();
    }

    private void Storyboard_Completed(object sender, EventArgs e)
    {
        if (timer.ElapsedMilliseconds < 6000)
        {
            RunStoryboard();
        }
    }

    private void RunStoryboard()
    {
        this.easingFunction.Power += powerFactor;
        storyboard.Begin();
    }
}