可重用的画布代码?

时间:2016-06-18 15:26:01

标签: javascript html5 canvas

我需要使用具有不同值的多个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列表。问题是我无法使用setIntervalclearTimeout这种方法。动态变量名称?我以后如何引用它们?

这是我的代码,只有一个圆圈,试一试。

// 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>

您可以在自己的项目中使用此代码段。

1 个答案:

答案 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,如果不清楚的话。