我正在尝试寻找一种方法来实现没有动画的简单进度圈(静态)。我发现的示例具有非常不同的百分比偏移量,如下例所示。如何以这样的方式制作进度圈:如果我提供偏移量为 50%,那么它恰好是 50%(半填充)?
.u-absoluteCenter {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
}
.u-flexCenter {
display: flex;
align-items: center;
justify-content: center;
}
.u-offscreen {
position: absolute;
left: -999em;
}
.demo {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
display: flex;
align-items: center;
justify-content: center;
}
.progress {
transform: rotate(-90deg);
}
.progress__value {
stroke-dasharray: 0;
stroke-dashoffset: 0;
}
@-webkit-keyframes progress {
from {
stroke-dashoffset: 339.292;
}
to {
stroke-dashoffset: 0;
}
}
@keyframes progress {
from {
stroke-dashoffset: 339.292;
}
to {
stroke-dashoffset: 0;
}
}
<svg width="120" height="120" viewBox="0 0 120 120">
<circle cx="60" cy="60" r="54" fill="none" stroke="#e6e6e6" stroke-width="12" />
<circle cx="60" cy="60" r="54" fill="none" stroke="#f77a52" stroke-width="12"
stroke-dasharray="339.292" stroke-dashoffset="339.292" />
</svg>
您可以利用 SVG 属性来设置路径长度,而不必计算它。
pathLength
将长度设置为您需要的任何长度...例如进度条为 100。
pathLength 属性允许作者以用户单位指定路径的总长度。然后,通过使用路径长度/(路径长度的计算值)比率缩放所有距离计算,该值用于校准浏览器的距离计算与作者的距离计算。
pathLength="100"
然后您也可以将
stroke-dasharray
设置为 100,然后根据需要调整 stroke-dashoffset
....
::root {
--val: 0;
}
svg {
transform: rotate(-90deg);
}
.percent {
stroke-dasharray: 100;
stroke-dashoffset: calc(100 - var(--val));
}
.fifty {
--val: 50;
}
.sixty {
--val: 60;
}
.ninety {
--val: 90;
}
<svg width="120" height="120" viewBox="0 0 120 120">
<circle cx="60" cy="60" r="54" fill="none" stroke="#e6e6e6" stroke-width="12" />
<circle class="percent fifty" cx="60" cy="60" r="54" fill="none" stroke="#f77a52" stroke-width="12" pathLength="100" />
</svg>
<svg width="120" height="120" viewBox="0 0 120 120">
<circle cx="60" cy="60" r="54" fill="none" stroke="#e6e6e6" stroke-width="12" />
<circle class="percent sixty" cx="60" cy="60" r="54" fill="none" stroke="#f77a52" stroke-width="12" pathLength="100" />
</svg>
<svg width="120" height="120" viewBox="0 0 120 120">
<circle cx="60" cy="60" r="54" fill="none" stroke="#e6e6e6" stroke-width="12" />
<circle class="percent ninety" cx="60" cy="60" r="54" fill="none" stroke="#f77a52" stroke-width="12" pathLength="100" />
</svg>
正如保利所说,
pathLength
是进步圈子的关键
现代 JavaScript Web 组件(所有现代浏览器都支持 JSWC)可实现可重用的 HTML 元素
<svg-progress-circle percent="30"></svg-progress-circle>
<svg-progress-circle percent="20" color="blue"></svg-progress-circle>
<svg-progress-circle percent="80" color="gold"></svg-progress-circle>
添加了用于交互式演示目的的范围输入。
Percent 是元素的一个属性,您可以使用如下代码设置:
document.getElementById("Slider1").percent = <PERCENTAGE>;
如果您不需要灰色虚线全圆,请从
pathLenght=120
path
中删除虚线设置
我使用了
path
而不是重叠 circles
,因为通过其他一些设置,几乎相同的代码可以创建饼图。
<style>
svg { width: 150px; background: teal }
svg-progress-circle[percent="100"] path { stroke: green }
</style>
<svg-progress-circle percent="30"></svg-progress-circle>
<svg-progress-circle percent="20" color="blue"></svg-progress-circle>
<svg-progress-circle percent="80" color="gold"></svg-progress-circle>
<script>
customElements.define("svg-progress-circle", class extends HTMLElement {
connectedCallback() {
let d = 'M5,30a25,25,0,1,1,50,0a25,25,0,1,1,-50,0'; // circle
this.innerHTML =
`<input type="range" min="0" max="100" step="10" value="30"`+ // delete 2 lines
` oninput="this.parentNode.percent=this.value" /><br>`+ // just for demo
`<svg viewBox="0 0 60 60">
<path stroke-dasharray="10 2" stroke-dashoffset="-19"
pathlength="120" d="${d}" fill="grey" stroke="lightgrey" stroke-width="5"/>
<path stroke-dasharray="30 70" stroke-dashoffset="-25"
pathlength="100" d="${d}" fill="none"
stroke="${this.getAttribute("color")||"red"}" stroke-width="5"/>
<text x="50%" y="57%" text-anchor="middle">30%</text></svg>`;
this.style.display='inline-block';
this.percent = this.getAttribute("percent");
}
set percent(val = 0) {
this.setAttribute("percent", val);
let dash = val + " " + (100 - val);
this.querySelector("path+path").setAttribute('stroke-dasharray', dash);
this.querySelector("text").innerHTML = val + "%";
this.querySelector("input").value = val;
}
})
</script>
注意:我正在开发一个完整的 Web 组件,它可以执行饼图和精美的进度圆圈,例如:
但是,它是众多副项目之一...HTML 示例和混淆的源代码可在 https://pie-meister.github.io/
获取我设法通过使用为 svg 元素提供的不同属性来创建这个简单的静态进度条:
这是进度条 80% 的示例
viewBox="0 0 100 100"
100 * 100 是盒子大小,方便计算。
cx="50" cy="50"
x=50, y=50 是圆的中心点。
r="45"
半径为45,因为描边宽度为10px,这样描边的边缘就在盒子的边缘。半径结束处的每一侧的描边都是 5px。
pathLength
允许以用户单位定义路径的总长度。因此在本例中为 100,因为我们希望整个圆为 100%。
stroke-dasharray
定义路径的破折号和间隙的图案。我们在这里使用值 80 20。填充部分占 80%,空部分占 20%。这样,一旦我们应用偏移,路径就会保持正确的形状。
stroke-dashoffset
定义笔划的起始位置。默认情况下它从右侧开始,因此将其定义为 -75 会将起点推到顶部。
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle
cx="50"
cy="50"
r="45"
fill="transparent"
stroke="#e0e0e0"
stroke-width="10px"
/>
<circle
cx="50"
cy="50"
r="45"
fill="transparent"
stroke="#60e6a8"
stroke-width="10px"
pathLength="100"
stroke-dasharray="80 20"
stroke-dashoffset="-75"
/>
<text x="50%" y="50%" text-anchor="middle" alignment-baseline="middle">80%</text>
</svg>