7.畫布(Canvas)元素
** 注意: **
最新的構(gòu)建時間:2016/03/21
這章的源代碼能夠在assetts folder找到。
早在 Qt 4 引入 QML 時摄闸,是有一些關(guān)于 Qt Quick 需要一個橢圓的討論的云茸。如果要加入橢圓的話是目,那么是不是其他人可以提出加入其他的形狀,那么是不是也需要支持呢标捺?所以在 Qt Quick 中并沒有橢圓形只有矩形懊纳。如果我們在 Qt 4 中需要的話,則需要使用圖片或者編寫自己的 C++ 橢圓元素亡容。
為了支持腳本繪圖 Qt 5 引入了 Canvas 元素长踊。畫布元素提供了一個依賴于分辨率的位圖畫布,可用于圖形萍倡,游戲或使用 JavaScript 即時繪制其他可視圖像身弊。Canvas 元素基于 HTML5 的 Canvas 元素。
canvas 元素的基本思想是使用上下文 2D 對象來渲染路徑列敲。 上下文 2D 對象包含必要的圖形功能阱佛,而畫布則作為繪圖畫布。2D 上下文支持筆畫戴而,填充凑术,漸變,文本和不同的路徑創(chuàng)建命令集所意。
我們來看一個簡單的路徑圖的例子:
import QtQuick 2.5
Canvas {
id: root
// canvas size
width: 200; height: 200
// handler to override for drawing
onPaint: {
// get context to draw with
var ctx = getContext("2d")
// setup the stroke
ctx.lineWidth = 4
ctx.strokeStyle = "blue"
// setup the fill
ctx.fillStyle = "steelblue"
// begin a new path to draw
ctx.beginPath()
// top-left start point
ctx.moveTo(50,50)
// upper line
ctx.lineTo(150,50)
// right line
ctx.lineTo(150,150)
// bottom line
ctx.lineTo(50,150)
// left line through path closing
ctx.closePath()
// fill using fill style
ctx.fill()
// stroke using line width and stroke style
ctx.stroke()
}
}
這產(chǎn)生一個填充的矩形淮逊,起始點(diǎn)為 50,50催首,大小為 100,筆畫用作邊框裝飾泄鹏。
筆畫寬度設(shè)置為 4郎任,并使用由 strokeStyle 定義的藍(lán)色。最終的形狀被設(shè)置為通過 fillStyle 填充的“steelblue” 顏色备籽。只有通過調(diào)用 stroke 或 fill 實(shí)際路徑才能繪制出來舶治,可以獨(dú)立使用。調(diào)用 stroke 或 fill 將繪制當(dāng)前路徑车猬。不能存儲路徑以供稍后重用霉猛,繪制狀態(tài)只能存儲(stored)和還原(restored)。
在 QML 中珠闰,Canvas 元素充當(dāng)繪圖的容器惜浅。 2D 上下文對象提供實(shí)際繪圖操作。實(shí)際繪圖需要在 onPaint 事件處理程序中完成伏嗜。
Canvas {
width: 200; height: 200
onPaint: {
var ctx = getContext("2d")
// setup your path
// fill or/and stroke
}
}
畫布本身提供了典型的二維笛卡爾坐標(biāo)系坛悉,其中左上角是(0,0)點(diǎn)。y 值隨著向下增加而增加阅仔,x 值隨著向右移動增加吹散。
基于路徑的 API 的典型命令順序如下:
- 設(shè)置筆觸弧械、填充或筆觸和填充同時設(shè)置
- 創(chuàng)建路徑
- 設(shè)置筆觸八酒、填充或筆觸和填充同時設(shè)置
onPaint: {
var ctx = getContext("2d")
// setup the stroke
ctx.strokeStyle = "red"
// create a path
ctx.beginPath()
ctx.moveTo(50,50)
ctx.lineTo(150,50)
// stroke path
ctx.stroke()
}
這產(chǎn)生從點(diǎn) P1(50,50) 到點(diǎn) P2(150,50) 的水平劃線。
** 注意: **
通常刃唐,我們總是希望在重置路徑時設(shè)置一個起點(diǎn)羞迷,因此在 beginPath 之后的第一個操作通常是 moveTo。
7.1 便捷的 API
對于矩形操作画饥,提供方便的API衔瓮,直接調(diào)用筆觸或填充進(jìn)行繪制。
// convenient.qml
import QtQuick 2.5
Canvas {
id: root
width: 120; height: 120
onPaint: {
var ctx = getContext("2d")
ctx.fillStyle = 'green'
ctx.strokeStyle = "blue"
ctx.lineWidth = 4
// draw a filles rectangle
ctx.fillRect(20, 20, 80, 80)
// cut our an inner rectangle
ctx.clearRect(30,30, 60, 60)
// stroke a border from top-left to
// inner center of the larger rectangle
ctx.strokeRect(20,20, 40, 40)
}
}
** 注意: **
行程區(qū)域延伸各占路徑兩側(cè)線寬的一半抖甘。4 px lineWidth 將在路徑外面繪制 2 像素热鞍,內(nèi)部 2 像素。
7.2 漸變
畫布可以使用顏色的形狀填充衔彻,但也可以使用漸變或圖片薇宠。
onPaint: {
var ctx = getContext("2d")
var gradient = ctx.createLinearGradient(100,0,100,200)
gradient.addColorStop(0, "blue")
gradient.addColorStop(0.5, "lightsteelblue")
ctx.fillStyle = gradient
ctx.fillRect(50,50,100,100)
}
該示例中的漸變沿著起始點(diǎn)(100,0)到終點(diǎn)(100,200)定義,這在畫布的中間給出了一條垂直線艰额。 梯度停止可以定義為從0.0(漸變起始點(diǎn))到1.0(漸變終點(diǎn))的顏色澄港。 這里我們在位置 0.0(100,0) 使用顏色“blue”,在位置 0.5(100,200) 使用顏色“l(fā)ightsteelblue”柄沮。漸變的范圍比我們要繪制的矩形大得多回梧,因此矩形將漸變剪切和限定在其形狀范圍內(nèi)废岂。
** 注意: **
漸變要在畫布坐標(biāo)中定義,而不是相對于要繪制的路徑的坐標(biāo)狱意。畫布沒有相對坐標(biāo)的概念湖苞,就像現(xiàn)在我們在 QML 中使用的那樣。
7.3 陰影
可以使用 2D 上下文對象的陰影來增強(qiáng)路徑的顯示效果髓涯。陰影是路徑周圍的區(qū)域袒啼,具有偏移,顏色和指定的模糊纬纪。為此蚓再,我們可以指定一個 shadowColor、shadowOffsetX包各、shadowOffsetY 和 shadowBlur摘仅。 所有這一切都需要使用 2D 上下文來定義。 2D 上下文是我們唯一的繪圖操作 API问畅。
也可以使用陰影在路徑周圍創(chuàng)建輝光效果娃属。在下一個例子中,我們創(chuàng)建一個文字“Canvas”护姆,周圍有白色的光暈矾端。 所有這一切都在黑暗的背景下,以提高可見度卵皂。
首先我們畫出黑暗的背景:
// setup a dark background
ctx.strokeStyle = "#333"
ctx.fillRect(0,0,canvas.width,canvas.height);
然后秩铆,我們定義我們的陰影配置,它將用于下一個路徑的顯示:
// setup a blue shadow
ctx.shadowColor = "#2ed5fa";
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
ctx.shadowBlur = 10;
最后灯变,我們使用 Ubuntu 字體系列中的一個大膽的 80px 大小的字體繪制 “Canvas” 文本殴玛。
// render green text
ctx.font = 'bold 80px Ubuntu';
ctx.fillStyle = "#24d12e";
ctx.fillText("Canvas!",30,180);
下面是其顯示效果: