UI 控件-绘图画布
阅读本文大概需要 5 分钟
本文概述了 UI 控件—绘图画布的各项属性以及使用方法。
什么是绘图画布?
绘图画布可用于绘制直线、曲线、文本和自定义图形。绘图功能需要在TS脚本中实现。
- 变换/对齐/通用/渲染属性请见 UI 控件的基础属性
- 绘图画布控件的渲染属性不会影响其绘制的图形,并且其绘制的图形可以超过绘图画布控件范围外。
- 为了节省性能,从下层到上层连续渲染的同类图形会合批。
- 请注意:drawLines、drawSpline、drawCubicBezierSpline三种线暂不支持在世界UI上绘制。
绘图画布的功能介绍
绘制直线
- 两点之间连接一条直线;线的长度、颜色、层级在DrawDataBase类中配置。
ts
let lineDrawData1= new DrawDataBase
lineDrawData1.lineColor=new LinearColor(1,0,0)
lineDrawData1.lineThickness=3
let drawcanvas = this.uiWidgetBase.findChildByPath("RootCanvas/MWDrawCanvas") as DrawCanvas;
drawcanvas.drawLines([new Vector2(500, 500),new Vector2(500, 800)], lineDrawData1)
let lineDrawData1= new DrawDataBase
lineDrawData1.lineColor=new LinearColor(1,0,0)
lineDrawData1.lineThickness=3
let drawcanvas = this.uiWidgetBase.findChildByPath("RootCanvas/MWDrawCanvas") as DrawCanvas;
drawcanvas.drawLines([new Vector2(500, 500),new Vector2(500, 800)], lineDrawData1)
绘制埃尔米特曲线
- 两点之间连接一条埃尔米特曲线,并可以指定开始点和结束点的方向;线的长度、颜色、层级在DrawDataBase类中配置。
ts
let drawcanvas = this.uiWidgetBase.findChildByPath("RootCanvas/MWDrawCanvas") as DrawCanvas;
drawcanvas.drawSpline(new Vector2(1200, 500), new Vector2(100, 100),new Vector2(1700, 500),new Vector2(100, -100), lineDrawData1);
let drawcanvas = this.uiWidgetBase.findChildByPath("RootCanvas/MWDrawCanvas") as DrawCanvas;
drawcanvas.drawSpline(new Vector2(1200, 500), new Vector2(100, 100),new Vector2(1700, 500),new Vector2(100, -100), lineDrawData1);
绘制三阶贝塞尔曲线
- 根据四个点的位置绘制一条三阶贝塞尔曲线;线的长度、颜色、层级在DrawDataBase类中配置。
- 也可以用三阶贝塞尔曲线绘制圆形或者半圆形。
ts
let drawcanvas = this.uiWidgetBase.findChildByPath("RootCanvas/MWDrawCanvas") as DrawCanvas;
drawcanvas.drawCubicBezierSpline(new Vector2(1200, 800), new Vector2(1300, 900),new Vector2(1400, 800),new Vector2(1500, 900), lineDrawData1);
let drawcanvas = this.uiWidgetBase.findChildByPath("RootCanvas/MWDrawCanvas") as DrawCanvas;
drawcanvas.drawCubicBezierSpline(new Vector2(1200, 800), new Vector2(1300, 900),new Vector2(1400, 800),new Vector2(1500, 900), lineDrawData1);
绘制文字
- 相比文本框控件,仅单纯绘制文本,没有换行/文本对齐/富文本等功能。
ts
let drawcanvas = this.uiWidgetBase.findChildByPath("RootCanvas/MWDrawCanvas") as DrawCanvas;
drawcanvas.drawText("text", new Vector2(200, 800), 50, new LinearColor(1,0,0), 0);
let drawcanvas = this.uiWidgetBase.findChildByPath("RootCanvas/MWDrawCanvas") as DrawCanvas;
drawcanvas.drawText("text", new Vector2(200, 800), 50, new LinearColor(1,0,0), 0);
绘制自定义图形
- 先确定若干个顶点位置,并设置顶点的位置信息、颜色信息、纹理坐标信息;然后三个一组的将顶点连接为三角形并组成自定义图形;
- 每个三角形的颜色能根据顶点的颜色信息自动实现为渐变效果;
- 并且自定义图形可以配置一张UI贴图,UI贴图的方向取决于各顶点的纹理坐标信息;
ts
//创建UIDrawCustomVertex数组,设置顶点的位置信息、颜色信息、纹理坐标信息
let vertex = [];
let data = new UIDrawCustomVertex();
data.color = LinearColor.white;
data.texCoord = new Vector2(0, 0);
data.position = new Vector2(0, 0);
vertex.push(data);
data = new UIDrawCustomVertex();
data.color = LinearColor.red;
data.texCoord = new Vector2(0.5, 0);
data.position = new Vector2(500, 0);
vertex.push(data);
data = new UIDrawCustomVertex();
data.color = LinearColor.blue;
data.texCoord = new Vector2(1, 0);
data.position = new Vector2(1000, 0);
vertex.push(data);
data = new UIDrawCustomVertex();
data.color = LinearColor.blue;
data.texCoord = new Vector2(1, 1);
data.position = new Vector2(1000, 50);
vertex.push(data);
data = new UIDrawCustomVertex();
data.color = LinearColor.red;
data.texCoord = new Vector2(0.5, 1);
data.position = new Vector2(500, 50);
vertex.push(data);
data = new UIDrawCustomVertex();
data.color = LinearColor.white;
data.texCoord = new Vector2(0, 1);
data.position = new Vector2(0, 50);
vertex.push(data);
let drawcanvas = this.uiWidgetBase.findChildByPath("RootCanvas/MWDrawCanvas") as DrawCanvas;
//绘制自定义图形,根据UIDrawCustomVertex数组中各顶点的信息,三个一组的将顶点连接为三角形
drawcanvas.drawCustom(vertex,[0,1,4,4,5,0,1,2,3,3,4,1],"assetID",0);
//创建UIDrawCustomVertex数组,设置顶点的位置信息、颜色信息、纹理坐标信息
let vertex = [];
let data = new UIDrawCustomVertex();
data.color = LinearColor.white;
data.texCoord = new Vector2(0, 0);
data.position = new Vector2(0, 0);
vertex.push(data);
data = new UIDrawCustomVertex();
data.color = LinearColor.red;
data.texCoord = new Vector2(0.5, 0);
data.position = new Vector2(500, 0);
vertex.push(data);
data = new UIDrawCustomVertex();
data.color = LinearColor.blue;
data.texCoord = new Vector2(1, 0);
data.position = new Vector2(1000, 0);
vertex.push(data);
data = new UIDrawCustomVertex();
data.color = LinearColor.blue;
data.texCoord = new Vector2(1, 1);
data.position = new Vector2(1000, 50);
vertex.push(data);
data = new UIDrawCustomVertex();
data.color = LinearColor.red;
data.texCoord = new Vector2(0.5, 1);
data.position = new Vector2(500, 50);
vertex.push(data);
data = new UIDrawCustomVertex();
data.color = LinearColor.white;
data.texCoord = new Vector2(0, 1);
data.position = new Vector2(0, 50);
vertex.push(data);
let drawcanvas = this.uiWidgetBase.findChildByPath("RootCanvas/MWDrawCanvas") as DrawCanvas;
//绘制自定义图形,根据UIDrawCustomVertex数组中各顶点的信息,三个一组的将顶点连接为三角形
drawcanvas.drawCustom(vertex,[0,1,4,4,5,0,1,2,3,3,4,1],"assetID",0);
如何使用绘图画布?
示例一:用绘图画布制作一个简单的画板功能
- 下面我们使用绘图画布来实现一个画板功能,玩家可以通过手指/鼠标在屏幕上触碰并拖动来绘制线条。
- 首先我们在UI编辑器中创建一个绘图画布控件,并铺满全屏;
- 然后编写脚本:
ts
@UIBind('')
export default class DefaultUI extends UIScript {
drawcanvas:DrawCanvas
lineDrawData1: DrawDataBase
point1:Vector2
point2:Vector2
/** 仅在游戏时间对非模板实例调用一次 */
protected onStart() {
this.drawcanvas = this.uiWidgetBase.findChildByPath("RootCanvas/MWDrawCanvas") as DrawCanvas;
//新建一个DrawDataBase类,配置线的长度、颜色、层级。
this.lineDrawData1= new DrawDataBase
this.lineDrawData1.lineColor=new LinearColor(1,0,0)
this.lineDrawData1.lineThickness=5
//按下数字键1清空当前所有绘制的图形
InputUtil.onKeyDown(Keys.One, () => {
this.drawcanvas.clearDraws()
});
}
//需要注意为了能触发onTouchMoved,onTouchStarted必须返回EventReply.handled
protected onTouchStarted(InGemotry :Geometry,InPointerEvent:PointerEvent) :EventReply{
return EventReply.handled; //EventReply.handled
}
//用onTouchMoved检测手指/鼠标移动,并且在移动前后的两点之间绘制线段
protected onTouchMoved(InGemotry :Geometry,InPointerEvent:PointerEvent) :EventReply{
console.log("onTouchMoved");
this.point1=absoluteToLocal(this.drawcanvas.tickSpaceGeometry,InPointerEvent.lastScreenSpacePosition)
this.point2=absoluteToLocal(this.drawcanvas.tickSpaceGeometry,InPointerEvent.screenSpacePosition)
this.drawcanvas.drawLines([this.point1,this.point2], this.lineDrawData1)
return EventReply.unHandled; //EventReply.handled
}
}
@UIBind('')
export default class DefaultUI extends UIScript {
drawcanvas:DrawCanvas
lineDrawData1: DrawDataBase
point1:Vector2
point2:Vector2
/** 仅在游戏时间对非模板实例调用一次 */
protected onStart() {
this.drawcanvas = this.uiWidgetBase.findChildByPath("RootCanvas/MWDrawCanvas") as DrawCanvas;
//新建一个DrawDataBase类,配置线的长度、颜色、层级。
this.lineDrawData1= new DrawDataBase
this.lineDrawData1.lineColor=new LinearColor(1,0,0)
this.lineDrawData1.lineThickness=5
//按下数字键1清空当前所有绘制的图形
InputUtil.onKeyDown(Keys.One, () => {
this.drawcanvas.clearDraws()
});
}
//需要注意为了能触发onTouchMoved,onTouchStarted必须返回EventReply.handled
protected onTouchStarted(InGemotry :Geometry,InPointerEvent:PointerEvent) :EventReply{
return EventReply.handled; //EventReply.handled
}
//用onTouchMoved检测手指/鼠标移动,并且在移动前后的两点之间绘制线段
protected onTouchMoved(InGemotry :Geometry,InPointerEvent:PointerEvent) :EventReply{
console.log("onTouchMoved");
this.point1=absoluteToLocal(this.drawcanvas.tickSpaceGeometry,InPointerEvent.lastScreenSpacePosition)
this.point2=absoluteToLocal(this.drawcanvas.tickSpaceGeometry,InPointerEvent.screenSpacePosition)
this.drawcanvas.drawLines([this.point1,this.point2], this.lineDrawData1)
return EventReply.unHandled; //EventReply.handled
}
}
- 启动游戏后,在屏幕上绘制,可实现以下效果: