DropShadow 类提供了创建可应用于 SpriteVisual 或 LayerVisual(视觉对象的子树)的可配置阴影的方法。 与视觉层中的对象一样,DropShadow 的所有属性都可以使用 CompositionAnimations 进行动画处理。
基本阴影
若要创建基本阴影,只需创建新的 DropShadow 并将其关联到视觉对象。 默认情况下,阴影为矩形。 可以使用一组标准属性来调整阴影的外观。
var basicRectVisual = _compositor.CreateSpriteVisual();
basicRectVisual.Brush = _compositor.CreateColorBrush(Colors.Blue);
basicRectVisual.Offset = new Vector3(100, 100, 20);
basicRectVisual.Size = new Vector2(300, 300);
var basicShadow = _compositor.CreateDropShadow();
basicShadow.BlurRadius = 25f;
basicShadow.Offset = new Vector3(20, 20, 20);
basicRectVisual.Shadow = basicShadow;
塑造阴影
可通过几种方法为 DropShadow 定义形状:
- 使用默认值 - 默认情况下,DropShadow 形状由 CompositionDropShadowSourcePolicy 上的“默认”模式定义。 对于 SpriteVisual,默认为矩形,除非提供了掩码。 对于 LayerVisual,默认值是继承一个掩码,具体方式为使用视觉对象的画笔的 alpha 通道。
- 设置掩码 – 可以设置 Mask 属性来定义阴影的不透明度掩码。
- 指定为使用继承掩码 – 将 SourcePolicy 属性设置为使用 CompositionDropShadowSourcePolicy。 InheritFromVisualContent 使用从视觉对象的画笔 alpha 生成的掩码。
屏蔽以匹配内容
如果希望阴影与Visual对象的内容匹配,可以使用Visual对象的画笔设置阴影掩码属性,或者将阴影设置为自动从内容继承掩码。 如果使用 LayerVisual,阴影默认将继承掩码。
var imageSurface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///Assets/myImage.png"));
var imageBrush = _compositor.CreateSurfaceBrush(imageSurface);
var imageSpriteVisual = _compositor.CreateSpriteVisual();
imageSpriteVisual.Size = new Vector2(400,400);
imageSpriteVisual.Offset = new Vector3(100, 500, 20);
imageSpriteVisual.Brush = imageBrush;
var shadow = _compositor.CreateDropShadow();
shadow.Mask = imageBrush;
// or use shadow.SourcePolicy = CompositionDropShadowSourcePolicy.InheritFromVisualContent;
shadow.BlurRadius = 25f;
shadow.Offset = new Vector3(20, 20, 20);
imageSpriteVisual.Shadow = shadow;
使用替代掩码
在某些情况下,你可能想要调整阴影,使其与视觉对象的内容不匹配。 若要达到此效果,需要使用具有 alpha 的画笔显式设置 Mask 属性。
在下面的示例中,我们加载两个图面 - 一个用于视觉内容,一个用于阴影掩码:
var imageSurface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///Assets/myImage.png"));
var imageBrush = _compositor.CreateSurfaceBrush(imageSurface);
var circleSurface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///Assets/myCircleImage.png"));
var customMask = _compositor.CreateSurfaceBrush(circleSurface);
var imageSpriteVisual = _compositor.CreateSpriteVisual();
imageSpriteVisual.Size = new Vector2(400,400);
imageSpriteVisual.Offset = new Vector3(100, 500, 20);
imageSpriteVisual.Brush = imageBrush;
var shadow = _compositor.CreateDropShadow();
shadow.Mask = customMask;
shadow.BlurRadius = 25f;
shadow.Offset = new Vector3(20, 20, 20);
imageSpriteVisual.Shadow = shadow;
制作动画
与视觉层中的标准一样,可以使用合成动画对 DropShadow 属性进行动画处理。 下面,我们修改上面的洒水示例中的代码,以对阴影的模糊半径进行动画处理。
ScalarKeyFrameAnimation blurAnimation = _compositor.CreateScalarKeyFrameAnimation();
blurAnimation.InsertKeyFrame(0.0f, 25.0f);
blurAnimation.InsertKeyFrame(0.7f, 50.0f);
blurAnimation.InsertKeyFrame(1.0f, 25.0f);
blurAnimation.Duration = TimeSpan.FromSeconds(4);
blurAnimation.IterationBehavior = AnimationIterationBehavior.Forever;
shadow.StartAnimation("BlurRadius", blurAnimation);
WinUI XAML 中的阴影
如果要向更复杂的框架元素添加阴影,可通过几种方法与 WinUI XAML 和合成之间的阴影进行互操作:
- 使用 CommunityToolkit.WinUI 包中可用的
DropShadowPanel。 - 创建视觉对象以用作阴影主机,并将其绑定到 XAML 交接视觉对象。
- 使用合成示例库的 SamplesCommon 自定义 CompositionShadow 控件。 有关用法,请参阅此处的示例。
性能
尽管视觉层有许多优化来使效果高效且可用,但生成阴影可能是一个相对昂贵的操作,具体取决于设置的选项。 下面是不同类型的阴影的总体“成本”。 请注意,虽然某些阴影可能很昂贵,但在某些情况下,它们可能仍适合谨慎使用。
| 阴影特征 | Cost |
|---|---|
| 矩形 | 低 |
| 阴影遮罩 | 高 |
| CompositionDropShadowSourcePolicy.InheritFromVisualContent | 高 |
| 静态模糊半径 | 低 |
| 对模糊半径进行动画处理 | 高 |