Windows UI 中的阴影

DropShadow 类提供了创建可配置阴影的方法,该阴影可应用于 SpriteVisualLayerVisual(视觉对象的子树)。 按照 Visual Layer 中对象的惯例,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;

具有 Basic DropShadow 的矩形视觉对象

定形阴影

有几种方法可以定义 DropShadow 的形状:

  • 使用默认值 - 默认情况下,DropShadow 形状由 CompositionDropShadowSourcePolicy 上的“Default”模式定义。 对于 SpriteVisual,除非提供遮罩,否则默认值为矩形。 对于 LayerVisual,默认是使用视觉对象的画笔的 alpha 继承遮罩。
  • 设置遮罩 — 可以设置 Mask 属性来定义阴影的不透明遮罩。
  • 指定使用继承遮罩 – 将 SourcePolicy 属性设置为使用 CompositionDropShadowSourcePolicy. InheritFromVisualContent 以使用通过视觉对象的画笔的 alpha 生成的蒙版。

用于匹配内容的遮罩

如果你希望阴影与视觉对象的内容相匹配,可以使用视觉对象的画笔作为阴影遮罩属性,或者将阴影设置为自动从内容继承遮罩。 如果使用的是 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;

已连接 Web 图像,带有屏蔽的投影

使用备用遮罩

在某些情况下,您可能想要塑造阴影,使其与你的视觉对象的内容不匹配。 要实现此效果,需要使用带 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;

带圆面遮盖投影的连接 Web 图像

动画处理

作为可视层中的标准,DropShadow 属性可以使用合成动画进行动画处理。 下面,我们修改上面的 sprinkles 示例中的代码,对阴影的模糊半径进行动画处理。

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);

XAML 中的阴影

如果想为更复杂的框架元素添加阴影,有几种方法可以在 XAML 和 Composition 之间与阴影进行互操作:

  1. 使用 Windows 社区工具包中提供的 DropShadowPanel。 有关使用方法的详细信息,请参阅 DropShadowPanel 文档
  2. 创建一个用作阴影宿主的视觉对象,并将其与 XAML 讲义视觉对象相关联。
  3. 使用合成示例库的 SamplesCommon 自定义 CompositionShadow 控件。 有关用法,请参阅此处的示例。

性能

尽管视觉对象层具有很多优化功能,以使效果高效且可供使用,但根据你设置的选项,生成阴影可能是一个相对成本较高的操作。 以下是不同类型阴影的高级别“成本”。 请注意,尽管某些阴影可能成本很高,但在某些场景中可能仍适合谨慎使用。

阴影特征 成本
矩形
Shadow.Mask
CompositionDropShadowSourcePolicy.InheritFromVisualContent
静态模糊半径
对模糊半径进行动画处理

其他资源