UWP采用的是純扁平化的設計,個人感覺極端了點,整個世界都是平的,導致App分不清層次,看不出重點。其實扁平化是趨勢,android, ios都在搞,問題是android, ios都可以很輕松的實現陰影來突出重點和分層,android的material design更是火了一通,其中也大量用到陰影(card, float button等)。
做UWP應用的時候就想WinRT用的xaml和WPF差不多,WPF畫陰影很輕松,WinRT應該也很方便吧,結果查了半天資料,硬是找不到解決方案。
只能自己來想辦法了,當時首先想到了兩種辦法:
第一種:利用NineGrid圖片
UWP是支持NineGrid圖片,熟悉Android的應該知道點9圖,一回事。
先在photoshop里先做個陰影圖

在xaml里設置陰影圖的NineGrid設置,做為對比,第一個圖是沒用NineGrid,第二個是用了。

NineGrid的值是Thickness,分別表示左,上,右,下, 這樣就畫出一個九格圖:![]()
NineGrid有以下幾個好處:
1.因為各廠家分辨率不一致,用九圖不用再辛苦的針對每種機型做特定適配了,因為點九圖具有在拉伸的時候還能夠保持圖片的細節。
2.使用了九圖,可以把圖片做的很小,從而減小應用程序的大小。
3.圖片變小了,內存使用也就小了,程序運行和加載起來速度更快了。
上面Xaml顯示出來的結果:

沒用九圖的就很模糊,因為是整體放大,一樣的300*300就顯得小了好多,被陰影占了很大一部分,用九圖的就很清晰。
總結下九圖做陰影的優缺點:
優點是用起來很簡單,支持大小變化
缺點是每次要做個圖片,不同角度的圓角矩形和不同大小的圓形不能很好支持,因為九圖是要拉長兩邊的,圓的拉長就不是圓了。
第二種:用border來模擬
想想每次做個按鈕可能都要做圖片挺煩的,有沒有用代碼的方式來解決。
把陰影放大了看,其實也就是由不同透明度的線組成:

那用border來模擬行不行呢,通過算法生成一組模擬陰影的透明度,再用border表示出來,想起來還不錯哦,試下。
結果如下:

尼瑪,這是什么梗,說好的陰影呢。。
再在photoshop里看一下正常的陰影,原來拐角處和直線處的不一樣,是有弧度的。

暈死,只能怪自己想當然了,沒在photoshop里先注意到這塊。失敗!還浪費不少時間在陰影算法上。。
第三種:Win2D
基於第二種想法,用代碼的方式應該是有辦法的,后來找了下WinRT Direct2D的資料,可以通過Direct2D畫出陰影,封裝成庫給App調用。想法不錯,實現起來有點難度,在找Direct2D相關資料時在Microsoft的github下面找到了神器Win2D,尼瑪這么好的庫怎么不放到標准庫里來。。。
Win2D github:
https://github.com/Microsoft/Win2D。另外官方有個例子在WinStore上,裝了Win10的同學有興趣可以安裝看看,里面實現很多很酷的效果:

Win2D里用Direct2D實現了2d繪圖的各種方法,XPShadow就是基於Win2D的,先看下效果:

是不是有點Material Design的味道。
用起來也很簡單:
1 <xp:Shadow 2 IsCached="True" //default is False, if page use NavigationCacheMode = NavigationCacheMode.Required, should set IsCached=True 3 Z_Depth="1" //shadow depth, from 1 to 5 4 CornerRadius="10"> // shadow corner radius, 0-1 for percent of width, > 1 for actual value 5 <Border Width="80" Height="80" Background="White" CornerRadius="10"/> 6 </xp:Shadow>
來看看實現:
因為是封裝成一個內容控件,那畫了陰影之后,控件里的內容大小就會相應變小,不然陰影會畫到外面去。具體請看:

最后
“這么好的庫實在是各位UWP程序猿行走江湖,奮力碼磚之必備良庫”。
“那么……在哪里才能搞得到呢?”。
“啊!這位仁兄運氣真好,小弟正好放到github上開源,仁兄只要訪問
https://github.com/brookshi/XPShadow就可以了,另外別忘了Star/Fork哦”