1. Canvas介绍
在QML中自定义控件,除了使用基本的控件组合创建封装成单独的 .qml 文件之外,还可使用 canvas 绘画控件进行绘制,这个控件就相当于是一个画布,需要什么样式就绘制什么样式即可。
2. 常用名词介绍
画布:Canvas 控件本身即为画布,下面的简易代码就是定义了一个画布
Canvas {
width: 320
height: 320
}
画师:Context2D,可以通过 getContext(“2d”) 来创建画师,也就是在画布上绘画的“人”。
画笔:也就是画师用的,可以立即为是赋予画师的一些功能或者属性,比如 lineWidth 属性,strokeStyle 属性赋予画师一些特征,就是画师手中的画笔。
画刷:当画师使用画笔在画布上绘制完成形状之后,如果需要对绘制的形状进行区域填充,就可使用画刷,也就是画师的 fillStyle 属性。
3. 基本绘图框架
Canvas是继承子Item的,在窗口中使用 width 和 height 属性定义了一个画布区域之后,需要在 onPaint()信号中进行绘制,基本框架如下(例如:绘制一个红色边框的蓝色矩形):
//Canvas学习
Canvas{ //定义画布
width: 300
height: 300
anchors.centerIn: parent
onPaint: {
var ctx = getContext("2d") //创建画师
//为画师创建画笔并设置画笔属性
ctx.lineWidth = 1 //设置画笔粗细
ctx.strokeStyle = "red" //设置画笔颜色
ctx.fillStyle = "lightblue" //设置填充颜色
ctx.beginPath() //启动绘制
ctx.rect(100,80,120,80) //绘制矩形,左上角原点为(100,80),宽度为120,高度为80
ctx.fill() //根据fillStyle对区域进行填充
ctx.stroke() //根据strokeStyle对边框进行描绘
}
}
4. 效果如下:
5. 常用绘制路径函数
ctx.moveTo() 移动画笔到画布中的某一坐标点
ctx.lineTo() 从当前坐标点绘制一条直线到指定坐标点
ctx.arcTo() 从当前坐标点绘制一条弧线到指定坐标点
ctx.rect() 绘制矩形
ctx.arc() 绘制弧形
ctx.ellipse() 绘制椭圆
ctx.text() 绘制纯文本
ctx.strokeText() 绘制文本,并用strokeStyle对文本边框进行描绘
ctx.fillText() 绘制文本,并用fillStyle对文本进行填充
ctx.drawImage() 绘制图片
6. 注意事项
6.1 fillStyle 和 strokeStyle 可以使用渐变色进行赋值
createLinearGradient(x1,y1,x2,y2) 线性渐变对象:x1,y1渐变起点,x2,y2渐变终点
createRadialGradient(x1,y1,r1,x2,y2,r2) 放射渐变对象:x1,y1渐变圆形的起点,r1起点渐变圆形的半径,x2,y2渐变圆形的终点,r2终点渐变原型的半径
addColorStop() 在渐变路径上添加关键点颜色
var gradient = ctx.createLinearGradient(60,50,180,130)
gradient.addColorStop(0.0,Qt.rgba(1,0,0,1.0))
gradient.addColorStop(1.0,Qt.rgba(0,0,1,1.0))
ctx.fillStyle = gradient
var gradient = ctx.createRadialGradient(60,50,20,180,130,30)
gradient.addColorStop(0.0,Qt.rgba(1,0,0,1.0))
gradient.addColorStop(1.0,Qt.rgba(0,0,1,1.0))
ctx.fillStyle = gradient
6.2 ctx.beginPath() 和 ctx.closePath() 开始和结束绘制
在绘制时,ctx.beginPath() 函数一般时必须设置的,表示开始启动绘制,但 ctx.closePath() 函数并非需要的,如果使用自带的绘制路径的函数,它可以自动完成区域封闭,那么在结尾调用 ctx.fill() 或者 ctx.stroke() 函数即可,如果绘制的路径不能自动封闭,比如绘制一个三角线,但是只绘制了两条边,第三条边可以使用 ct.closePath() 函数让两条线的首尾端点自动闭合,然后再使用 ctx.fill() 或者 ctx.stroke() 函数进行区域填充和描边处理。
6.3 ctx.save() 和 ctx.restore() 保存和恢复画布状态
绘制图形时,如果某一次绘制需要对原点进行移动或者旋转缩放等操作,但下一次的绘制有需要新的原点状态,此时就需要对画布的当前状态使用 save() 函数进行保存,一般情况下保存的都是最原始的画布状态,然后改变画布状态进行绘制,当前绘制结束后需要恢复画布状态到之前,使用 restore()函数,然后再进行下一次绘制前还是需要先保存当前画布状态,依次类推…
例如下面绘制同心圆的代码:
import QtQuick 2.2
Canvas{
width:300
height:300
contextType:"2d" //使用另一种方式创建画师
onPaint:{
context.lineWidth = 2
context.strokeStyle = "blue"
context.fillStyle = "red"
//第一次绘制
context.save() //变换前先保存当前画布状态,方便后面二次绘制时恢复
context.translate(width/2,height/2)
context.beginPath()
context.arc(0,0,30,0,Math.PI*2)
context.arc(0,0,50,0,Math.PI*2)
context.arc(0,0,70,0,Math.PI*2)
context.arc(0,0,90,0,Math.PI*2)
context.stroke()
context.restore() //绘制结束后将画布恢复到之前的状态
//第二次绘制
context.save() //同样需要先保存当前画布状态,便于后面恢复
context.translate(width/2,30)
context.font = "26px serif"
context.textAlign = "center"
context.fillText("同心圆",0,0)
context.restore() //恢复画布状态,方便下次绘制时状态转换
// .....
}
}
实际效果:
7. 变换
变换常用函数:
ctx.translate() 平移,针对坐标原点
ctx.rotate() 旋转
ctx.scale() 缩放
ctx.shear() 错切
ctx.clip() 裁切(后面的东西不会再显示)
ctx.setTransform() 矩阵变换