WPF如何仿制QQ2013登录窗口的关闭效果
昨天,有位朋友问我,WPF能做出像QQ2013窗口在关闭时那个貌似透明过渡的动画吗?我就歪着脸跟他说:"只有你想不到的,没有WPF做不到的"。
他又接着说:"我知道肯定会用到动画来控制画刷,但是那个透明的'淡出'怎么弄呢?"
我就给他演示了一个类似的效果。
大家有没有注意到System.Windows.UIElement.OpacityMask这个属性,它是一个Brush类型,也就是说,你可以使用任意Brush的类来充当。这个属性只提取赋给它的Brush中的所有颜色的A值。即ARGB中的A值,其他通道将忽略,然后用这些不透明值来替目标可视化元素中的不透明值。具体大家可参考MSDN。
其实原理非常简单,就以下两个条件:一是把窗口变成透明,这个不介绍,大家可以看我后面贴的代码。第二就是OpacityMask属性用渐变画刷,只有这样才能做到渐变透明的效果。然后我们就对这个渐变画刷中各颜色点的Offset进行动画处理就可以了。
先看看最终效果,看看像不像,呵呵。

原理很easy,我就放XAML了。
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="300" Width="300"
AllowsTransparency="True" Background="Transparent" WindowStyle="None"
WindowStartupLocation="CenterScreen">
<Grid x:Name="layoutroot">
<Grid.OpacityMask>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF000000" Offset="0"/>
<GradientStop Color="#FF000000" Offset="1"/>
<GradientStop Color="#FF000000" Offset="1"/>
</LinearGradientBrush>
</Grid.OpacityMask>
<Grid.Clip>
<EllipseGeometry Center="150 150" RadiusX="150" RadiusY="150"/>
</Grid.Clip>
<Grid.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF4141A6" Offset="0.003"/>
<GradientStop Color="#FF5E5ED4" Offset="1"/>
<GradientStop Color="#FFDCDCFD" Offset="0.38"/>
<GradientStop Color="#FF161674" Offset="0.84"/>
</LinearGradientBrush>
</Grid.Background>
<Button Content="关闭" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="20" Background="#FFF70D0D" Foreground="White" BorderBrush="#FFD8A00A" FontSize="28" Click="OnClick">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Ellipse x:Name="bg" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="2" />
<Ellipse x:Name="fr" Opacity="0" >
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#CCFFFFFF" Offset="0"/>
<GradientStop Offset="1"/>
<GradientStop Color="#7FFFFFFF" Offset="0.392"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<ContentPresenter x:Name="ContentPresenter" Margin="{TemplateBinding Padding}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsMouseOver" Value="True" >
<Setter TargetName="fr" Property="Opacity" Value="1"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
<Grid.Resources>
<Storyboard x:Key="std">
<DoubleAnimation From="1" To="0" Duration="0:0:6"
Storyboard.TargetName="layoutroot"
Storyboard.TargetProperty="(UIElement.OpacityMask).(GradientBrush.GradientStops)[1].Offset"/>
<DoubleAnimation Duration="0:0:4.5" BeginTime="0:0:1.5" From="1" To="0"
Storyboard.TargetName="layoutroot"
Storyboard.TargetProperty="(UIElement.OpacityMask).(GradientBrush.GradientStops)[2].Offset"/>
<ColorAnimation Duration="0" To="#00000000" Storyboard.TargetName="layoutroot"
Storyboard.TargetProperty="(UIElement.OpacityMask).(GradientBrush.GradientStops)[2].Color"/>
</Storyboard>
</Grid.Resources>
</Grid>
</Window>
然后是少量的处理代码。
public partial class MainWindow : Window
{
System.Windows.Media.Animation.Storyboard std = null;
public MainWindow()
{
InitializeComponent();
std = (System.Windows.Media.Animation.Storyboard)layoutroot.Resources["std"];
std.Completed += (t, r) => this.Close();
this.layoutroot.Loaded += (sd, ee) => {
// 设置Grid的圆形剪辑的圆心和半径
EllipseGeometry eg = (EllipseGeometry)this.layoutroot.Clip;
double dx = layoutroot.ActualWidth /2d;
double dy=layoutroot.ActualHeight/2d;
eg.Center = new Point(dx, dy);
eg.RadiusX = dx;
eg.RadiusY = dy;
}; } private void OnClick(object sender, RoutedEventArgs e)
{
if (std != null)
{
std.Begin();
}
}
}
OK,完事,88。
WPF如何仿制QQ2013登录窗口的关闭效果的更多相关文章
- 【转】【WPF】WPF 登录窗口关闭时打开主窗口
在WPF中设计登录窗口关闭时打开主窗口,自动生成的App.xaml不能满足要求, 1.把App.xaml的属性窗口中的生成操作设定为 无 2.添加Program类 static class Progr ...
- WPF:验证登录后关闭登录窗口,显示主窗口的解决方法
http://www.27ba.com/post/145.html WPF:验证登录后关闭登录窗口,显示主窗口的解决方法 最近想做一个基于Socket的通讯工具,想模仿QQ那样,需要先登录,登录成功后 ...
- C# WPF 建立无边框(标题栏)的登录窗口
前言:笔者最近用c#写WPF做了一个项目,此前未曾做过完整的WPF项目,算是一边学一边用,网上搜了不少资料,效率当然是不敢恭维的,有时会在一些很简单的问题上纠结很长时间,血与泪的教训可不少. 不过,正 ...
- WPF MVVM从入门到精通2:实现一个登录窗口
原文:WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM从入门到精通3:数据绑定 ...
- WPF的消息机制(三)- WPF内部的5个窗口之处理激活和关闭的消息窗口以及系统资源通知窗口
原文:WPF的消息机制(三)- WPF内部的5个窗口之处理激活和关闭的消息窗口以及系统资源通知窗口 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/p ...
- WPF 解决弹出模态窗口关闭后,主窗口不在最前
本文告诉大家如何解决这个问题,在 WPF 的软件,弹出一个模态窗口.使用另一个窗口在模态窗口前面.从任务栏打开模态窗口.关闭模态窗口.这时发现,主窗口会在刚才使用的另一个窗口下面 这是 Windows ...
- 高仿QQ即时聊天软件开发系列之二登录窗口界面
继上一篇高仿QQ即时聊天软件开发系列之一开端之后,开始做登录窗口 废话不多说,先看效果,只有界面 可能还有一些细节地方没有做,例如那个LOGO嘛,不要在意这些细节 GIF虽短,可是这做起来真难,好吧因 ...
- WPF中实现先登录后启动主程序的方法
原文:WPF中实现先登录后启动主程序的方法 我觉得先登录后启动应用主程序是一个很经典的问题,基本上如果要写一个应用程序都会用到这个的小环节.我在这个问题上挣扎了大半天才找到解决方案,我的实现方法我觉得 ...
- 基于WPF的酷炫GUI窗口的实现全过程
title: 基于WPF的酷炫GUI窗口的实现全过程 date: 2020-08-14 permalink: /build/wpfgui sidebarDepth: 2 tags: wpf gui 软 ...
随机推荐
- 如何让TortoiseSVN导出新增或修改过的文件
利用Windows系统下的TortoiseSVN客户端,可以导出指定版本之间修改过的文件,并保留完整的文件夹结构.下面我就来说说操作的步骤: 1.在网站项目的根目录下右键选择 “TortoiseSVN ...
- docker学习之二镜像创建
继上一篇docker入门之后写一点使用的经验. 通过命令:docker run -it REPOSITORY或IMAGE ID 注:-it后面跟的字段可以通过下面指令获得 创建运行的容器,会进入一 ...
- fragment 重叠问题
项目中用到了Android Fragment 在程序异常的时候 fragment 点击会造成fragment 重叠 在fragmentActivity中加入一下方法 @Override public ...
- 关于DOM对象与JQuery对象的那些事
这个问题源自上一次的工作室讨论班,主题是"jQuery选择器的使用",在讨论班的结尾,我留了一个思考题: jQuery获取到的对象和直接调用原生Javascript方法获得的对象 ...
- java 的各种实用类库(jar包)
总列表:# dom4j # org.json # pinyin4j # sqlite-jdbc # JavaMail # JLayer # dom4j 介绍:处理 xml 的类库.采用了 Java 集 ...
- python实现最简单的计算器功能源码
import re def calc(formula): formula = re.sub(' ', '', formula) formula_ret = 0 match_brackets = re. ...
- 跨域无法获取自定义header的问题
同域的时候,header里面的参数可以随便自己定义.服务端都是可以获取的. 但是跨域的时候,除了设置 <add name="Access-Control-Allow-Origin&qu ...
- git学习笔记一
一.概念理解 1.理解工作区和暂存区以及版本库 工作区我理解就是我们创建的程序所在的文件夹,比如test文件夹.其中有个.git文件,这个就是版本库,其中版本库中有个区域叫暂存区或叫索引. 截自廖雪峰 ...
- siteserver cms选择栏目搜索无效
标签必须以空格分开,且option 的value必须给id不能给名称
- nginx超时重发
最近一直遇到一个bug: 客户端会二次请求服务端,服务端多次调用remote服务. 特点是,这些请求都是模型切片相关的,耗时很长的请求,往往需要1分钟左右. 开始以为是客户端代码有问题,进行了二次请求 ...