15. Canvas制作汽车油耗仪表盘

1. 说明

本篇文章在14. 利用Canvas组件制作时钟的基础上进行一些更改,想查看全面的代码可以点击链接查看即可。

效果展示:

2. 整体代码

cpp 复制代码
import QtQuick 2.15
import QtQuick.Controls 2.15

Item{
    id:root
    implicitWidth: 400
    implicitHeight: implicitWidth

    // 尺寸属性
    property real outerCircleRadius:root.width / 2.05
    property real innerCircleRadius:root.width / 2.05

    // 颜色属性
    property color bgColor:Qt.rgba(0,0,0,0)
    property color outerColor:"black"
    property color innerColor:"black"
    property color innerRootColor:"lightSlateGray"
    property color innerLineColorL:Qt.rgba(1,1,1,1)
    property color innerLineColorS:Qt.rgba(1,1,1,0.8)
    property color textColor:"white"
    property color secondLineColor:"red"

    // 指针
    property var seconds
    property alias secondsAngle:secondLine.angle

    // 绘制背景
    Canvas{
        id:bgCircle
        width: root.width
        height: root.height
        anchors.centerIn: parent
        onPaint: {
            // 绘制背景
            var ctx = getContext("2d")  
            ctx.save()
            ctx.lineWidth = root.width/50   
            ctx.fillStyle = bgColor
            ctx.beginPath()
            ctx.arc(root.width/2,root.height/2,outerCircleRadius,Math.PI * (5/6),Math.PI * (1/6))
            ctx.fill()
            ctx.restore()
        }
    }
    // 绘制圆环轮廓
    Canvas{
        id:outerCircle
        width: root.width
        height: root.height
        anchors.centerIn: parent
        onPaint: {
            var ctx = getContext("2d")  //创建画师
            //为画师创建画笔并设置画笔属性
            ctx.lineWidth = root.width/50   //设置画笔粗细
            ctx.strokeStyle = outerColor    //设置画笔颜色
            ctx.beginPath()     //每次绘制调用此函数,重新设置一个路径
            // 按照钟表刻度进行划分,一圈是Math.PI * 2,分成12个刻度,每个刻度占用 1/6
            // canvas绘制圆弧,是按照顺时针绘制,起点默认在三点钟方向
            ctx.arc(root.width/2,root.height/2,outerCircleRadius,Math.PI * (5/6),Math.PI * (1/6))
            ctx.stroke()    //根据strokeStyle对边框进行描绘
        }
    }
    // 绘制秒针线
    Canvas{
        id:secondLine
        width: root.width
        height: root.height
        anchors.centerIn: parent
        property real angle:Math.PI * (8/6)
        onPaint: {
            var ctx = getContext("2d")
            ctx.clearRect(0,0,width,height)
            ctx.save()
            ctx.beginPath()
            ctx.lineWidth = root.width/100
            ctx.strokeStyle=secondLineColor
            // 平移坐标点(注意:坐标系原点先平移,再旋转)
            ctx.translate(root.width/2,root.height/2)
            // 旋转坐标系
            ctx.rotate(angle)
            // 坐标原点变化之后再进行实际的绘图
            ctx.moveTo(0,-10);
            ctx.lineTo(0,outerCircleRadius / 1.5);
            ctx.stroke()
            ctx.restore()
        }
    }
    // 绘制圆环内衬
    Canvas{
        id:innerCircle
        width: root.width
        height: root.height
        anchors.centerIn: parent
        property real endAngle:Math.PI * (12/6)
        onPaint: {
            var ctx = getContext("2d")  
            ctx.save()
            ctx.lineWidth = root.width/50   
            ctx.strokeStyle = innerColor     
            ctx.beginPath()     
            ctx.arc(root.width/2,root.height/2,innerCircleRadius,Math.PI * (5/6),Math.PI * (1/6))
            ctx.stroke()    
            ctx.restore()

            // 绘制指针根部圆圈
            ctx.save()
            ctx.lineWidth = root.width/50   
            ctx.fillStyle = innerRootColor
            ctx.beginPath()
            ctx.arc(root.width/2,root.height/2,innerCircleRadius/8,0,endAngle)
            ctx.fill()
            ctx.restore()
        }
    }
    // 绘制刻度线
    Canvas{
        id:innerLine
        width: root.width
        height: root.height
        anchors.centerIn: parent
        property real lineNums:60
        onPaint: {
            var ctx = getContext("2d")  
            for (var i = 0; i <= lineNums; ++i){
                if(i > 5 && i < 25){
                    continue
                }
                ctx.beginPath();
                var angle = 2 * Math.PI / 60 * i;
                var dx = Math.cos(angle)*(outerCircleRadius-15);
                var dy = Math.sin(angle)*(outerCircleRadius-15);
                var dx2 = Math.cos(angle)*(outerCircleRadius-7);
                var dy2 = Math.sin(angle)*(outerCircleRadius-7);
                if (i % 5 === 0 && i != 25 && i != 30){
                    ctx.lineWidth = root.width/100
                    ctx.strokeStyle = innerLineColorL
                }else if(i >= 25 && i <= 30){
                    ctx.strokeStyle = "red"
                }
                else{
                    ctx.lineWidth = root.width/200
                    ctx.strokeStyle = innerLineColorS
                }
                ctx.moveTo(root.width/2+dx,root.height/2+dy);
                ctx.lineTo(root.width/2+dx2,root.height/2+dy2);
                ctx.stroke();
            }
        }
    }
    // 绘制数字
    Canvas{
        id:drawText
        width: root.width
        height: root.height
        anchors.centerIn: parent
        property var numbers : [1,2,3,4,5,6,7,8,9,10,11,12]
        onPaint: {
            var ctx = getContext("2d")
            ctx.font = "18px Arial";
            ctx.textAlign = "center";
            ctx.textBaseline = "middle";
            for(var i = 0; i < 12; ++i)
            {
                ctx.fillStyle = textColor
                var angle = 2 * Math.PI / 12 * numbers[i] - 3.14 / 2;
                var dx = Math.cos(angle)*(outerCircleRadius-35);
                var dy = Math.sin(angle)*(outerCircleRadius-35);
                switch(i){
                case 3:
                    ctx.fillText(1,root.width/2 + dx,root.height / 2 + dy);
                    ctx.fill()
                    break
                case 7:
                    ctx.fillText(0,root.width/2 + dx,root.height / 2 + dy);
                    ctx.fill()
                    break
                case 11:
                    ctx.fillText("1/2",root.width/2 + dx,root.height / 2 + dy);
                    ctx.fill()
                    break
                default:
                    break
                }
            }
        }
    }
    Image{
        id:iconImg
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.top: parent.top
        anchors.topMargin: 5
        scale: 0.25
        source: "qrc:/油箱.png"
    }
}
相关推荐
某公司摸鱼前端2 天前
推荐 uniapp 相对好用的海报生成插件
小程序·uni-app·canvas
&活在当下&5 天前
js 实现视频封面截图
前端·javascript·音视频·canvas
xachary10 天前
前端使用 Konva 实现可视化设计器(23)- 绘制曲线、属性面板
前端·canvas·konva
Jiaberrr10 天前
微信小程序教程:如何在个人中心实现头像贴纸功能
前端·微信小程序·小程序·canvas·头像
xiangxiongfly91510 天前
微信小程序-canvas
微信小程序·小程序·canvas
胡西风_foxww11 天前
canvas分享,从入门到入门。
javascript·教程·canvas·入门·分享
爱搞事的程小猿20 天前
4.qml单例模式
单例模式·js·qml
梦起丶21 天前
Qml 实现星级评分组件 已发布
qt·ui·控件·qml
梦起丶22 天前
Qml 实现水波进度动画条
qt·ui·控件·qml