包含此页的版本:
不含此页的版本:
可以使用网格 API 或 Painter2D 在视觉元素上生成 2D 视觉内容。
可以使用网格 API 绘制自定义形状。Mesh API 是面向高级用户的工具。如果您只想生成简单的几何体,请改用矢量 API。受 HTML Canvas 的启发,矢量 API 绘制 2D 矢量图形,例如线条、弧线和形状。
要使用 Mesh API,请使用MeshGenerationContext.Allocate方法,然后填充顶点和索引。这MeshGenerationContext.Allocate方法分配和绘制指定数量的顶点和索引,以表达绘制视觉元素内容的几何图形。有关几何体生成约定的详细信息,请参阅 Vertex.position。
以下代码片段生成单个四边形。它分配顶点和索引,并提供顺时针方向的坐标:
class QuadMeshElement : VisualElement
{
public Color color = Color.red;
public QuadMeshElement()
{
generateVisualContent += OnGenerateVisualContent;
}
void OnGenerateVisualContent(MeshGenerationContext mgc)
{
var mesh = mgc.Allocate(4, 6);
var p0 = Vector2.zero;
var p1 = new Vector2(layout.width, 0);
var p2 = new Vector2(layout.width, layout.height);
var p3 = new Vector2(0, layout.height);
mesh.SetNextVertex(new Vertex() { position = new Vector3(p0.x, p0.y, Vertex.nearZ), tint = color });
mesh.SetNextVertex(new Vertex() { position = new Vector3(p1.x, p1.y, Vertex.nearZ), tint = color });
mesh.SetNextVertex(new Vertex() { position = new Vector3(p2.x, p2.y, Vertex.nearZ), tint = color });
mesh.SetNextVertex(new Vertex() { position = new Vector3(p3.x, p3.y, Vertex.nearZ), tint = color });
mesh.SetNextIndex(0);
mesh.SetNextIndex(1);
mesh.SetNextIndex(2);
mesh.SetNextIndex(0);
mesh.SetNextIndex(2);
mesh.SetNextIndex(3);
}
}
要使用 Painter2D API,请访问Painter2D对象MeshGenerationContext并用它生成路径。然后,您可以使用Stroke画线或Fill以绘制形状。
若要构建路径,请发出移动一种“虚拟笔”的命令。例如,若要在网格 API 示例中生成相同的四边形,请将“笔”移动到第一个位置,并将线条链接在一起。路径完成后,使用Fill构建形状。
class QuadVectorElement : VisualElement
{
public Color color = Color.red;
public QuadVectorElement()
{
generateVisualContent += OnGenerateVisualContent;
}
void OnGenerateVisualContent(MeshGenerationContext mgc)
{
var p0 = Vector2.zero;
var p1 = new Vector2(layout.width, 0);
var p2 = new Vector2(layout.width, layout.height);
var p3 = new Vector2(0, layout.height);
var painter2D = mgc.painter2D;
painter2D.fillColor = color;
painter2D.BeginPath();
painter2D.MoveTo(p0);
painter2D.LineTo(p1);
painter2D.LineTo(p2);
painter2D.LineTo(p3);
painter2D.ClosePath();
painter2D.Fill();
}
}
这LineTo方法生成一条从当前笔位置到提供的笔位置的直线。在绘制线条之前,请定义属性,例如描边颜色、线宽、连接和大写字母。
绘制线条时,属性LineJoin和LineCap控制线连接和大写字母的样式。
下图说明了线帽和联接的不同样式:
以下代码片段绘制了一条锯齿形线:
painter2D.lineWidth = 10.0f;
painter2D.strokeColor = Color.white;
painter2D.lineJoin = LineJoin.Round;
painter2D.lineCap = LineCap.Round;
painter2D.BeginPath();
painter2D.MoveTo(new Vector2(100, 100));
painter2D.LineTo(new Vector2(120, 120));
painter2D.LineTo(new Vector2(140, 100));
painter2D.LineTo(new Vector2(160, 120));
painter2D.LineTo(new Vector2(180, 100));
painter2D.LineTo(new Vector2(200, 120));
painter2D.LineTo(new Vector2(220, 100));
painter2D.Stroke();
您可以使用以下方法绘制圆弧:
以下代码片段使用Arc要绘制带边框的扇区:
painter2D.lineWidth = 2.0f;
painter2D.strokeColor = Color.red;
painter2D.fillColor = Color.blue;
painter2D.BeginPath();
// Move to the arc center
painter2D.MoveTo(new Vector2(100, 100));
// Draw the arc, and close the path
painter2D.Arc(new Vector2(100, 100), 50.0f, 10.0f, 95.0f);
painter2D.ClosePath();
// Fill and stroke the path
painter2D.Fill();
painter2D.Stroke();
以下代码片段使用ArcTo要在线条的拐角处绘制所需半径的圆弧:
painter2D.BeginPath();
painter2D.MoveTo(new Vector2(100, 100));
painter2D.ArcTo(new Vector2(150, 150), new Vector2(200, 100), 20.0f);
painter2D.LineTo(new Vector2(200, 100));
painter2D.Stroke();
您可以使用以下方法绘制曲线:
BezierCurveTo方法通过两个控制点和立方贝塞尔曲线的最终位置生成立方贝塞尔曲线。QuadraticCurveTo方法通过控制点和二次贝塞尔曲线的最终位置生成二次贝塞尔曲线。以下代码片段使用BezierCurveTo要绘制贝塞尔曲线:
painter2D.BeginPath();
painter2D.MoveTo(new Vector2(100, 100));
painter2D.BezierCurveTo(new Vector2(150, 150), new Vector2(200, 50), new Vector2(250, 100));
painter2D.Stroke();
以下代码片段使用QuadraticCurveTo要绘制二次曲线:
painter2D.BeginPath();
painter2D.MoveTo(new Vector2(100, 100));
painter2D.QuadraticCurveTo(new Vector2(150, 150), new Vector2(250, 100));
painter2D.Stroke();
当你执行Fill.当您调用MoveTo,它会启动一个新的子路径。要创建孔,请使用填充规则将各个子路径相互重叠。
填充规则确定如何填充形状的内部:
OddEven:从该点到无限远的任意方向绘制光线,并计算光线穿过的给定形状的路径段数。如果这个数字是奇数,则点在里面;如果偶数,则点在外面。NonZero:从该点到无限远的任意方向绘制一条光线,然后检查形状的一段与光线相交的位置。从计数零开始,每次路径段从左到右穿过光线时添加一个。每当路径段从右到左穿过光线时减去 1。计算交叉点后,如果结果为零,则该点位于路径之外。否则,它在里面。以下代码片段创建一个矩形,其中有一个菱形孔:
painter2D.BeginPath();
painter2D.MoveTo(new Vector2(10, 10));
painter2D.LineTo(new Vector2(300, 10));
painter2D.LineTo(new Vector2(300, 150));
painter2D.LineTo(new Vector2(10, 150));
painter2D.ClosePath();
painter2D.MoveTo(new Vector2(150, 50));
painter2D.LineTo(new Vector2(175, 75));
painter2D.LineTo(new Vector2(150, 100));
painter2D.LineTo(new Vector2(125, 75));
painter2D.ClosePath();
painter2D.Fill(FillRule.OddEven);