js:使用canvas画一个半圆

news2024/9/29 5:24:39

背景

需求需要画一个半圆,或者多半圆,其实一下子就能想到 canvas 中的圆弧,核心使用 context.arc

context.arc(x,y,r,sAngle,eAngle,counterclockwise)

在这里插入图片描述
在这里插入图片描述

接下来我们看看示例

例一

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>

<canvas id="myCanvas" width="400" height="400"></canvas>

<script>
  const canvas = document.getElementById('myCanvas');
  const context = canvas.getContext('2d');
  const width = canvas.width;
  const height = canvas.height;
  const angle = 50; // 你的角度值
  const score = 50; // 你的分数值

  // 外层圆环
  context.beginPath();
  context.arc(width / 2, height - 20, width / 2 - 30, 1 * Math.PI, 2 * Math.PI);
  context.lineWidth = 4;
  context.lineCap = 'round';
  context.strokeStyle = '#DEDEDE';
  context.stroke();

  // 外层进度圆环
  context.beginPath();
  context.arc(width / 2, height - 20, width / 2 - 30, 1 * Math.PI, (1 + angle / 100) * Math.PI);
  context.lineWidth = 4;
  context.lineCap = 'round';
  const gnt1 = context.createLinearGradient(0, 0, 180, 0);
  gnt1.addColorStop(0, '#8ce459');
  gnt1.addColorStop(1, '#62af35');
  context.strokeStyle = gnt1;
  context.stroke();

  // 指示器
  const xAxis = Math.cos(Math.PI * 2 / 360 * (1.8 * (100 + angle))) * (width / 2 - 30);
  const yAxis = Math.sin(Math.PI * 2 / 360 * (1.8 * (100 + angle))) * (width / 2 - 30);
  context.beginPath();
  context.arc(width / 2 + xAxis, height - 20 + yAxis, 5, 0, 2 * Math.PI);
  context.fillStyle = '#5EAD35';
  context.fill();

  // 文本
  const textY = Math.sin(Math.PI * 2 / 360 * (1.8 * (100 + 15))) * (width / 2 - 30);
  context.fillStyle = '#168C66';
  context.font = '40px Arial';
  context.textAlign = 'center';
  context.textBaseline = 'middle';
  context.fillText(score, width / 2 - 5, height + 10 + textY);

  context.fillStyle = '#62AF35';
  context.font = '14px Arial';
  context.fillText('分', width / 2 + 30, height + 18 + textY);

  // 内层圆环
  context.beginPath();
  context.arc(width / 2, height - 20, width / 2 - 40, 1 * Math.PI, 2 * Math.PI);
  context.lineWidth = 2;
  context.setLineDash([1, 4]);
  context.lineCap = 'round';
  context.strokeStyle = '#A2BCC3';
  context.stroke();
</script>

</body>
</html>

在这里插入图片描述

例二

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    .canvas-main {
      width: 400px;
      height: 400px;
      position: relative;
    }
    .main-text {
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      position: absolute;
      top: 0;
      left: 0;
    }
  </style>
</head>
<body>
<div class="canvas-main">
  <canvas id="main-canvas" width="400" height="400"></canvas>
  <div class="main-text">10分</div>
</div>

<script>
  const canvas = document.getElementById('main-canvas');
  const context = canvas.getContext('2d');
  const width = canvas.width;
  const height = canvas.height;
  const score = 50; // 你的分数值
  const totalScore = 100; // 总分
  const scorePercentage = score / totalScore; // 你的分数值占总分的百分比

  // 外层圆环
  context.beginPath();
  context.arc(width / 2, height / 2, width / 2 - 30, 0.75 * Math.PI, 2.25 * Math.PI, false);
  context.lineWidth = 14;
  context.lineCap = 'round';
  context.strokeStyle = '#f5edfc';
  context.stroke();

  // 外层进度圆环
  context.beginPath();
  // 最小-最大:0.75 * Math.PI 到 2.25 * Math.PI    2.25 - 0.75 = 1.5
  context.arc(width / 2, height / 2, width / 2 - 30, 0.75 * Math.PI, (0.75 + 1.5 * scorePercentage) * Math.PI, false);
  context.lineWidth = 14;
  context.lineCap = 'round';
  const gnt1 = context.createLinearGradient(0, 0, 180, 0);
  gnt1.addColorStop(0, '#f5edfc');
  gnt1.addColorStop(1, '#9c4ce3');
  context.strokeStyle = gnt1;
  context.stroke();

  // 指示器
  const indicatorAngle = 0.75 + 1.5 * scorePercentage;
  const indicatorRadius = width / 2 - 30;
  const indicatorX = width / 2 + Math.cos(indicatorAngle * Math.PI) * indicatorRadius;
  const indicatorY = height / 2 + Math.sin(indicatorAngle * Math.PI) * indicatorRadius;

  context.beginPath();
  context.arc(indicatorX, indicatorY, 10, 0, 2 * Math.PI); // 外圈半径设置为 10
  context.fillStyle = '#fff';
  context.strokeStyle = '#fff'; // 外圈线颜色也为白色
  context.lineWidth = 2; // 设置线宽,增加外圈线的宽度
  context.fill();
  context.stroke();

  // 指示器内部填充红色
  context.beginPath();
  context.arc(indicatorX, indicatorY, 6, 0, 2 * Math.PI);
  context.fillStyle = '#9c4ce3';
  context.fill();
</script>

</body>
</html>

在这里插入图片描述

小程序

如果是小程序的话,把 api 换一下

<canvas id="ring" canvas-id="ring" class="progress-canvas"></canvas>
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    score: {
      type: Number
    },
    totalScore: {
      type: Number
    }
  },
  observers: {
    score: function(data) {
      if (data || data === 0) {
        this.init()
      }
    }
  },

  /**
   * 组件的方法列表
   */
  methods: {
    init() {
      const query = this.createSelectorQuery()
      query
        .select('#ring')
        .boundingClientRect(res => {
          this.drawRing(
            'ring',
            res.width,
            res.height,
            this.data.score,
            this.data.totalScore
          )
        })
        .exec()
    },
    drawRing: function(canvasId, width, height, score, totalScore) {
      var context = wx.createCanvasContext(canvasId, this)

      // const score = 50 // 你的分数值
      // const totalScore = 100 // 总分
      const scorePercentage = score / totalScore // 你的分数值占总分的百分比

      // 外层圆环
      context.beginPath()
      context.arc(
        width / 2,
        height / 2,
        width / 2 - 30,
        0.75 * Math.PI,
        2.25 * Math.PI,
        false
      )
      context.lineWidth = 14
      context.lineCap = 'round'
      context.strokeStyle = '#f5edfc'
      context.stroke()

      // 外层进度圆环
      context.beginPath()
      context.arc(
        width / 2,
        height / 2,
        width / 2 - 30,
        0.75 * Math.PI,
        (0.75 + 1.5 * scorePercentage) * Math.PI,
        false
      )
      context.lineWidth = 14
      context.lineCap = 'round'
      const gnt1 = context.createLinearGradient(0, 0, 180, 0)
      gnt1.addColorStop(0, '#f5edfc')
      gnt1.addColorStop(1, '#9c4ce3')
      context.strokeStyle = gnt1
      context.stroke()

      // 指示器
      const indicatorAngle = 0.75 + 1.5 * scorePercentage
      const indicatorRadius = width / 2 - 30
      const indicatorX =
        width / 2 + Math.cos(indicatorAngle * Math.PI) * indicatorRadius
      const indicatorY =
        height / 2 + Math.sin(indicatorAngle * Math.PI) * indicatorRadius

      // 指示器外圈
      context.beginPath()
      context.arc(indicatorX, indicatorY, 10, 0, 2 * Math.PI) // 外圈半径设置为 10
      context.setFillStyle('#fff')
      context.setStrokeStyle('#fff') // 外圈线颜色也为白色
      context.setLineWidth(2) // 设置线宽,增加外圈线的宽度
      context.fill()
      context.stroke()

      // 指示器内部填充红色
      context.beginPath()
      context.arc(indicatorX, indicatorY, 6, 0, 2 * Math.PI)
      context.setFillStyle('#9c4ce3')
      context.fill()

      context.draw()
    }
  }
})

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

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

相关文章

机器学习基本算法:算法流程和算法分类

1、算法流程 机器学习的过程是一个完整的项目周期&#xff0c;其中包括数据的采集、数据的特征提取与分类&#xff0c;之后采用何种算法去创建机器学习模型从而获得预测数据。 算法流程 从上图可以看出一个完整的机器学习项目包含以下这些内容&#xff1a; 输入数据&#x…

JAVA毕业设计121—基于Java+Springboot的房屋租赁管理系统(源代码+数据库+9000字文档)

毕设所有选题&#xff1a; https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringboot的房屋租赁管理系统(源代码数据库9000字文档)121 一、系统介绍 本项目还有ssm版本&#xff0c;分为用户、房东、管理员三种角色 1、用户&#xff1a; 注册、登…

Ubuntu 卸载重装 Nvidia 显卡驱动

问题描述 我使用 airsim 的时候&#xff0c;发现 UE4 没法使用显卡&#xff0c;导致非常卡顿 输入 nvidia-smi 有显卡型号等信息的输出&#xff0c;但是进程 process 里面没有显示 airsim 和其他软件占用显卡情况 因此&#xff0c;我选择了卸载重装 一.卸载旧版本的驱动 …

Komodor:Kubernetes 监控工具全面指南

为了方便起见&#xff0c;Komodor 提供了一个简单的 Web 界面&#xff0c;以帮助您监控 Kubernetes 集群的状态。它拥有付费和免费增值计划&#xff0c;除了在出现问题时通知用户外&#xff0c;还拥有一系列方便的工具&#xff0c;用于跟踪和管理集群中部署的资源的状态。让我们…

Python集合(set)

目录 集合创建集合访问集合向集合中添加和删除元素集合的 交集&#xff0c;并集&#xff0c;差集运算**交集****并集****差集** 集合方法 集合 集合是无序和无索引的集合。在 Python 中&#xff0c;集合用花括号编写。 创建集合 创建集合&#xff1a; thisset {"a"…

RISC-V Bytes: Caller and Callee Saved Registers

原文链接1&#xff1a;https://danielmangum.com/posts/risc-v-bytes-caller-callee-registers/ 原文链接2&#xff1a;https://zhuanlan.zhihu.com/p/77663680 //主要讲栈帧 原文链接3&#xff1a;https://www.jianshu.com/p/b666213cdd8a //主要讲栈帧 This is part of a new…

Ftrans飞驰云联荣获“CSA 2023安全创新奖”

2023年12月21日&#xff0c;第七届云安全联盟大中华区大会在深圳成功举办。会上&#xff0c;CSA大中华区发布了多个研究成果并进行 CSA 2023年度颁奖仪式&#xff0c;Ftrans飞驰云联以其突出的技术创新能力和广泛的市场应用前景&#xff0c;荣获备受瞩目的“CSA 2023安全创新奖…

redis夯实之路-哨兵(Sentinel)机制详解

Sentinel&#xff08;哨兵&#xff09;保证了redis的高可用性&#xff0c;一个Sentinel或多个Sentinel组成的系统监视多个主从服务器&#xff0c;当主服务器下线时&#xff0c;自动将一个从服务器升级为主服务器。 sentinel的主要功能 集群监控&#xff1a;负责监控redis mas…

imgaug库指南(20):从入门到精通的【图像增强】之旅

引言 在深度学习和计算机视觉的世界里&#xff0c;数据是模型训练的基石&#xff0c;其质量与数量直接影响着模型的性能。然而&#xff0c;获取大量高质量的标注数据往往需要耗费大量的时间和资源。正因如此&#xff0c;数据增强技术应运而生&#xff0c;成为了解决这一问题的…

【Python】使用Opencv裁剪指定区域,再重构大小和保存示例

在Python中&#xff0c;使用OpenCV库可以很方便地截取图像的某一区域&#xff0c;然后尺寸重构&#xff0c;最后保存为新的图像文件。以下是一个示例代码&#xff0c;演示如何实现这一操作&#xff1a; import cv2# 读取图像 img cv2.imread(img.jpg)# 定义截取的区域&#x…

Istio 实战:WasmPlugin(Proxy-Wasm 插件)开发(实现限流和修改请求和响应的 header)

更多 istio 文章&#xff1a;Istio 专栏目录 WasmPlugin 的典型应用 限流&#xff1a;当前 envoy 提供的限流能力虽然比较强大&#xff0c;但主要提供了一些 api&#xff0c;在使用上对用户不够友好&#xff0c;且全局限流对每个请求都调用一次限流服务&#xff0c;性能损耗较…

SSM-SpringMVC+Spring+Mybatis

创建项目 创建好 项目后, 项目目录分析 数据库设计 我们采用员工表 Employee 与 部门表 Department 部门表 表设计--- 员工表 --表设计 因为有文件上传操作,因此 建立 info表 (其中 员工只能隶属一个部门,因此 两张表之间 有外键关系) java 代码 设计 数据库建立完毕后,需要…

自定义数据实现SA3D

SA3D&#xff1a;Segment Anything in 3D with NeRFs 实现了3D目标分割 原理是利用SAM(segment anything) 模型和Nerf分割渲染3D目标&#xff0c; SAM只能分块&#xff0c;是没有语义标签的&#xff0c;如何做到语义连续&#xff1f; SA3D中用了self-prompt, 根据前一帧的mask…

C#编程-了解线程的优先级

了解线程的优先级 控制线程行为的一个属性是它的优先级。.NET运行时环境基于它们的优先级执行线程。CPU一次仅执行一个线程。因此,处于执行的可运行状态的线程,排队等待轮到被处理器执行。线程是固定优先级调度的。带有优先级的每个线程在处理器的线程队列中有自己的位置。 …

Java面试之虚拟机

1、前言 本篇的面试题基于网络整理&#xff0c;和自己编辑。在不断的完善补充哦。 2、什么是虚拟机&#xff1f; Java 虚拟机&#xff0c;是一个可以执行 Java 字节码的虚拟机进程。Java 源文件被编译成能被 Java 虚拟机执行的字节码文件( .class )。 Java 被设计成允许应用程…

老胡的周刊(第124期)

老胡的信息周刊[1]&#xff0c;记录这周我看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 &#x1f3af; 项目 QAnything[2] 开源的企业级本地知识库问答解…

Java入门IDEA基础语法

1&#xff1a;Java入门 1.1 Java简介 Java是什么&#xff1a; Java是一门非常优秀的计算机语言 语言&#xff1a;人与人交流沟通的表达方式 计算机语言&#xff1a;人与计算机之间进行信息交流沟通的一种特殊语言 Java之父&#xff1a;詹姆斯高斯林&#xff08;James Gosli…

深入理解计算机系统(2):信息的表示和处理

信息存储 大多数计算机使用 8 位的块&#xff0c;或者字节(byte)&#xff0c;作为最小的可寻址的内存单位&#xff0c;而不是访问内存中单独的位。机器级程序将内存视为一个非常大的字节数组&#xff0c;称为虚拟内存(virtual memory)。内存的每个字节都由一个唯一的数字来标识…

Elasticsearch:是时候离开了! - 在 Elasticsearch 文档上使用 TTL

作者&#xff1a;来自 Elastic David Pilato 想象一下&#xff0c;圣诞老人必须向世界上所有的孩子们分发礼物。 他有很多工作要做&#xff0c;他需要保持高效。 他有一份所有孩子的名单&#xff0c;并且知道他们住在哪里。 他很可能会将礼物按区域分组&#xff0c;然后再交付。…

2024上半年教资笔试报名详细教程1月12日开始报名啦

重点提醒&#xff1a; 1、注册开放时间&#xff1a;2024年1月10日开始。 &#xff08;参加过笔试的考生&#xff0c;需要重新注册&#xff0c; 不影响已获得的笔试成绩。名额少的考点建议提前注册抢名额&#xff09; 2、网上报名时间&#xff1a;2024年1月12日至15日。 千万不…