1. 前言

最近常常接触到GetAlphaMask,所以想写这篇文章介绍下GetAlphaMask怎么使用。其实GetAlphaMask的使用场景十分有限,Github上能搜到的内容都是用来配合DropShadow的,所以这篇文章也以介绍DropShadow为主。

2. 合成阴影

先介绍一下合成阴影。Compositor.CreateDropShadow()可以创建一个DropShadow,将这个DropShadowDropShadow赋值到SpriteVisual的Shadow属性,然后使用ElementCompositionPreview.SetElementChildVisual 将这个SpriteVisual设置到某个UIElement的可视化层里,再将这个UIElement放到需要阴影的元素后面,这样基本的合成阴影就完成了。

具体代码如下:

<Grid VerticalAlignment="Center"
HorizontalAlignment="Center">
<Grid x:Name="BackgroundGrid"/>
<Grid Background="Turquoise"
x:Name="Host">
<TextBlock Text="I need shadow"
Foreground="White"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="36"
Margin="16"/>
</Grid>
</Grid>
private readonly Compositor _compositor;
private readonly SpriteVisual _backgroundVisual;
private readonly DropShadow _dropShadow;
public MainPage() : base()
{
InitializeComponent();
_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor; //创建并配置DropShadow
_dropShadow = _compositor.CreateDropShadow();
_dropShadow.BlurRadius = 16;
_dropShadow.Offset = new Vector3(8); //创建SpriteVisual并设置Shadow
_backgroundVisual = _compositor.CreateSpriteVisual();
_backgroundVisual.Shadow = _dropShadow; //将SpriteVisual放到可视化树
ElementCompositionPreview.SetElementChildVisual(BackgroundGrid, _backgroundVisual); Host.SizeChanged += OnHostSizeChanged;
} private void OnHostSizeChanged(object sender, SizeChangedEventArgs e)
{
Vector2 newSize = new Vector2(0, 0);
Vector3 centerPoint = new Vector3(0, 0, 0);
if (Host != null)
{
newSize = new Vector2((float)Host.ActualWidth, (float)Host.ActualHeight);
centerPoint = new Vector3((float)Host.ActualWidth / 2, (float)Host.ActualHeight / 2, 0);
}
_backgroundVisual.CenterPoint = centerPoint;
_backgroundVisual.Size = newSize;
}

3. 使用GetAlphaMask裁剪阴影

上面的代码需要可以实现阴影,但只能实现矩形的阴影,在WPF和Silverlight中常用的Shape的阴影,或者文字的阴影都做不出来。

例如将XAML改成这样的话,结果绝不是我想要的东西:

<Grid VerticalAlignment="Center"
HorizontalAlignment="Center">
<Grid x:Name="BackgroundGrid"/>
<TextBlock Text="I need shadow"
x:Name="Host"
Foreground="Turquoise"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="36"/>
</Grid>

这时候就需要用到GetAlphaMask这个函数。

Image、 TextBlock和Shape分别实现一个名为GetAlphaMask的方法, 该方法返回一个CompositionBrush , 该方法表示具有元素形状的灰度图像。

官当文档 中是这样描述GetAlphaMask函数的,简单来说就是拿到一个Image、TextBlock或Shape的轮廓,这个轮廓可以作为DropShadow.Mask的值,这样DropShadow的形状就可调用GetAlphaMask的元素的形状一样了。

具体代码和结果如下,这才是我想要的效果:

_dropShadow.Mask = Host.GetAlphaMask();

4. 使用DropShadowPanel

如果觉得自己写代码太过复杂, 可以使用Toolkit中的DropShadowPanel

DropShadowPanel继承自ContentControl,当它的Cotnent为Shape、TextBlock、Image之一(或Toolkit中实现了GetAlphaMask的其它控件)时,它就调用GetAlphaMask获取阴影的形状,否则就是简单的举行,代码如下:

CompositionBrush mask = null;

if (Content is Image)
{
mask = ((Image)Content).GetAlphaMask();
}
else if (Content is Shape)
{
mask = ((Shape)Content).GetAlphaMask();
}
else if (Content is TextBlock)
{
mask = ((TextBlock)Content).GetAlphaMask();
}
else if (Content is ImageExBase imageExBase)
{
imageExBase.ImageExInitialized += ImageExInitialized; if (imageExBase.IsInitialized)
{
imageExBase.ImageExInitialized -= ImageExInitialized; mask = ((ImageExBase)Content).GetAlphaMask();
}
} _dropShadow.Mask = mask;

之后它的做法和上面介绍的一样,把这个阴影设置到一个元素放在ContentPresenter后面,看起来就实现了Content的阴影:

_border = GetTemplateChild(PartShadow) as Border;

if (_border != null)
{
ElementCompositionPreview.SetElementChildVisual(_border, _shadowVisual);
}
<Grid Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}">
<Border x:Name="ShadowElement"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>

5. 参考

将可视化层与 XAML 结合使用 - Windows UWP applications Microsoft Docs

Shape.GetAlphaMask Method (Windows.UI.Xaml.Shapes) - Windows UWP applications Microsoft Docs

DropShadow.Mask Property (Windows.UI.Composition) - Windows UWP applications Microsoft Docs

WindowsCommunityToolkit_Microsoft.Toolkit.Uwp.UI.Controls_DropShadowPanel at master

DropShadowPanel XAML Control - Windows Community Toolkit Microsoft Docs

[UWP]使用GetAlphaMask制作阴影的更多相关文章

  1. UWP Button添加圆角阴影(二)

    原文:UWP Button添加圆角阴影(二) 阴影 对于阴影呢,WindowsCommunityToolkit中已经有封装好的DropShadowPanel啦,只要引用Microsoft.Toolki ...

  2. UWP Button添加圆角阴影(三)

    原文:UWP Button添加圆角阴影(三) Composition DropShadow是CompositionAPI中的东西,使用Storyboard设置某个属性,就是频繁的触发put_xxx() ...

  3. UWP Button添加圆角阴影(一)

    原文:UWP Button添加圆角阴影(一) 众所周知,17763之前的UWP控件,大部分是没有圆角属性的:而阴影也只有17763中的ThemeShadow可以直接在xaml中使用,之前的版本只能用D ...

  4. [UWP]使用GetAlphaMask和ContainerVisual制作长阴影(Long Shadow)

    1. 什么是长阴影 前几年扁平化设计(Flat Design)十分流行,后来在扁平化的基础上又流行起了长阴影(Long Shadow).长阴影其实就是扩展了对象的投影,感觉是一种光线照射下的影子,通常 ...

  5. cocos2d-x 全面总结--字体描边和制作阴影

    关于字体描边的实现,不考虑效果和效率的话,是有三种方式: ① 利用CCLabelTTF制作文字描边和阴影效果 ② 利用CCRenderTexture渲染文理的方式生成带有描边效果的文字 ③ 利用sha ...

  6. [UWP]为番茄钟应用设计一个平平无奇的状态按钮

    1. 为什么需要设计一个状态按钮 OnePomodoro应用里有个按钮用来控制计时器的启动/停止,本来这应该是一个包含"已启动"和"已停止"两种状态的按钮,但我 ...

  7. Unity 阴影的制作方式

    Unity阴影制作的三种方式. 方式一:Light中Shadow Type的类型 包括Hard Shadows.Soft Shadows.No Shadows:  Mesh Renderer中的属性 ...

  8. box-shadow制作各种单边,多边阴影

    一.box-shadow问题探究 box-shadow 在MDN定义以及详解: box-shadow 以由逗号分隔的列表来描述一个或多个阴影效果.该属性让你可以对几乎所有元素的边框产生阴影.如果元素同 ...

  9. [UWP]使用AlphaMaskEffect提升故障艺术动画的性能(顺便介绍怎么使用性能探测器分析UWP程序)

    前几天发布了抄抄<CSS 故障艺术>的动画这篇文章,在这篇文章里介绍了如何使用Win2D绘制文字然后配合BlendEffect制作故障艺术的动画.本来打算就这样收手不玩这个动画了,但后来又 ...

随机推荐

  1. opencv图像处理之常见滤波器

    图像平滑 Smoothing, also called blurring, is a simple and frequently used image processing operation. 平滑 ...

  2. Intellij IDEA 2019 + Java Spring MVC + Hibernate学习笔记(1)

    之前的技术栈一直是围绕.net 做的,现在.net 技术栈的使用越来越少,越来越窄.好多原来的同事都转Java开发了. 最近公司变动,自己需要重新找个坑,压力山大.好多要求Java技术栈的根本没机会进 ...

  3. 安装sublime text3 、转化为汉化版、安装SublimeREPL使得在交互条件下运行代码,设置快捷键

    一.sublime Sublime Text 3是轻量级的,安装包很小,它的大部分功能是依靠丰富的插件实现的,而且占用资源少.目前主流版本是Sublime Text3,在官网就可以下载,http:// ...

  4. Maven报错: Could not resolve archetype org.apache.maven.archetypes:maven-archetype-webapp

    郁闷了两天,创建maven项目时,eclipse报错:Could not resolve artifact org.apache.maven.archetypes:maven-archetype-we ...

  5. 物料导出FreeMaker模板定义

    <?xml version="1.0"?><?mso-application progid="Excel.Sheet"?><Wor ...

  6. 《老师说的都对》第一次作业:OUC网上课程评价系统

    项目介绍: 项目名称:OUC网上课程评价系统 项目概述:实现一个公开的网上课程评价系统.开课老师也可以在自己的课程主页填写自己的课程内容介绍,学生可以在课程页面中评价自己上过的课程.为想要选课的学生提 ...

  7. [Redis] Redis的基本数据结构

    key-value 通过key获取或设置value SET key value GET key SET server:name "fido" GET server:name SET ...

  8. Nginx开启Gzip压缩提升页面加载速度

    1.在 nginx 的conf 目录下新建 gzip.conf 文件 #开启gzip压缩 gzip on; #设置允许压缩的页面最小字节数 gzip_min_length 1k; #申请4个单位为16 ...

  9. EF Core设置字段默认时间

    ---恢复内容开始--- 在EF的官方文档上只提到了用 Fluent API来设置默认值. 但是我们日常开发中,会把公用字段都写成基类.比如行创建时间 在需要默认时间的字段加上一个特性 [Databa ...

  10. 六、springboot 简单优雅是实现短信服务

    前言 上一篇讲了 springboot 集成邮件服务,接下来让我们一起学习下springboot项目中怎么使用短信服务吧. 项目中的短信服务基本上上都会用到,简单的注册验证码,消息通知等等都会用到.所 ...