1. 什么是长阴影

2. 使用GetAlphaMask和ContainerVisual制作长阴影#

要在UWP中制作长阴影的话,可以用GetAlphaMask拿到轮廓,做成灰色,然后复制一百几十个摆在后面。不过当然并不是直接创建这么多个UIElement,而是使用ContainerVisual类实现这个功能。ContainerVisual用于组合子级的Visual,只需简单地调用VisualCollection.InsertAtBottom即可。

下面是具体的实现例子,和上篇文章介绍的一样,首先在需要阴影的元素(TitleElement)后面放一个用于显示阴影的UIElement(ShadowElement),布局如下:

Copy
<Grid Background="#FFE87A69" Padding="40" Margin="50" x:Name="ShadowRoot"> <Rectangle x:Name="ShadowElement" /> <TextBlock Text="One Pomodoro" Foreground="#FFfee8da" FontSize="64" x:Name="TitleElement"/> </Grid>

然后在代码里创建一个ContainerVisual并使用ElementCompositionPreview.SetElementChildVisual将这个ContainerVisual设置到ShadowElement的可视化层:

Copy
var textVisual = ElementCompositionPreview.GetElementVisual(TitleElement); compositor = textVisual.Compositor; containerVisual = compositor.CreateContainerVisual(); ElementCompositionPreview.SetElementChildVisual(ShadowElement, containerVisual);

之后调用TitleElement的GetAlphaMask获取轮廓,然后将这个轮廓作为Mask设置到CompositionMaskBrush的Mask属性,重复一百次:

Copy
var mask = TitleElement.GetAlphaMask(); var shadowColor = Color.FromArgb(255, 160, 59, 49); int depth = 100; for (int i = 0; i < depth; i++) { //创建Brush var maskBrush = compositor.CreateMaskBrush(); maskBrush.Mask = mask; maskBrush.Source = compositor.CreateColorBrush(shadowColor); //创建Visual var visual = compositor.CreateSpriteVisual(); visual.Brush = maskBrush; visual.Offset = new Vector3(i + 1, i + 1, 0); //将Visual添加到ContainerVisual containerVisual.Children.InsertAtBottom(visual); //同步Visual和TextVisual的尺寸 var bindSizeAnimation = compositor.CreateExpressionAnimation("textVisual.Size"); bindSizeAnimation.SetReferenceParameter("textVisual", textVisual); visual.StartAnimation("Size", bindSizeAnimation); }

然后终于……

……还是没完成,还需要为ContainerVisual设置Clip以免阴影越界。看起来需要写很多代码去实现,但其实有个简单的方法,将外面那层的ShadowRoot的