何为交叉栅栏效果?
交叉栅栏 (Cross Fence)是一种前一个元素淡出,后一个元素淡入的效果,常用于页面切换上,该效果需要两个元素才能完成,切换时给人一种渐变的切换效果,下图是我实现的一种与Win11上面的截图切换模式时文字发生变化时一样的交叉栅栏动画效果:

这种渐变效果是同时进行的,渐隐和渐变是同时出现的,这样给人看起来似乎是一种模糊切换效果,但实际上是两个元素交替显示。
在WinUI3上实现它
首先你需要定义两个元素,一个元素用于显示初始内容,另外一个元素用于显示下一个要显示的元素,如果要封装,那么你需要手动实现这两个元素业务切换功能,这里我只简单实现这个效果:
<Grid>
<TextBlock x:Name="MyText" Text="按 Windows 徽标键 + Shift + S 开始截图" FontSize="12" />
<TextBlock x:Name="MyText1" Text="按 Windows 徽标键 + Shift + R 开始录像" FontSize="12" Opacity="0" />
</Grid>
<Button Content="切换模式" Click="On_Switch" HorizontalAlignment="Center" />
首先将MyText1的Opacity设置为0,让其不可见,使用Grid元素将两个元素置为同一格子里,你也可以使用Canvas布局控件实现。
On_Switch用于实现切换业务,在实现切换业务之前,需要使用VisualStateManager来定义控件的动画:
<UserControl x:Name="swc" >
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="OpacityStates">
<VisualState x:Name="Screenshot">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="MyText"
Storyboard.TargetProperty="Opacity"
To="0" Duration="0:0:0.5" />
<DoubleAnimation Storyboard.TargetName="MyText1"
Storyboard.TargetProperty="Opacity"
To="1" Duration="0:0:0.5" />
</Storyboard>
</VisualState>
<VisualState x:Name="Recording">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="MyText"
Storyboard.TargetProperty="Opacity"
To="1" Duration="0:0:0.5" />
<DoubleAnimation Storyboard.TargetName="MyText1"
Storyboard.TargetProperty="Opacity"
To="0" Duration="0:0:0.5" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</UserControl>
UserControl用于控制状态切换,VisualStateManager必须包含在Grid里面,因为UserControl会寻找宿主容器,然后包含里面的状态,它的寻找单位是以宿主容器为单位,像Grid、StackPanel…,上面定义了两个状态分别是Screenshot、Recording,这两个状态里都有一个Storyboard,Screenshot的Storyboard用于控制切换到截图模式,Recording的Storyboard用于控制切换到录像模式的动画效果,里面使用了DoubleAnimation来用于控制像Opacity这样的浮点数属性。
这两个动画就是将不同控件的透明度动画式的发生改变,设定的是在500ms内完成这些工作,你也可以使用by属性来改变它们的步长。
然后回到On_Switch函数里去实现切换逻辑:
void MainWindow::On_Switch(IInspectable const& sender, Microsoft::UI::Xaml::RoutedEventArgs const& args)
{
static bool model = false;
if (model == false)
VisualStateManager::GoToState(swc(), L"Screenshot", true);
else
VisualStateManager::GoToState(swc(), L"Recording", true);
model = !model;
}
这样运行时点击切换按钮你就可以看到上图的运行效果了。
720

被折叠的 条评论
为什么被折叠?



