可缩放 css 百分比环
Scaleable css percentage ring
我正在尝试将下面的代码基本上转换为可缩放版本,我已经尝试使用 vw 和 vh、%values 等,但我似乎无法获得有效值的正确平衡。感谢任何帮助。
此代码笔也可能有帮助:http://codepen.io/anon/pen/dPNgvP
.arrow {
position: relative;
height: 0px;
width: 0px;
border-top: 18px solid #dd1111;
border-left: 11px solid transparent;
border-right: 11px solid transparent;
position: absolute;
bottom: 40px;
left: 57px;
z-index: 1;
animation: load-arrow 1.6s linear;
animation-fill-mode: forwards;
-webkit-animation: load-arrow 1.6s linear;
-webkit-animation-fill-mode: forwards;
}
@keyframes load-arrow {
from {
transform: translate(0, 0);
}
to {
transform: translate(0, 55px);
}
}
@-webkit-keyframes load-arrow {
from {
-webkit-transform: translate(0, 0);
}
to {
-webkit-transform: translate(0, 55px);
}
}
.pie {
width: 140px;
height: 140px;
position: relative;
border-radius: 140px;
background-color: #DD1111;
float: left;
margin-right: 10px;
}
.pie .title {
position: absolute;
bottom: -40px;
text-align: center;
width: 100%;
}
.mask {
position: absolute;
width: 100%;
height: 100%;
}
.pie1 .inner-right {
transform: rotate(160deg);
animation: load-right-pie-1 1s linear;
-webkit-animation: load-right-pie-1 1s linear;
-webkit-transform: rotate(160deg);
}
@keyframes load-right-pie-1 {
from {
transform: rotate(0deg);
}
to {
transform: rotate(160deg);
}
}
@-webkit-keyframes load-right-pie-1 {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(160deg);
}
}
.outer-left {
clip: rect(0px 70px 140px 0px);
}
.outer-right {
clip: rect(0px 140px 140px 70px);
}
.inner-left {
background-color: #710000;
position: absolute;
width: 100%;
height: 100%;
border-radius: 100%;
clip: rect(0px 70px 140px 0px);
transform: rotate(-180deg);
-webkit-transform: rotate(-180deg);
}
.inner-right {
background-color: #710000;
position: absolute;
width: 100%;
height: 100%;
border-radius: 100%;
clip: rect(0px 70px 140px 0px);
transform: rotate(180deg);
-webkit-transform: rotate(180deg);
}
.content {
width: 100px;
height: 100px;
border-radius: 50%;
background-color: #fff;
position: absolute;
top: 20px;
left: 20px;
line-height: 100px;
font-family: arial, sans-serif;
font-size: 35px;
text-align: center;
z-index: 2;
}
.content span {
opacity: 0;
animation: load-content 3s;
animation-fill-mode: forwards;
animation-delay: 0.6s;
-webkit-animation: load-content 3s;
-webkit-animation-fill-mode: forwards;
-webkit-animation-delay: 0.6s;
}
@keyframes load-content {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@-webkit-keyframes load-content {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
<div class="pie pie1">
<div class="title">Twitter</div>
<div class="outer-right mask">
<div class="inner-right"></div>
</div>
<div class="outer-left mask">
<div class="inner-left"></div>
</div>
<div class="content">
<span>44%</span>
</div>
</div>
这是一个不错的插件pieProgress.js to do this. Here is the demo and the tutorial how to use this.
希望这能解决您的问题。
您可以使用 svg
和 JavaScript.
简化您的代码并使其动态化
此代码的作用是什么?
- 从
text
个标签中提取百分比值,计算角度并将其存储以用于动画。
- 将深色部分从
theta = 0
动画化到计算出的角度。
使用这种方法可以做的事情:
- 您可以通过简单地更改
text
标签中的 44%
来动态设置百分比。
- 有效格式---->
-%
|--%
|---%
,包括浮点值。
- 您可以通过更改
t
变量来更改动画速度。
- 你也可以让它响应。
CodePen 上的响应式演示 ---> width
和 [ svg
的 =25=] 取决于 #container
的 width
。
var dark = document.getElementById('dark'),
t = 5,
percentage = parseInt(document.getElementById('perc').innerHTML.slice(0, -1), 10),
theta = 0,
maxTheta = (180 * percentage) / 50,
radius = document.getElementById('svg').getBBox().width / 2;
dark.setAttribute('transform', 'translate(' + radius + ',' + radius + ')');
var animate = setInterval(function() {
theta += 0.5;
var d = 'M0,0 v' + -radius + 'A' + radius + ',' + radius + ' 1 ' + ((theta > 180) ? 1 : 0) + ',1 ' + Math.sin(theta * Math.PI / 180) * radius + ',' + Math.cos(theta * Math.PI / 180) * -radius + 'z';
dark.setAttribute('d', d);
if (theta > maxTheta) {
clearInterval(animate);
}
}, t);
<svg id="svg" width="140" height="140" viewBox="0 0 141 141">
<path id="light" d="M70,70 v-70 a70,70 0 0,1 0,140 a70,70 0 1,1 0,-140" fill="#DD1111" />
<path id="dark" d="M70,70 v-70 a70,70 0 0,1 0,0" fill="#710000" />
<path d="M20,70 a50,50 0 0,1 100,0 a50,50 0 0,1 -100,0" fill="white" />
<text id="perc" x="70" y="79" font-size="30px" text-anchor="middle">44%</text>
</svg>
要放置多个百分比环,您可以使用 class
es 而不是 id
s。同样,您无需对 JavaScript 代码进行任何更改,只需更改 text
标签中的百分比即可。
var dark = document.getElementsByClassName('dark'),
radius = document.getElementsByClassName('svg')[0].getBBox().width / 2,
t = 0.5,
x = 0,
y = 0,
theta = {},
maxTheta = calcTheta(document.getElementsByClassName('perc')),
intervals = [];
function calcTheta(el) {
var jbo = {};
for (i = 0; i < el.length; i++) {
theta[i] = 0;
dark[i].setAttribute('transform', 'translate(' + radius + ',' + radius + ')');
jbo[i] = (180 * parseInt(el[i].innerHTML.slice(0, -1), 10)) / 50;
}
return jbo;
}
var anim = function(j) {
return function() {
theta[j] += 0.5;
var d = 'M0,0 v' + -radius + 'A' + radius + ',' + radius + ' 1 ' + ((theta[j] > 180) ? 1 : 0) + ',1 ' + Math.sin(theta[j] * Math.PI / 180) * radius + ',' + Math.cos(theta[j] * Math.PI / 180) * -radius + 'z';
dark[j].setAttribute('d', d);
if (theta[j] > maxTheta[j]) {
clearInterval(intervals[j]);
}
}
};
for (var j = 0; j < dark.length; j++) {
intervals.push(setInterval(anim(j), t));
}
#container {
width: 100%;
}
.svg {
display: inline-block;
width: 16.5%;
}
<div id="container">
<svg class="svg" viewBox="0 0 141 141">
<path class="light" d="M70,70 v-70 a70,70 0 0,1 0,140 a70,70 0 1,1 0,-140" fill="#DD1111" />
<path class="dark" d="M70,70 v-70 a70,70 0 0,1 0,0" fill="#710000" />
<path d="M20,70 a50,50 0 0,1 100,0 a50,50 0 0,1 -100,0" fill="white" />
<text class="perc" x="70" y="79" font-size="30px" text-anchor="middle">44%</text>
</svg
><svg class="svg" viewBox="0 0 141 141">
<path class="light" d="M70,70 v-70 a70,70 0 0,1 0,140 a70,70 0 1,1 0,-140" fill="#DD1111" />
<path class="dark" d="M70,70 v-70 a70,70 0 0,1 0,0" fill="#710000" />
<path d="M20,70 a50,50 0 0,1 100,0 a50,50 0 0,1 -100,0" fill="white" />
<text class="perc" x="70" y="79" font-size="30px" text-anchor="middle">20%</text>
</svg
><svg class="svg" viewBox="0 0 141 141">
<path class="light" d="M70,70 v-70 a70,70 0 0,1 0,140 a70,70 0 1,1 0,-140" fill="#DD1111" />
<path class="dark" d="M70,70 v-70 a70,70 0 0,1 0,0" fill="#710000" />
<path d="M20,70 a50,50 0 0,1 100,0 a50,50 0 0,1 -100,0" fill="white" />
<text class="perc" x="70" y="79" font-size="30px" text-anchor="middle">90%</text>
</svg
><svg class="svg" viewBox="0 0 141 141">
<path class="light" d="M70,70 v-70 a70,70 0 0,1 0,140 a70,70 0 1,1 0,-140" fill="#DD1111" />
<path class="dark" d="M70,70 v-70 a70,70 0 0,1 0,0" fill="#710000" />
<path d="M20,70 a50,50 0 0,1 100,0 a50,50 0 0,1 -100,0" fill="white" />
<text class="perc" x="70" y="79" font-size="30px" text-anchor="middle">14%</text>
</svg
><svg class="svg" viewBox="0 0 141 141">
<path class="light" d="M70,70 v-70 a70,70 0 0,1 0,140 a70,70 0 1,1 0,-140" fill="#DD1111" />
<path class="dark" d="M70,70 v-70 a70,70 0 0,1 0,0" fill="#710000" />
<path d="M20,70 a50,50 0 0,1 100,0 a50,50 0 0,1 -100,0" fill="white" />
<text class="perc" x="70" y="79" font-size="30px" text-anchor="middle">60%</text>
</svg
><svg class="svg" viewBox="0 0 141 141">
<path class="light" d="M70,70 v-70 a70,70 0 0,1 0,140 a70,70 0 1,1 0,-140" fill="#DD1111" />
<path class="dark" d="M70,70 v-70 a70,70 0 0,1 0,0" fill="#710000" />
<path d="M20,70 a50,50 0 0,1 100,0 a50,50 0 0,1 -100,0" fill="white" />
<text class="perc" x="70" y="79" font-size="30px" text-anchor="middle">50%</text>
</svg>
</div>
我正在尝试将下面的代码基本上转换为可缩放版本,我已经尝试使用 vw 和 vh、%values 等,但我似乎无法获得有效值的正确平衡。感谢任何帮助。
此代码笔也可能有帮助:http://codepen.io/anon/pen/dPNgvP
.arrow {
position: relative;
height: 0px;
width: 0px;
border-top: 18px solid #dd1111;
border-left: 11px solid transparent;
border-right: 11px solid transparent;
position: absolute;
bottom: 40px;
left: 57px;
z-index: 1;
animation: load-arrow 1.6s linear;
animation-fill-mode: forwards;
-webkit-animation: load-arrow 1.6s linear;
-webkit-animation-fill-mode: forwards;
}
@keyframes load-arrow {
from {
transform: translate(0, 0);
}
to {
transform: translate(0, 55px);
}
}
@-webkit-keyframes load-arrow {
from {
-webkit-transform: translate(0, 0);
}
to {
-webkit-transform: translate(0, 55px);
}
}
.pie {
width: 140px;
height: 140px;
position: relative;
border-radius: 140px;
background-color: #DD1111;
float: left;
margin-right: 10px;
}
.pie .title {
position: absolute;
bottom: -40px;
text-align: center;
width: 100%;
}
.mask {
position: absolute;
width: 100%;
height: 100%;
}
.pie1 .inner-right {
transform: rotate(160deg);
animation: load-right-pie-1 1s linear;
-webkit-animation: load-right-pie-1 1s linear;
-webkit-transform: rotate(160deg);
}
@keyframes load-right-pie-1 {
from {
transform: rotate(0deg);
}
to {
transform: rotate(160deg);
}
}
@-webkit-keyframes load-right-pie-1 {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(160deg);
}
}
.outer-left {
clip: rect(0px 70px 140px 0px);
}
.outer-right {
clip: rect(0px 140px 140px 70px);
}
.inner-left {
background-color: #710000;
position: absolute;
width: 100%;
height: 100%;
border-radius: 100%;
clip: rect(0px 70px 140px 0px);
transform: rotate(-180deg);
-webkit-transform: rotate(-180deg);
}
.inner-right {
background-color: #710000;
position: absolute;
width: 100%;
height: 100%;
border-radius: 100%;
clip: rect(0px 70px 140px 0px);
transform: rotate(180deg);
-webkit-transform: rotate(180deg);
}
.content {
width: 100px;
height: 100px;
border-radius: 50%;
background-color: #fff;
position: absolute;
top: 20px;
left: 20px;
line-height: 100px;
font-family: arial, sans-serif;
font-size: 35px;
text-align: center;
z-index: 2;
}
.content span {
opacity: 0;
animation: load-content 3s;
animation-fill-mode: forwards;
animation-delay: 0.6s;
-webkit-animation: load-content 3s;
-webkit-animation-fill-mode: forwards;
-webkit-animation-delay: 0.6s;
}
@keyframes load-content {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@-webkit-keyframes load-content {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
<div class="pie pie1">
<div class="title">Twitter</div>
<div class="outer-right mask">
<div class="inner-right"></div>
</div>
<div class="outer-left mask">
<div class="inner-left"></div>
</div>
<div class="content">
<span>44%</span>
</div>
</div>
这是一个不错的插件pieProgress.js to do this. Here is the demo and the tutorial how to use this.
希望这能解决您的问题。
您可以使用 svg
和 JavaScript.
此代码的作用是什么?
- 从
text
个标签中提取百分比值,计算角度并将其存储以用于动画。 - 将深色部分从
theta = 0
动画化到计算出的角度。
使用这种方法可以做的事情:
- 您可以通过简单地更改
text
标签中的44%
来动态设置百分比。- 有效格式---->
-%
|--%
|---%
,包括浮点值。
- 有效格式---->
- 您可以通过更改
t
变量来更改动画速度。 - 你也可以让它响应。
CodePen 上的响应式演示 ---> width
和 [ svg
的 =25=] 取决于 #container
的 width
。
var dark = document.getElementById('dark'),
t = 5,
percentage = parseInt(document.getElementById('perc').innerHTML.slice(0, -1), 10),
theta = 0,
maxTheta = (180 * percentage) / 50,
radius = document.getElementById('svg').getBBox().width / 2;
dark.setAttribute('transform', 'translate(' + radius + ',' + radius + ')');
var animate = setInterval(function() {
theta += 0.5;
var d = 'M0,0 v' + -radius + 'A' + radius + ',' + radius + ' 1 ' + ((theta > 180) ? 1 : 0) + ',1 ' + Math.sin(theta * Math.PI / 180) * radius + ',' + Math.cos(theta * Math.PI / 180) * -radius + 'z';
dark.setAttribute('d', d);
if (theta > maxTheta) {
clearInterval(animate);
}
}, t);
<svg id="svg" width="140" height="140" viewBox="0 0 141 141">
<path id="light" d="M70,70 v-70 a70,70 0 0,1 0,140 a70,70 0 1,1 0,-140" fill="#DD1111" />
<path id="dark" d="M70,70 v-70 a70,70 0 0,1 0,0" fill="#710000" />
<path d="M20,70 a50,50 0 0,1 100,0 a50,50 0 0,1 -100,0" fill="white" />
<text id="perc" x="70" y="79" font-size="30px" text-anchor="middle">44%</text>
</svg>
要放置多个百分比环,您可以使用 class
es 而不是 id
s。同样,您无需对 JavaScript 代码进行任何更改,只需更改 text
标签中的百分比即可。
var dark = document.getElementsByClassName('dark'),
radius = document.getElementsByClassName('svg')[0].getBBox().width / 2,
t = 0.5,
x = 0,
y = 0,
theta = {},
maxTheta = calcTheta(document.getElementsByClassName('perc')),
intervals = [];
function calcTheta(el) {
var jbo = {};
for (i = 0; i < el.length; i++) {
theta[i] = 0;
dark[i].setAttribute('transform', 'translate(' + radius + ',' + radius + ')');
jbo[i] = (180 * parseInt(el[i].innerHTML.slice(0, -1), 10)) / 50;
}
return jbo;
}
var anim = function(j) {
return function() {
theta[j] += 0.5;
var d = 'M0,0 v' + -radius + 'A' + radius + ',' + radius + ' 1 ' + ((theta[j] > 180) ? 1 : 0) + ',1 ' + Math.sin(theta[j] * Math.PI / 180) * radius + ',' + Math.cos(theta[j] * Math.PI / 180) * -radius + 'z';
dark[j].setAttribute('d', d);
if (theta[j] > maxTheta[j]) {
clearInterval(intervals[j]);
}
}
};
for (var j = 0; j < dark.length; j++) {
intervals.push(setInterval(anim(j), t));
}
#container {
width: 100%;
}
.svg {
display: inline-block;
width: 16.5%;
}
<div id="container">
<svg class="svg" viewBox="0 0 141 141">
<path class="light" d="M70,70 v-70 a70,70 0 0,1 0,140 a70,70 0 1,1 0,-140" fill="#DD1111" />
<path class="dark" d="M70,70 v-70 a70,70 0 0,1 0,0" fill="#710000" />
<path d="M20,70 a50,50 0 0,1 100,0 a50,50 0 0,1 -100,0" fill="white" />
<text class="perc" x="70" y="79" font-size="30px" text-anchor="middle">44%</text>
</svg
><svg class="svg" viewBox="0 0 141 141">
<path class="light" d="M70,70 v-70 a70,70 0 0,1 0,140 a70,70 0 1,1 0,-140" fill="#DD1111" />
<path class="dark" d="M70,70 v-70 a70,70 0 0,1 0,0" fill="#710000" />
<path d="M20,70 a50,50 0 0,1 100,0 a50,50 0 0,1 -100,0" fill="white" />
<text class="perc" x="70" y="79" font-size="30px" text-anchor="middle">20%</text>
</svg
><svg class="svg" viewBox="0 0 141 141">
<path class="light" d="M70,70 v-70 a70,70 0 0,1 0,140 a70,70 0 1,1 0,-140" fill="#DD1111" />
<path class="dark" d="M70,70 v-70 a70,70 0 0,1 0,0" fill="#710000" />
<path d="M20,70 a50,50 0 0,1 100,0 a50,50 0 0,1 -100,0" fill="white" />
<text class="perc" x="70" y="79" font-size="30px" text-anchor="middle">90%</text>
</svg
><svg class="svg" viewBox="0 0 141 141">
<path class="light" d="M70,70 v-70 a70,70 0 0,1 0,140 a70,70 0 1,1 0,-140" fill="#DD1111" />
<path class="dark" d="M70,70 v-70 a70,70 0 0,1 0,0" fill="#710000" />
<path d="M20,70 a50,50 0 0,1 100,0 a50,50 0 0,1 -100,0" fill="white" />
<text class="perc" x="70" y="79" font-size="30px" text-anchor="middle">14%</text>
</svg
><svg class="svg" viewBox="0 0 141 141">
<path class="light" d="M70,70 v-70 a70,70 0 0,1 0,140 a70,70 0 1,1 0,-140" fill="#DD1111" />
<path class="dark" d="M70,70 v-70 a70,70 0 0,1 0,0" fill="#710000" />
<path d="M20,70 a50,50 0 0,1 100,0 a50,50 0 0,1 -100,0" fill="white" />
<text class="perc" x="70" y="79" font-size="30px" text-anchor="middle">60%</text>
</svg
><svg class="svg" viewBox="0 0 141 141">
<path class="light" d="M70,70 v-70 a70,70 0 0,1 0,140 a70,70 0 1,1 0,-140" fill="#DD1111" />
<path class="dark" d="M70,70 v-70 a70,70 0 0,1 0,0" fill="#710000" />
<path d="M20,70 a50,50 0 0,1 100,0 a50,50 0 0,1 -100,0" fill="white" />
<text class="perc" x="70" y="79" font-size="30px" text-anchor="middle">50%</text>
</svg>
</div>