UWP 流畅设计中的光照效果(容易的 RevealBorderBrush 和不那么容易的 RevealBackgroundBrush)

UWP 流畅设计中的光照效果(容易的 RevealBorderBrush 和不那么容易的 RevealBackgroundBrush)

2018-04-15 01:37

在 Windows 10.0.16299 中,RevealBrush 被引入,可以实现炫酷的鼠标滑过高亮效果和点击光照。本文将告诉大家如何完整地实现这样的效果。


Reveal 的效果(自带)

在微软官方推荐的 XAML Controls Gallery 应用中,我们可以找到 Reveal 的实现章节。下图是应用中演示的 Reveal 效果:

不过在其实现中,全都是使用的系统自带的样式,例如:

<Button Style="{StaticResource ButtonRevealStyle}" Content="Button" />
<Grid HorizontalAlignment="Center" Margin="5" Background="{ThemeResource CustomAcrylicInAppBrush_dark}" RequestedTheme="Dark">
    <StackPanel Orientation="Vertical">
        <StackPanel Orientation="Horizontal">
            <AppBarButton Style="{ThemeResource AppBarButtonRevealStyle}" Icon="World" Margin="1, 2, 0, 0"/>
            <AppBarButton Style="{ThemeResource AppBarButtonRevealStyle}" Icon="CellPhone" Margin="0, 2, 1, 0"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <AppBarButton Style="{ThemeResource AppBarButtonRevealStyle}" Icon="Delete" Margin="1, 2, 0, 2"/>
            <AppBarButton Style="{ThemeResource AppBarButtonRevealStyle}" Icon="Comment" Margin="0, 2, 1, 2"/>
        </StackPanel>
    </StackPanel>
</Grid>

Reveal 的制作(自己实现)

采用自带效果的控件看起来实现很容易,不过 UWP 控件的自带样式略坑,自己实现控件样式和模板是不可避免的事儿。

这是定制的 ListViewItem 的模板的一部分,写了 RevealBorderBrushRevealBackgroundBrush

<Grid x:Name="Root" Width="120" Height="40" BorderThickness="0 1 1 0">
    <Grid.BorderBrush>
        <RevealBorderBrush />
    </Grid.BorderBrush>
    <Grid.Background>
        <RevealBackgroundBrush />
    </Grid.Background>
    <ContentPresenter />
</Grid>

运行看,发现只有边框效果,背景效果是不存在的。

然而官方文档对于 RevealBackgroundBrush 的实现竟然没有提及,也是挺奇怪的。比如:Reveal highlight - UWP app developer - Microsoft DocsRevealBackgroundBrush Class (Windows.UI.Xaml.Media) - UWP app developer - Microsoft Docs

注意到 RevealBackgroundBrush 有一个附加属性 RevealBrush.State,设置到控件上用于指定采用哪一种光照效果:RevealBrush.State="Pressed"。直接将其设置到控件上,发现依然是没有效果的:

看来需要动态地改变,于是必须加上 VisualStateManager

<Grid x:Name="Root" Width="120" Height="40" BorderThickness="0 1 1 0">
    <Grid.BorderBrush>
        <RevealBorderBrush />
    </Grid.BorderBrush>
    <Grid.Background>
        <RevealBackgroundBrush />
    </Grid.Background>
    <ContentPresenter />
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="CommonStates">
            <VisualState x:Name="Normal" />
            <VisualState x:Name="Selected" />
            <VisualState x:Name="PointerOver">
                <VisualState.Setters>
                    <Setter Target="Root.(RevealBrush.State)" Value="PointerOver"/>
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="PointerOverSelected">
                <VisualState.Setters>
                    <Setter Target="Root.(RevealBrush.State)" Value="PointerOver"/>
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="PointerOverPressed">
                <VisualState.Setters>
                    <Setter Target="Root.(RevealBrush.State)" Value="Pressed"/>
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="Pressed">
                <VisualState.Setters>
                    <Setter Target="Root.(RevealBrush.State)" Value="Pressed"/>
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="PressedSelected">
                <VisualState.Setters>
                    <Setter Target="Root.(RevealBrush.State)" Value="Pressed"/>
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
        <VisualStateGroup x:Name="DisabledStates">
            <VisualState x:Name="Enabled"/>
            <VisualState x:Name="Disabled">
                <VisualState.Setters>
                    <Setter Target="Root.RevealBorderThickness" Value="0"/>
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
</Grid>

在以上这段新的代码中,我们适时在指针设备滑过的时候切换 RevealBrush.StatePointerOver,在按下时切换 RevealBrush.StatePressed。再次运行才发现背景光照效果正常出现了。

本文相关

本文会经常更新,请阅读原文: https://walterlv.com/post/uwp-reveal-background-brush.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 (walter.lv@qq.com)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏针针小站

【IFE】Day 1 – 百度前端技术学院 基础学院 学习笔记(一)

1646
来自专栏知晓程序

如何优雅地发朋友圈?你需要这款简洁好看的小程序

普通的一天中,我们能看到各种各样的风景。人来人往,相遇离别,每一天,都能产生新的故事和回忆。

1734
来自专栏进击的君君的前端之路

什么是CSS预处理器

1232
来自专栏知晓程序

不用锤子手机也能 Big Bang!识字、分词,就用这款小程序

前不久,我在《懒得打字?这两款文字识别小程序,解放你的双手》一文中,推荐了两款「智能识别图文」小程序。

2521
来自专栏达摩兵的技术空间

web字体规范

对于设计稿的解析中,肯定是有些设计稿有特殊的字体,而这些字体可能只有设计师才有,或者只有前端拓展了系统字库才能显示器正确效果。但对于前端页面的终极使用者,他们可...

3604
来自专栏数据小魔方

妈妈再也不用担心我不会配色了

记得之前的推送有两篇专门介绍关于取色的 但是毕竟是操作性的东西 总得动动手才能有感觉 今天就教大家怎么取色 会用到四个小软件及PPT插件 ColorPix(桌...

3637
来自专栏大数据钻研

前端开发,从草根到英雄(第一部分)

我还记得当我刚开始学习前端开发时,我被大量的技术文章淹没,当时让我非常困惑的是:我究竟需要学多少知识才算足够,我甚至不知道从哪里开始。 这篇指南会告诉你学习前端...

2965
来自专栏WeTest质量开放平台团队的专栏

iOS UITableView左滑操作功能的实现(iOS8-11)

作者:sonia,腾讯移动客户端开发 工程师

5248
来自专栏大数据钻研

给前端新人看的前端之路漫谈

前言 前端之路何其漫漫~ 说明:本篇文章原是写给学弟学妹的,但想来花的功夫确实不少,就把此篇文章当做自己的一个阶段性总结文章了,会保持长期更新。 HTML 总的...

3929
来自专栏闰土大叔

西安电话面试:谈谈Vue数据双向绑定原理,看看你的回答能打几分

最近我参加了一次来自西安的电话面试(第二轮,技术面),是大厂还是小作坊我在这里按下不表,先来说说这次电面给我留下印象较深的几道面试题,这次先来谈谈Vue的数据双...

1463

扫码关注云+社区

领取腾讯云代金券