c# - 笔刷动画

标签 c# wpf animation brush

我设法找到了如何制作 WPF 动画 - 两种颜色之间的过渡。

它叫做 ColorAnimation,效果很好。

ColorAnimation animation = new ColorAnimation
{
    From = Colors.DarkGreen,
    To = Colors.Transparent,
    Duration = new Duration(TimeSpan.FromSeconds(1.5)),
    AutoReverse = false
};
animation.Completed += new EventHandler(animation_Completed);
SolidColorBrush brush = new SolidColorBrush(Colors.Transparent);
animation.AccelerationRatio = 0.5;

Background = brush;
brush.BeginAnimation(SolidColorBrush.ColorProperty, animation);

我正在使用它来为我的用户控件设置动画背景。我的控件背景是 SolidColorBrush。最近我换成了LinearGradientBrush。现在我不能再使用我的动画了。

我需要画笔之间的动画,而不是颜色之间的动画。最好的选择是抽象画笔类型,其中包括 SolidColor、LinearGradient 等,因此我可以制作动画,例如从 SolidColorBrushLinearGradientBrush。这可能吗?谢谢。

最佳答案

另一种可能的方法是,创建一个自定义动画类来为画笔设置动画。 我找到了一种简单的方法来创建一个派生自 AnimationTimeline 的类.我们可以覆盖自定义类中的一些成员,其中包括 AnimationTimeline.GetCurrentValue method。 .它返回一个值,该值取决于动画进度以及开始值和结束值。

最简单的方法是创建一个 VisualBrush 并使用子控件上的 Opacity 属性交叉淡入淡出开始值和结束值。结果是如下类:

public class BrushAnimation : AnimationTimeline
{
    public override Type TargetPropertyType
    {
        get
        {
            return typeof(Brush);
        }
    }

    public override object GetCurrentValue(object defaultOriginValue,
                                           object defaultDestinationValue,
                                           AnimationClock animationClock)
    {
        return GetCurrentValue(defaultOriginValue as Brush,
                               defaultDestinationValue as Brush,
                               animationClock);
    }
    public object GetCurrentValue(Brush defaultOriginValue,
                                  Brush defaultDestinationValue,
                                  AnimationClock animationClock)
    {
        if (!animationClock.CurrentProgress.HasValue)
            return Brushes.Transparent;

        //use the standard values if From and To are not set 
        //(it is the value of the given property)
        defaultOriginValue = this.From ?? defaultOriginValue;
        defaultDestinationValue = this.To ?? defaultDestinationValue;

        if (animationClock.CurrentProgress.Value == 0)
            return defaultOriginValue;
        if (animationClock.CurrentProgress.Value == 1)
            return defaultDestinationValue;

        return new VisualBrush(new Border()
        {
            Width = 1,
            Height = 1,
            Background = defaultOriginValue,
            Child = new Border()
            {
                Background = defaultDestinationValue,
                Opacity = animationClock.CurrentProgress.Value,
            }
        });
    }

    protected override Freezable CreateInstanceCore()
    {
        return new BrushAnimation();
    }

    //we must define From and To, AnimationTimeline does not have this properties
    public Brush From
    {
        get { return (Brush)GetValue(FromProperty); }
        set { SetValue(FromProperty, value); }
    }
    public Brush To
    {
        get { return (Brush)GetValue(ToProperty); }
        set { SetValue(ToProperty, value); }
    }

    public static readonly DependencyProperty FromProperty =
        DependencyProperty.Register("From", typeof(Brush), typeof(BrushAnimation));
    public static readonly DependencyProperty ToProperty =
        DependencyProperty.Register("To", typeof(Brush), typeof(BrushAnimation));
}

您可以像往常一样在 XAML 中使用它:

<EventTrigger RoutedEvent="Loaded">
    <BeginStoryboard>
        <Storyboard >
            <local:BrushAnimation Storyboard.TargetName="border"
                                  Storyboard.TargetProperty="Background" 
                                  Duration="0:0:5" From="Red" 
                                  RepeatBehavior="Forever" AutoReverse="True" >
                <local:BrushAnimation.To>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FF00FF2E" Offset="0.005"/>
                        <GradientStop Color="#FFC5FF00" Offset="1"/>
                        <GradientStop Color="Blue" Offset="0.43"/>
                    </LinearGradientBrush>
                </local:BrushAnimation.To>
            </local:BrushAnimation>
        </Storyboard>
    </BeginStoryboard>
</EventTrigger>

或在代码后面:

var animation = new BrushAnimation
{
    From = Brushes.Red,
    To = new LinearGradientBrush (Colors.Green, Colors.Yellow, 45),
    Duration = new Duration(TimeSpan.FromSeconds(5)),
};
animation.Completed += new EventHandler(animation_Completed);
Storyboard.SetTarget(animation, border);
Storyboard.SetTargetProperty(animation, new PropertyPath("Background"));

var sb = new Storyboard();
sb.Children.Add(animation);
sb.Begin();

也可以使用构造函数重载等方式扩展 BrushAnimation,因此它看起来像 .NET 给定的动画类型。

关于c# - 笔刷动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8096852/

相关文章:

ios - 更改数据源时 UICollectionView 中的平滑动画

javascript - 错误 : First row is not an array. Google 饼图

c# - 使用 Dapper 启用多个事件结果集

c# - 找不到 Microsoft.SqlServer.Types 的版本 10 或更高版本

c# - 如何在 C#/WPF 中生成本地化的键盘快捷键?

wpf - 使用 MVVM 使用 Caliburn Micro 关闭所有子窗口

c# - 无论选择什么,ComboBox都会显示System.Data.DataRowView。 ItemTemplate问题

javascript - 什么是动画 DOM 元素最快的 CSS 显示属性

Javascript 框架动画在加载时闪烁

c# - 如何在ios中永远运行后台服务以同步数据