当前位置: 首页 > article >正文

canvas绘制仪表盘刻度盘

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.kler.cn/a/449283.html

相关文章:

  • 数据结构---------二叉树前序遍历中序遍历后序遍历
  • 【YashanDB知识库】jdbc查询st_geometry类型的数据时抛出YAS-00101错误
  • linux socket编程之udp_dict_serve服务端--引入配置文件
  • 任务2 配置防火墙firewalld
  • 数据分析思维(五):分析方法——假设检验分析方法
  • 【机器学习与数据挖掘实战】案例06:基于Apriori算法的餐饮企业菜品关联分析
  • WorkManager
  • Centos8安装源出错 设置基础软件仓库出错(已解决-秒解)
  • ubuntu 安装docker
  • 【枚举】假币问题
  • 《Vue进阶教程》第十六课:深入完善响应式系统之单例模式
  • 从0到1手写实现Event Emitter
  • 关于Buildroot如何配置qtwebengine [未能成功编译]
  • 面试题整理15----K8s常见的网络插件有哪些
  • 对于其他管理的理解(中)
  • 【Flink-scala】DataSet编程模型介绍及数据源
  • Pytorch | 从零构建ParNet/Non-Deep Networks对CIFAR10进行分类
  • 在FreeRTOS中动态创建任务,假如在最后一个参数写NULL,该任务有任务句柄吗
  • 安装管理docker
  • 重温设计模式--享元模式
  • 路由器做WPAD、VPN、透明代理中之间一个
  • CSS系列(24)-- 打印样式详解
  • 基于JAVA_JSP电子书下载系统的设计与实现【源码+文档+部署讲解】
  • 设计模式详解(十二):单例模式——Singleton
  • 如何注册和使用Facebook企业号
  • uniapp验证码