如何绘制图形
内容正在准备中。
图形
Avalonia引入了一个广泛、可伸缩、灵活的图形功能集,具有以下优势:
- 分辨率无关和设备无关的图形。Avalonia图形系统的基本测量单位是设备无关像素,即1/96英寸,与实际屏幕分辨率无关,并为分辨率无关和设备无关的渲染提供基础。每个设备无关像素会自动缩放以匹配所渲染系统的每英寸点数(dpi)设置。
- 改进的精度。Avalonia坐标系统使用双精度浮点数进行测量,而不是单精度浮点数。变换和不透明度值也用双精度表示。
- 高级图形和动画支持。Avalonia通过为您管理动画场景来简化图形编程;无需担心场景处理、渲染循环和双线性插值。此外,Avalonia提供了命中测试支持和完整的alpha合成支持。
- Skia。Avalonia默认使用Skia渲染引擎,这是Google Chrome和Chrome OS、Android、Mozilla Firefox和Firefox OS以及许多其他产品所使用的相同渲染引擎。
2D形状和几何图形
Avalonia提供了一组常见的矢量绘制2D形状,如Ellipse
(椭圆)、Line
(线)、Path
(路径)、Polygon
(多边形)和Rectangle
(矩形)。
<Canvas Background="Yellow" Width="300" Height="400">
<Rectangle Fill="Blue" Width="63" Height="41" Canvas.Left="40" Canvas.Top="31">
<Rectangle.OpacityMask>
<LinearGradientBrush StartPoint="0%,0%" EndPoint="100%,100%">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0" Color="Black"/>
<GradientStop Offset="1" Color="Transparent"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Rectangle.OpacityMask>
</Rectangle>
<Ellipse Fill="Green" Width="58" Height="58" Canvas.Left="88" Canvas.Top="100"/>
<Path Fill="Orange" Data="M 0,0 c 0,0 50,0 50,-50 c 0,0 50,0 50,50 h -50 v 50 l -50,-50 Z" Canvas.Left="30" Canvas.Top="250"/>
<Path Fill="OrangeRed" Canvas.Left="180" Canvas.Top="250">
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="0,0" IsClosed="True">
<QuadraticBezierSegment Point1="50,0" Point2="50,-50" />
<QuadraticBezierSegment Point1="100,-50" Point2="100,0" />
<LineSegment Point="50,0" />
<LineSegment Point="50,50" />
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
<Line StartPoint="120,185" EndPoint="30,115" Stroke="Red" StrokeThickness="2"/>
<Polygon Points="75,0 120,120 0,45 150,45 30,120" Stroke="DarkBlue" StrokeThickness="1" Fill="Violet" Canvas.Left="150" Canvas.Top="31"/>
<Polyline Points="0,0 65,0 78,-26 91,39 104,-39 117,13 130,0 195,0" Stroke="Brown" Canvas.Left="30" Canvas.Top="350"/>
</Canvas>
添加动画
Avalonia UI具有动画支持,可以让您的控件实现增长、抖动、旋转和淡出效果,从而创建有趣的页面过渡效果等。Avalonia使用类似CSS的动画系统,支持属性过渡和关键帧动画。
如何添加菜单图标
在 Avalonia 中,通过为菜单项添加图标,您可以增强应用程序的外观和用户体验。图标可以为菜单项的操作提供视觉提示,使用户更容易浏览您的应用程序。本指南将指导您如何在 Avalonia 中为菜单项添加图标。
添加菜单项图标
使用 MenuItem.Icon
属性可以为菜单项设置图标。您可以使用各种类型的图像源作为图标,包括资源 URI、文件路径或 web URL。以下是一个将图标添加到菜单项的示例:
<Menu>
<MenuItem Header="File">
<MenuItem Header="Open" Command="{Binding OpenCommand}">
<MenuItem.Icon>
<Image Width="16" Height="16" Source="avares://MyApp/Assets/open_icon.png" />
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</Menu>
在此示例中,MenuItem.Icon
属性被设置为一个 Image
控件,用于显示来自应用程序资源的图像。Image
控件的 Source
属性被设置为表示图像源的资源 URI。Width
和 Height
属性用于控制图像的大小。
如何使用图标
在Avalonia中,使用图标可以改善应用程序的外观,使其更加用户友好。图标可以提供动作或内容的视觉表示,帮助用户更容易理解应用程序的功能。本指南将向您展示如何在Avalonia应用程序中添加和使用图标。
在Avalonia中使用图标
可以通过多种方式向Avalonia应用程序添加图标。本指南将介绍两种常见的方法:使用图像文件和使用图标字体。
使用图像文件
一种在Avalonia中使用图标的方法是使用图像文件。您可以使用各种格式,如PNG,JPG或BMP。以下是如何将图像文件用作图标的示例:
<Image Width="16" Height="16" Source="avares://MyApp/Assets/icon.png" />
在此示例中,使用Image
控件从应用程序资源中显示图像作为图标。Image
控件的Source
属性设置为指向图像文件的资源URI。
使用图标字体
另一种在Avalonia中使用图标的方法是使用图标字体。图标字体允许您使用可缩放的矢量图标,可以使用CSS自定义其大小、颜色、阴影等。以下是如何在Avalonia中使用图标字体的示例:
<TextBlock FontFamily="avares://MyApp/Assets/#FontAwesome" Text="" />
在此示例中,使用TextBlock
控件显示来自FontAwesome
图标字体的图标。TextBlock
控件的FontFamily
属性设置为指向字体文件的资源URI,并且Text属性设置为所需图标的Unicode值。
最佳实践
虽然使用图标可以增强应用程序的可用性,但明智地使用它们很重要。在使用图标时,请牢记以下提示:
- 确保图标的大小适合,并且在背景下清晰可见。
- 对于常见操作,请使用广为人知的图标,使您的应用程序更直观易懂。
如何使用关键帧动画
您可以使用关键帧动画来在时间轴上更改一个或多个控件属性。关键帧在动画的 持续时间 内由 Avalonia UI 样式中的 提示 点定义,并在某个时间点上设置属性的中间值。
关键帧之间的属性值根据 缓动函数 的曲线设置。默认的缓动函数是直线插值。
动画可以在启动后运行任意次数,也可以在正向或反向运行。还有选项可以延迟动画的启动,并进行重复。
信息
如果您熟悉 CSS 中的关键帧动画,您会注意到它在 Avalonia UI 中是如何实现的。
示例
您可以使用样式定义关键帧动画。
信息
若要了解 Avalonia UI 如何使用样式,请查看 这里的概念。
按照以下步骤使用 XAML 定义一个简单的颜色渐变动画:
- 在您选择的层级中创建一个样式集合。
- 向集合中添加一个带有选择器的样式,以定位要进行动画的控件。
- 添加一个
Setter
元素来定义您希望动画更改的属性。例如<Setter Property="Fill" Value="Red"/>
。 - 添加一个
Style.Animations
元素来包含您的动画。 - 添加一个
Animation
元素,并设置其Duration
属性。格式为时:分:秒
。 - 现在定义动画的关键帧。这个示例在 0% 和 100% 处设置了提示点。
- 在每个关键帧上添加
Setter
元素来设置填充不透明度的值。这个示例在 0.0 和 1.0 之间进行动画。
完成后的代码如下所示:
<Window xmlns="https://github.com/avaloniaui">
<Window.Styles>
<Style Selector="Rectangle.red">
<Setter Property="Fill" Value="Red"/>
<Style.Animations>
<Animation Duration="0:0:3">
<KeyFrame Cue="0%">
<Setter Property="Opacity" Value="0.0"/>
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="Opacity" Value="1.0"/>
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</Window.Styles>
<Rectangle Classes="red" Width="100" Height="100"/>
</Window>
动画效果如下:
该动画在矩形控件加载并被样式选择时就会运行。事实上,它在预览窗格中也能运行!
同时动画两个属性
此示例展示了如何在同一时间轴上同时动画两个属性。
<Window.Styles>
<Style Selector="Rectangle.red">
<Setter Property="Fill" Value="Red"/>
<Style.Animations>
<Animation Duration="0:0:3" IterationCount="4">
<KeyFrame Cue="0%">
<Setter Property="Opacity" Value="0.0"/>
<Setter Property="RotateTransform.Angle" Value="0.0"/>
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="Opacity" Value="1.0"/>
<Setter Property="RotateTransform.Angle" Value="90.0"/>
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</Window.Styles>
红色矩形同时进行淡入和旋转。
延迟
您可以通过设置动画元素的延迟属性来延迟动画的启动。例如:
<Animation Duration="0:0:1"
Delay="0:0:1">
...
</Animation>
重复
您可以使动画重复一定次数,或无限次数。要重复有限次数的动画,请在动画元素上设置 RepeatCount
属性,例如:
<Animation RepeatCount="5">
...
</Animation>
要无限次地重复动画,请使用特殊值 INFINITE
。例如:
<Animation RepeatCount="INFINITE">
...
</Animation>
播放方向
默认情况下,动画正向播放,即它按照缓动函数的曲线从左向右进行。您可以通过设置动画元素的 PlaybackDirection
属性来改变这种行为。例如:
<Animation RepeatCount="9" PlaybackDirection="AlternateReverse">
...
</Animation>
以下表格描述了各个选项:
值 | 描述 |
---|---|
Normal | (默认)正向播放动画。 |
Reverse | 反向播放动画。 |
Alternate | 先正向播放动画,然后反向播放。 |
AlternateReverse | 先反向播放动画,然后正向播放。 |
填充模式
动画的填充模式属性定义了动画运行后,属性如何持续保留或在运行之间的任何间隙中显示。例如:
<Animation RepeatCount="9" FillMode="Backward">
...
</Animation>
以下表格描述了各个选项:
值 | 描述 |
---|---|
None | 动画运行后,值不会保留,也不会在动画延迟时应用第一个值。 |
Forward | 最后的插值值将持续保留到目标属性。 |
Backward | 在动画延迟时,第一个插值值将显示。 |
Both | 将同时应用 Forward 和 Backward 行为。 |
缓动函数
缓动函数定义了动画期间属性如何随时间变化。
默认的缓动函数是线性的(上图左),但您可以通过在缓动属性中设置所需函数的名称来使用其他模式。例如,要使用“弹跳淡入”函数(上图右):
<Animation Duration="0:0:1"
Delay="0:0:1"
Easing="BounceEaseIn">
...
</Animation>
信息
要获取 Avalonia UI 缓动函数的完整列表,请参阅 此处的参考。
您还可以添加自定义的缓动函数类,如下所示:
<Animation Duration="0:0:1"
Delay="0:0:1">
<Animation.Easing>
<local:YourCustomEasingClassHere/>
</Animation.Easing>
...
</Animation>
如何使用过渡效果
Avalonia中的过渡效果也受到CSS动画的很大启发。它们监听目标属性的值的任何变化,并根据其参数对变化进行动画处理。可以通过Transitions
属性在任何Control
上定义过渡效果:
<Window xmlns="https://github.com/avaloniaui">
<Window.Styles>
<Style Selector="Rectangle.red">
<Setter Property="Height" Value="100"/>
<Setter Property="Width" Value="100"/>
<Setter Property="Fill" Value="Red"/>
<Setter Property="Opacity" Value="0.5"/>
</Style>
<Style Selector="Rectangle.red:pointerover">
<Setter Property="Opacity" Value="1"/>
</Style>
</Window.Styles>
<Rectangle Classes="red">
<Rectangle.Transitions>
<Transitions>
<DoubleTransition Property="Opacity" Duration="0:0:0.2"/>
</Transitions>
</Rectangle.Transitions>
</Rectangle>
</Window>
上述示例将监听Rectangle
的Opacity
属性的变化,并在值变化时,在2秒内将其平滑地过渡从旧值到新值。
过渡效果也可以在任何样式中使用Setter
来定义,目标属性设为Transitions
,并将它们封装在Transitions
对象中,如下所示:
<Window xmlns="https://github.com/avaloniaui">
<Window.Styles>
<Style Selector="Rectangle.red">
<Setter Property="Height" Value="100"/>
<Setter Property="Width" Value="100"/>
<Setter Property="Fill" Value="Red"/>
<Setter Property="Opacity" Value="0.5"/>
<Setter Property="Transitions">
<Transitions>
<DoubleTransition Property="Opacity" Duration="0:0:0.2"/>
</Transitions>
</Setter>
</Style>
<Style Selector="Rectangle.red:pointerover">
<Setter Property="Opacity" Value="1"/>
</Style>
</Window.Styles>
<Rectangle Classes="red"/>
</Window>
每个过渡效果都有Property
、Delay
、Duration
和可选的Easing
属性。
Property
表示过渡效果的目标属性,用于监听和动画处理值。
Delay
表示过渡效果应用于目标之前的等待时间。
Duration
表示过渡效果播放的时间长度。
缓动函数与 关键帧动画 中描述的相同。
以下是可用的过渡效果类型。必须根据要动画处理的属性类型选择正确的类型。
BoxShadowsTransition
:用于BoxShadows
目标属性BrushTransition
:用于IBrush
目标属性ColorTransition
:用于Color
目标属性CornerRadiusTransition
:用于CornerRadius
目标属性DoubleTransitions
:用于double
目标属性FloatTransitions
:用于float
目标属性IntegerTransitions
:用于int
目标属性PointTransition
:用于Point
目标属性SizeTransition
:用于Size
目标属性ThicknessTransition
:用于Thickness
目标属性TransformOperationsTransition
:用于ITransform
目标属性VectorTransition
:用于Vector
目标属性
过渡渲染变换
可以过渡应用于使用类似CSS语法的控件的渲染变换。以下示例显示了一个边框,在指针悬停在其上方时旋转45度:
XAML
<Border Width="100" Height="100" Background="Red">
<Border.Styles>
<Style Selector="Border">
<Setter Property="RenderTransform" Value="rotate(0)"/>
</Style>
<Style Selector="Border:pointerover">
<Setter Property="RenderTransform" Value="rotate(45deg)"/>
</Style>
</Border.Styles>
<Border.Transitions>
<Transitions>
<TransformOperationsTransition Property="RenderTransform" Duration="0:0:1"/>
</Transitions>
</Border.Transitions>
</Border>
C#
new Border
{
Width = 100,
Height = 100,
Background = Brushes.Red,
Styles =
{
new Style(x => x.OfType<Border>())
{
Setters =
{
new Setter(
Border.RenderTransformProperty,
TransformOperations.Parse("rotate(0)"))
},
},
new Style(x => x.OfType<Border>().Class(":pointerover"))
{
Setters =
{
new Setter(
Border.RenderTransformProperty,
TransformOperations.Parse("rotate(45deg)"))
},
},
},
Transitions = new Transitions
{
new TransformOperationsTransition
{
Property = Border.RenderTransformProperty,
Duration = TimeSpan.FromSeconds(1),
}
}
};
可用的过渡效果如下:
过渡效果 | 示例 | 可接受的单位 |
---|---|---|
translate | translate(10px) , translate(0px, 10px) | px |
translateX | translateX(10px) | px |
translateY | translateY(10px) | px |
scale | scale(10) , scale(0, 10) | |
scaleX | scaleX(10) | |
scaleY | scaleY(10) | |
skew | skew(90deg) , skew(0, 90deg) | deg , grad , rad , turn |
skewX | skewX(90deg) | deg , grad , rad , turn |
skewY | skewY(90deg) | deg , grad , rad , turn |
rotate | rotate(90deg) | deg , grad , rad , turn |
matrix | matrix(1,2,3,4,5,6) |
信息
Avalonia还支持类似WPF的渲染变换,如RotateTransform
,ScaleTransform
等。这些变换不能进行过渡:如果要对渲染变换应用过渡效果,请始终使用类似CSS的格式。
How To Use Gradients
This guide explains how to effectively use LinearGradientBrush in Avalonia to create beautiful gradient effects.
Basic Syntax
A LinearGradientBrush is defined using the following basic structure:
<LinearGradientBrush StartPoint="0%,0%" EndPoint="100%,0%">
<GradientStop Color="#COLOR1" Offset="0.0"/>
<GradientStop Color="#COLOR2" Offset="1.0"/>
</LinearGradientBrush>
Key Properties
StartPoint and EndPoint
- Defines the direction of the gradient
- Uses percentage values (e.g., "0%,0%") or decimal values (0,0)
- Common patterns:
- Horizontal: StartPoint="0%,50%" EndPoint="100%,50%"
- Vertical: StartPoint="50%,0%" EndPoint="50%,100%"
- Diagonal: StartPoint="0%,0%" EndPoint="100%,100%"
GradientStop Elements
- Define colors and their positions in the gradient
- Properties:
Color
: The color value (Hex code or named color)Offset
: Position in the gradient (0.0 to 1.0)
Common Gradient Patterns
1. Simple Horizontal Gradient
<LinearGradientBrush StartPoint="0%,50%" EndPoint="100%,50%">
<GradientStop Color="#FF6B6B" Offset="0.0"/>
<GradientStop Color="#4ECDC4" Offset="1.0"/>
</LinearGradientBrush>
2. Multi-Color Gradient
<LinearGradientBrush StartPoint="0%,50%" EndPoint="100%,50%">
<GradientStop Color="#FF6B6B" Offset="0.0"/>
<GradientStop Color="#FF8E53" Offset="0.3"/>
<GradientStop Color="#FF5E3A" Offset="0.6"/>
<GradientStop Color="#4ECDC4" Offset="1.0"/>
</LinearGradientBrush>
3. Vertical Gradient
<LinearGradientBrush StartPoint="50%,0%" EndPoint="50%,100%">
<GradientStop Color="#A8E6CF" Offset="0.0"/>
<GradientStop Color="#3D84A8" Offset="1.0"/>
</LinearGradientBrush>
Common Use Cases
Button Backgrounds
<Button>
<Button.Background>
<LinearGradientBrush StartPoint="0%,0%" EndPoint="0%,100%">
<GradientStop Color="#4CAF50" Offset="0.0"/>
<GradientStop Color="#45A049" Offset="1.0"/>
</LinearGradientBrush>
</Button.Background>
</Button>
Panel Backgrounds
<Border CornerRadius="8">
<Border.Background>
<LinearGradientBrush StartPoint="0%,0%" EndPoint="100%,100%">
<GradientStop Color="#FF9A9E" Offset="0.0"/>
<GradientStop Color="#FAD0C4" Offset="0.5"/>
<GradientStop Color="#FFD1FF" Offset="1.0"/>
</LinearGradientBrush>
</Border.Background>
</Border>
Example
Below is the code to replicate the following sample.
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SampleApp.MainWindow"
Title="Gradient Example">
<StackPanel Spacing="20" Margin="20">
<!-- Horizontal gradient with multiple color stops -->
<Border Height="100" CornerRadius="8">
<Border.Background>
<LinearGradientBrush StartPoint="0%,50%" EndPoint="100%,50%">
<GradientStop Color="#FF6B6B" Offset="0.0"/>
<GradientStop Color="#FF8E53" Offset="0.3"/>
<GradientStop Color="#FF5E3A" Offset="0.6"/>
<GradientStop Color="#4ECDC4" Offset="1.0"/>
</LinearGradientBrush>
</Border.Background>
<TextBlock Text="Horizontal Gradient"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="White"/>
</Border>
<!-- Vertical gradient with smooth transitions -->
<Border Height="100" CornerRadius="8">
<Border.Background>
<LinearGradientBrush StartPoint="50%,0%" EndPoint="50%,100%">
<GradientStop Color="#A8E6CF" Offset="0.0"/>
<GradientStop Color="#3D84A8" Offset="0.5"/>
<GradientStop Color="#46CDCF" Offset="1.0"/>
</LinearGradientBrush>
</Border.Background>
<TextBlock Text="Vertical Gradient"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="White"/>
</Border>
<!-- Diagonal gradient with multiple stops -->
<Border Height="100" CornerRadius="8">
<Border.Background>
<LinearGradientBrush StartPoint="0%,0%" EndPoint="100%,100%">
<GradientStop Color="#FF9A9E" Offset="0.0"/>
<GradientStop Color="#FAD0C4" Offset="0.25"/>
<GradientStop Color="#FFB6C1" Offset="0.5"/>
<GradientStop Color="#FFD1FF" Offset="1.0"/>
</LinearGradientBrush>
</Border.Background>
<TextBlock Text="Diagonal Gradient"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="Black"/>
</Border>
<!-- Custom angle gradient with cycling effect -->
<Border Height="100" CornerRadius="8">
<Border.Background>
<LinearGradientBrush StartPoint="0%,0%" EndPoint="100%,50%">
<GradientStop Color="#08AEEA" Offset="0.0"/>
<GradientStop Color="#2AF598" Offset="0.3"/>
<GradientStop Color="#08AEEA" Offset="0.6"/>
<GradientStop Color="#2AF598" Offset="1.0"/>
</LinearGradientBrush>
</Border.Background>
<TextBlock Text="Custom Angle Gradient"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="White"/>
</Border>
</StackPanel>
</Window>