我已经创建了一个svg
百分比的戒指,如下所示。
var dark = document.getElementById('dark');
var light = document.getElementById('light');
var svg = document.getElementById('svg');
var t = 5;
var percentage = parseInt(document.getElementById('perc').innerHTML.slice(0, -1), 10);
var theta = 0;
var maxTheta = (180 * percentage) / 50;
var radius = svg.getAttribute('width') / 2;
dark.setAttribute('transform', 'translate(' + radius + ',' + radius + ')');
var animate = setInterval(function() {
theta += 0.5;
var x = Math.sin(theta * Math.PI / 180) * radius;
var y = Math.cos(theta * Math.PI / 180) * -radius;
var d = 'M0,0 v' + -radius + 'A' + radius + ',' + radius + ' 1 ' + ((theta > 180) ? 1 : 0) + ',1 ' + x + ',' + y + 'z';
dark.setAttribute('d', d);
if (theta > maxTheta) {
clearInterval(animate);
}
}, t);
<svg id="svg" width="140" height="140" viewBox="-1 -1 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>
它运行正常,但是我很难实现多个环的动画部分。
例如我有三个戒指。
我目前使用setInterval()
处理动画的方式是:
var animOne = setInterval(function() {
theta[0] += 0.5;
var x = Math.sin(theta[0] * Math.PI / 180) * radius;
var y = Math.cos(theta[0] * Math.PI / 180) * -radius;
var d = 'M0,0 v' + -radius + 'A' + radius + ',' + radius + ' 1 ' + ((theta[0] > 180) ? 1 : 0) + ',1 ' + x + ',' + y + 'z';
dark[0].setAttribute('d', d);
if (theta[0] > maxTheta[0]) {
clearInterval(animOne);
}
}, t);
var animTwo = setInterval(function() {
theta[1] += 0.5;
var x = Math.sin(theta[1] * Math.PI / 180) * radius;
var y = Math.cos(theta[1] * Math.PI / 180) * -radius;
var d = 'M0,0 v' + -radius + 'A' + radius + ',' + radius + ' 1 ' + ((theta[1] > 180) ? 1 : 0) + ',1 ' + x + ',' + y + 'z';
dark[1].setAttribute('d', d);
if (theta[1] > maxTheta[1]) {
clearInterval(animTwo);
}
}, t);
var animThree = setInterval(function() {
theta[2] += 0.5;
var x = Math.sin(theta[2] * Math.PI / 180) * radius;
var y = Math.cos(theta[2] * Math.PI / 180) * -radius;
var d = 'M0,0 v' + -radius + 'A' + radius + ',' + radius + ' 1 ' + ((theta[2] > 180) ? 1 : 0) + ',1 ' + x + ',' + y + 'z';
dark[2].setAttribute('d', d);
if (theta[2] > maxTheta[2]) {
clearInterval(animThree);
}
}, t);
这不是应该做的事情。
如何为此代码创建for
循环?
应该看起来像:
for (i = 0; i < dark.length; i++) {
var ____ = setInterval(function() {
theta[2] += 0.5;
var x = Math.sin(theta[i] * Math.PI / 180) * radius;
var y = Math.cos(theta[i] * Math.PI / 180) * -radius;
var d = 'M0,0 v' + -radius + 'A' + radius + ',' + radius + ' 1 ' + ((theta[i] > 180) ? 1 : 0) + ',1 ' + x + ',' + y + 'z';
dark[i].setAttribute('d', d);
if (theta[i] > maxTheta[i]) {
clearInterval(____);
}
}, t);
}
有可能做这样的事吗?如果没有,这怎么可能呢?
完整代码:
var dark = document.getElementsByClassName('dark');
var svg = document.getElementsByClassName('svg')[0];
var radius = svg.getBBox().width / 2;
var t = 0.5,
x = 0,
y = 0;
var theta = {
0: 0,
1: 0,
2: 0
};
var anims = {};
var maxTheta = calcTheta(document.getElementsByClassName('perc'));
for (i = 0; i < dark.length; i++) {
dark[i].setAttribute('transform', 'translate(' + radius + ',' + radius + ')');
}
function calcTheta(el) {
var jbo = {};
for (i = 0; i < el.length; i++) {
jbo[i] = (180 * parseInt(el[i].innerHTML.slice(0, -1), 10)) / 50;
}
return jbo;
}
var animOne = setInterval(function() {
theta[0] += 0.5;
var x = Math.sin(theta[0] * Math.PI / 180) * radius;
var y = Math.cos(theta[0] * Math.PI / 180) * -radius;
var d = 'M0,0 v' + -radius + 'A' + radius + ',' + radius + ' 1 ' + ((theta[0] > 180) ? 1 : 0) + ',1 ' + x + ',' + y + 'z';
dark[0].setAttribute('d', d);
if (theta[0] > maxTheta[0]) {
clearInterval(animOne);
}
}, t);
var animTwo = setInterval(function() {
theta[1] += 0.5;
var x = Math.sin(theta[1] * Math.PI / 180) * radius;
var y = Math.cos(theta[1] * Math.PI / 180) * -radius;
var d = 'M0,0 v' + -radius + 'A' + radius + ',' + radius + ' 1 ' + ((theta[1] > 180) ? 1 : 0) + ',1 ' + x + ',' + y + 'z';
dark[1].setAttribute('d', d);
if (theta[1] > maxTheta[1]) {
clearInterval(animTwo);
}
}, t);
var animThree = setInterval(function() {
theta[2] += 0.5;
var x = Math.sin(theta[2] * Math.PI / 180) * radius;
var y = Math.cos(theta[2] * Math.PI / 180) * -radius;
var d = 'M0,0 v' + -radius + 'A' + radius + ',' + radius + ' 1 ' + ((theta[2] > 180) ? 1 : 0) + ',1 ' + x + ',' + y + 'z';
dark[2].setAttribute('d', d);
if (theta[2] > maxTheta[2]) {
clearInterval(animThree);
}
}, t);
#container {
width: 100%;
}
svg {
display: inline-block;
}
<div id="container">
<svg class="svg" width="33%" height="33%" viewBox="0 0 141 141" shape-rendering="geometricPrecision">
<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" width="33%" height="33%" viewBox="0 0 141 141" shape-rendering="geometricPrecision">
<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" width="33%" height="33%" viewBox="0 0 141 141" shape-rendering="geometricPrecision">
<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>
</div>
答案 0 :(得分:1)
您可能会遇到上下文的问题。我们不会在for循环中创建函数:)有关更多信息,请参阅此&gt; https://jslinterrors.com/dont-make-functions-within-a-loop。所以,作为解决方法,做这样的事情? http://jsfiddle.net/Lrhxbc5c/
var intervals = [];
var getSetIntervalFunc = function (ii) {
return function () {
theta[ii] += 0.5;
var x = Math.sin(theta[ii] * Math.PI / 180) * radius;
var y = Math.cos(theta[ii] * Math.PI / 180) * -radius;
var d = 'M0,0 v' + -radius + 'A' + radius + ',' + radius + ' 1 ' + ((theta[ii] > 180) ? 1 : 0) + ',1 ' + x + ',' + y + 'z';
dark[ii].setAttribute('d', d);
if (theta[ii] > maxTheta[ii]) {
clearInterval(intervals[ii]);
}
}
};
for (var ii = 0; ii < 3; ii++) {
intervals.push(setInterval(getSetIntervalFunc(ii), t));
}