我正在尝试使用SVG和JS的一个点来创建一个30秒倒数计时器显示。这个想法很简单
window.requestAnimationFrame
以一秒的间隔更新该扇区我的努力如下所示。虽然它有效但最终的结果远非流畅和令人信服。
我在这里做错了什么,怎么可以改进?
var _hold = {tickStart:0,stopTime:30,lastDelta:0};
String.prototype.format = function (args)
{
var newStr = this,key;
for (key in args) {newStr = newStr.replace('{' + key + '}',args[key]);}
return newStr;
};
Boolean.prototype.intval = function(places)
{
places = ('undefined' == typeof(places))?0:places;
return (~~this) << places;
};
function adjustSpent(timeStamp)
{
if (0 === _hold.tickStart) _hold.tickStart = timeStamp;
var delta = Math.trunc((timeStamp - _hold.tickStart)/1000);
if (_hold.lastDelta < delta)
{
_hold.lastDelta = delta;
var angle = 2*Math.PI*(delta/_hold.stopTime),
dAngle = 57.2958*angle,
cx = cy = 50,
radius = 38,
top = 12,
x = cx + radius*Math.sin(angle),
y = cy - radius*Math.cos(angle),
large = (180 < dAngle).intval();
var d = (360 <= dAngle)?"M50,50 L50,12 A38,38 1 0,1 51,12 z":"M50,50 L50,12 A38,38 1 {ll},1 {xx},{yy} z".format({ll:large,xx:x,yy:y});
var spent = document.getElementById('spent');
if (spent) spent.setAttribute("d",d);
}
if (delta < _hold.stopTime) window.requestAnimationFrame(adjustSpent);
}
window.requestAnimationFrame(adjustSpent);
timer
{
position:absolute;
height:20vh;
width:20vh;
border-radius:100%;
background-color:orange;
left:calc(50vw - 5vh);
top:15vh;
}
#clockface{fill:white;}
#spent{fill:#6683C2;}
<timer>
<svg width="20vh" height="20vh" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="38" id="clockface"></circle>
<path d="M50,50 L50,12 A38,38 1 0,1 51,12 z" id="spent"></path>
</svg>
</timer>
一个可能的解决方案是使用这样的笔画动画:
蓝色圆圈的半径为38/2 = 19
蓝色圆圈的stroke-width
是38,给出了38个单位的圆圈的错觉。
请看一下路径:它也是一个半径= 19的圆。
svg {
border: 1px solid;
height:90vh;
}
#clockface {
fill: silver;
}
#spent {
fill:none;
stroke: #6683c2;
stroke-width: 38px;
stroke-dasharray: 119.397px;
stroke-dashoffset: 119.397px;
animation: dash 5s linear infinite;
}
@keyframes dash {
to {
stroke-dashoffset: 0;
}
}
<svg viewBox="0 0 100 100">
<circle cx="50" cy="50" r="38" id="clockface"></circle>
<path d="M50,31 A19,19 1 0,1 50,69 A19,19 1 0,1 50,31" id="spent"></path>
</svg>
在这种情况下,我使用了css动画,但您可以使用JavaScript控制stroke-dashoffset
的值。
使用stroke-dasharray
获得spent.getTotalLength()
的值
如果您不熟悉SVG中的中风动画,请阅读qazxsw poi