接着上一章的內容,本章繼續進行后續畫圖相關操作。
一、漸變填充
Canvas支持3種漸變:線性漸變、輻射漸變、錐形漸變。
1.1 線性漸變
- createLinearGradient(real x0, real y0, real x1, real y1),返回一個CanvasGradient對象,該對象表示線性漸變,該漸變沿起點(x0,y0)和終點(x1,y1)之間的線過渡顏色;
- addColorStop函數添加漸變點;
下面看一個示例:
import QtQuick 2.12 Canvas { width:120; height: 120 onPaint: { var ctx = getContext("2d") ctx.lineWidth = 2 var linear = ctx.createLinearGradient(10, 10, 100, 10) linear.addColorStop(0, "white") linear.addColorStop(0.5, "#FF00FF") linear.addColorStop(1, "#333333") ctx.fillStyle = linear ctx.fillRect(10, 10, 100, 100) ctx.strokeRect(10, 10, 100, 100) } }
運行結果如下:
1.2 輻射漸變
- createRadialGradient(real x0, real y0, real r0, real x1, real y1, real r1),返回一個CanvasGradient對象,該對象表示一個輻射漸變,該漸變沿由起始圓(x0,y0)和半徑r0以及終止圓的原點(x1,y1)和半徑r1給出的圓錐進行繪制。
- addColorStop函數添加漸變點;
下面看一個示例:
import QtQuick 2.12 Canvas { width:120; height: 120 onPaint: { var ctx = getContext("2d") ctx.lineWidth = 2 var radial = ctx.createRadialGradient(30, 70, 5, 60, 50, 80) radial.addColorStop(0, "white") radial.addColorStop(0.5, "#FF00FF") radial.addColorStop(1, "#333333") ctx.fillStyle = radial ctx.fillRect(10, 10, 100, 100) ctx.strokeRect(10, 10, 100, 100) } }
運行效果如下:
1.3 錐形漸變
-
createConicalGradient(real x, real y, real angle),返回一個CanvasGradient對象,該對象表示一個圓錐形漸變,該圓錐形漸變圍繞中心點(x,y)沿逆時針方向插入顏色,起始角度以弧度為單位。
- addColorStop函數添加漸變點;
下面看一個示例:
import QtQuick 2.12 Canvas { width:120; height: 120 onPaint: { var ctx = getContext("2d") var conical = ctx.createConicalGradient(60, 60, Math.PI / 4) conical.addColorStop(0, "white") conical.addColorStop(0.5, "#FF00FF") conical.addColorStop(1, "#333333") ctx.fillStyle = conical ctx.fillRect(10, 10, 100, 100) ctx.strokeRect(10, 10, 100, 100) } }
運行效果如下:
二、陰影
shadowOffsetX:陰影在x軸方向偏移
shadowOffsetY:陰影在y軸方向偏移
下面看一個示例:
import QtQuick 2.12 Canvas { width:500; height: 200 onPaint: { var ctx = getContext("2d") ctx.fillStyle = "grey" ctx.save() ctx.shadowBlur = 20 ctx.shadowColor = "blue" ctx.fillRect(60, 30, 100, 100) ctx.restore() ctx.save(); ctx.shadowBlur = 20 ctx.shadowColor = "green" ctx.shadowOffsetX = 15 ctx.shadowOffsetY = 15 ctx.fillRect(200, 30, 100, 100) ctx.restore() ctx.fillRect(350, 30, 100, 100) } }
運行效果如下:
三、使用圖像
在Canvas種可以直接使用已經存在的圖形,Context2D類型提供了drawImage函數用於繪制圖形,該函數提供3個重載版本;
- 將image繪制在Canvas上,圖像左上角位於(dx,dy)處
- 將image繪制在矩形(dx,dy,dw,dh)上
- 將image的矩形(sx,sy,sw,sh)繪制在Canvas的矩形(dx,dy,dw,dh)上
下面看一個示例:
import QtQuick 2.12 Rectangle { width: 300; height: 180 Canvas { id: canvas anchors.fill: parent onImageLoaded: { if (canvas.isImageError("http://www.baidu.com/img/bdlogo.gif")) { console.log("Image failed to load!") } var ctx = getContext("2d") ctx.drawImage("http://www.baidu.com/img/bdlogo.gif", 0, 0, 270, 129) canvas.requestPaint() } } Component.onCompleted: { canvas.loadImage("http://www.baidu.com/img/bdlogo.gif") } }
運行效果如下:
四、坐標轉換
Context2D提供的圖形變換全部是仿射變換:平移、縮放、旋轉和扭曲,根據計算機圖形學原理,所有的仿射變換都歸結於矩陣乘法,Context2D提供了如下兩個函數:
- setTransform(real a, real b, real c, real d, real e, real f):將轉換矩陣更改為參數指定的矩陣,替換舊的變換矩陣;
- transform(real a, real b, real c, real d, real e, real f):通過將給定的變換矩陣乘以當前矩陣,將其應用於當前矩陣;
二者關聯:setTransform(a,b,c,d,e,f)方法實際上將當前變換重置為單位矩陣,然后使用相同的參數調用transform(a,b,c,d,e,f)方法。
HTML Canvas 2D上下文規范將轉換矩陣定義為:
a是x軸方向的縮放因子;
c是x軸方向的斜切因子;
e是x軸方向的平移因子;
b是y軸方向的縮放因子;
d是y軸方向的斜切因子;
f是y軸方向的平移因子;
比例因子和偏斜因子是倍數; e和f是坐標空間單位,就像平移(x,y)方法中的單位一樣。
4.1 平移
使用translate函數進行坐標軸的平移,translate(x,y)等價於transform(1,0,0,1,x,y)。
下面看一個示例:
import QtQuick 2.12 Canvas { width: 150; height: 150 onPaint: { var ctx = getContext("2d") ctx.fillRect(10, 10, 50, 50) ctx.strokeText("1", 30, 40) ctx.translate(70, 60); ctx.fillRect(10, 10, 50, 50) ctx.strokeText("2", 30, 40) } }
運行效果如下:
4.2 縮放
使用scale函數進行縮放,scale(x,y)等價於transform(a*x,0,0,b*y,0,0)。
下面看一個示例:
import QtQuick 2.12 Canvas { width: 150; height: 150 onPaint: { var ctx = getContext("2d") ctx.fillRect(10, 10, 50, 50) ctx.strokeText("1", 30, 40) ctx.translate(70, 0) ctx.scale(0.5, 0.5) ctx.fillRect(10, 10, 50, 50) ctx.strokeText("2", 30, 40) } }
運行效果如下:
4.3 旋轉
使用rotate函數進行旋轉,rotate(x)是將坐標軸順時針旋轉x,等價於transform(cos(x),sin(x),-sin(x),cos(x),0,0)。
旋轉后的變換矩陣如下:
下面看一個示例:
import QtQuick 2.12 Canvas { width: 150; height: 150 onPaint: { var ctx = getContext("2d") ctx.fillRect(10, 10, 50, 50) ctx.strokeText("1", 30, 40) ctx.translate(100, 0) ctx.rotate(Math.PI / 4) ctx.fillRect(10, 10, 50, 50) ctx.strokeText("2", 30, 40) } }
運行效果如下:
4.4 斜切
斜切也就是扭曲,使用shear函數進行斜切,shear(x,y)等價於transform(1,b*y,c*x,1,0,0)。
下面看一個示例:
import QtQuick 2.12 Canvas { width: 170; height: 150 onPaint: { var ctx = getContext("2d") ctx.fillRect(10, 10, 50, 50) ctx.strokeText("1", 30, 40) ctx.translate(70, 0) ctx.shear(0.5, 0.5) ctx.fillRect(10, 10, 50, 50) ctx.strokeText("2", 30, 40) } }
運行效果如下: