2011-11-11 31 views
18

Tôi đã tìm cách tạo ra một hình động WPF - chuyển đổi giữa hai màu.Brush to Brush Animation

Được gọi là ColorAnimation và hoạt động tốt.

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

Tôi đang sử dụng tính năng này để tạo hiệu ứng nền cho điều khiển người dùng của mình. Nền điều khiển của tôi là SolidColorBrush. Gần đây tôi đã thay đổi thành LinearGradientBrush. Bây giờ tôi có thể sử dụng hoạt hình của tôi không còn nữa.

Tôi cần hoạt ảnh từ cọ vẽ, không phải màu đến màu. Và lựa chọn tốt nhất là kiểu bàn chải trừu tượng, bao gồm SolidColor, LinearGradient vv, vì vậy tôi có thể tạo hiệu ứng động từ ví dụ từ SolidColorBrush đến LinearGradientBrush. Điều đó thậm chí có thể? Cảm ơn bạn.

Trả lời

5

Bạn chỉ cần sử dụng hoạt ảnh màu trên các điểm dừng gradient của bút vẽ gradient. Dưới đây là một ví dụ để làm động một gradient hình chữ nhật bằng cách sử dụng bảng phân cảnh.

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    x:Class="GradientBrushAnimation.MainWindow" 
    x:Name="Window" 
    Title="MainWindow" 
    Width="640" Height="480"> 
    <Window.Resources> 
     <Storyboard x:Key="Storyboard1"> 
      <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="rectangle"> 
       <EasingColorKeyFrame KeyTime="0:0:2" Value="Red"/> 
      </ColorAnimationUsingKeyFrames> 
      <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="rectangle"> 
       <EasingColorKeyFrame KeyTime="0:0:2" Value="#FF71FF00"/> 
      </ColorAnimationUsingKeyFrames> 
     </Storyboard> 
    </Window.Resources> 
    <Window.Triggers> 
     <EventTrigger RoutedEvent="FrameworkElement.Loaded"> 
      <BeginStoryboard Storyboard="{StaticResource Storyboard1}"/> 
     </EventTrigger> 
    </Window.Triggers> 

    <Grid x:Name="LayoutRoot"> 
     <Rectangle x:Name="rectangle" Margin="78,102,292,144" Stroke="Black"> 
      <Rectangle.Fill> 
       <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 
        <GradientStop Color="Black" Offset="0"/> 
        <GradientStop Color="White" Offset="1"/> 
       </LinearGradientBrush> 
      </Rectangle.Fill> 
     </Rectangle> 
    </Grid> 
</Window> 
+0

Điều đó hoạt động tốt nếu tôi biết loại bàn chải nào mong đợi. Nhưng trong trường hợp của tôi, có thể có màu đồng nhất, gradient tuyến tính hoặc radialgradient tùy thuộc vào cài đặt suer. Có cách nào chung để cọ vẽ hoạt hình (độc lập với kiểu cọ vẽ)? –

2

Bạn có thể biến đổi màu của bàn chải nếu bạn có một mẫu phong cách mà bạn cung cấp cho các điền chải một cái tên, như vậy:

<Rectangle Width="100" Height="100"> 
    <Rectangle.Fill> 
    <SolidColorBrush x:Name="MyAnimatedBrush" Color="Orange" /> 
    </Rectangle.Fill> 
    <Rectangle.Triggers> 

    <!-- Animates the brush's color to gray 
     When the mouse enters the rectangle. --> 
    <EventTrigger RoutedEvent="Rectangle.MouseEnter"> 
     <BeginStoryboard> 
     <Storyboard> 
      <ColorAnimation 
      Storyboard.TargetName="MyAnimatedBrush" 
      Storyboard.TargetProperty="Color" 
      To="Gray" Duration="0:0:1" /> 
     </Storyboard> 
     </BeginStoryboard> 
    </EventTrigger> 
    </Rectangle.Triggers> 
</Rectangle> 

Như lấy từ MSDN

+0

Tính năng này chỉ hoạt động với các cọ màu - điều này không có tác dụng đối với các bút vẽ gradient. – Will

23

Một cách có thể là, để tạo một lớp hoạt hình tùy chỉnh tạo hiệu ứng cho bàn chải. Tôi đã tìm thấy một cách đơn giản để làm điều đó bằng cách tạo một lớp học, bắt nguồn từ AnimationTimeline. Chúng ta có thể ghi đè lên một số thành viên trong lớp tùy chỉnh, trong số những thứ khác là AnimationTimeline.GetCurrentValue method. Nó trả về một giá trị phụ thuộc vào tiến trình hoạt ảnh và giá trị bắt đầu và kết thúc.

Cách đơn giản nhất là tạo VisualBrush và crossfade bắt đầu- với giá trị cuối cùng với thuộc tính Opacity trên điều khiển con. Kết quả là một lớp như sau:

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

Bạn có thể sử dụng nó như mọi khi trong 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> 

hoặc trong mã đằng sau:

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

Nó cũng có thể mở rộng các BrushAnimation với quá tải constructor vv, do đó, nó trông giống như một loại hình hoạt hình .NET.

+0

Tôi thích giao diện này - tôi sẽ cho nó một vòng quay. – Will

+3

Oh người bạn đóng đinh nó; làm tốt. – Will

+0

Công cụ tuyệt vời, cảm ơn! – MoonKnight