为了使用脚本化的绘图机制,Qt 5 引入的元素。Canvas
元素提供了一种与分辨率无关的位图绘制机制。通过Canvas
,你可以使用 JavaScript 代码进行绘制。如果熟悉 HTML5 的话,Qt Quick 的Canvas
元素与 HTML5 中的Canvas
元素如出一辙。
Canvas
元素的基本思想是,使用一个 2D 上下文对象渲染路径。这个 2D 上下文对象包含所必须的绘制函数,从而使Canvas
元素看起来就像一个画板。这个对象支持画笔、填充、渐变、文本以及其它一系列路径创建函数。
下面我们看一个简单的路径绘制的例子:
上面的代码将在左上角为 (50, 50) 处,绘制一个长和宽均为 100 像素的矩形。这个矩形使用钢铁蓝填充,并且具有蓝色边框。程序运行结果如下所示:
在 QML 中,Canvas
元素就是一种绘制的容器。2D 上下文对象作为实际绘制的执行者。绘制过程必须在onPaint
事件处理函数中完成。下面即一个代码框架:
- Canvas {
- width: 200; height: 200
- onPaint: {
- var ctx = getContext("2d")
- // 设置绘制属性
- // 开始绘制
- }
- }
Canvas
本身提供一个典型的二维坐标系,原点在左上角,X 轴正方向向右,Y 轴正方向向下。使用Canvas
进行绘制的典型过程是:
- 设置画笔和填充样式
- 创建路径
- 应用画笔和填充
例如:
上面这段代码运行结果应该是一个从 (50, 50) 开始,到 (150, 50) 结束的一条红色线段。
由于我们在创建路径之前会将画笔放在起始点的位置,因此,在调用beginPath()
函数之后的第一个函数往往是。
除了自己进行路径的创建之外,Canvas
还提供了一系列方便使用的函数,用于一次添加一个矩形等,例如:
- import QtQuick 2.0
- Canvas {
- width: 120; height: 120
- onPaint: {
- var ctx = getContext("2d")
- ctx.fillStyle = 'green'
- ctx.strokeStyle = "blue"
- ctx.lineWidth = 4
- // 填充矩形
- ctx.fillRect(20, 20, 80, 80)
- // 裁减掉内部矩形
- ctx.clearRect(30,30, 60, 60)
- // 从左上角起,到外层矩形中心绘制一个边框
- ctx.strokeRect(20,20, 40, 40)
- }
- }
Canvas
元素可以使用颜色进行填充,同样也可以使用渐变。例如下面的代码:
运行结果如下所示:在这个例子中,渐变的起始点位于 (100, 0),终止点位于 (100, 200)。注意这两个点的位置,这两个点实际创建了一条位于画布中央位置的竖直线。渐变类似于插值,可以在 [0.0, 1.0] 区间内插入一个定义好的确定的颜色;其中,0.0 意味着渐变的起始点,1.0 意味着渐变的终止点。上面的例子中,我们在 0.0 的位置(也就是渐变起始点 (100, 0) 的位置)设置颜色为“blue”;在 1.0 的位置(也就是渐变终止点 (100, 200) 的位置)设置颜色为“lightsteelblue”。注意,渐变的范围可以大于实际绘制的矩形,此时,绘制出来的矩形实际上裁减了渐变的一部分。因此,渐变的定义其实是依据画布的坐标,也不是定义的绘制路径的坐标。
路径可以使用阴影增强视觉表现力。我们可以把阴影定义为一个围绕在路径周围的区域,这个区域会有一定的偏移、有一定的颜色和特殊的模糊效果。我们可以使用shadowColor
属性定义阴影的颜色;使用shadowOffsetX
属性定义阴影在 X 轴方向的偏移量;使用shadowOffsetY
属性定义阴影在 Y 轴方向的偏移量;使用shadowBlur
属性定义阴影模糊的程度。不仅是阴影,利用这种效果,我们也可以实现一种围绕在路径周边的发光特效。下面的例子中,我们将创建一个带有发光效果的文本。为了更明显的显示发光效果,其背景界面将会是深色的。下面是相应的代码:
- import QtQuick 2.0
- id: root
- width: 280; height: 120
- onPaint: {
- var ctx = getContext("2d")
- // 背景矩形
- ctx.strokeStyle = "#333"
- ctx.fillRect(0, 0, root.width, root.height);
- // 设置阴影属性
- ctx.shadowColor = "blue";
- ctx.shadowOffsetX = 2;
- ctx.shadowOffsetY = 2;
- ctx.shadowBlur = 10;
- // 设置字体并绘制
- ctx.font = 'bold 80px sans-serif';
- ctx.fillStyle = "#33a9ff";
- ctx.fillText("Earth", 30, 80);
- }
首先,我们利用 #333 填充了一个背景矩形。矩形的起始点位于原点,长度和宽度分别绑定到画布的长度和宽度。接下来定义阴影的属性。最后,我们设置文本字体为 80 像素加粗的 sans-serif,会绘制了“Earth”单词。代码运行结果如下所示:注意观察字母旁边的发光效果,这其实是使用阴影制作的。
Canvas
元素支持从多种源绘制图像。为了绘制图像,需要首先加载图像;使用Component.onCompleted
事件处理函数可以达到这一目的: