我目前有一个像“实心”边框的径向进度条,我想要一个带有截面的径向进度条(比如“虚线”边框,但对它有更多控制)。
我在寻找:
这是我到目前为止所做的:
var el = document.getElementById('graph'); // get canvas
var options = {
percent: el.getAttribute('data-percent'),
size: el.getAttribute('data-size'),
lineWidth: el.getAttribute('data-line'),
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
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('#57d39d', options.lineWidth, 100 / 100);
drawCircle('#14928e', options.lineWidth, options.percent / 100);
div {
position: relative;
margin: 30px;
width: 110px;
height: 110px;
}
canvas {
display: block;
position: absolute;
top: 0;
left: 0;
}
span {
color: black;
display: block;
line-height: 110px;
text-align: center;
width: 110px;
font-family: sans-serif;
font-weight: bold;
font-size: 30px;
margin-left: 5px;
}
<div class="chart" id="graph" data-percent="30" data-size="110" data-line="6"></div>
答案 0 :(得分:3)
受到sass & haml笔的启发:
代码段下面的Demo和纯HTML / CSS
.boo {
text-align: left;
position: absolute;
top: 50%;
left: 50%;
margin: -35px;
width: 70px;
height: 70px;
background: lime;
z-index: -1;
border-radius: 100%;
}
.boo:nth-child(1) {
transform: rotate(-71deg) translate(70px);
}
.boo:nth-child(2) {
transform: rotate(1deg) translate(70px);
}
.boo:nth-child(3) {
transform: rotate(73deg) translate(70px);
}
.boo:nth-child(4) {
transform: rotate(145deg) translate(70px);
}
.boo:nth-child(5) {
transform: rotate(217deg) translate(70px);
}
.a1 .boo + .boo {
background: gray;
}
.a2 .boo:nth-child(2) ~ .boo {
background: gray;
}
.a3 .boo:nth-child(3) ~ .boo {
background: gray;
}
.a4 .boo:nth-child(4) ~ .boo {
background: gray;
}
.a1:after {
content: '1/5';
}
.a2:after {
content: '2/5';
}
.a3:after {
content: '3/5';
}
.a4:after {
content: '4/5';
}
.a5:after {
content: '5/5';
}
.gge {
float: left;
font-size: 50px;
position: relative;
width: 150px;
border-radius: 100%;
text-align: center;
margin: 20px 10px ;
padding: 15px;
overflow: hidden;
}
.gge:before {
content: '';
display: inline-block;
padding: 50% 0;
margin-left: -0.25em;
vertical-align: middle;
z-index: 2;
}
.gge:after {
line-height: 150px;
position: absolute;
z-index: 1;
background: white;
border-radius: 100%;
left: 15px;
top: 15px;
right: 15px;
bottom: 15px;
}
.boo:before,
.boo:after {
left: auto;
content: '';
position: absolute;
height: 20px;
width: 16px;
background: inherit;
border-radius: 8px;
transform: rotate(-35deg);
}
.boo:before {
top: -7px;
right: 21px;
}
.boo:after {
transform: rotate(30deg);
bottom: -7px;
right: 21px;
left: auto;
}
&#13;
<div class='gge a1'>
<div class='boo'></div>
<div class='boo'></div>
<div class='boo'></div>
<div class='boo'></div>
<div class='boo'></div>
</div>
<div class='gge a2'>
<div class='boo'></div>
<div class='boo'></div>
<div class='boo'></div>
<div class='boo'></div>
<div class='boo'></div>
</div>
<div class='gge a3'>
<div class='boo'></div>
<div class='boo'></div>
<div class='boo'></div>
<div class='boo'></div>
<div class='boo'></div>
</div>
<div class='gge a4'>
<div class='boo'></div>
<div class='boo'></div>
<div class='boo'></div>
<div class='boo'></div>
<div class='boo'></div>
</div>
<div class='gge a5'>
<div class='boo'></div>
<div class='boo'></div>
<div class='boo'></div>
<div class='boo'></div>
<div class='boo'></div>
</div>
&#13;
答案 1 :(得分:3)
你可以完全使用破折号模式。只需根据圆周长度计算短划线模式:
假设变量已声明:
radius = 140;
circum = 2 * Math.PI * radius;
gap = 7;
sections = 5;
dashOn = circum / sections - gap;
然后以这种方式设置破折号模式:
ctx.setLineDash([dashOn, gap]); // set dash pattern
ctx.lineDashOffset = -gap * 0.5; // center dash gap
我想让第一个间隙/部分朝上,你只需要首先旋转上下文-90°。
更新:如果您想为每个细分受众群提供圆顶上限,只需执行以下操作:
ctx.lineCap = "round";
然而,“上限”将消耗部分差距,因此我们需要通过将线宽添加到间隙值来补偿间隙的大小。
演示如何设置和删除短划线图案,并演示如何旋转上下文以便从顶部位置绘制剖面,以及如何制作圆角。
var ctx = c.getContext("2d"),
radius = 140,
circum = 2 * Math.PI * radius,
lineWidth = 12,
gap = 9 + lineWidth; // compensate for rounded caps
function render() {
var sections = s.max = +seg.value;
var dashOn = circum / sections - gap;
var t = +s.value / sections; // normalize value on sections
ctx.clearRect(0, 0, 300, 300); // clear previous drawn content
ctx.setTransform(1,0,0,1, 150, 150); // translate to center
ctx.rotate(-Math.PI*0.5); // rotate -90° so 0° is up
ctx.beginPath();
ctx.arc(0,0,radius, Math.PI*2*t, Math.PI*2); // circle from angle x t
ctx.setLineDash([dashOn, gap]); // set dash pattern
ctx.lineDashOffset = -gap * 0.5; // center dash gap
ctx.lineWidth = lineWidth; // line width
ctx.lineCap = "round"; // line width
ctx.strokeStyle = "#9ac"; // base color
ctx.stroke(); // render it
ctx.beginPath();
ctx.arc(0, 0, radius, 0, Math.PI*2 * t); // render arc based on angle x t
ctx.strokeStyle = "#06c"; // top color
ctx.stroke();
ctx.setLineDash([]); // reset dash
ctx.setTransform(1,0,0,1,0,0); // reset transforms
// render text here
}
(s.oninput = seg.oninput = render)(); // demo slider and first run
<label>Segments: <input id=seg type=range min=3 max=40 value=5></label><br>
<label>Progress: <input id=s type=range min=0 max=5 value=0></label><br>
<canvas id=c height=300></canvas>