fix(Avatar): clip image content to avatar shape

This commit is contained in:
chinboy
2026-07-09 17:27:51 +08:00
parent e750e1052d
commit 26caf01092
2 changed files with 62 additions and 15 deletions
@@ -20,20 +20,34 @@
IsVisible="False"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
<Image Name="ImagePresenter"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
IsVisible="False"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Source="{TemplateBinding BitmapSrc}" />
<Svg Name="SvgPresenter"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
IsVisible="False"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Path="{TemplateBinding Src}" />
<Border Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
CornerRadius="{TemplateBinding CornerRadius}"
ClipToBounds="True"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Image Name="ImagePresenter"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
IsVisible="False"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Source="{TemplateBinding BitmapSrc}" />
</Border>
<Border Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
CornerRadius="{TemplateBinding CornerRadius}"
ClipToBounds="True"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Svg Name="SvgPresenter"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
IsVisible="False"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Path="{TemplateBinding Src}" />
</Border>
<atom:TextBlock Name="PART_TextPresenter"
Text="{TemplateBinding Text}"
RenderTransform="{TemplateBinding TextRenderTransform}"
@@ -116,4 +130,4 @@
</Style>
</ControlTheme>
</ResourceDictionary>
</ResourceDictionary>
@@ -3,7 +3,9 @@ using AtomUI.Controls;
using Avalonia;
using Avalonia.Controls;
using Avalonia.LogicalTree;
using Avalonia.Media.Imaging;
using Avalonia.Threading;
using Avalonia.VisualTree;
using Shouldly;
using Xunit;
@@ -212,6 +214,37 @@ public class AvatarGroupFoldInfoTests
avatar.SizeType.ShouldBe(CustomizableSizeType.Large);
}
[Fact]
public void Avatar_BitmapSrc_Content_Is_Clipped_By_Circle_Shape()
{
using var bitmap = new RenderTargetBitmap(new PixelSize(4, 4), new Vector(96, 96));
var avatar = new DesktopAvatar
{
Size = 64,
Shape = AvatarShape.Circle,
BitmapSrc = bitmap
};
ShowInWindow(avatar, () =>
{
var imagePresenter = avatar.GetVisualDescendants()
.OfType<Image>()
.Single(image => image.Name == "ImagePresenter");
imagePresenter.IsVisible.ShouldBeTrue();
var clippingFrame = imagePresenter.GetVisualAncestors()
.OfType<Border>()
.FirstOrDefault(border => border.ClipToBounds);
clippingFrame.ShouldNotBeNull();
clippingFrame.CornerRadius.TopLeft.ShouldBe(32);
clippingFrame.CornerRadius.TopRight.ShouldBe(32);
clippingFrame.CornerRadius.BottomRight.ShouldBe(32);
clippingFrame.CornerRadius.BottomLeft.ShouldBe(32);
});
}
private static AvatarGroup CreateFoldedGroup()
{
return new AvatarGroup