使用CSS制作动态的环形图/饼图

使用纯 CSS + Animation + conic-gradient 实现一个环形图。

饼图的实现思路和环形图一样,去掉中间的圆形遮盖 after 伪类元素即可。

一、构建基础样式

构建圆形节点和中间的遮盖元素。

<style>
  body {
    background-color: rgb(130, 226, 255);
  }

  .circle {
    top: 160px;
    left: 160px;
    width: 300px;
    aspect-ratio: 1;
    border: 1px solid white;
    border-radius: 50%;
    position: relative;

    &::after {
      content: "";
      position: absolute;
      top: 7px;
      left: 7px;
      width: 286px;
      height: 286px;
      border-radius: 50%;
      background: rgb(0, 183, 255);
      display: block;
      box-sizing: border-box;
    }
  }
</style>

<body>
  <div class="circle"></div>
</body>

二、设置环形、饼图

设置锥形渐变,设置三个颜色(transparent,white,transparent),方便后边通过动画动态调整

.circle {
  ...
  background: conic-gradient(transparent 0 0, white 0 90deg, transparent 90deg 360deg);
  
  &::after {
    ...
  }
}

三、添加动画

添加动画前,将 background 重置一下

.circle {
  ...
  background: conic-gradient(transparent 0 0, white 0 0, transparent 0 360deg);

  &::after {
    ...
  }
}

然后添加动画

.circle {
  ...
  animation: rotated 10s linear infinite;

  &::after {
    ...
  }
}
@keyframes rotated {
  0% {
    background: conic-gradient(transparent 0 0, white 0 0, transparent 0 360deg);
  }
  12% {
    background: conic-gradient(transparent 0 0, white 0 90deg, transparent 90deg 360deg);
  }
  25% {
    background: conic-gradient(transparent 0 90deg, white 90deg 90deg, transparent 90deg 360deg);
  }
  37% {
    background: conic-gradient(transparent 0 90deg, white 90deg 180deg, transparent 180deg 360deg);
  }
  50% {
    background: conic-gradient(transparent 0 180deg, white 180deg 180deg, transparent 180deg 360deg);
  }
  62% {
    background: conic-gradient(transparent 0 180deg, white 180deg 270deg, transparent 270deg 360deg);
  }
  75% {
    background: conic-gradient(transparent 0 270deg, white 270deg 270deg, transparent 270deg 360deg);
  }
  87% {
    background: conic-gradient(transparent 0 270deg, white 270deg 360deg, transparent 360deg 360deg);
  }
  100% {
    background: conic-gradient(transparent 0 360deg, white 360deg 360deg, transparent 360deg 360deg);
  }
}

可以看到,为渐变gradient的元素设置animation、transition是不会有过渡的效果。这是由于gradient属性并不像width这类型的属性一样,无法通过gradient的变化实现过渡效果。

四、解决过渡不生效的问题

使用 @property 自定义属性,在 gradient 各个颜色的起始、结束角度上使用。

重新调整 @keyframes 中变化的属性,不改变 gradient,而是改变我们自定义的 angle 属性。

CSS变量和@property-CSDN博客

<style>
  body {
    ...
  }
  @property --angle1 {
    syntax: '<angle>';
    initial-value: 0deg;
    inherits: false;
  }
  @property --angle2 {
    syntax: '<angle>';
    initial-value: 0deg;
    inherits: false;
  }
  .circle {
    ...
    background: conic-gradient(transparent 0 var(--angle1), white var(--angle1) var(--angle2), transparent var(--angle2) 360deg);
    ...
    &::after {
      ...
    }
  }
  @keyframes rotated {
    0% {
      --angle1: 0deg;
      --angle2: 0deg;
      /* background: conic-gradient(transparent 0 0, white 0 0, transparent 0 360deg); */
    }
    12% {
      --angle1: 0deg;
      --angle2: 90deg;
      /* background: conic-gradient(transparent 0 0, white 0 90deg, transparent 90deg 360deg); */
    }
    25% {
      --angle1: 90deg;
      --angle2: 90deg;
      /* background: conic-gradient(transparent 0 90deg, white 90deg 90deg, transparent 90deg 360deg); */
    }
    37% {
      --angle1: 90deg;
      --angle2: 180deg;
      /* background: conic-gradient(transparent 0 90deg, white 90deg 180deg, transparent 180deg 360deg); */
    }
    50% {
      --angle1: 180deg;
      --angle2: 180deg;
      /* background: conic-gradient(transparent 0 180deg, white 180deg 180deg, transparent 180deg 360deg); */
    }
    62% {
      --angle1: 180deg;
      --angle2: 270deg;
      /* background: conic-gradient(transparent 0 180deg, white 180deg 270deg, transparent 270deg 360deg); */
    }
    75% {
      --angle1: 270deg;
      --angle2: 270deg;
      /* background: conic-gradient(transparent 0 270deg, white 270deg 270deg, transparent 270deg 360deg); */
    }
    87% {
      --angle1: 270deg;
      --angle2: 360deg;
      /* background: conic-gradient(transparent 0 270deg, white 270deg 360deg, transparent 360deg 360deg); */
    }
    100% {
      --angle1: 360deg;
      --angle2: 360deg;
      /* background: conic-gradient(transparent 0 360deg, white 360deg 360deg, transparent 360deg 360deg); */
    }
  }
</style>

完整代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      body {
        background-color: rgb(130, 226, 255);
      }
      @property --angle1 {
        syntax: "<angle>";
        initial-value: 0deg;
        inherits: false;
      }
      @property --angle2 {
        syntax: "<angle>";
        initial-value: 0deg;
        inherits: false;
      }
      .circle {
        top: 160px;
        left: 160px;
        width: 300px;
        aspect-ratio: 1;
        border-radius: 50%;
        position: relative;
        background: conic-gradient(transparent 0 var(--angle1), white var(--angle1) var(--angle2), transparent var(--angle2) 360deg);
        animation: rotated 10s linear infinite;
        &::after {
          content: "";
          position: absolute;
          top: 7px;
          left: 7px;
          width: 286px;
          height: 286px;
          border-radius: 50%;
          background: rgb(0, 183, 255);
          display: block;
          box-sizing: border-box;
        }
      }
      @keyframes rotated {
        0% {
          --angle1: 0deg;
          --angle2: 0deg;
          /* background: conic-gradient(transparent 0 0, white 0 0, transparent 0 360deg); */
        }
        12% {
          --angle1: 0deg;
          --angle2: 90deg;
          /* background: conic-gradient(transparent 0 0, white 0 90deg, transparent 90deg 360deg); */
        }
        25% {
          --angle1: 90deg;
          --angle2: 90deg;
          /* background: conic-gradient(transparent 0 90deg, white 90deg 90deg, transparent 90deg 360deg); */
        }
        37% {
          --angle1: 90deg;
          --angle2: 180deg;
          /* background: conic-gradient(transparent 0 90deg, white 90deg 180deg, transparent 180deg 360deg); */
        }
        50% {
          --angle1: 180deg;
          --angle2: 180deg;
          /* background: conic-gradient(transparent 0 180deg, white 180deg 180deg, transparent 180deg 360deg); */
        }
        62% {
          --angle1: 180deg;
          --angle2: 270deg;
          /* background: conic-gradient(transparent 0 180deg, white 180deg 270deg, transparent 270deg 360deg); */
        }
        75% {
          --angle1: 270deg;
          --angle2: 270deg;
          /* background: conic-gradient(transparent 0 270deg, white 270deg 270deg, transparent 270deg 360deg); */
        }
        87% {
          --angle1: 270deg;
          --angle2: 360deg;
          /* background: conic-gradient(transparent 0 270deg, white 270deg 360deg, transparent 360deg 360deg); */
        }
        100% {
          --angle1: 360deg;
          --angle2: 360deg;
          /* background: conic-gradient(transparent 0 360deg, white 360deg 360deg, transparent 360deg 360deg); */
        }
      }
    </style>
  </head>
  <body>
    <div class="circle"></div>
  </body>
</html>

饼图例子

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      body {
        background-color: rgb(130, 226, 255);
      }
      @property --angle {
        syntax: "<angle>";
        initial-value: 0deg;
        inherits: false;
      }
      .circle {
        top: 160px;
        left: 160px;
        width: 300px;
        aspect-ratio: 1;
        border: 1px solid white;
        border-radius: 50%;
        position: relative;
        background: conic-gradient(white 0 var(--angle), transparent var(--angle) 360deg);
        transition: --angle 0.5s linear;
        
        &:hover {
          --angle: 360deg;
        }
      }
    </style>
  </head>
  <body>
    <div class="circle"></div>
  </body>
</html>

GIF 略显卡顿🤣🤣

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

个人网站展示(静态)

大学期间做了一个个人博客网站&#xff0c;纯H5编码的网站&#xff0c;利用php搭建了一个留言模块。 有需要源码的同学&#xff0c;可以联系我~ 首页&#xff1a; IT杂记模块 文人墨客模块 劳有所获模块 生活日志模块 关于我 一个推崇全栈开发的前端开发人员 微信: itrzzh …

蓝桥杯备战刷题five(自用)

1.数字三角形&#xff08;方向次数限制&#xff0c;动态规划&#xff09; //如果n为奇数时&#xff0c;最后必然走到最后行最中间的数&#xff0c;如果为偶数&#xff0c;则取中间两个数的最大值&#xff0c; //因为向左下走的次数与向右下走的次数相差不能超过 1 #include …

【动态规划】代码随想录算法训练营第四十四天 |完全背包,518. 零钱兑换 II , 377. 组合总和 Ⅳ (待补充)

完全背包理论基础 完全背包 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品都有无限个&#xff08;也就是可以放入背包多次&#xff09;&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 完全背包和…

仿牛客网项目---项目总结

本篇文章是对整个项目的一个总结。下面这张图要好好理解。 整个项目都是构建在SpringBoot之上的&#xff0c;所以把它画到最底下&#xff0c;其它技术依托在springboot之上。但是springboot并不是技术的核心&#xff0c;而只是起到了一个辅助的作用&#xff0c;它的作用仅仅是降…

后端项目访问不了

问题&#xff1a; 后端启动不了&#xff0c;无法访问网站 原因&#xff1a; 1.防火墙没有关 2.有缓存 3、项目没有启动 4、docker没有启动 解决&#xff1a; 先查看进程&#xff1a;docker ps&#xff0c;必须有三个 详细查看&#xff1a;docker ps -a exited代表没有开启…

AI相关的实用工具分享

AI实用工具大赏&#xff1a;赋能科研与生活&#xff0c;探索AI的无限可能 前言 在数字化浪潮汹涌而至的今天&#xff0c;人工智能&#xff08;AI&#xff09;已经渗透到我们生活的方方面面&#xff0c;无论是工作还是生活&#xff0c;都在悄然发生改变。AI的崛起不仅为我们带…

怎么看待Groq

用眼睛看。 就是字面上的意思用眼睛看。 我属于第一波玩到的,先给大家一个直观的印象,Groq到底有多快。 目前Groq只能选Llama的70b,和Mixtral的MoE,那我选7*8的这个MoE模型来实验。 这么好些字大概花了不到1秒,流式响应,其实是不是流式已经没那么重要了 ,然后看每秒Toke…

dbeaver 数据库连接工具使用教程

dbeaver是一款很强大的数据库连接工具&#xff0c;本人之前使用的是navicat&#xff0c;挺好用的&#xff0c;只不过每次激活都要整半天&#xff0c;然后看到了dbeaver这款工具&#xff0c;本着尝试的心态&#xff0c;体验了下&#xff0c;真香。 下面来配置dbeaver 1.下载安…

软件测试相关内容第三弹--软件测试基础

写在前&#xff1a;在前篇的两篇博客介绍中我们主要学习软件测试的相关概念&#xff0c;对软件测试进行了初步的了解&#xff0c;本篇博客将进一步进行学习。重点内容包括&#xff1a;软件测试的生命周期、如何描述一个bug、如何定义bug的级别、bug的生命周期以及在实际工作中如…

ElasticSearch学习篇10_Lucene数据存储之BKD动态磁盘树

前言 基础的数据结构如二叉树衍生的的平衡二叉搜索树通过左旋右旋调整树的平衡维护数据&#xff0c;靠着二分算法能满足一维度数据的logN时间复杂度的近似搜索。对于大规模多维度数据近似搜索&#xff0c;Lucene采用一种BKD结构&#xff0c;该结构能很好的空间利用率和性能。 …

系统分析与设计(一)

我们有这么多各式各样的工具,互联网给我们带来了这么多用户和数据,这是好事也有副作用。 世界上能访问用户数据,并根据数据做分析和改进的公司,大概Google是其中翘楚,这种 data-centric 的做法做过了头,也有悲剧发生: Douglas Bowman 曾经是Google 的视觉设计主管,2009年的一天…

VUE_自适应布局lib-flexible+postcss-pxtorem、lib-flexible + postcss-px2rem,nuxt页面自适配

lib-flexible postcss-pxtorem适配 我采用的是flexable.js和postcss-pxtorem。我一开始用的是postcss-px2rem后来发现和nuxt引入公共css的时候发生了冲突所以改用了postcss-pxtorem。 安装依赖 npm i lib-flexible -S npm install postcss-pxtorem --save 1、lib-flexible.…

鸿蒙Harmony应用开发—ArkTS声明式开发(通用属性:动态属性设置)

动态设置组件的属性&#xff0c;支持开发者在属性设置时使用if/else语法&#xff0c;且根据需要使用多态样式设置属性。 说明&#xff1a; 从API Version 11开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 attributeModifier attributeMo…

Mint_21.3 drawing-area和goocanvas的FB笔记(六)

FreeBASIC gfx 基本 graphics 绘图 一、旧故事 DOS时代PC技术将各类硬插卡限制在 640K到1MB的空间范围内&#xff0c;BIOS负责在相关位置写读测试卡的存在&#xff0c;那时期的Color Video在0xB800&#xff0c;Monochrome Video在0xB000&#xff0c;这是显卡的内存地址&#…

算法学习之动态规划DP——背包问题

一、01背包问题 &#xff08;一&#xff09;题目 有 N 件物品和一个容量是 V的背包。每件物品只能使用一次。 第i件物品的体积是 vi&#xff0c;价值是 wi。 求解将哪些物品装入背包&#xff0c;可使这些物品的总体积不超过背包容量&#xff0c;且总价值最大。 输出最大价值…

前后端交互理解 简易表白墙(servlet)

前后端交互理解 简易表白墙&#xff08;servlet&#xff09; 文章目录 前后端交互理解 简易表白墙&#xff08;servlet&#xff09;后端核心内容前后端交互接口约定后端代码展示 上期介绍过 Servlet API &#xff0c;本篇文章目的是借助 servlet 做出一个完整的网站。在一个网站…

51单片机基础篇系列-人人都能学会单片机

&#x1f308;个人主页: 会编程的果子君 &#x1f4ab;个人格言:“成为自己未来的主人~” 什么是单片机 在一片集成电路芯片上集成计算机所有基 本部分&#xff08;中央处理器CPU、存储器RAM、ROM、 定时计数器T/C&#xff0c;输入输出接口IO、中断系 统&#xff09;都集成…

【UVM_phase objection_2024.03.08

phase 棕色&#xff1a;function phase 不消耗仿真时间 绿色&#xff1a;task phase 消耗仿真时间 run_phase与右边的phase并行执行&#xff0c;右边的phase&#xff08;run_time phase&#xff09;依次执行&#xff1a; List itemreset_phase对DUT进行复位&#xff0c;初始…

Elastic Stack--07--JavaAPI----文档(新增 、修改 、 查询 、 删除)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 JavaAPI-文档1.新增 Insert2.修改 Update3.查询 Get4.删除 Delete5.批量操作 BulkRequest批量新增批量删除 高级查询1.查询所有索引数据2.条件查询3.分页查询4.查询…

代码随想录算法训练营Day39 || leetCode 762.不同路径 || 63. 不同路径 II

62.不同路径 每一位的结果等于上方与左侧结果和 class Solution { public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m,vector(n,0));for (int i 0; i < m; i) dp[i][0] 1;for (int j 0; j < n; j) dp[0][j] 1;for (int i 1; i < m; …