Xamarin.Forms 形状:路径转换
Transform
定义如何将 Path
对象从一个坐标空间转换为另一个坐标空间。 将转换应用于 Path
对象时,它会更改对象在 UI 中的呈现方式。
转换可分为四种常规分类:旋转、缩放、倾斜和平移。 Xamarin.Forms 为这些转换分类中的每一个定义一个类:
RotateTransform
,旋转由Angle
指定的Path
。ScaleTransform
,将Path
对象按指定的ScaleX
和ScaleY
数量缩放。SkewTransform
,对Path
对象按照指定的AngleX
和AngleY
数量进行倾斜。TranslateTransform
,将Path
对象按照指定的X
和Y
数量进行移动。
为了创建更复杂的转换,Xamarin.Forms 还提供了以下类:
TransformGroup
,表示由多个转换对象组成的复合转换。CompositeTransform
,将多个转换操作应用于Path
对象。MatrixTransform
,创建其他转换类不提供的自定义转换。
所有这些类都派生自定义 Value
属性(类型为 Matrix
)的 Transform
类,该属性将当前转换表示为 Matrix
对象。 此属性由 BindableProperty
对象提供支持,这意味着它可以作为数据绑定的目标,并进行样式设置。 要详细了解 Matrix
结构,请参阅转换矩阵。
要将转换应用于 Path
,请创建转换类,并将其设置为 Path.RenderTransform
属性的值。
旋转转换
旋转转换将 Path
对象围绕二维 x-y 坐标系中的指定点顺时针旋转。
派生自 Transform
类的 RotateTransform
类定义以下属性:
Angle
,类型为double
,表示顺时针旋转的角度(以度为单位)。 此属性的默认值为 0.0。CenterX
,类型为double
,表示旋转中心点的 x 坐标。 此属性的默认值为 0.0。CenterY
,类型为double
,表示旋转中心点的 y 坐标。 此属性的默认值为 0.0。
这些属性由 BindableProperty
对象提供支持,表示它们可以是数据绑定的目标,并可以设置样式。
CenterX
和 CenterY
属性指定 Path
对象绕其旋转的点。 此中心点以转换对象的坐标空间表示。 默认情况下,旋转应用于 (0,0),即 Path
对象的左上角。
以下示例演示如何旋转 Path
对象:
<Path Stroke="Black"
Aspect="Uniform"
HorizontalOptions="Center"
HeightRequest="100"
WidthRequest="100"
Data="M13.908992,16.207977L32.000049,16.207977 32.000049,31.999985 13.908992,30.109983z">
<Path.RenderTransform>
<RotateTransform CenterX="0"
CenterY="0"
Angle="45" />
</Path.RenderTransform>
</Path>
在此示例中,Path
对象围绕其左上角旋转 45 度。
缩放转换
缩放转换在二维 x-y 坐标系中缩放 Path
对象。
派生自 Transform
类的 ScaleTransform
类定义以下属性:
ScaleX
,类型为double
,表示 x 轴缩放因子。 此属性的默认值为 1.0。ScaleY
,类型为double
,表示 y 轴缩放因子。 此属性的默认值为 1.0。CenterX
,类型为double
,表示此转换中心点的 x 坐标。 此属性的默认值为 0.0。CenterY
,类型为double
,表示此转换中心点的 y 坐标。 此属性的默认值为 0.0。
这些属性由 BindableProperty
对象提供支持,表示它们可以是数据绑定的目标,并可以设置样式。
ScaleX
和 ScaleY
的值对生成的缩放有巨大影响:
- 值介于 0 和 1 之间时会减少缩放对象的宽度和高度。
- 值大于 1 时会增加缩放对象的宽度和高度。
- 值为 1 时指示对象未缩放。
- 负值将缩放对象水平和垂直翻转。
- 值介于 0 和 -1 之间时翻转缩放对象并减小其宽度和高度。
- 值小于 -1 时翻转对象并增加其宽度和高度。
- 值为 -1 时可翻转缩放对象,但不更改其水平或垂直大小。
CenterX
和 CenterY
属性指定 Path
对象围绕其缩放的点。 此中心点以转换对象的坐标空间表示。 默认情况下,缩放应用于 (0,0),即 Path
对象的左上角。 这样做的效果是移动 Path
对象并使其看起来更大,因为在应用转换时会更改 Path
对象所在的坐标空间。
以下示例演示如何缩放 Path
对象:
<Path Stroke="Black"
Aspect="Uniform"
HorizontalOptions="Center"
HeightRequest="100"
WidthRequest="100"
Data="M13.908992,16.207977L32.000049,16.207977 32.000049,31.999985 13.908992,30.109983z">
<Path.RenderTransform>
<ScaleTransform CenterX="0"
CenterY="0"
ScaleX="1.5"
ScaleY="1.5" />
</Path.RenderTransform>
</Path>
在此示例中,Path
对象的大小缩放为 1.5 倍。
倾斜转换
倾斜转换在二维 x-y 坐标系中倾斜 Path
对象,对在二维对象中创建三维深度错觉非常有用。
派生自 Transform
类的 SkewTransform
类定义以下属性:
AngleX
,类型为double
,表示 x 轴倾斜角,该角度从 y 轴逆时针测量得到(以度为单位)。 此属性的默认值为 0.0。AngleY
,类型为double
,表示 y 轴倾斜角,该角度从 x 轴逆时针测量得到(以度为单位)。 此属性的默认值为 0.0。CenterX
,类型为double
,表示转换中心的 x 坐标。 此属性的默认值为 0.0。CenterY
,类型为double
,表示转换中心的 y 坐标。 此属性的默认值为 0.0。
这些属性由 BindableProperty
对象提供支持,表示它们可以是数据绑定的目标,并可以设置样式。
若要预测扭曲转换的效果,请考虑 AngleX
相对于原始坐标系统扭曲 x 轴的值。 因此,当 AngleX
为 30 时,y 轴将绕原点旋转 30 度,并将 x 轴的值从该原点倾斜 30 度。 同样地,当 AngleY
为 30 时,Path
对象的 y 值将从原点倾斜 30 度。
注意
要将 Path
对象原地倾斜,请将 CenterX
和 CenterY
属性设置为对象的中心点。
以下示例演示如何倾斜 Path
对象:
<Path Stroke="Black"
Aspect="Uniform"
HorizontalOptions="Center"
HeightRequest="100"
WidthRequest="100"
Data="M13.908992,16.207977L32.000049,16.207977 32.000049,31.999985 13.908992,30.109983z">
<Path.RenderTransform>
<SkewTransform CenterX="0"
CenterY="0"
AngleX="45"
AngleY="0" />
</Path.RenderTransform>
</Path>
在以下示例中,从中心点 (0,0) 对 Path
对象应用 45 度水平倾斜。
平移转换
平移转换在二维 x-y 坐标系中移动对象。
派生自 Transform
类的 TranslateTransform
类定义以下属性:
X
,类型为double
,表示沿 x 轴移动的距离。 此属性的默认值为 0.0。Y
,类型为double
,表示要沿 y 轴移动的距离。 此属性的默认值为 0.0。
这些属性由 BindableProperty
对象提供支持,表示它们可以是数据绑定的目标,并可以设置样式。
X
的负值将对象向左移动,而正值将对象向右移动。 Y
的负值将对象向上移动,而正值将对象向下移动。
以下示例演示如何平移 Path
对象:
<Path Stroke="Black"
Aspect="Uniform"
HorizontalOptions="Center"
HeightRequest="100"
WidthRequest="100"
Data="M13.908992,16.207977L32.000049,16.207977 32.000049,31.999985 13.908992,30.109983z">
<Path.RenderTransform>
<TranslateTransform X="50"
Y="50" />
</Path.RenderTransform>
</Path>
在此示例中,Path
对象向右移动 50 个与设备无关的单位,并向下移动 50 个与设备无关的单位。
多重转换
Xamarin.Forms 有两个支持对 Path
对象应用多种转换的类。 它们是 TransformGroup
和 CompositeTransform
。 TransformGroup
按任意所需顺序执行转换,而 CompositeTransform
按特定顺序执行转换。
转换组
转换组表示由多个 Transform
对象组成的复合转换。
派生自 Transform
类的 TransformGroup
类定义类型为 TransformCollection
的 Children
属性,该属性表示 Transform
对象的集合。 此属性由 BindableProperty
对象提供支持,这意味着它可以作为数据绑定的目标,并进行样式设置。
转换顺序在使用 TransformGroup
类的复合转换中非常重要。 例如,“先旋转再缩放后平移”与“先平移再旋转后缩放”得到的结果并不一样。 顺序之所以重要,原因之一就是旋转和缩放等转换是相对于坐标系原点执行的。 缩放以原点为中心的对象生成的结果不同于缩放远离原点的对象生成的结果。 同样,旋转以原点为中心的对象产生的结果不同于旋转远离原点的对象所产生的结果。
以下示例演示如何使用 TransformGroup
类执行复合转换:
<Path Stroke="Black"
Aspect="Uniform"
HorizontalOptions="Center"
HeightRequest="100"
WidthRequest="100"
Data="M13.908992,16.207977L32.000049,16.207977 32.000049,31.999985 13.908992,30.109983z">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1.5"
ScaleY="1.5" />
<RotateTransform Angle="45" />
</TransformGroup>
</Path.RenderTransform>
</Path>
在此示例中,Path
对象缩放到其大小的 1.5 倍,然后旋转 45 度。
复合转换
复合转换将多重转换应用于对象。
派生自 Transform
类的 CompositeTransform
类定义以下属性:
CenterX
,类型为double
,表示此转换中心点的 x 坐标。 此属性的默认值为 0.0。CenterY
,类型为double
,表示此转换中心点的 y 坐标。 此属性的默认值为 0.0。ScaleX
,类型为double
,表示 x 轴缩放因子。 此属性的默认值为 1.0。ScaleY
,类型为double
,表示 y 轴缩放因子。 此属性的默认值为 1.0。SkewX
,类型为double
,表示 x 轴倾斜角,该角度从 y 轴逆时针测量得到(以度为单位)。 此属性的默认值为 0.0。SkewY
,类型为double
,表示 y 轴倾斜角,该角度从 x 轴逆时针测量得到(以度为单位)。 此属性的默认值为 0.0。Rotation
,类型为double
,表示顺时针旋转的角度(以度为单位)。 此属性的默认值为 0.0。TranslateX
,类型为double
,表示要沿 x 轴移动的距离。 此属性的默认值为 0.0。TranslateY
,类型为double
,表示要沿 y 轴移动的距离。 此属性的默认值为 0.0。
这些属性由 BindableProperty
对象提供支持,表示它们可以是数据绑定的目标,并可以设置样式。
CompositeTransform
按以下顺序应用转换:
- 缩放(
ScaleX
和ScaleY
)。 - 倾斜(
SkewX
和SkewY
)。 - 旋转 (
Rotation
)。 - 平移(
TranslateX
、TranslateY
)。
如果要以不同的顺序将多重转换应用于对象,应创建 TransformGroup
并按预期顺序插入转换。
重要
CompositeTransform
对所有转换使用相同的中心点 CenterX
和 CenterY
。 如果要为每个转换指定不同的中心点,请使用 TransformGroup
,
以下示例演示如何使用 CompositeTransform
类执行复合转换:
<Path Stroke="Black"
Aspect="Uniform"
HorizontalOptions="Center"
HeightRequest="100"
WidthRequest="100"
Data="M13.908992,16.207977L32.000049,16.207977 32.000049,31.999985 13.908992,30.109983z">
<Path.RenderTransform>
<CompositeTransform ScaleX="1.5"
ScaleY="1.5"
Rotation="45"
TranslateX="50"
TranslateY="50" />
</Path.RenderTransform>
</Path>
在此示例中,将 Path
对象的大小缩放为 1.5 倍,再旋转 45 度,然后平移 50 个与设备无关的单位。
转换矩阵
可以在 3x3 仿射转换矩阵中描述转换,该矩阵在二维空间中执行转换。 此 3x3 矩阵由 Matrix
结构表示,该结构是三行和三列 double
值的集合。
Matrix
结构定义以下属性:
Determinant
,类型为double
,获取矩阵的行列式。HasInverse
,类型为bool
,指示矩阵是否不可逆。Identity
,类型为Matrix
,获取标识矩阵。HasIdentity
,类型为bool
,指示矩阵是否为标识矩阵。M11
,类型为double
,表示矩阵第一行和第一列的值。M12
,类型为double
,表示矩阵第一行和第二列的值。M21
,类型为double
,表示矩阵第二行和第一列的值。M22
,类型为double
,表示矩阵第二行和第二列的值。OffsetX
,类型为double
,表示矩阵第三行和第一列的值。OffsetY
,类型为double
,表示矩阵第三行和第二列的值。
OffsetX
和 OffsetY
属性之所以如此命名,是因为它们分别指定沿 x 轴和 y 轴平移坐标空间的量。
此外,Matrix
结构还公开一系列可用于操作矩阵值的方法,包括 Append
、Invert
、Multiply
、Prepend
等等。
下表显示了 Xamarin.Forms 矩阵的结构:
M11
M12
0.0
M21
M22
0.0
OffsetX
OffsetY
1.0
注意
由于仿射转换矩阵的最后一列等于 (0,0,1),因此仅需要指定前两列中的成员。
通过操作矩阵值,可以旋转、缩放、倾斜和平移 Path
对象。 例如,如果将 OffsetX
值更改为100,则可以使用它将 Path
对象沿 x 轴移动 100 个与设备无关的单位。 如果将 M22
值更改为 3,则可使用它将 Path
对象的当前高度拉伸三倍。 如果同时更改这两个值,将使 Path
对象沿 x 轴移动 100 个与设备无关的单位,并将其高度拉伸 3 倍。 此外,仿射转换矩阵可以相乘以形成任意数量的线性转换,例如旋转和倾斜,并随之平移。
自定义转换
派生自 Transform
类的 MatrixTransform
类定义类型为 Matrix
的 Matrix
属性,该属性表示定义转换的矩阵。 此属性由 BindableProperty
对象提供支持,这意味着它可以作为数据绑定的目标,并进行样式设置。
任何可用 TranslateTransform
、ScaleTransform
、RotateTransform
或 SkewTransform
对象描述的转换都可以用 MatrixTransform
来描述。 但是,TranslateTransform
、ScaleTransform
、RotateTransform
和 SkewTransform
类比在 Matrix
中设置矢量分量更易于概念化。 因此,MatrixTransform
类通常用于创建 RotateTransform
、ScaleTransform
、SkewTransform
或 TranslateTransform
类不提供的自定义转换。
以下示例演示如何使用 MatrixTransform
转换 Path
对象:
<Path Stroke="Black"
Aspect="Uniform"
HorizontalOptions="Center"
Data="M13.908992,16.207977L32.000049,16.207977 32.000049,31.999985 13.908992,30.109983z">
<Path.RenderTransform>
<MatrixTransform>
<MatrixTransform.Matrix>
<!-- M11 stretches, M12 skews -->
<Matrix OffsetX="10"
OffsetY="100"
M11="1.5"
M12="1" />
</MatrixTransform.Matrix>
</MatrixTransform>
</Path.RenderTransform>
</Path>
在此示例中,Path
对象同时在 X 和 Y 维度中被拉伸、倾斜和偏移。
也可采用一种简化形式来编写它,该形式使用 Xamarin.Forms 中内置的类型转换器:
<Path Stroke="Black"
Aspect="Uniform"
HorizontalOptions="Center"
Data="M13.908992,16.207977L32.000049,16.207977 32.000049,31.999985 13.908992,30.109983z">
<Path.RenderTransform>
<MatrixTransform Matrix="1.5,1,0,1,10,100" />
</Path.RenderTransform>
</Path>
在此示例中,将 Matrix
属性指定为以逗号分隔的字符串,该字符串由六个成员组成:M11
、M12
、M21
、M22
、OffsetX
和 OffsetY
。 虽然此示例中的成员以逗号分隔,但它们也可以由一个或多个空格分隔。
此外,还可以通过指定六个与 RenderTransform
属性的值相同的成员,来进一步简化前面的示例:
<Path Stroke="Black"
Aspect="Uniform"
HorizontalOptions="Center"
RenderTransform="1.5 1 0 1 10 100"
Data="M13.908992,16.207977L32.000049,16.207977 32.000049,31.999985 13.908992,30.109983z" />