原文:UWP Button添加圓角陰影(二)html
對於陰影呢,WindowsCommunityToolkit中已經有封裝好的DropShadowPanel啦,只要引用Microsoft.Toolkit.Uwp.UI.Controls
這個Nuget包就可使用啦。
直接把陰影套在我們的圓角Button外面呢,會出現圓角的Button映出直角的陰影的醜陋情況。對於這種狀況確定是有處理方式的。
看DropShadowPanel的源碼,對Content的特殊類型作了處理。下面我詳細的說下。
CompositionAPI中的DropShadow這個東西,很是反人類的兩點:windows
GetAlphaMask()
,能夠返回一個CompositionSurfaceBrush,Brush的內容是控件的內容填黑,其餘地方留空,給DropShadow.Mask設置成這個Brush,陰影就會按照這個輪廓去繪製。<Style TargetType="Button" x:Key="CornerRadiusShadowButtonStyle"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Grid x:Name="RootGrid"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal" /> <VisualState x:Name="PointerOver"> <Storyboard> </Storyboard> </VisualState> <VisualState x:Name="Pressed"> <Storyboard> </Storyboard> </VisualState> <VisualState x:Name="Disabled"> <Storyboard> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <control:DropShadowPanel x:Name="Shadow" xmlns:control="using:Microsoft.Toolkit.Uwp.UI.Controls"> <Rectangle x:Name="Background"></Rectangle> </control:DropShadowPanel> <ContentPresenter x:Name="ContentPresenter"> </ContentPresenter> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>
注意這裏有個小坑,DropShadowPanel的HorizontalContentAlignment默認是Left,Content裏若是隻裝Rectangle,是撐不開的。。。要作以下設置:動畫
<control:DropShadowPanel x:Name="Shadow" xmlns:control="using:Microsoft.Toolkit.Uwp.UI.Controls" HorizontalContentAlignment="Stretch"> <Rectangle x:Name="Background" Fill="{TemplateBinding Background}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RadiusX="5" RadiusY="5" /> </control:DropShadowPanel>
接下來就是編寫VisualState了,若是要對DropShadowPanel進行有過渡的動畫,須要在DoubleAnimation中設置EnableDependentAnimation="True"
,否則只播放起始和終止狀態。詳情請見:情節提要動畫 - 從屬動畫和獨立動畫。
注:調試過程當中熱更新DropShadowPanel的BlurRadius和Offset動畫,再播放會掉幀,從新運行一下就行了。
可是用DoubleAnimation去控制CompositionAPI中的動畫是很很差的,Composition有本身的Animation系統,咱們將會在下一篇文章中一塊兒給DropShadowPanel附加隱式(過渡)動畫。
下面是完整的代碼:spa
<Style TargetType="Button" x:Key="CornerRadiusShadowButtonStyle"> <Setter Property="Background" Value="{ThemeResource ButtonBackground}" /> <Setter Property="Foreground" Value="{ThemeResource ButtonForeground}" /> <Setter Property="BorderBrush" Value="Transparent" /> <Setter Property="BorderThickness" Value="0" /> <Setter Property="Padding" Value="20,10,20,10" /> <Setter Property="HorizontalAlignment" Value="Left" /> <Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" /> <Setter Property="FontWeight" Value="Normal" /> <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" /> <Setter Property="UseSystemFocusVisuals" Value="True" /> <Setter Property="FocusVisualMargin" Value="-3" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Grid x:Name="RootGrid"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualStateGroup.Transitions> <VisualTransition To="Normal" > <Storyboard> <DoubleAnimation Storyboard.TargetName="Shadow" Storyboard.TargetProperty="OffsetY" To="1" Duration="0:0:0.1" EnableDependentAnimation="True" /> <DoubleAnimation Storyboard.TargetName="Shadow" Storyboard.TargetProperty="BlurRadius" To="5" Duration="0:0:0.1" EnableDependentAnimation="True" /> </Storyboard> </VisualTransition> <VisualTransition To="PointerOver" > <Storyboard> <DoubleAnimation Storyboard.TargetName="Shadow" Storyboard.TargetProperty="OffsetY" To="2" Duration="0:0:0.1" EnableDependentAnimation="True" /> <DoubleAnimation Storyboard.TargetName="Shadow" Storyboard.TargetProperty="BlurRadius" To="8" Duration="0:0:0.1" EnableDependentAnimation="True" /> </Storyboard> </VisualTransition> <VisualTransition To="Pressed" > <Storyboard> <DoubleAnimation Storyboard.TargetName="Shadow" Storyboard.TargetProperty="OffsetY" To="3" Duration="0:0:0.1" EnableDependentAnimation="True" /> <DoubleAnimation Storyboard.TargetName="Shadow" Storyboard.TargetProperty="BlurRadius" To="12" Duration="0:0:0.1" EnableDependentAnimation="True" /> </Storyboard> </VisualTransition> </VisualStateGroup.Transitions> <VisualState x:Name="Normal" > <Storyboard> <DoubleAnimation Storyboard.TargetName="Shadow" Storyboard.TargetProperty="OffsetY" To="1" Duration="0" EnableDependentAnimation="True" /> <DoubleAnimation Storyboard.TargetName="Shadow" Storyboard.TargetProperty="BlurRadius" To="5" Duration="0" EnableDependentAnimation="True" /> </Storyboard> </VisualState> <VisualState x:Name="PointerOver"> <Storyboard> <DoubleAnimation Storyboard.TargetName="Shadow" Storyboard.TargetProperty="OffsetY" To="2" Duration="0" EnableDependentAnimation="True" /> <DoubleAnimation Storyboard.TargetName="Shadow" Storyboard.TargetProperty="BlurRadius" To="8" Duration="0" EnableDependentAnimation="True" /> </Storyboard> </VisualState> <VisualState x:Name="Pressed"> <Storyboard> <DoubleAnimation Storyboard.TargetName="Shadow" Storyboard.TargetProperty="OffsetY" To="3" Duration="0" EnableDependentAnimation="True" /> <DoubleAnimation Storyboard.TargetName="Shadow" Storyboard.TargetProperty="BlurRadius" To="12" Duration="0" EnableDependentAnimation="True" /> </Storyboard> </VisualState> <VisualState x:Name="Disabled"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Background" Storyboard.TargetProperty="Fill"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundDisabled}" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <control:DropShadowPanel x:Name="Shadow" xmlns:control="using:Microsoft.Toolkit.Uwp.UI.Controls" HorizontalContentAlignment="Stretch" BlurRadius="5" ShadowOpacity="0.8" OffsetX="1" OffsetY="1" Color="Black"> <Rectangle x:Name="Background" Fill="{TemplateBinding Background}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RadiusX="5" RadiusY="5" /> </control:DropShadowPanel> <ContentPresenter x:Name="ContentPresenter" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" ContentTemplate="{TemplateBinding ContentTemplate}" Padding="{TemplateBinding Padding}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" AutomationProperties.AccessibilityView="Raw" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>