CSS 进步圈

我已经搜索了这个网站,找到进度条,但我已经能够找到的显示动画圈,去完成100% 。

我希望它停止在某些百分比喜欢在下面的截图。有没有办法我可以做到这一点,只使用 CSS?

Circular progress bars

458164 次浏览

我使用 只有 CSS创建了一个小提琴。

.wrapper {
width: 100px; /* Set the size of the progress bar */
height: 100px;
position: absolute; /* Enable clipping */
clip: rect(0px, 100px, 100px, 50px); /* Hide half of the progress bar */
}
/* Set the sizes of the elements that make up the progress bar */
.circle {
width: 80px;
height: 80px;
border: 10px solid green;
border-radius: 50px;
position: absolute;
clip: rect(0px, 50px, 100px, 0px);
}
/* Using the data attributes for the animation selectors. */
/* Base settings for all animated elements */
div[data-anim~=base] {
-webkit-animation-iteration-count: 1;  /* Only run once */
-webkit-animation-fill-mode: forwards; /* Hold the last keyframe */
-webkit-animation-timing-function:linear; /* Linear animation */
}


.wrapper[data-anim~=wrapper] {
-webkit-animation-duration: 0.01s; /* Complete keyframes asap */
-webkit-animation-delay: 3s; /* Wait half of the animation */
-webkit-animation-name: close-wrapper; /* Keyframes name */
}


.circle[data-anim~=left] {
-webkit-animation-duration: 6s; /* Full animation time */
-webkit-animation-name: left-spin;
}


.circle[data-anim~=right] {
-webkit-animation-duration: 3s; /* Half animation time */
-webkit-animation-name: right-spin;
}
/* Rotate the right side of the progress bar from 0 to 180 degrees */
@-webkit-keyframes right-spin {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(180deg);
}
}
/* Rotate the left side of the progress bar from 0 to 360 degrees */
@-webkit-keyframes left-spin {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
}
}
/* Set the wrapper clip to auto, effectively removing the clip */
@-webkit-keyframes close-wrapper {
to {
clip: rect(auto, auto, auto, auto);
}
}
<div class="wrapper" data-anim="base wrapper">
<div class="circle" data-anim="base left"></div>
<div class="circle" data-anim="base right"></div>
</div>

也检查这个 在这里拉小提琴(仅 CSS)

@import url(http://fonts.googleapis.com/css?family=Josefin+Sans:100,300,400);
    

.arc1 {
width: 160px;
height: 160px;
background: #00a0db;
-webkit-transform-origin: -31% 61%;
margin-left: -30px;
margin-top: 20px;
-webkit-transform: translate(-54px,50px);
-moz-transform: translate(-54px,50px);
-o-transform: translate(-54px,50px);
}
.arc2 {
width: 160px;
height: 160px;
background: #00a0db;
-webkit-transform: skew(45deg,0deg);
-moz-transform: skew(45deg,0deg);
-o-transform: skew(45deg,0deg);
margin-left: -180px;
margin-top: -90px;
position: absolute;
-webkit-transition: all .5s linear;
-moz-transition: all .5s linear;
-o-transition: all .5s linear;
}


.arc-container:hover .arc2 {
margin-left: -50px;
-webkit-transform: skew(-20deg,0deg);
-moz-transform: skew(-20deg,0deg);
-o-transform: skew(-20deg,0deg);
}


.arc-wrapper {
width: 150px;
height: 150px;
border-radius:150px;
background: #424242;
overflow:hidden;
left: 50px;
top: 50px;
position: absolute;
}
.arc-hider {
width: 150px;
height: 150px;
border-radius: 150px;
border: 50px solid #e9e9e9;
position:absolute;
z-index:5;
box-shadow:inset 0px 0px 20px rgba(0,0,0,0.7);
}


.arc-inset  {
font-family: "Josefin Sans";
font-weight: 100;
position: absolute;
font-size: 413px;
margin-top: -64px;
z-index: 5;
left: 30px;
line-height: 327px;
height: 280px;
-webkit-mask-image: -webkit-linear-gradient(top, rgba(0,0,0,1), rgba(0,0,0,0.2));
}
.arc-lowerInset {
font-family: "Josefin Sans";
font-weight: 100;
position: absolute;
font-size: 413px;
margin-top: -64px;
z-index: 5;
left: 30px;
line-height: 327px;
height: 280px;
color: white;
-webkit-mask-image: -webkit-linear-gradient(top, rgba(0,0,0,0.2), rgba(0,0,0,1));
}
.arc-overlay {
width: 100px;
height: 100px;
background-image: linear-gradient(bottom, rgb(217,217,217) 10%, rgb(245,245,245) 90%, rgb(253,253,253) 100%);
background-image: -o-linear-gradient(bottom, rgb(217,217,217) 10%, rgb(245,245,245) 90%, rgb(253,253,253) 100%);
background-image: -moz-linear-gradient(bottom, rgb(217,217,217) 10%, rgb(245,245,245) 90%, rgb(253,253,253) 100%);
background-image: -webkit-linear-gradient(bottom, rgb(217,217,217) 10%, rgb(245,245,245) 90%, rgb(253,253,253) 100%);


padding-left: 32px;
box-sizing: border-box;
-moz-box-sizing: border-box;
line-height: 100px;
font-family: sans-serif;
font-weight: 400;
text-shadow: 0 1px 0 #fff;
font-size: 22px;
border-radius: 100px;
position: absolute;
z-index: 5;
top: 75px;
left: 75px;
box-shadow:0px 0px 20px rgba(0,0,0,0.7);
}
.arc-container {
position: relative;
background: #e9e9e9;
height: 250px;
width: 250px;
}
<div class="arc-container">
<div class="arc-hider"></div>
<div class="arc-inset">
o
</div>
<div class="arc-lowerInset">
o
</div>
<div class="arc-overlay">
35%
</div>
<div class="arc-wrapper">
<div class="arc2"></div>
<div class="arc1"></div>
</div>
</div>

或者这个带有 HTML5、 CSS3和 JavaScript 的漂亮的 圆形进度条进度条

另一个纯粹的基于 css 的解决方案,是基于两个剪切圆形元素,我旋转到正确的角度:

Http://jsfiddle.net/maayan/byt76/

这是基本的 css,使它:

.clip1 {
position:absolute;
top:0;left:0;
width:200px;
height:200px;
clip:rect(0px,200px,200px,100px);
}
.slice1 {
position:absolute;
width:200px;
height:200px;
clip:rect(0px,100px,200px,0px);
-moz-border-radius:100px;
-webkit-border-radius:100px;
border-radius:100px;
background-color:#f7e5e1;
border-color:#f7e5e1;
-moz-transform:rotate(0);
-webkit-transform:rotate(0);
-o-transform:rotate(0);
transform:rotate(0);
}


.clip2
{
position:absolute;
top:0;left:0;
width:200px;
height:200px;
clip:rect(0,100px,200px,0px);
}


.slice2
{
position:absolute;
width:200px;
height:200px;
clip:rect(0px,200px,200px,100px);
-moz-border-radius:100px;
-webkit-border-radius:100px;
border-radius:100px;
background-color:#f7e5e1;
border-color:#f7e5e1;
-moz-transform:rotate(0);
-webkit-transform:rotate(0);
-o-transform:rotate(0);
transform:rotate(0);
}

然后 js 根据需要旋转它。

很容易理解。

希望能有所帮助, 玛雅人

怎么样?

超文本标示语言

<div class="chart" id="graph" data-percent="88"></div>

Javascript

var el = document.getElementById('graph'); // get canvas


var options = {
percent:  el.getAttribute('data-percent') || 25,
size: el.getAttribute('data-size') || 220,
lineWidth: el.getAttribute('data-line') || 15,
rotate: el.getAttribute('data-rotate') || 0
}


var canvas = document.createElement('canvas');
var span = document.createElement('span');
span.textContent = options.percent + '%';


if (typeof(G_vmlCanvasManager) !== 'undefined') {
G_vmlCanvasManager.initElement(canvas);
}


var ctx = canvas.getContext('2d');
canvas.width = canvas.height = options.size;


el.appendChild(span);
el.appendChild(canvas);


ctx.translate(options.size / 2, options.size / 2); // change center
ctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI); // rotate -90 deg


//imd = ctx.getImageData(0, 0, 240, 240);
var radius = (options.size - options.lineWidth) / 2;


var drawCircle = function(color, lineWidth, percent) {
percent = Math.min(Math.max(0, percent || 1), 1);
ctx.beginPath();
ctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, false);
ctx.strokeStyle = color;
ctx.lineCap = 'round'; // butt, round or square
ctx.lineWidth = lineWidth
ctx.stroke();
};


drawCircle('#efefef', options.lineWidth, 100 / 100);
drawCircle('#555555', options.lineWidth, options.percent / 100);

和 CSS

div {
position:relative;
margin:80px;
width:220px; height:220px;
}
canvas {
display: block;
position:absolute;
top:0;
left:0;
}
span {
color:#555;
display:block;
line-height:220px;
text-align:center;
width:220px;
font-family:sans-serif;
font-size:40px;
font-weight:100;
margin-left:5px;
}

Http://jsfiddle.net/aapn8/3410/

基本代码取自简单 PIE 图 http://rendro.github.io/easy-pie-chart/

径向进度条的柔性 SVG 解决方案: SVG 内圆边长计算(通过计算)的解决方案。

样品中的进度圆是覆盖在元素上的,并且可以是透明的。

jQuery(function($){
setTimeout(() => $('#element1 [data-role="radial-progress"]').css('--progress-percent', '100'), 1000);
$('#element2 [data-role="radial-progress"]').css('--progress-percent', '80');
$('#element3 [data-role="radial-progress"]').css('--progress-percent', '100');
 

let progress4 = 0;
let progress4incrementor = setInterval(() => {
progress4++;
$('#element4 .value').html(progress4 + '%');
$('#element4 [data-role="radial-progress"]').css('--progress-percent', progress4.toString());
if (progress4 >= 100) clearInterval(progress4incrementor);
}, 100);
});
.element
{
position: relative;
}
[data-role="radial-progress"]
{
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
z-index: 1;
--progress-percent: 0;
--progress-color: #CC000077;
--progress-bar-width: 100%;
}
[data-role="radial-progress"] > circle
{
stroke-width: var(--progress-bar-width);
stroke-dasharray: calc(100% * 3.141592);
stroke-dashoffset: calc(100% * (100 - var(--progress-percent))/100 * 3.141592);
stroke: var(--progress-color);
}






/*Just for animate --data-percent */
#element1 [data-role="radial-progress"] > circle
{
transition: stroke-dashoffset 4s linear;
}


#element2 [data-role="radial-progress"] > circle
{
transition: stroke-dashoffset 2s linear;
}
#element3 [data-role="radial-progress"] > circle
{
transition: stroke-dashoffset 6s linear;
}
#element4 [data-role="radial-progress"] > circle
{
transition: stroke-dashoffset 0.1s linear;
}
/*Сode that does not depend on radial-progress*/
.element
{
background-image: url(https://static.wikia.nocookie.net/dune/images/2/2f/Duneii-wind-trap.jpg/revision/latest);
background-size: 100% 100%;
display: inline-block;
width: 180px;
height: 110px;
border: 2px solid red;
text-align: center;
color: red;
}
#element3
{
width: 110px;
}
#element3 [data-role="radial-progress"]
{
transform: rotate(-90deg);
}


#element4
{
display: inline-flex;
align-items: center;
justify-content: center;
}
#element4 .value
{
font-size: 2em;
font-weight: bold;
z-index: 2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<div id="element1" class="element">
Content
<svg data-role="radial-progress" width="100%" height="100%" viewPort="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg"><circle r="50%" cx="50%" cy="50%" fill="transparent"></circle></svg>
</div>


<div id="element2" class="element">
Content
<svg style="--progress-percent:30" data-role="radial-progress" width="100%" height="100%" viewPort="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg"><circle r="50%" cx="50%" cy="50%" fill="transparent"></circle></svg>
</div>




<div id="element3" class="element">
Content
<svg style="--progress-bar-width:10px;--progress-color:red;" data-role="radial-progress" width="100%" height="100%" viewPort="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg"><circle r="44%" cx="50%" cy="50%" fill="transparent"></circle></svg>
</div>


<div id="element4" class="element">
<span class="value">0%</span>
<svg data-role="radial-progress" width="100%" height="100%" viewPort="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg"><circle r="50%" cx="50%" cy="50%" fill="transparent"></circle></svg>
</div>

看看这个:)

我用 圆锥曲线-梯度曲线做了这个。

background: conic-gradient(
SomeColor1 80%,
SomeColor2 80%
);

可以使用圆锥渐变创建 饼图

div {
background: conic-gradient(
red 36deg, orange 36deg 170deg, yellow 170deg);
border-radius: 50%
}

我只为饼图选择了两种颜色。

  background: conic-gradient(
rgb(3, 133, 255) 80%,
rgb(242, 242, 242) 80%
);

enter image description here

然后在饼图顶部放置一个 div,使其看起来像一个循环进度指示器。然后使用 HTMLDOMinnerHTML 选项设置进度。

enter image description here

然后,可以使用增量 Progress ()和减量 Progress ()函数动态地更改进程。

按照我完整的例子得到一些想法:)

您可以使用这个来制作上传/下载进度指示器、仪表板图表等等。

<html>
<head>
<style>
body {
display: flex;
align-items: center;
justify-content: center;
}


#progress-spinner {
border-radius: 50%;
height: 100px;
width: 100px;
}


#middle-circle {
position: absolute;
border-radius: 50%;
height: 80px;
width: 80px;
background-color: rgb(248, 248, 248);
display: flex;
align-items: center;
justify-content: center;
font-size: large;
font-weight: bold;
}
</style>
</head>
<body>
<div
style="
position: relative;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
"
>
<div
style="
position: relative;
display: flex;
justify-content: center;
align-items: center;
"
>
<div id="middle-circle"></div>
<div id="progress-spinner"></div>
</div>


<div style="margin-top: 30px">
<button type="button" id="incbtn">+</button>
<button type="button" id="decbtn">-</button>
</div>
</div>


<script>
var progress = 0;


document
.getElementById("incbtn")
.addEventListener("click", incrementProgress);
document
.getElementById("decbtn")
.addEventListener("click", decrementProgress);


function incrementProgress() {
if (progress != 100) {
progress = progress + 10;
console.log(progress);
setProgress();
}
}


function decrementProgress() {
if (progress != 0) {
progress = progress - 10;
console.log(progress);
setProgress();
}
}


function setProgress() {
document.getElementById("progress-spinner").style.background =
"conic-gradient(rgb(3, 133, 255) " +
progress +
"%,rgb(242, 242, 242) " +
progress +
"%)";


document.getElementById("middle-circle").innerHTML =
progress.toString() + "%";
}


window.onload = function () {
setProgress();
};
</script>
</body>
</html>

与新的 @property.看看支持表有不同的想法

@property --a {
syntax: '<angle>';
inherits: false;
initial-value: 90deg;
}


.circle {
width: 120px;
height: 120px;
padding: 12px;
box-sizing: border-box;
-webkit-mask:
conic-gradient(#000 var(--a), transparent var(--a)),
linear-gradient(#000, #000) content-box;
-webkit-mask-composite: source-out;
mask-composite: subtract;
background: tomato;
border-radius: 50%;
animation: progress 1s .3s linear forwards;
}


@keyframes progress {
to {
--a: 250deg;
}
}
<div class="circle"></div>

And I saw a more powerful example by Alvaro Montoro. Be sure to check this out.

一种简约的方法,只使用一个元素和一对夫妇的属性:

enter image description here

使用 data-progress定义内部标签,使用 --progress定义从 0deg360deg的进度。

<div data-progress="36" style="--progress: 36deg;">36%</div>

div {
display: flex;
width: 100px;
height: 100px;
border-radius: 50%;
background: conic-gradient(red var(--progress), gray 0deg);
font-size: 0;
}


div::after {
content: attr(data-progress) '%';
display: flex;
justify-content: center;
flex-direction: column;
width: 100%;
margin: 10px;
border-radius: 50%;
background: white;
font-size: 1rem;
text-align: center;
}
<div data-progress="36" style="--progress: 36deg;">36%</div>

Here's a naïve approach to the animation, again all CSS, no JS and just one element:

div {
display: flex;
width: 100px;
height: 100px;
border-radius: 50%;
background: conic-gradient(red var(--progress), gray 0deg);
font-size: 0;
animation: .4s ease-out turn_in reverse;
}


div::after {
content: attr(data-progress);
display: flex;
justify-content: center;
flex-direction: column;
width: 100%;
margin: 10px;
border-radius: 50%;
background: white;
font-size: 1rem;
text-align: center;
}


@keyframes turn_in {
5% {
background: conic-gradient(red calc(var(--progress) * .95), gray 0deg);
}
10% {
background: conic-gradient(red calc(var(--progress) * .9), gray 0deg);
}
15% {
background: conic-gradient(red calc(var(--progress) * .85), gray 0deg);
}
20% {
background: conic-gradient(red calc(var(--progress) * .8), gray 0deg);
}
25% {
background: conic-gradient(red calc(var(--progress) * .75), gray 0deg);
}
30% {
background: conic-gradient(red calc(var(--progress) * .7), gray 0deg);
}
35% {
background: conic-gradient(red calc(var(--progress) * .65), gray 0deg);
}
40% {
background: conic-gradient(red calc(var(--progress) * .6), gray 0deg);
}
45% {
background: conic-gradient(red calc(var(--progress) * .55), gray 0deg);
}
50% {
background: conic-gradient(red calc(var(--progress) * .5), gray 0deg);
}
55% {
background: conic-gradient(red calc(var(--progress) * .45), gray 0deg);
}
60% {
background: conic-gradient(red calc(var(--progress) * .4), gray 0deg);
}
65% {
background: conic-gradient(red calc(var(--progress) * .35), gray 0deg);
}
70% {
background: conic-gradient(red calc(var(--progress) * 0.3), gray 0deg);
}
75% {
background: conic-gradient(red calc(var(--progress) * 0.25), gray 0deg);
}
80% {
background: conic-gradient(red calc(var(--progress) * .2), gray 0deg);
}
85% {
background: conic-gradient(red calc(var(--progress) * .15), gray 0deg);
}
90% {
background: conic-gradient(red calc(var(--progress) * .1), gray 0deg);
}
95% {
background: conic-gradient(red calc(var(--progress) * .05), gray 0deg);
}
100% {
background: conic-gradient(gray 0deg);
}
}
<div data-progress="85%" style="--progress: 85%;">85%</div>

Disclaimer: cross-browsing not tested.

接近你的数据你可以改变过程像 <div ... data-num="50">输出 50%那样去显示完全动画的圆圈和数字。

  • data-num="/* 0-100 */"的变化。
  • 您可以添加多个进程,如 5,10
  • 使用 JavascriptCSSHtml与动画 circlenumber

Output

enter image description here

Code

let items = document.querySelectorAll('.progress-item');
const counters = Array(items.length);
const intervals = Array(items.length);
counters.fill(0);
items.forEach((number,index) => {
intervals[index] = setInterval(() => {
if(counters[index] == parseInt(number.dataset.num)){
clearInterval(intervals[index]);
}else{
counters[index] += 1;
number.style.background = "conic-gradient(red calc(" + counters[index] + "%), gray 0deg)";
number.setAttribute('data-value', counters[index] + "%");
number.innerHTML = counters[index] + "%";
}
}, 15);
});
#progress{
display: flex;
justify-content: space-around;
}
.progress-item {
display: flex;
width: 100px;
height: 100px;
border-radius: 50%;
font-size: 0;
animation: .4s ease-out reverse;
}


.progress-item::after {
content: attr(data-value);
display: flex;
justify-content: center;
flex-direction: column;
width: 100px;
margin: 10px;
border-radius: 50%;
background: white;
font-size: 1rem;
text-align: center;
}
<div id="progress" >
<div data-num="40" class="progress-item">sd</div>
<div data-num="80" class="progress-item">sd</div>
<div data-num="57" class="progress-item">sd</div>
<div data-num="83" class="progress-item">sd</div>
<div data-num="90" class="progress-item">ds</div>
</div>