2016-06-18 1 views
0

Ich brauche mehrere canvas-es mit verschiedenen Werten (siehe data-percent) mit dem gleichen wiederverwendbaren Code-Block, aber "Animation" macht es ein bisschen schwierig. Ich bin nicht sicher, wie man es wiederverwendbar macht. Es ist offensichtlich ein falscher Schritt, den gleichen Code immer wieder neu zu kopieren, was ich normalerweise um jeden Preis vermeiden kann.Wiederverwendbarer Canvas-Code?


Das erste, was ist offensichtlich id zu entfernen und class stattdessen verwenden, dann könnte ich alle canvas -es wählen:

<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'); 

Aber jetzt kommt der schwierigeren Teil .. Wie wäre es canvas JavaScript-Code? Es gibt wahrscheinlich eine sehr einfache Lösung, aber ich kann es nicht sehen! Schreckliche Zeit mit dem Rauchen aufzuhören Ich denke (wie immer), Gehirn ist wie heruntergefahren.


Was ich versucht:for loop mit allCircles Liste. Problem ist, dass ich setInterval und clearTimeout mit diesem Ansatz nicht verwenden kann. Dynamische Variablennamen? Wie referenziere ich sie später?


mein Code hier mit einem einzigen Kreis, versuchen Sie es.

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

Erstellen Sie diesen Code-Schnipsel in Ihren eigenen Projekten zu verwenden.

Antwort

1

Sie können bind verwenden, um dies zu lösen.

eine Hilfsfunktion erstellen, die Animation für gegebene canvas beginnt:

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

ändern circle Funktion beziehen Variablen aus this statt global diejenigen:

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 
} 

Arbeits JSFiddle, wenn etwas unklar.

+0

Sie sollten setInterval nicht für Animationen verwenden, da eine Reihe von Problemen damit verbunden sind, die eine schlechte Qualität der Animation verursachen können (Scheren, Nachlaufen, inkonsistente Bildraten und unvorhersehbare und unvermeidbare Seitencrashes, um nur einige zu nennen). Verwenden Sie requestAnimationFrame für jede Art von Animation. Es ist mit der Anzeigeaktualisierung synchronisiert, der Browser versteht, dass Sie eine Animation ausführen, und stellt somit die Zeichenfläche/n ohne Scheren dar und versucht nicht mehr zu rendern, als das Gerät pro Bild verarbeiten kann. Es wird eine sehr hochwertige Animation auf allen Plattformen geben. – Blindman67