2016-06-18 12 views
0

異なる値(data-percentを参照)を持つ複数のcanvas-esを同じ再利用可能なコードブロックで使用する必要がありますが、「アニメーション」を使用するとややこしいことになります。それを再利用可能にする方法がわからない。同じコードを何度もコピーして貼り付けるのは間違いですが、私はいつもそれを避けています。 ...いかがcanvas JavaScriptコード再利用可能なキャンバスコードですか?

<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 -esを選択することができidを削除し、代わりにclassを使用することは明らかですか?おそらく非常に簡単な解決策がありますが、私はそれを見ることができません!喫煙をやめるためのひどい時間(いつものように)、脳は閉ざされているようです。 allCirclesリストをfor loopを:私が試した何


。問題は、このアプローチではsetIntervalclearTimeoutを使用できないということです。動的変数名?後でそれらをどのように参照するのですか?


ここに私のコードが1つの円で示されています。

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

bindを使用して解決できます。

与えcanvasのためのアニメーションを開始しますヘルパー関数を作成します。代わりに、グローバルなもののthisから変数を参照するために、あなたのcircle機能を変更

function animateCircle(canvas) { 
    var scope = { 
     ctx: canvas.getContext('2d') 
     // other properties, like currentPercent, finalPercent, etc 
    };   
    scope.interval = setInterval(circle.bind(scope), 20); 
} 

を:

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、何かがある場合定かでない。

+0

アニメーションにsetIntervalを使用するべきではありません。アニメーションの品質の低下(シャーリング、遅れ、フレームレートの不一致、予想外の避けられないページクラッシュなど)が発生する可能性があります。任意の種類のアニメーションに対してrequestAnimationFrameを使用します。これはディスプレイのリフレッシュに同期され、ブラウザはアニメーションを行っていることを理解しているので、せん断なしにキャンバスを表示し、そのデバイスがフレーム単位で処理できる以上のレンダリングを試みません。すべてのプラットフォームで高品質のアニメーションを提供します。 – Blindman67

関連する問題