如何在进度圆的末端绘制一个小圆圈,并在其上方/上方添加一个小文本块?
示例img:
src/widgets/styles/qstylesheetstyle.cpp
{{1}}
感谢Andre的medium.com文章,我已经编辑了他的版本 - 一个UPDATED版本说明了我想要为给定的%值动态实现的内容:
然而,编译的CSS太多了。对于每百分之一的百分比来说,用于定位事物的CSS太多了。当前的CSS(@codepen示例)已经加权~50 KB。不是最好的做法。
我已经在基于JS Canvas的变体上取得了一些进展,将vert& horz居中img定位在画布上方。但对于一个好看的响应式网站来说,它真的是唯一的方法和最佳实践吗?
答案 0 :(得分:6)
CSS绝对不是正确的工具,我会敦促你放弃这个想法。 Canvas绝对是一个不错的选择,但对于响应式网站,我建议你使用SVG。使用SVG,可以根据用户输入轻松绘制进度圆,并在其顶部添加圆/点。
以下是首次创建进度循环时必须执行的步骤:
计算弧度角后,使用简单的三角函数根据角度在圆上找到一个点:
一旦找到该点,我们需要创建路径,使其从上一步中找到的点开始,到达圆心,然后到弧的起点,从该点再次将弧线绘制到原点。路径是以这种方式创建的,因为我们需要路径在所需的点结束(因为我们将标记附加到终点)。
要在其尖端添加点/圆,需要执行以下操作:
marker
元素添加到SVG,并使用circle
元素创建圆形标记。 circle
元素有3个属性 - cx,cy是点的中心点,r是点的半径。marker-end
属性,此标记会添加到path
。设置此属性意味着创建的任何路径都会在其结束点自动附加此点。不需要为此进行其他编码,因为SVG会自动处理定位。 也可以使用text
元素添加文字,然后可以使用x
和y
属性设置其位置。 (此位仍需要在下面的代码段中调整。)
<强>演示:强>
下面是一个非常粗略的实施演示。
window.onload = function() {
var btn = document.querySelector('button'),
inp = document.querySelector('#progress'),
path = document.querySelector('#p'),
text = document.querySelector('#val'),
rect = document.querySelector('rect'),
output = document.querySelector('#path-output');
var x = 0,
y = 0,
r = 30,
cx = 50,
cy = 50,
d = '',
fill = 'yellowgreen',
stroke = 'transparent';
btn.addEventListener('click', function() {
progress = (inp.value == '') ? 0 : inp.value;
arcRad = ((progress * 360 / 100) - 90) * Math.PI / 180;
x = Math.cos(arcRad) * r + cx;
y = Math.sin(arcRad) * r + cy;
if (progress > 0 && progress <= 50) {
d = 'M' + x + ',' + y + ' L' + cx + ',' + cy + ' L' + cx + ',' + (cy - r) + ' A' + r + ',' + r + ' 0 0,1' + x + ',' + y;
setColors(fill, stroke);
setOutput();
} else if (progress > 50 && progress <= 100) {
d = 'M' + x + ',' + y + ' L' + cx + ',' + cy + ' L' + cx + ',' + (cy - r) + ' A' + r + ',' + r + ' 0 0,1' + cx + ',' + (cy + r) + ' A' + r + ',' + r + ' 0 0,1' + x + ',' + y;
setColors(fill, stroke);
setOutput();
} else {
text.innerHTML = '';
path.setAttribute('d', '');
output.innerHTML = 'Enter a value between 0 and 100';
setColors('transparent', 'transparent');
}
if (progress > 0 && progress <= 10) {
rect.setAttribute('x', x);
rect.setAttribute('y', y + 7.5);
text.setAttribute('x', x + 2);
text.setAttribute('y', y + 15);
} else if (progress > 10 && progress <= 62) {
rect.setAttribute('x', x - 5);
rect.setAttribute('y', y + 7.5);
text.setAttribute('x', x - 3.5);
text.setAttribute('y', y + 15);
} else if (progress > 62 && progress <= 100) {
rect.setAttribute('x', x - 5);
rect.setAttribute('y', y - 15);
text.setAttribute('x', x - 3.5);
text.setAttribute('y', y - 7.5);
}
});
function setColors(fill, stroke) {
rect.setAttribute('fill', fill);
rect.setAttribute('stroke', stroke);
path.setAttribute('fill', fill);
path.setAttribute('stroke', stroke);
}
function setOutput() {
path.setAttribute('d', d);
text.innerHTML = progress;
output.innerHTML = 'Angle in Radians: ' + arcRad + '<br/>';
output.innerHTML += 'Point in Circle: ' + x + ',' + y + '<br/>';
output.innerHTML += 'Path d attribute: ' + d;
}
}
&#13;
svg {
width: 200px;
height: 200px;
}
.output {
min-height: 20px;
}
h4 {
border-bottom: 1px solid;
}
&#13;
<input id='progress' type='number' />
<button>Generate</button>
<br/>
<svg viewBox='0 0 100 100'>
<defs>
<marker id='dot' viewBox='0 0 10 10' markerHeight='10' markerWidth='10' refX='5' refY='5'>
<circle cx='5' cy='5' r='2' />
</marker>
</defs>
<path d='' marker-end='url(#dot)' id='p' stroke='transparent' fill='transparent' />
<rect height='10' width='10' x='10' y='10' stroke='transparent' fill='transparent' />
<text x='10' y='10' id='val' font-family='Arial' font-size='6'></text>
</svg>
<div class='output'>
<h4>Output:</h4>
<output id='path-output'></output>
</div>
&#13;
进一步阅读:
您可以在以下链接中阅读有关SVG及其元素和属性的更多信息: