1. 什么是长阴影

前几年扁平化设计(Flat Design)十分流行,后来在扁平化的基础上又流行起了长阴影(Long Shadow)。长阴影其实就是扩展了对象的投影,感觉是一种光线照射下的影子,通常采用角度为 45 度的投影,给对象添加了一份立体感。长阴影快速发展为流行的设计趋势,并经常被应用到扁平设计方案的对象。它很适合用在较小的元素上,一时之间几乎应用的图标都加上了长阴影。(不过现在又不流行了)

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

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

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

<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的可视化层:

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

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

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的CornerRadius设置为1,Grid就会自动自觉把超出范围的内容裁剪掉。虽然不知道具体原理,但有需要的话其它情况也可以偷懒这样做,也许有人不喜欢圆角,但区区1像素的圆角你不说我不说又有谁会知道呢。

Grid Background="#FFE87A69" Padding="40" Margin="50" x:Name="ShadowRoot" CornerRadius="1">

这样一个漂亮的长阴影就完成了。

3. 淡出的阴影

要实现淡出的阴影原理也很简单,别想太复杂,就只是准备好多个颜色渐渐改变的Visual,插进去ContainerVisual里就完成了。代码及效果如下(顺便一提这种情况下Vector3真好用):

int depth = 60;
float opacity = 0.3f;
Vector3 background = new Vector3(232, 122, 105); var maskBrush = compositor.CreateMaskBrush();
maskBrush.Mask = mask; //计算阴影的颜色
Vector3 shadowColor = background - (background - new Vector3(0, 0, 0)) * opacity;
shadowColor = Vector3.Max(Vector3.Zero, shadowColor);
shadowColor += (background - shadowColor) * i / depth; maskBrush.Source = compositor.CreateColorBrush(Color.FromArgb(255, (byte)shadowColor.X, (byte)shadowColor.Y, (byte)shadowColor.Z));

4. 实际应用

就只是一个静态的长阴影的话,那还不如用PS做成图片在放进UWP里。GetAlphaMask另一个好处是它并不仅获取静态的轮廓,而是一直和源头同步。这样可玩性就大多了,例如我把长阴影的设计元素添加到番茄钟里面,成果如下:

5. 结语

虽然长阴影已经有点过时了,但自己做起来还是觉得很酷很酷。刚开始还担心这样搞性能会很差,实际运行起来后发觉超级OK。上面的动画可以安装我的番茄钟应用试玩一下,安装地址:

一个番茄钟

6. 参考

[ContainerVisual Class (Windows.UI.Composition) - Windows UWP applications Microsoft Docs]((https://docs.microsoft.com/en-us/uwp/api/windows.ui.composition.containervisual)

VisualCollection Class (Windows.UI.Composition) - Windows UWP applications Microsoft Docs

Vector3 Struct (Windows.Foundation.Numerics) - Windows UWP applications Microsoft Docs

7. 源码

OnePomodoro_LongShadow.xaml.cs at master

[UWP]使用GetAlphaMask和ContainerVisual制作长阴影(Long Shadow)的更多相关文章

  1. [WPF] 使用 Effect 玩玩阴影、内阴影、 长阴影

    最近在学习怎么用 Shazzam Shader Editor 编写自定义的 Effect,并试着去实现阴影.内阴影和长阴影的效果.结果我第一步就放弃了,因为阴影用到的高斯模糊算法对我来说太太太太太太太 ...

  2. 20款精致的长阴影 LOGO 设计【附免费生成工具】

    长阴影(Long Shadow)概念来自于最新非常流行的扁平化设计(Flat Design).扁平化设计趋势影响最大的是用户界面元素和图标,但它也开始蔓延到其他网页设计的其他部分. 长阴影其实就是扩展 ...

  3. 扁平化设计的最新趋势 – 长阴影(Long Shadow)

    随着互联网的发展,网页设计变得越来越复杂,如今设计的外观和感觉实现网站功能说使用的开发技术一样重要.互联网的功能远远不只是基本的信息共享,现在人们对网站的期望是远远大于几年前的. 如今,HTML5 & ...

  4. 小教程:自己创建一个jQuery长阴影插件

    长阴影设计是平面设计的一个变体,添加了阴影,产生了深度的幻觉,并导致了三维的设计.在本教程中,我们将创建一个jQuery插件,通过添加完全可自定义的长阴影图标,我们可以轻松地转换平面图标. 戳我查看效 ...

  5. Long Shadows Generate是一款在线使用纯CSS3实现长阴影的效果,一款强大的扁平化长投影制造器。

    Long Shadows Generate是一款在线使用纯CSS3实现长阴影的效果,一款强大的扁平化长投影制造器. Long Shadows Generate 彩蛋爆料直击现场 Long Shadow ...

  6. OpenGL阴影,Shadow Volumes(附源程序,使用 VCGlib )

    实验平台:Win7,VS2010 先上结果截图:    本文是我前一篇博客:OpenGL阴影,Shadow Mapping(附源程序)的下篇,描述两个最常用的阴影技术中的第二个,Shadow Volu ...

  7. 阴影锥(shadow volume)原理与展望

    转记:找了不少关于shadow volume原理的资料,还是这个帖子讲解的一目了然,转帖在这里,方便查阅.引用链接:http://blog.donews.com/yyh/archive/2005/05 ...

  8. OpenGL阴影,Shadow Mapping(附源程序)

    实验平台:Win7,VS2010 先上结果截图(文章最后下载程序,解压后直接运行BIN文件夹下的EXE程序): 本文描述图形学的两个最常用的阴影技术之一,Shadow Mapping方法(另一种是Sh ...

  9. OpenGL 阴影之Shadow Mapping和Shadow Volumes

    先说下开发环境.VS2013,C++空项目,引用glut,glew.glut包含基本窗口操作,免去我们自己新建win32窗口一些操作.glew使我们能使用最新opengl的API,因winodw本身只 ...

随机推荐

  1. 23种设计模式之观察者模式(Observer Pattern)

    观察者模式(Observer Pattern):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主体对象,这个主题对象在状态发生变化时,会通知所有观察者.当一个对象改变需要同时改变其他对象, ...

  2. eclipse与hadoop集成,运行wordCount1

    搭好了hadoop集群之后,就该使用它了 第一步:下载hadoop eclipse的插件,将它放到eclipse\plugins的目录下,然后重启eclipse,点击windows->show ...

  3. Docker系列(一):容器监控工具Weave Scope安装

    项目进行容器化之后,配套的基础设施包括监控.编排.管理等都需要进行一并完善.这里也是自己一边学习一边进行记录. Weave Scope 的最大特点是会自动生成一张 Docker 容器地图,让我们能够直 ...

  4. 使用 BeanDefinition 描述 Spring Bean

    什么是BeanDefinition 在Java中,一切皆对象.在JDK中使用java.lang.Class来描述类这个对象. 在Spring中,存在bean这样一个概念,那Spring又是怎么抽象be ...

  5. QQ第三方授权登录OAuth2.0实现(Java)

    准备材料 1.已经备案好的域名 2.服务器(域名和服务器为统一主体或域名已接入服务器) 3.QQ号 4.开发流程:https://wiki.connect.qq.com/%E5%87%86%E5%A4 ...

  6. 04-09 XgBoost算法

    目录 XgBoost算法 一.XgBoost算法学习目标 二.XgBoost算法详解 2.1 XgBoost算法参数 2.2 XgBoost算法目标函数 2.3 XgBoost算法正则化项 2.4 X ...

  7. B-经济学-基尼指数

    目录 基尼指数 一.基尼指数简介 更新.更全的<机器学习>的更新网站,更有python.go.数据结构与算法.爬虫.人工智能教学等着你:https://www.cnblogs.com/ni ...

  8. 网页布局——grid语法属性详解

    grid目前兼容性目前还可以,主流浏览器对它的支持力度很大,ie9,10宣布它未来不久会对它有很好的支持,目前则需要使用过时的语法.我相信不久的将来grid将成为每一个前端工作人员必备的布局技能. 属 ...

  9. vue3.0 vue.config.js 配置实战

    今天讲述一下vue-config.js配置,我们前面搭建好脚手架会发现,这个对比2.x版本少了很多东西,没有build的配置,也没有webpack的配置,那么问题来了,我们如何去开发我们的项目呢,比如 ...

  10. ES6——新增数据结构Set与Map的用法

    ES6 提供了新的数据结构 Set以及Map,下面我们来一一讲解. 一.Set 特性 似于数组,但它的一大特性就是所有元素都是唯一的,没有重复. 我们可以利用这一唯一特性进行数组的去重工作. 1.单一 ...