UWP Composition API: Rounded Corners?

482 Views Asked by At

I'm struggling to figure out to to create rounded corners of content using Composition API. This is where I'm at, any help would be much appreciated:

void CreateRoundedCorners(Vector2 cornerRadius, CompositionSurfaceBrush imageSourceBrush, SpriteVisual targetVisual)
{
    CompositionRoundedRectangleGeometry roundedRectangle = _compositor.CreateRoundedRectangleGeometry();
    roundedRectangle.Size = new Vector2(;
    roundedRectangle.CornerRadius = cornerRadius;

    CompositionSpriteShape spriteShape = _compositor.CreateSpriteShape(roundedRectangle);
    spriteShape.FillBrush = _compositor.CreateColorBrush(Colors.Black);
    spriteShape.CenterPoint = new Vector2(_imageSize.X / 2, _imageSize.Y / 2);

    ShapeVisual spriteShapeVisual = _compositor.CreateShapeVisual();
    spriteShapeVisual.Size = _imageSize;
    spriteShapeVisual.Shapes.Add(spriteShape);

    CompositionMaskBrush maskBrush = _compositor.CreateMaskBrush();
    maskBrush.Source = imageSourceBrush;
    maskBrush.Mask = null; // How do I get the rectangle shape in here?

    targetVisual.Brush = maskBrush;
}
2

There are 2 best solutions below

1
Sean O'Neil On BEST ANSWER

I have figured out a solution. Creating a CompositionVisualSurface, adding the ShapeVisual to it, and creating a CompositionSurfaceBrush from that to use as the Mask source.

void CreateRoundedCorners(Vector2 cornerRadius, CompositionBrush imageSourceBrush, SpriteVisual targetVisual)
{
    CompositionRoundedRectangleGeometry roundedRectangle =_compositor.CreateRoundedRectangleGeometry();
    roundedRectangle.Size = _imageSize;
    roundedRectangle.CornerRadius = cornerRadius;

    CompositionSpriteShape spriteShape = _compositor.CreateSpriteShape(roundedRectangle);
    spriteShape.FillBrush = _compositor.CreateColorBrush(Colors.Black);
    spriteShape.CenterPoint = new Vector2(_imageSize.X / 2, _imageSize.Y / 2);

    ShapeVisual spriteShapeVisual = _compositor.CreateShapeVisual();
    spriteShapeVisual.BorderMode = CompositionBorderMode.Soft;
    spriteShapeVisual.Size = _imageSize;
    spriteShapeVisual.Shapes.Add(spriteShape);

    CompositionVisualSurface surface = _compositor.CreateVisualSurface();
    surface.SourceSize = _imageSize;
    surface.SourceVisual = spriteShapeVisual;

    CompositionMaskBrush maskBrush = _compositor.CreateMaskBrush();
    maskBrush.Source = imageSourceBrush;
    maskBrush.Mask = _compositor.CreateSurfaceBrush(surface);

    targetVisual.Brush = maskBrush;
}

EDIT: A mask can also be obtained from a Shape but only if it's already in the visual tree:

Windows.UI.Xaml.Shapes.Shape rect = new Rectangle();
CompositionBrush mask = rect.GetAlphaMask();
6
Nico Zhu On

UWP Composition API: Rounded Corners?

For your requirement, you could use SetElementChildVisual method to add the CompositionRoundedRectangleGeometry to current page.

For example:

private void Page_Loaded(object sender, RoutedEventArgs e)
{
    var visual = ElementCompositionPreview.GetElementVisual(this);
    var compositor = visual.Compositor;
  
    CompositionRoundedRectangleGeometry roundedRectangle = compositor.CreateRoundedRectangleGeometry();
    roundedRectangle.Size = new Vector2(200, 200);
    roundedRectangle.CornerRadius = new Vector2(30,30);

    CompositionSpriteShape spriteShape = compositor.CreateSpriteShape(roundedRectangle);
    spriteShape.FillBrush = compositor.CreateColorBrush(Colors.Blue);
    spriteShape.CenterPoint = new Vector2(100, 100);

    ShapeVisual spriteShapeVisual = compositor.CreateShapeVisual();
    spriteShapeVisual.Size = new Vector2(200, 200); 
    
    spriteShapeVisual.Shapes.Clear();
    spriteShapeVisual.Shapes.Add(spriteShape);
  
    ElementCompositionPreview.SetElementChildVisual(this, spriteShapeVisual);
}