HTML 如何实现一个带间隙的圆环

实际效果:

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/5e634cedded9424d96fbe6d46f34f61a.png#pic_center![在这里插入图片描述](https://file.jishuzhan.net/article/1783777159681150978/6b2263c205bd7ce62b9e087eddef2ac1.webp)

代码实现:

HTML部分:

xml 复制代码
<svg width="500" height="500" viewBox="0 0 100 100">
  <!-- 各参数详解 -->
  <!-- stroke:圆环(轮廓)填充色 -->
  <!-- stroke-width: 圆环(圆的轮廓)的宽度 -->
  <!-- stroke-dasharray: 设置轮廓的间隙,会按照轮廓颜色-空白-轮廓颜色-空白...这样的规律去无限渲染 -->
  <!-- r:圆环的半径,该半径的计算为两个圆的中心点。例如:圆环的宽度为10 组成圆环的两个圆半径分别为10,20,则r应该设为15 -->
  <!-- fill:圆的内部填充色,我们想实现圆环效果,就需要设置其为transparent让其显示背景色,这样圆只显示轮廓,即圆环 -->
  <!-- cx,cy:圆心点的坐标 -->
  <!-- transform:平移、旋转、缩放圆环 -->

  <!-- 最下层的圆 蓝色区域 -->
  <circle
    id="circle1"
    cx="50"
    cy="50"
    r="31"
    stroke="blue"
    stroke-width="5"
    fill="transparent"
    stroke-dasharray="100,0"
    transform="rotate(-94 50 50)"
  />

  <!-- 中间的圆 灰色区域 -->
  <circle
    id="circle2"
    cx="50"
    cy="50"
    r="31"
    stroke="gray"
    stroke-width="5"
    fill="transparent"
    stroke-dasharray="0,100"
    transform="rotate(-94 50 50)"
  />
  <!-- 顶部圆环 设置间隙 颜色设为白色(背景色) -->
  <!-- stroke-width属性设置的比前两个圆稍微大一些,否则圆的轮廓会出现两条圆环的线 -->
  <circle
    id="circle3"
    cx="50"
    cy="50"
    r="31"
    stroke="white"
    stroke-width="6"
    fill="transparent"
    stroke-dasharray="0,100"
    transform="rotate(-94 50 50)"
  />
</svg>

JS部分

typescript 复制代码
  // 在线数量
  onlineCount = 3;
  // 离线数量
  offlineCount = 4;
typescript 复制代码
    const circle1 = document.getElementById('circle1');
    const circle2 = document.getElementById('circle2');
    const circle3 = document.getElementById('circle3');
    circle1?.setAttribute('stroke-dasharray', this.getCircle(1));
    circle2?.setAttribute('stroke-dasharray', this.getCircle(2));
    circle3?.setAttribute('stroke-dasharray', this.getCircle(3));
typescript 复制代码
// 此函数主要为计算三个圆环的占比
  // 需要先计算出圆环的周长,再根据周长分配各部分的长度,例如:此处三个圆环半径为31,则周长为31*3.14*2=194.68,约等于195
  // 第一个圆环渲染蓝色区域,计算出蓝色区域与空白区域
  // 第二个圆环渲染灰色区域,由于渲染的起始位置相同,所以计算时先渲染一段0长度的实际区域,再渲染一段蓝色区域长度的空白区域,显示第一个圆环的蓝色区域,然后再渲染灰色区域
  // 第三个圆环则添加圆环中的间隙(此函数设置为2,可根据实际需求更改)
  getCircle(index: any) {
    switch (index) {
      case 1:
        if (this.onlineCount === 0) {
          if (this.offlineCount === 0) {
            return '195,0';
          } else {
            return '0,195';
          }
        } else if (this.offlineCount === 0) {
          return `195,0`;
        } else {
          const length =
            (195 / (this.onlineCount + this.offlineCount)) * this.onlineCount;
          return `${length},${195 - length}`;
        }

      case 2:
        if (this.onlineCount === 0) {
          if (this.offlineCount === 0) {
            return '0,195';
          } else {
            return '195,0';
          }
        } else if (this.offlineCount === 0) {
          return '0,195';
        } else {
          const length =
            (195 / (this.onlineCount + this.offlineCount)) * this.offlineCount;
          // 先绘制0长度的实际灰色区域,再绘制空白区域(用于显示第一个圆环的蓝色),再绘制灰色区域
          return `0,${195 - length},${length}`;
        }

      case 3:
        if (this.onlineCount === 0) {
          if (this.offlineCount === 0) {
            return '0,195';
          } else {
            const length = 195 / this.offlineCount - 2;
            return `2,${length}`;
          }
        } else if (this.offlineCount === 0) {
          const length = 195 / this.onlineCount - 2;
          return `2,${length}`;
        } else {
          const length = 195 / (this.onlineCount + this.offlineCount) - 2;
          return `2,${length}`;
        }

      default:
        return '';
    }
  }
相关推荐
程序员小寒1 小时前
JavaScript设计模式(八):命令模式实现与应用
前端·javascript·设计模式·ecmascript·命令模式
wgod1 小时前
new AbortController()
前端
UXbot2 小时前
UXbot 是什么?一句指令生成完整应用的 AI 工具
前端·ai·交互·个人开发·ai编程·原型模式·ux
棒棒的唐2 小时前
WSL2用npm安装的openclaw,无法正常使用openclaw gateway start启动服务的问题
前端·npm·gateway
哔哩哔哩技术2 小时前
使用Compose Navigation3进行屏幕适配
前端
Z_Wonderful3 小时前
在 Next.js 中,使用 [id] 或 public 作为文件夹或文件名是两种完全不同的概念,分别对应 动态路由 和 静态资源托管
javascript·网络·chrome
咬人喵喵3 小时前
E2.COOL 平台深度解析:从特效分类到实战操作指南
前端·编辑器·svg
RisunJan4 小时前
Linux命令-named-checkzone
linux·前端
小陈工4 小时前
Python Web开发入门(十):数据库迁移与版本管理——让数据库变更可控可回滚
前端·数据库·人工智能·python·sql·云原生·架构
吹晚风吧4 小时前
解决vite打包,base配置前缀,nginx的dist包找不到资源
服务器·前端·nginx