canvas绘制仪表盘刻度盘

news2025/2/25 8:47:57

canvas画布可以实现在网页上绘制图形的方法,比如图表、图片处理、动画、游戏等。今天我们在vue模板下用canvas实现仪表盘的绘制。

对canvas不熟悉的同学可以先了解下canvas的API文档:canvas API中文网 - Canvas API中文文档首页地图

一、创建模板,创建canvas标签

<template>
  <canvas ref="gauge"></canvas>
</template>

<script>
export default {
  name: 'Gauge',
  data() {
    return {
      width:220,    // 画布的宽度
      height:220,   // 画布的高度
      progress:0.6  // 值-进度
    }
  },
  mounted(){
    this.draw()
  },
  methods:{
    draw(){}
  },
}
</script>

二、初始化画布,并绘制背景圆弧

    draw(){
      // 获取canvas元素和上下文
      let canvas = this.$refs.gauge
      let ctx = canvas.getContext("2d")

      // 获取设备像素比,解决移动端显示锯齿、模糊等问题
      const dpr = window.devicePixelRatio || 1
      canvas.style.width = this.width + "px"
      canvas.style.height = this.height + "px"
      canvas.height = this.height * dpr
      canvas.width = this.width * dpr
      ctx.scale(dpr, dpr)

      // 清除画布--更新画布前需要清除之前的画布内容
      ctx.clearRect(0, 0, canvas.width, canvas.height)

      // 圆心位置-宽高的一半
      const centerX = this.width / 2
      const centerY = this.height / 2
      const startAngle = (3 * Math.PI) / 4   // 仪表盘的初始角度
      const endAngle = Math.PI / 4           // 仪表盘的结束角度
      const totalAngle = (3 * Math.PI) / 2   // 仪表盘的总角度

      // 绘制背景圆弧
      ctx.beginPath()
      ctx.arc(centerX, centerY, (this.width-20)/2, startAngle, endAngle)
      ctx.lineWidth = 16
      ctx.lineCap = 'round'
      ctx.strokeStyle = '#FAFAFA '
      ctx.stroke()

    }

详解:

1、仪表盘的初始角度、结束角度、总角度根据你需要的弧形进行配置。

可以参照arc api 的此图进行理解。

角度

180

270

360

初始角度

1 * Math.PI

(3 * Math.PI) / 4

0.5 * Math.PI

结束角度

0

Math.PI / 4

-0.5 * Math.PI

总角度

1 * Math.PI

(3 * Math.PI) / 2

2 * Math.PI

2、lineCap:设置或返回线条的结束端点样式;

butt

默认。向线条的每个末端添加平直的边缘。

round

向线条的每个末端添加圆形线帽。

square

向线条的每个末端添加正方形线帽。

三、绘制上层圆弧

      // 绘制上层圆弧
      const endAngle1 = startAngle + (totalAngle * this.progress)
      ctx.save()
      ctx.beginPath()
      ctx.arc(centerX, centerY, (this.width-20)/2, startAngle, endAngle1)
      ctx.lineWidth = 16
      ctx.lineCap = 'round'
      var gradient = ctx.createLinearGradient(0, this.height/2*Math.sqrt(2), this.width/2*Math.sqrt(2), 0);
      gradient.addColorStop(0, '#DDF5EC');
      gradient.addColorStop(1, '#04FACF');
      ctx.strokeStyle = gradient
      ctx.stroke()

详解:

1、颜色设置渐变,渐变色x轴、y轴的起点和终点。根据勾股定理计算为半径的平方根。

四、绘制刻度、刻度值

      // 绘制刻度
      ctx.save()
      // 将原点移到圆心处
      ctx.translate(centerX, centerY)
      const numTicks = 100 // 刻度数量
      let tickLength = 0  // 刻度长度
      let tickWidth = 0 // 刻度宽度
      const scaleRadius = (this.width-50)/2   // 刻度半径
      let angleStep = totalAngle / numTicks
      for (let i = 0; i <= numTicks; i++) {
        let angle = startAngle + (i * angleStep)
        if (i % 10 == 0) {
          tickWidth = 1*2   // 长刻度线的宽是小刻度的2倍
          tickLength = 6*1.5   // 长刻度线的长是小刻度的1.5倍
        } else {
          tickWidth = 1
          tickLength = 6
        }
        ctx.beginPath();
        ctx.lineWidth = tickWidth
        ctx.strokeStyle = '#cccccc'

        // 计算刻度起点和终点的坐标
        let startX = (scaleRadius - tickLength) * Math.cos(angle)
        let startY = (scaleRadius - tickLength) * Math.sin(angle)
        let endX = (scaleRadius) * Math.cos(angle)
        let endY = (scaleRadius) * Math.sin(angle)

        // 绘制刻度线段
        ctx.moveTo(startX, startY)
        ctx.lineTo(endX, endY)
        ctx.stroke()

        // 绘制刻度值文本
        let text = i % 10 == 0 ? i : ''
        let textX = (scaleRadius - 20) * Math.cos(angle)
        let textY = (scaleRadius - 20) * Math.sin(angle)
        ctx.font = "12px Arial"
        ctx.fillStyle = '#666666'
        ctx.textAlign = "center"
        ctx.textBaseline = "middle"
        ctx.fillText(text, textX, textY)
        
      }
      ctx.restore()

五、绘制指针

      // 绘制指针
      const angle = startAngle + (totalAngle * this.progress)
      let endX = (scaleRadius - 30) * Math.cos(angle)
      let endY = (scaleRadius - 30) * Math.sin(angle)
      ctx.save()
      ctx.translate(centerX, centerY)  // 将原点移到圆心处
      ctx.beginPath()
      
      ctx.moveTo(0, 0)
      ctx.lineTo(endX,endY)
      ctx.lineWidth = 3
      ctx.strokeStyle = '#F8E71C'
      ctx.stroke()
      ctx.restore()

六、绘制中心点

      // 绘制中心点
      ctx.save()
      ctx.beginPath()
      ctx.arc(centerX, centerY, 4, 0, 2*Math.PI)
      ctx.fillStyle = "#666666"
      ctx.fill()
      ctx.restore()

如有疑问,欢迎留言交流;

如有定制需求,欢迎私信沟通~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2264668.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

搭建Alist(Windows系统环境下的)并挂载阿里云盘open映射到公网

文章目录 前言1. 使用Docker本地部署Alist1.1 本地部署 Alist1.2 访问并设置Alist1.3 在管理界面添加存储 2. 安装cpolar内网穿透 前言 本文将讲解如何在 Windows 系统中借助 Docker 部署 Alist 这一强大的全平台网盘工具&#xff0c;并结合 cpolar 内网穿透&#xff0c;实现随…

【QT常用技术讲解】发送POST包(两种方式:阻塞方式及非阻塞方式)

前言 http/https(应用层)协议是广泛使用的网络通信协议。在很多与第三方API对接的场景中&#xff0c;通常是通过http/https协议完成&#xff0c;比如API对接时&#xff0c;通常要通过POST包获取access_token进行鉴权&#xff0c;然后再进行数据交互&#xff08;本篇也包含有对接…

【电商搜索】文档的信息论生成聚类

【电商搜索】文档的信息论生成聚类 目录 文章目录 【电商搜索】文档的信息论生成聚类目录文章信息概览研究背景技术挑战如何破局技术应用主要相关工作与参考文献后续优化方向 后记 文章信息 https://arxiv.org/pdf/2412.13534 概览 本文提出了一种基于信息论的生成聚类&#…

【数据结构与算法】排序算法(下)——计数排序与排序总结

写在前面 书接上文&#xff1a;【数据结构与算法】排序算法(中)——交换排序之快速排序 文章主要讲解计数排序的细节与分析源码。之后进行四大排序的总结。 文章目录 写在前面一、计数排序(非比较排序)代码的实现&#xff1a; 二、排序总结 2.1、稳定性 3.2、排序算法复杂度及…

Unity全局雾效

1、全局雾效是什么 全局雾效&#xff08;Global Fog&#xff09;是一种视觉效果&#xff0c;用于在3D场景中模拟大气中的雾气对远处物体的遮挡 它通过在场景中加入雾的效果&#xff0c;使得距离摄像机较远的物体看起来逐渐被雾气覆盖&#xff0c;从而创造出一种朦胧、模糊的视…

Kafka Streams 在监控场景的应用与实践

作者&#xff1a;来自 vivo 互联网服务器团队- Pang Haiyun 介绍 Kafka Streams 的原理架构&#xff0c;常见配置以及在监控场景的应用。 一、背景 在当今大数据时代&#xff0c;实时数据处理变得越来越重要&#xff0c;而监控数据的实时性和可靠性是监控能力建设最重要的一环…

数据分析思维(五):分析方法——假设检验分析方法

数据分析并非只是简单的数据分析工具三板斧——Excel、SQL、Python&#xff0c;更重要的是数据分析思维。没有数据分析思维和业务知识&#xff0c;就算拿到一堆数据&#xff0c;也不知道如何下手。 推荐书本《数据分析思维——分析方法和业务知识》&#xff0c;本文内容就是提取…

解读DiffusionNER: Boundary Diffusion for Named Entity Recognition

content 摘要1. 图1图21. 上方&#xff1a;扩散过程与实体边界2. 下方&#xff1a;网络结构&#xff08;Sentence Encoder Entity Decoder&#xff09;3. 关键思想小结 摘要 主要内容分为四个部分&#xff1a; 模型定位与基本原理&#xff1a; 提出了DiffusionNER模型将命名…

【QSS样式表 - ⑥】:QPushButton控件样式

文章目录 QPushBUtton控件样式QSS示例 QPushBUtton控件样式 常用子控件 常用伪状态 QSS示例 代码&#xff1a; QPushButton {background-color: #99B5D1;color: white;font-weigth: bold;border-radius: 20px; }QPushButton:hover {background-color: red; }QPushButton:p…

数字经济下的 AR 眼镜

目录 1. &#x1f4c2; AR 眼镜发展历史 1.1 AR 眼镜相关概念 1.2 市面主流 XR 眼镜 1.3 AR 眼镜大事记 1.4 国内外 XR 眼镜 1.5 国内 AR 眼镜四小龙 2. &#x1f531; 关键技术 2.1 AR 眼镜近眼显示原理 2.2 AR 眼镜关键技术 2.3 AR 眼镜技术难点 3. &#x1f4a…

smb和nfs双栈协议共享目录

1 简介 NFS和SAMBA协议都是文件共享&#xff0c;Linux客户端常用于NFS协议访问远程共享目录&#xff0c;Windows客户端常用于SAMBA协议访问远程共享目录。 2 环境 合计使用三台服务器&#xff0c;服务器都位于同一个子网&#xff08;10.0.0.0/19&#xff09;、同一个安全组…

Day13 用Excel表体验梯度下降法

Day13 用Excel表体验梯度下降法 用所学公式创建Excel表 用Excel表体验梯度下降法 详见本Day文章顶部附带资源里的Excel表《梯度下降法》&#xff0c;可以对照表里的单元格公式进行理解&#xff0c;还可以多尝试几次不同的学习率 η \eta η来感受&#xff0c;只需要更改学习率…

Python获取系统负载并打印折线图

#! /opt/py36/bin/python import psutil import matplotlib.pyplot as plt import time# 创建一个空列表&#xff0c;用于存储负载数据 load_data []# 循环收集负载数据 while True:# 获取当前系统负载load_avg psutil.getloadavg()# 将平均负载添加到load_data列表中load_da…

RCE 命令执行漏洞 过滤模式 基本的过滤问题 联合ctf题目进行实践

前言 知道RCE 命令执行分为 代码执行 和 命令执行 原理 &#xff1a; 就是用户的输入被当做命令或者代码执行了 从而造成了危害 代码执行 除了eval php代码执行漏洞的函数还有 eval()、a ssert()、 preg_replace()、 create_function()、 array_map()、 call_user_func(…

Leetcode打卡:考场就坐

执行结果&#xff1a;通过 题目&#xff1a; 855 考场就坐 在考场里&#xff0c;有 n 个座位排成一行&#xff0c;编号为 0 到 n - 1。 当学生进入考场后&#xff0c;他必须坐在离最近的人最远的座位上。如果有多个这样的座位&#xff0c;他会坐在编号最小的座位上。(另外&am…

数据结构(哈希表(上)纯概念版)

前言 在软件开发和计算机科学中&#xff0c;数据结构的选择直接影响到程序的性能和效率。不同的数据结构适用于不同的场景&#xff0c;合理地选择合适的数据结构是高效编程的关键之一。哈希表&#xff08;哈希表&#xff08;Hash Table&#xff09;作为一种高效的键值对存储结…

【机器学习与数据挖掘实战】案例06:基于Apriori算法的餐饮企业菜品关联分析

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈机器学习与数据挖掘实战 ⌋ ⌋ ⌋ 机器学习是人工智能的一个分支,专注于让计算机系统通过数据学习和改进。它利用统计和计算方法,使模型能够从数据中自动提取特征并做出预测或决策。数据挖掘则是从大型数据集中发现模式、关联…

深入解析 Spring WebFlux:原理与应用

优质博文&#xff1a;IT-BLOG-CN WebFlux 是 Spring Framework 5 引入的一种响应式编程框架&#xff0c;和Spring MVC同级&#xff0c;旨在处理高并发和低延迟的非阻塞应用。这是一个支持反应式编程模型的新Web框架体系。 顺便一提&#xff0c;Spring Cloud Gateway在实现上是…

C语言基础——指针(4)

一&#xff0e; 字符指针变量 字符指针变量的使用和整型指针变量的使用方法相似&#xff0c;以下是其基本使用方法的例子&#xff1a; &#xff08;1&#xff09;字符指针变量还有一种使用方法&#xff1a; const char* p "abcd" 需…

『 Linux 』高级IO (一)

文章目录 内容回顾及铺垫五种IO模型不同类型IO的区别非阻塞IOfcntl( ) 多路转接 - select( )select( ) 的基本使用 - SelectServer服务器 内容回顾及铺垫 在博客『 Linux 』基础IO/文件IO (万字)中介绍了对IO的认识; IO实际上为Input/Output,输入输出; 以网络协议栈的视角来看,…