Skip to content

Commit 555d6e9

Browse files
Add comments to AttachedCardShadow
1 parent b6cf5c1 commit 555d6e9

File tree

1 file changed

+42
-27
lines changed

1 file changed

+42
-27
lines changed

Microsoft.Toolkit.Uwp.UI.Media/Shadows/AttachedCardShadow.cs

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -210,20 +210,20 @@ private void UpdateVisualOpacityMask(AttachedShadowElementContext context)
210210
return;
211211
}
212212

213-
// Create a rounded rectangle Visual with a thick outline and no fill, then use a VisualSurface of it as an opacity mask for the shadow.
214-
// This will have the effect of clipping the inner content of the shadow, so that the casting element is not covered by the shadow,
215-
// while the shadow is still rendered outside of the element. Similar to what takes place in GetVisualClip,
216-
// except here we use a brush to mask content instead of a pure geometric clip.
217-
var shapeVisual = context.GetResource(OpacityMaskShapeVisualResourceKey) ??
213+
// Create ShapeVisual, and CompositionSpriteShape with geometry, these will provide the visuals for the opacity mask.
214+
ShapeVisual shapeVisual = context.GetResource(OpacityMaskShapeVisualResourceKey) ??
218215
context.AddResource(OpacityMaskShapeVisualResourceKey, context.Compositor.CreateShapeVisual());
219216

220-
CompositionRoundedRectangleGeometry geom = context.GetResource(OpacityMaskGeometryResourceKey) ??
217+
CompositionRoundedRectangleGeometry geometry = context.GetResource(OpacityMaskGeometryResourceKey) ??
221218
context.AddResource(OpacityMaskGeometryResourceKey, context.Compositor.CreateRoundedRectangleGeometry());
222219
CompositionSpriteShape shape = context.GetResource(OpacityMaskSpriteShapeResourceKey) ??
223-
context.AddResource(OpacityMaskSpriteShapeResourceKey, context.Compositor.CreateSpriteShape(geom));
220+
context.AddResource(OpacityMaskSpriteShapeResourceKey, context.Compositor.CreateSpriteShape(geometry));
224221

225-
geom.Offset = new Vector2(MaxBlurRadius / 2);
226-
geom.CornerRadius = new Vector2((MaxBlurRadius / 2) + (float)CornerRadius);
222+
// Set the attributes of the geometry, and add the CompositionSpriteShape to the ShapeVisual.
223+
// The geometry will have a thick outline and no fill, meaning that when used as a mask,
224+
// the shadow will only be rendered on the outer area covered by the outline, clipping out its inner portion.
225+
geometry.Offset = new Vector2(MaxBlurRadius / 2);
226+
geometry.CornerRadius = new Vector2((MaxBlurRadius / 2) + (float)CornerRadius);
227227
shape.StrokeThickness = MaxBlurRadius;
228228
shape.StrokeBrush = shape.StrokeBrush ?? context.Compositor.CreateColorBrush(Colors.Black);
229229

@@ -232,42 +232,57 @@ private void UpdateVisualOpacityMask(AttachedShadowElementContext context)
232232
shapeVisual.Shapes.Add(shape);
233233
}
234234

235-
var visualSurface = context.GetResource(OpacityMaskShapeVisualSurfaceResourceKey) ??
235+
// Create CompositionVisualSurface using the ShapeVisual as the source visual.
236+
CompositionVisualSurface visualSurface = context.GetResource(OpacityMaskShapeVisualSurfaceResourceKey) ??
236237
context.AddResource(OpacityMaskShapeVisualSurfaceResourceKey, context.Compositor.CreateVisualSurface());
237238
visualSurface.SourceVisual = shapeVisual;
238239

239-
geom.Size = new Vector2((float)context.Element.ActualWidth, (float)context.Element.ActualHeight) + new Vector2(MaxBlurRadius);
240+
geometry.Size = new Vector2((float)context.Element.ActualWidth, (float)context.Element.ActualHeight) + new Vector2(MaxBlurRadius);
240241
shapeVisual.Size = visualSurface.SourceSize = new Vector2((float)context.Element.ActualWidth, (float)context.Element.ActualHeight) + new Vector2(MaxBlurRadius * 2);
241242

242-
var surfaceBrush = context.GetResource(OpacityMaskShapeVisualSurfaceBrushResourceKey) ??
243+
// Create a CompositionSurfaceBrush using the CompositionVisualSurface as the source, this essentially converts the ShapeVisual into a brush.
244+
// This brush can then be used as a mask.
245+
CompositionSurfaceBrush opacityMask = context.GetResource(OpacityMaskShapeVisualSurfaceBrushResourceKey) ??
243246
context.AddResource(OpacityMaskShapeVisualSurfaceBrushResourceKey, context.Compositor.CreateSurfaceBrush());
244-
surfaceBrush.Surface = visualSurface;
247+
opacityMask.Surface = visualSurface;
245248
}
246249

247250
/// <inheritdoc/>
248251
protected override void SetElementChildVisual(AttachedShadowElementContext context)
249252
{
250-
if (context.TryGetResource(OpacityMaskShapeVisualSurfaceBrushResourceKey, out var opacityMask))
253+
if (context.TryGetResource(OpacityMaskShapeVisualSurfaceBrushResourceKey, out CompositionSurfaceBrush opacityMask))
251254
{
252-
var visualSurface = context.GetResource(OpacityMaskVisualSurfaceResourceKey) ??
255+
// If the resource for OpacityMaskShapeVisualSurfaceBrushResourceKey exists it means this.InnerContentClipMode == CompositionVisualSurface,
256+
// which means we need to take some steps to set up an opacity mask.
257+
258+
// Create a CompositionVisualSurface, and use the SpriteVisual containing the shadow as the source.
259+
CompositionVisualSurface shadowVisualSurface = context.GetResource(OpacityMaskVisualSurfaceResourceKey) ??
253260
context.AddResource(OpacityMaskVisualSurfaceResourceKey, context.Compositor.CreateVisualSurface());
254-
visualSurface.SourceVisual = context.SpriteVisual;
261+
shadowVisualSurface.SourceVisual = context.SpriteVisual;
255262
context.SpriteVisual.RelativeSizeAdjustment = Vector2.Zero;
256263
context.SpriteVisual.Size = new Vector2((float)context.Element.ActualWidth, (float)context.Element.ActualHeight);
257-
visualSurface.SourceOffset = new Vector2(-MaxBlurRadius);
258-
visualSurface.SourceSize = new Vector2((float)context.Element.ActualWidth, (float)context.Element.ActualHeight) + new Vector2(MaxBlurRadius * 2);
259264

260-
var surfaceBrush = context.GetResource(OpacityMaskSurfaceBrushResourceKey) ??
265+
// Adjust the offset and size of the CompositionVisualSurface to accommodate the thick outline of the shape created in UpdateVisualOpacityMask().
266+
shadowVisualSurface.SourceOffset = new Vector2(-MaxBlurRadius);
267+
shadowVisualSurface.SourceSize = new Vector2((float)context.Element.ActualWidth, (float)context.Element.ActualHeight) + new Vector2(MaxBlurRadius * 2);
268+
269+
// Create a CompositionSurfaceBrush from the CompositionVisualSurface. This allows us to render the shadow in a brush.
270+
CompositionSurfaceBrush shadowSurfaceBrush = context.GetResource(OpacityMaskSurfaceBrushResourceKey) ??
261271
context.AddResource(OpacityMaskSurfaceBrushResourceKey, context.Compositor.CreateSurfaceBrush());
262-
surfaceBrush.Surface = visualSurface;
263-
surfaceBrush.Stretch = CompositionStretch.None;
272+
shadowSurfaceBrush.Surface = shadowVisualSurface;
273+
shadowSurfaceBrush.Stretch = CompositionStretch.None;
264274

275+
// Create a CompositionMaskBrush, using the CompositionSurfaceBrush of the shadow as the source,
276+
// and the CompositionSurfaceBrush created in UpdateVisualOpacityMask() as the mask.
277+
// This creates a brush that renders the shadow with its inner portion clipped out.
265278
CompositionMaskBrush maskBrush = context.GetResource(OpacityMaskBrushResourceKey) ??
266279
context.AddResource(OpacityMaskBrushResourceKey, context.Compositor.CreateMaskBrush());
267-
maskBrush.Source = surfaceBrush;
280+
maskBrush.Source = shadowSurfaceBrush;
268281
maskBrush.Mask = opacityMask;
269282

270-
var visual = context.GetResource(OpacityMaskVisualResourceKey) ??
283+
// Create a SpriteVisual and set its brush to the CompositionMaskBrush created in the previous step,
284+
// then set it as the child of the element in the context.
285+
SpriteVisual visual = context.GetResource(OpacityMaskVisualResourceKey) ??
271286
context.AddResource(OpacityMaskVisualResourceKey, context.Compositor.CreateSpriteVisual());
272287
visual.RelativeSizeAdjustment = Vector2.One;
273288
visual.Offset = new Vector3(-MaxBlurRadius, -MaxBlurRadius, 0);
@@ -288,21 +303,21 @@ protected override void SetElementChildVisual(AttachedShadowElementContext conte
288303
/// <inheritdoc />
289304
protected internal override void OnSizeChanged(AttachedShadowElementContext context, Size newSize, Size previousSize)
290305
{
291-
var sizeAsVec2 = newSize.ToVector2();
306+
Vector2 sizeAsVec2 = newSize.ToVector2();
292307

293-
var geometry = context.GetResource(RoundedRectangleGeometryResourceKey);
308+
CompositionRoundedRectangleGeometry geometry = context.GetResource(RoundedRectangleGeometryResourceKey);
294309
if (geometry != null)
295310
{
296311
geometry.Size = sizeAsVec2;
297312
}
298313

299-
var visualSurface = context.GetResource(VisualSurfaceResourceKey);
314+
CompositionVisualSurface visualSurface = context.GetResource(VisualSurfaceResourceKey);
300315
if (geometry != null)
301316
{
302317
visualSurface.SourceSize = sizeAsVec2;
303318
}
304319

305-
var shapeVisual = context.GetResource(ShapeVisualResourceKey);
320+
ShapeVisual shapeVisual = context.GetResource(ShapeVisualResourceKey);
306321
if (geometry != null)
307322
{
308323
shapeVisual.Size = sizeAsVec2;

0 commit comments

Comments
 (0)