Brush to Brush Animation

后端 未结 3 1368
夕颜
夕颜 2020-12-09 08:30

I managed to find out how to make a WPF animation - transition between two colors.

It\'s called ColorAnimation and works well.

ColorAnimation animati         


        
3条回答
  •  有刺的猬
    2020-12-09 09:31

    Another possible way is, to create a custom animtion class that animate brushes. I found a simple way to do that by creating a class, derivated from AnimationTimeline. We can override some members in the custom class, among other things the AnimationTimeline.GetCurrentValue method. It returns a value depend on the animation progress and the start- and end value.

    The simplest way is to create a VisualBrush and crossfade the start- with the end value with the Opacity property on a child control. The result is a class like the following:

    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));
    }
    

    You can use it as always in XAML:

    
        
            
                
                    
                        
                            
                            
                            
                        
                    
                
            
        
    
    

    or in code behind:

    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();
    

    It is also possible to extend the BrushAnimation with constructor overloads etc., so it looks like a .NET given animation type.

提交回复
热议问题