SVG 实现拟物态圆环进度条

news2024/10/6 12:23:20

前言

👏SVG 实现拟物态圆环进度条,速速来Get吧~

🥇文末分享源代码。记得点赞+关注+收藏!

1.实现效果

在这里插入图片描述

2.实现步骤

  • 定义一个圆角矩形作为父容器,背景色为–bg

在这里插入图片描述

--bg: #edf1f5;
<div class="container"></div>
.container {
 padding: 30px;
 border-radius: 20px;
 background: var(--bg);
 box-shadow: 0px 20px 30px rgba(100, 131, 177, 0.2);
 border: 1px solid #fff;
}
  • 父容器添加一个正方形,宽高w

在这里插入图片描述

/* 宽度 */
 --w: 200px;
 <div class="container-box" ></div>
.container-box {
  position: relative;
  width: var(--w);
  height: var(--w);
  border: 1px solid red;
}
  • 在container-box容器中添加一个圆形,宽高为100%,基于父元素absolute定位,left为0,top为0,添加box-shadow阴影,定义阴影变量–back-bg和–back-shadow

在这里插入图片描述

--back-bg: #c5ccda;
--back-shadow: #ffffff;
<div class="circle-outer"></div>
.circle-outer {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  box-shadow: 6px 6px 8px var(--back-bg), -6px -6px 8px var(--back-shadow);
  background: var(--bg);
}
  • 为circle-outer添加前伪元素,用该伪元素实现一个圆形,定义css变量gap,表示该圆形与父元素之前的距离

在这里插入图片描述

/* 父容器gap*/
--gap: 30px;
  • 那么可以算出circle-outer前伪元素的宽高为–inner,即calc(var(–w) - var(–gap))

在这里插入图片描述

/* 第二层圆形宽度 */
--inner: calc(var(--w) - var(--gap));
.circle-outer::before {
 content: "";
 position: absolute;
 left: 50%;
 top: 50%;
 transform: translate(-50%, -50%);
 border-radius: 50%;
 background: var(--bg);
 width: var(--inner);
 height: var(--inner);
 box-shadow: inset 8px 8px 10px var(--back-bg),
   inset -4px -4px 8px var(--back-shadow);
}
  • 在container-box容器中添加svg,宽高为父元素的100%,基于父元素absolute定位

SVG:
可缩放矢量图形(Scalable Vector Graphics,SVG)基于 XML 标记语言,用于描述二维的矢量图形

svg {
 position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  //旋转90deg
  transform: rotate(-90deg);
}
  • svg中添加defs

defs:
SVG 允许我们定义以后需要重复使用的图形元素。建议把所有需要再次使用的引用元素定义在defs元素里面。这样做可以增加 SVG 内容的易读性和无障碍。在defs元素中定义的图形元素不会直接呈现。你可以在你的视口的任意地方利用 元素呈现这些元素。

  • defs中定义一个radialGradient

radialGradient:
radialGradient 用来定义径向渐变,以对图形元素进行填充或描边。

  • 定义两个颜色,表示radialGradient的色值,即环形的色值
--ring-color1: #c1dfc4;
--ring-color2: #3cba92;
<defs>
 <radialGradient
    id="gradient"
    cx="50%"
    cy="50%"
    r="60%"
    fx="50%"
    fy="50%"
  >
    <stop offset="30%" stop-color="var(--ring-color2)" />
    <stop offset="100%" stop-color="var(--ring-color1)" />
  </radialGradient>
</defs>
  • 在svg中添加circle,stroke为上述定义的radialGradient

circle:
SVG 元素是一个 SVG 的基本形状,用来创建圆,基于一个圆心和一个半径。
cx 属性定义一个中心点的 x 轴坐标。
cy 属性定义一个中心点的 y 轴坐标。
r 属性用来定义圆的半径。

<circle stroke="url(#gradient)" id="circle"></circle>
  • 这里我们先说明几个字段的意义

stroke-width:
stroke-width属性指定了当前对象的轮廓的宽度。它的默认值是1。如果使用了一个,这个值代表当前视口的百分比。如果使用了0值,则将不绘制轮廓。

stroke-dasharray:
属性 stroke-dasharray 可控制用来描边的点划线的图案范式。作为一个外观属性,它也可以直接用作一个 CSS 样式表内部的属性。

eg:

stroke-dasharray = 20 表示:虚线长20,间距20,然后重复 虚线长20,间距20

stroke-dashoffset:
stroke-dashoffset 属性指定了 dash 模式到路径开始的距离,偏移的意思

  • 定义css变量stroke,表示stroke-width,定义–circle表示svg中circle的宽高,由下图可以得到–circle为calc(var(–inner) - var(–stroke))

在这里插入图片描述

/* 环形stroke宽度 */
--stroke: 20px;
/* svg环形宽度 */
--circle: calc(var(--inner) - var(--stroke));
  • 为cricle添加样式,基于svg水平垂直居中,根据css变量设置cx,cy,r,stroke-dasharray为圆的周长,即3.14*圆的直径(–circle)
  • 这里先设置stroke-dashoffset为任意值,当stroke-dashoffset与stroke-dasharray相等的时候,将不显示内容,stroke-dashoffset设置的越小,显示内容越多,当为0时候,显示全部

在这里插入图片描述

svg circle {
 position: absolute;
 //设置垂直居中
 --z: calc(var(--w) / 2);
 --c: calc(var(--circle) / 2);
 transform: translate(
   calc(var(--z) - var(--c)),
   calc(var(--z) - var(--c))
 );
 cy: calc(var(--circle) / 2);
 cx: calc(var(--circle) / 2);
 r: calc(var(--circle) / 2);
 fill: none;
 stroke-linecap: round;
 stroke-dasharray: calc(3.14 * var(--circle));
 stroke-dashoffset: 250;
 stroke-width: var(--stroke);
}
  • 为circle-outer添加后伪元素,用该伪元素实现一个圆形

在这里插入图片描述

  • 那么可以算出circle-outer后伪元素的宽高为–center,即calc(var(–circle) - var(–stroke))

在这里插入图片描述

/* 第三层圆形宽度 */
--center: calc(var(--circle) - var(--stroke));
.circle-outer::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: var(--bg);
  width: var(--center);
  height: var(--center);
  box-shadow: 6px 6px 8px var(--back-bg), -2px -2px 8px var(--back-shadow);
}
  • 为container-box添加伪元素,显示当前百分比,标签内定义data-num,去掉辅助边框,有模有样了哈~

在这里插入图片描述

<div class="container-box" data-num="--" >
...
</div>
 .container-box::after {
  content: attr(data-num);
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  color: var(--text-aolor);
  font-size: 30px;
}
.container-box {
 - border: 1px solid red;
}
  • 接下来,写一个定时器,实现进度条加载,就完成了啦~

在这里插入图片描述

 const getData = () => {
  const circle = document.getElementById("circle");
  const box = document.getElementById("box");
  let perimeter = 3.14 * 150; //这是stroke-dasharray的值
  let i = 0;
  let timer = null;
  const loading = () => {
    if (i < 100) {
      i++;
      box.dataset.num = i + "%";
      let per = perimeter - (perimeter * i) / 100;
      circle.style.strokeDashoffset = per;
    } else {
      clearInterval(timer);
    }
  };
  loading();
  timer = setInterval(loading, 100);
};
getData();

3.实现代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>151.SVG 实现拟物态圆环进度条</title>
  </head>
  <link rel="stylesheet" href="../common.css" />
  <style>
    body {
      background: var(--back-bg);
    }
    :root {
      --bg: #edf1f5;
      --back-bg: #c5ccda;
      --back-shadow: #ffffff;
      --ring-color1: #c1dfc4;
      --ring-color2: #3cba92;
      --text-aolor: #497241;
      /* 父容器宽度 */
      --w: 200px;
      /* 父容器gap*/
      --gap: 30px;
      /* 第二层圆形宽度 */
      --inner: calc(var(--w) - var(--gap));
      /* 环形stroke宽度 */
      --stroke: 20px;
      /* svg环形宽度 */
      --circle: calc(var(--inner) - var(--stroke));
      /* 第三层圆形宽度 */
      --center: calc(var(--circle) - var(--stroke));
    }
    .container {
      padding: 30px;
      border-radius: 20px;
      background: var(--bg);
      box-shadow: 0px 20px 30px rgba(100, 131, 177, 0.2);
      border: 1px solid #fff;
    }
    .container-box {
      position: relative;
      width: var(--w);
      height: var(--w);
    }
    .circle-outer {
      position: relative;
      width: 100%;
      height: 100%;
      border-radius: 50%;
      box-shadow: 6px 6px 8px var(--back-bg), -6px -6px 8px var(--back-shadow);
      background: var(--bg);
    }
    .circle-outer::before {
      content: "";
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      border-radius: 50%;
      background: var(--bg);
      width: var(--inner);
      height: var(--inner);
      box-shadow: inset 8px 8px 10px var(--back-bg),
        inset -4px -4px 8px var(--back-shadow);
    }
    .circle-outer::after {
      content: "";
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      border-radius: 50%;
      background: var(--bg);
      width: var(--center);
      height: var(--center);
      box-shadow: 6px 6px 8px var(--back-bg), -2px -2px 8px var(--back-shadow);
    }
    .container-box::after {
      content: attr(data-num);
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      color: var(--text-aolor);
      font-size: 30px;
    }
    svg {
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      z-index: 1;
      transform: rotate(-90deg);
    }
    svg circle {
     position: absolute;
      --z: calc(var(--w) / 2);
      --c: calc(var(--circle) / 2);
      transform: translate(
        calc(var(--z) - var(--c)),
        calc(var(--z) - var(--c))
      );
      cy: calc(var(--circle) / 2);
      cx: calc(var(--circle) / 2);
      r: calc(var(--circle) / 2);
      fill: none;
      stroke-linecap: round;
      /* 设置圆的stroke-dasharray和stroke-dashoffset,为圆的周长 */
      stroke-dasharray: calc(3.14 * var(--circle));
      stroke-dashoffset:calc(3.14 * var(--circle));
      stroke-width: var(--stroke);
    }
  </style>
  <body>
    <div class="container">
      <div class="container-box" data-num="--" id="box">
        <div class="circle-outer"></div>
        <svg>
          <defs>
            <radialGradient
              id="gradient"
              cx="50%"
              cy="50%"
              r="60%"
              fx="50%"
              fy="50%"
            >
              <stop offset="30%" stop-color="var(--ring-color2)" />
              <stop offset="100%" stop-color="var(--ring-color1)" />
            </radialGradient>
          </defs>
          <circle stroke="url(#gradient)" id="circle"></circle>
        </svg>
      </div>
    </div>
  </body>
  <script>
    const getData = () => {
      const circle = document.getElementById("circle");
      const box = document.getElementById("box");
      let perimeter = 3.14 * 150; //这是stroke-dasharray的值
      let i = 0;
      let timer = null;
      const loading = () => {
        if (i < 100) {
          i++;
          box.dataset.num = i + "%";
          let per = perimeter - (perimeter * i) / 100;
          circle.style.strokeDashoffset = per;
        } else {
          clearInterval(timer);
        }
      };
      loading();
      timer = setInterval(loading, 100);
    };
    getData();
  </script>
</html>

4.写在最后🍒

看完本文如果觉得对你有一丢丢帮助,记得点赞+关注+收藏鸭 🍕
更多相关内容,关注🍥苏苏的bug,🍡苏苏的github,🍪苏苏的码云~

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

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

相关文章

lunar.js 基本使用学习笔记

文章目录lunar 基本使用学习笔记介绍基本使用部分文档 API 转载阳历相关的方法 APISolar 阳历阳历实例化阳历对象可以使用多种字符串输出方式&#xff1a;获取年、月、日儒略日获取星期判断是否闰年获取节日星座阳历日期推移&#xff08;可**跳过节假日、周六周日**&#xff09…

[附源码]Nodejs计算机毕业设计基于Java的医院预约挂号系统Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…

SpringMVC的传参方式?

Request参数传递 1. Servlet传统API 2. Map/Model/ModelMap 作用域&#xff1a;request Map 是原生态的JDK类 Model/ModelMap 是Spring的类 除了来源不同&#xff0c;传递参数的功能都一致&#xff0c;用哪个都可以 Session参数传递 1. 传统方法HttpServletSession 2. …

[附源码]计算机毕业设计工程施工多层级管理架构Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Python列表(list)原址反序的4种方法

Python列表(list)原址反序的方法 (本文获得CSDN质量评分【x】)【学习的细节是欢悦的历程】Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教程》&#xff0c;不仅仅是基础那么简单…… 自学并不是什么神秘的东西&a…

利用图文和代码深度解析操作系统OS内存泄漏检测实现原理与算法机制以及常见的泄露原因和解决方案

利用图文和代码深度解析操作系统OS内存泄漏检测实现原理与算法机制以及常见的泄露原因和解决方案。 计算机科学中,内存泄漏是一种资源泄漏。发生这种情况时,不再需要的内存未被释放,计算机程序以错误的方式管理内存分配。当对象存储在内存中但不能被运行代码无法访问时,也…

[附源码]Python计算机毕业设计殡仪馆管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

mha

MySQL MHA 报错处理 ​​​​​​- 走看看安装环境&#xff1a;CentOS 6.5 MySQL 5.7.22 MHA 0.56 1、找不到mysql 命令 Sat Mar 23 07:17:50 2019 - [info] Connecting tohttp://t.zoukankan.com/102x-p-10583959.html 实验 详解MHA搭建过程中的遇到的各种问题_时代广场的蟋蟀…

竞赛题-6257. 删除每行中的最大值

题目&#xff1a; 给你一个 m x n 大小的矩阵 grid &#xff0c;由若干正整数组成。 执行下述操作&#xff0c;直到 grid 变为空矩阵&#xff1a; 从每一行删除值最大的元素。如果存在多个这样的值&#xff0c;删除其中任何一个。将删除元素中的最大值与答案相加。 注意 每…

[附源码]Python计算机毕业设计大型零售电商平台——购物车管理子系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

[附源码]Python计算机毕业设计SSM基于的砂石矿山管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

[Linux学习笔记] 浅谈信号(文章含不少学习资源)

百金买骏马,千金买美人,万金买爵禄,何处买青春? 目录 信号的概念 信号的种类: kill -l 命令可以查看信号列表 man 7 signal 查看信号详细内容 信号的产生 补充知识 Core Dump(转储内存) 补充知识:与信号相关的数据结构 对于不可靠信号 接收信号 信号的处理: 阻塞信号集: 未决信…

qt之QCustomPlot动态更改曲线数量,单光标查看数值,选中曲线单独显示查看趋势

一、前言 本博客介绍如何由浅入深的使用一些qcustomplot的用法&#xff0c;对于开源的qcustomplot来说&#xff0c;功能实在实在是太强大了&#xff0c;如果只用于显示简单的曲线真是太浪费前人的心血了&#xff0c;本文就来介绍一些好玩的用法&#xff0c;可以实现的功能有&am…

基于javaweb的学籍管理系统计算机专业毕业论文java毕业设计开题报告

&#x1f496;&#x1f496;更多项目资源&#xff0c;最下方联系我们✨✨✨✨✨✨ 目录 Java项目介绍 资料获取 Java项目介绍 计算机毕业设计java毕设之基于javaweb的学籍管理系统-IT实战营_哔哩哔哩_bilibili项目资料网址: http://itzygogogo.com软件下载地址:http://itzy…

论文笔记:Template-Based Named Entity Recognition Using BART

论文来源&#xff1a;ACL 2021 Finding 论文链接&#xff1a;https://aclanthology.org/2021.findings-acl.161.pdf 论文代码&#xff1a;GitHub - Nealcly/templateNER: Source code for template-based NER 笔记仅供参考&#xff0c;撰写不易&#xff0c;请勿恶意转载抄袭…

[附源码]Python计算机毕业设计大学生扶贫创业平台Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

[附源码]Python计算机毕业设计SSM基于的企业人事管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【云计算与大数据技术】虚拟化技术、开源技术Xen、KVM、OpenVZ的讲解(图文解释 超详细)

一、系统虚拟化 系统虚拟化的核心思想是使用虚拟化软件在一台物理机上&#xff0c;虚拟出一台或多台虚拟机。步骤如下 利用虚拟化评估工具进行容量规划&#xff0c;实现同平台应用的资源整合&#xff1b; 首先采用容量规划工具决定每个系统的配置&#xff0c;利用虚拟化评估工…

【测绘程序设计】——潮汐调和分析

潮汐调和分析就是把某海面的潮位变化看成是许多分潮的余弦振动之和,根据最小二乘或频谱分析原理由实测数据计算出各个分潮平均振幅H和迟角g的过程。经典潮汐调和分析法有:Darwin分析法(频率成倍数的分潮看成一个分潮系)、Doodson分析法(周期相近的分潮看成一个分潮族)、现…

[附源码]Node.js计算机毕业设计大学生心理健康管理系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…