AvaloniaUI / Avalonia

Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The most popular .NET UI client technology
https://avaloniaui.net
MIT License
26.09k stars 2.26k forks source link

Support Clipping to rounded corners #2105

Open danwalmsley opened 6 years ago

danwalmsley commented 6 years ago

If you have something like:

<Border Height="40" Background="Red" Width="100" BorderBrush="Green" BorderThickness="1" CornerRadius="5">
        <Border Width="40" Background="Blue" HorizontalAlignment="Right" />
      </Border>

the containing border will have round corners, but with the inner border overlaying the right hand corners.

WPF would also produce the same result, but UWP would correctly clip the corners like so. image

I think this would be an advantage to allow the UWP behaviour and would greatly help in polishing controls.

frederik-hoeft commented 4 years ago

Any updates on this? Is it currently possible at all to achieve this behavior, even with an ugly workaround?

maxkatz6 commented 4 years ago

Doesn't ClipToBounds property fix it now?

dlukach commented 3 years ago

the problem with cliptobounds is the background of the control in a border will still overlap the border. Would be nice if the border overlaps the child control to avoid this issue.

davidackemandev commented 3 years ago

cliptoboundsproblem ^ Here is a screenshot showing what happens when you add ClipToBounds="True" to a parent element. The child element still overlaps with the border.

Gillibald commented 3 years ago

The GeometryClip feature is needed to support this

maxkatz6 commented 3 years ago

Probably box-sizing from CSS solves similar problem in web. And not sure about UWP, but I think it's configurable there with BackgroundSizing. Can somebody say, who are familiar with them, if I am right about these properties?

Apart from that, I see only one good and not ugly solution - set corner radius also on child element. Still it might be not convenient. Also we can't just follow UWP approach without any way to configure it, because some applications might depend on that WPF-like behavior.

davidackemandev commented 3 years ago

In CSS you can set overflow="hidden" to clip the child element correctly: codepen

I tried setting a corner radius on the child element, but it still isn't perfect, both parent and child have corner radius = 6: cornerproblem2

Does corner radius in Avalonia/WPF scale based on the element's width?

Gillibald commented 3 years ago

Corner radius depends on the borders thickness. There are multiple radii that are calculated. For uniform corners and thicknesses this is directly calculated by the render backend (Skia by default)

wieslawsoltes commented 3 years ago

Some trick using opacity mask:

<Border BorderBrush="Black" Background="Red" BorderThickness="3" Margin="10" Width="400" Height="267" CornerRadius="40" >
    <Grid>
        <Border Name="myBorder" CornerRadius="40" Background="White" Margin="1"/>
        <Rectangle Fill="Red" >
            <Rectangle.OpacityMask>
                <VisualBrush Visual="{Binding ElementName=myBorder}"/>
            </Rectangle.OpacityMask>
        </Rectangle>
    </Grid>
</Border>

image

nathanAjacobs commented 3 years ago

@wieslawsoltes I tried to use your exact XAML, but I'm getting a tiny white space near the border:

Capture

grokys commented 2 years ago

Problem here seems to be that although clipping to a rounded rect was added in #4081, it clips to the outer bounds of the rounded rect, not taking into account the border thickness.

UWP seems to handle this correctly, and given that we added this feature in part because UWP had it, we should match their behavior as it's more useful.

robloo commented 2 years ago

Just ran across this one. It makes it appear that CornerRadius doesn't work at all when authoring controls.

maxkatz6 commented 2 years ago

CornerRadius doesn't work at all when authoring controls.

Shouldn't be the case, this issue is not about that

JamDoggie commented 2 years ago

Still an issue on Avalonia 0.10.12. Notice how when the ComboBoxItem gets it's color changed from transparent to a color, it overlays the parent border's corners: https://i.gyazo.com/9c8c3e28915f15ad15d59f7799d72473.mp4

robloo commented 2 years ago

Again, ran across this for a new control. Children should always be clipped within their parents.

pr8x commented 2 years ago

Any update on this :/ ? Setting CornerRadius on ContentPresenter seems to correctly clip its child, but not on Border.

billhenn commented 2 years ago

I'm running into this too. It would be great if you have ClipToBounds=true set, the Border's Child would be automatically clipped to be exactly inside the visible BorderThickness.

SmRiley commented 1 year ago

Until now (11.0.5) I have to use two borders to solve this problem

robloo commented 7 months ago

Note that with the BackgroundSizing support this actually became a lot easier to do.

I believe we already support any Geometry for clipping. A geometry representing the inner part of the border can be built using the GeometryBuilder. Those same geometries are needed for BackgroundSizing. With that geometry, the clipping can then be calculated and set internally. We also have the WinUI source code to see how they did this within Border already.

https://github.com/AvaloniaUI/Avalonia/blob/81d2e7d4efb1c2c475c80e8e5893171aa94c25ab/src/Avalonia.Base/Media/GeometryBuilder.cs#L206-L210

Then

https://github.com/AvaloniaUI/Avalonia/blob/81d2e7d4efb1c2c475c80e8e5893171aa94c25ab/src/Avalonia.Base/Media/GeometryBuilder.cs#L35-L37

I see this issue continue to pop up time and time again so will probably get to it myself eventually. However, it's probably considered a breaking change so perhaps wouldn't be allowed until 12.0 anyway.

xmaxrayx commented 1 month ago

will be 2025 and no round ><? win11 push rounding design ideology,

please we need this other than our apps will look like from old day.

xmaxrayx commented 1 month ago

never mind I thought this WPF....

xmaxrayx commented 1 month ago

vanila wpf

        <Viewbox Stretch="Fill">

            <Grid>
                <Grid.OpacityMask>
                    <VisualBrush Visual="{Binding ElementName=Border1}" />
                </Grid.OpacityMask>
                <Border x:Name="Border1" CornerRadius="30" Background="Green" />
                <Grid ClipToBounds="True">
                    <Ellipse Width="420" Height="451" Fill="AntiqueWhite" Margin="473,153,-93,-154"></Ellipse>
                    <Ellipse Width="420" Height="451" Fill="AntiqueWhite" Margin="-138,225,518,-226"/>
                    <Ellipse Width="420" Height="451" Fill="AntiqueWhite" Margin="-47,-378,427,377"/>
                </Grid>
            </Grid>

        </Viewbox>

    </Grid>

image image