簡體   English   中英

如何使用唯一的setInterval變量名稱實現for循環?

[英]How to implement a for-loop with unique setInterval variable names?

我創建了一個如下的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> 

您可能會遇到上下文問題。 我們不會在for循環內創建函數:)以獲得更多信息,您可以參考> 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));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM