zoukankan      html  css  js  c++  java
  • WPF如何仿制QQ2013登录窗口的关闭效果

    昨天,有位朋友问我,WPF能做出像QQ2013窗口在关闭时那个貌似透明过渡的动画吗?我就歪着脸跟他说:"只有你想不到的,没有WPF做不到的"。

    他又接着说:"我知道肯定会用到动画来控制画刷,但是那个透明的'淡出'怎么弄呢?"

    我就给他演示了一个类似的效果。

    大家有没有注意到System.Windows.UIElement.OpacityMask这个属性,它是一个Brush类型,也就是说,你可以使用任意Brush的类来充当。这个属性只提取赋给它的Brush中的所有颜色的A值。即ARGB中的A值,其他通道将忽略,然后用这些不透明值来替目标可视化元素中的不透明值。具体大家可参考MSDN。

    其实原理非常简单,就以下两个条件:一是把窗口变成透明,这个不介绍,大家可以看我后面贴的代码。第二就是OpacityMask属性用渐变画刷,只有这样才能做到渐变透明的效果。然后我们就对这个渐变画刷中各颜色点的Offset进行动画处理就可以了。

    先看看最终效果,看看像不像,呵呵。

    原理很easy,我就放XAML了。

     1 <Window x:Class="WpfApplication1.MainWindow"
     2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4         Title="MainWindow" Height="300" Width="300"
     5         AllowsTransparency="True" Background="Transparent" WindowStyle="None"
     6         WindowStartupLocation="CenterScreen">
     7     <Grid x:Name="layoutroot">
     8         <Grid.OpacityMask>
     9             <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
    10                 <GradientStop Color="#FF000000" Offset="0"/>
    11                 <GradientStop Color="#FF000000" Offset="1"/>
    12                 <GradientStop Color="#FF000000" Offset="1"/>
    13             </LinearGradientBrush>
    14         </Grid.OpacityMask>
    15         <Grid.Clip>
    16             <EllipseGeometry Center="150 150" RadiusX="150" RadiusY="150"/>
    17         </Grid.Clip>
    18         <Grid.Background>
    19             <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
    20                 <GradientStop Color="#FF4141A6" Offset="0.003"/>
    21                 <GradientStop Color="#FF5E5ED4" Offset="1"/>
    22                 <GradientStop Color="#FFDCDCFD" Offset="0.38"/>
    23                 <GradientStop Color="#FF161674" Offset="0.84"/>
    24             </LinearGradientBrush>
    25         </Grid.Background>
    26         <Button Content="关闭" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="20" Background="#FFF70D0D" Foreground="White" BorderBrush="#FFD8A00A" FontSize="28" Click="OnClick">
    27             <Button.Template>
    28                 <ControlTemplate TargetType="{x:Type Button}">
    29                     <Grid>
    30                         <Ellipse x:Name="bg" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="2" />
    31                         <Ellipse x:Name="fr" Opacity="0" >
    32                             <Ellipse.Fill>
    33                                 <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
    34                                     <GradientStop Color="#CCFFFFFF" Offset="0"/>
    35                                     <GradientStop Offset="1"/>
    36                                     <GradientStop Color="#7FFFFFFF" Offset="0.392"/>
    37                                 </LinearGradientBrush>
    38                             </Ellipse.Fill>
    39                         </Ellipse>
    40                         <ContentPresenter x:Name="ContentPresenter" Margin="{TemplateBinding Padding}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
    41                     </Grid>
    42                     <ControlTemplate.Triggers>
    43                         <Trigger Property="UIElement.IsMouseOver" Value="True" >
    44                             <Setter TargetName="fr" Property="Opacity" Value="1"/>
    45                         </Trigger>
    46                     </ControlTemplate.Triggers>
    47                 </ControlTemplate>
    48             </Button.Template>
    49         </Button>
    50         <Grid.Resources>
    51             <Storyboard x:Key="std">
    52                 <DoubleAnimation From="1" To="0" Duration="0:0:6"
    53                                  Storyboard.TargetName="layoutroot"
    54                                  Storyboard.TargetProperty="(UIElement.OpacityMask).(GradientBrush.GradientStops)[1].Offset"/>
    55                 <DoubleAnimation Duration="0:0:4.5" BeginTime="0:0:1.5" From="1" To="0"
    56                                  Storyboard.TargetName="layoutroot"
    57                                  Storyboard.TargetProperty="(UIElement.OpacityMask).(GradientBrush.GradientStops)[2].Offset"/>
    58                 <ColorAnimation Duration="0" To="#00000000" Storyboard.TargetName="layoutroot"
    59                                  Storyboard.TargetProperty="(UIElement.OpacityMask).(GradientBrush.GradientStops)[2].Color"/>
    60             </Storyboard>
    61         </Grid.Resources>
    62     </Grid>
    63 </Window>

    然后是少量的处理代码。

     1     public partial class MainWindow : Window
     2     {
     3         System.Windows.Media.Animation.Storyboard std = null;
     4         public MainWindow()
     5         {
     6             InitializeComponent();
     7             std = (System.Windows.Media.Animation.Storyboard)layoutroot.Resources["std"];
     8             std.Completed += (t, r) => this.Close();
     9             this.layoutroot.Loaded += (sd, ee) => {
    10                 // 设置Grid的圆形剪辑的圆心和半径
    11                 EllipseGeometry eg = (EllipseGeometry)this.layoutroot.Clip;
    12                 double dx = layoutroot.ActualWidth /2d;
    13                 double dy=layoutroot.ActualHeight/2d;
    14                 eg.Center = new Point(dx, dy);
    15                 eg.RadiusX = dx;
    16                 eg.RadiusY = dy;
    17             };
    18 
    19         }
    20 
    21 
    22         private void OnClick(object sender, RoutedEventArgs e)
    23         {
    24             if (std != null)
    25             {
    26                 std.Begin();
    27             }
    28         }
    29     }

    OK,完事,88。

  • 相关阅读:
    模拟退火大法好
    宿命的PSS
    博客在summeroi.top上更新
    SPFA模板
    BZOJ 4551: [Tjoi2016&Heoi2016]树
    BZOJ 4152: [AMPPZ2014]The Captain
    BZOJ 3930: [CQOI2015]选数
    BZOJ 3875: [Ahoi2014&Jsoi2014]骑士游戏
    BZOJ4318: OSU!
    BZOJ3170: [Tjoi 2013]松鼠聚会
  • 原文地址:https://www.cnblogs.com/tcjiaan/p/3450797.html
Copyright © 2011-2022 走看看