3. Canvas 绘画系统

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() 矩阵变换

持续更新中,请大家多多关注…

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山间点烟雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值