我需要使用具有不同值的多个canvas-es
(请参阅data-percent
)具有相同的可重用代码块,但“动画”使其有点棘手。我不知道如何让它重复使用。一遍又一遍地复制粘贴相同的代码显然是一个错误的举动,我通常不惜一切代价避免它。
显然首先要删除id
并使用class
,然后我可以选择所有canvas
- es:
<canvas class="circle-thingy" width="120" height="120" data-percent="75"></canvas>
<canvas class="circle-thingy" width="120" height="120" data-percent="23"></canvas>
<canvas class="circle-thingy" width="120" height="120" data-percent="89"></canvas>
var allCircles = document.getElementsByClassName('circle-thingy');
但现在变得比较棘手了.. canvas
JavaScript代码怎么样?可能有一个非常简单的解决方案,但我看不到它!戒烟的可怕时间我猜(一如既往),大脑就像关闭一样。
我尝试了什么: for loop
,其中包含allCircles
列表。问题是我无法使用setInterval
和clearTimeout
这种方法。动态变量名称?我以后如何引用它们?
这是我的代码,只有一个圆圈,试一试。
// Get canvas context
var ctx = document.getElementById('my-circle').getContext('2d');
// Current percent
var currentPercent = 0;
// Canvas north (close enough)
var start = 4.72;
// Dimensions
var cWidth = ctx.canvas.width;
var cHeight = ctx.canvas.height;
// Desired percent -> comes from canvas data-* attribute
var finalPercent = ctx.canvas.getAttribute('data-percent');
var diff;
function circle() {
diff = ((currentPercent / 100) * Math.PI * 2 * 10).toFixed(2);
ctx.clearRect(0, 0, cWidth, cHeight);
ctx.lineWidth = 3;
// Bottom circle (grey)
ctx.strokeStyle = '#eee';
ctx.beginPath();
ctx.arc(60, 60, 55, 0, 2 * Math.PI);
ctx.stroke();
// Percent text
ctx.fillStyle = '#000';
ctx.textAlign = 'center';
ctx.font="900 10px arial";
ctx.fillText(currentPercent + '%', cWidth * 0.5, cHeight * 0.5 + 2, cWidth);
// Upper circle (blue)
ctx.strokeStyle = '#0095ff';
ctx.beginPath();
ctx.arc(60, 60, 55, start, diff / 10 + start);
ctx.stroke();
// If has desired percent -> stop
if( currentPercent >= finalPercent) {
clearTimeout(myCircle);
}
currentPercent++;
}
var myCircle = setInterval(circle, 20);
<canvas id="my-circle" width="120" height="120" data-percent="75"></canvas>
您可以在自己的项目中使用此代码段。
答案 0 :(得分:1)
您可以使用bind来解决此问题。
创建一个辅助函数,它将为给定的canvas
启动动画:
function animateCircle(canvas) {
var scope = {
ctx: canvas.getContext('2d')
// other properties, like currentPercent, finalPercent, etc
};
scope.interval = setInterval(circle.bind(scope), 20);
}
更改circle
功能以引用this
中的变量而不是全局变量:
function circle() {
// your old code with corresponding changes
// e.g.
var ctx = this.ctx; // references corresponding scope.ctx
// or
this.currentPercent++; // references corresponding scope.currentPercent
}
工作JSFiddle,如果不清楚的话。