2016-04-19 8 views
2

Ich habe eine Leinwand, in der ich Sachen animieren. Ich höre das Fenster Größe ändern Ereignis, aktualisieren Sie die Leinwandgröße und starten Sie die rekursive Zeichnung erneut. Aber es scheint, als würden die alten draw() - Aufrufe fortgesetzt und die Animation schneller als beabsichtigt ausgeführt. Hier ist der Code:HTML-Leinwand aktualisiert zu oft nach Größe ändern

HTML

<canvas id="myCanvas" width="1000" height="1000"></canvas> 

CSS

* { 
    margin: 0; 
    padding: 0; 
} 

html, 
body { 
    width: 100%; 
    height: 100%; 
} 

canvas { 
    display: block; 
} 

JavaScript

var canvas = document.getElementById("myCanvas"); 
var context = canvas.getContext('2d'); 
var frameCount = 0; 
var count = 0; 

var rectDistance = 100; 
var rectSize = 72; 
var rectOffset = (rectDistance - rectSize)/2; 
var angleSpeed = 1; 

var draw = function() { 
    count++; 

    var xCount = canvas.width/rectDistance; 
    var yCount = canvas.height/rectDistance; 

    context.fillStyle = "rgba(255,255,255,1)"; 
    context.fillRect(0, 0, canvas.width, canvas.height); 

    for (var i = 0; i < xCount; i++) { 
    for (var j = 0; j < yCount; j++) { 

     context.save(); 

     var r = Math.round(i/xCount * 255); 
     var g = Math.round(j/xCount * 255); 

     xPos = i * rectDistance + rectOffset + Math.sin(j + frameCount/20) * 10; 
     yPos = j * rectDistance + rectOffset + Math.cos(i + frameCount/20) * 10; 

     context.translate(xPos + rectSize/2, yPos + rectSize/2); 
     context.rotate(frameCount/100 * angleSpeed * Math.sin(frameCount/500) * 5); 

     context.fillStyle = "rgba(" + r + "," + g + ",0,1)"; 
     context.fillRect(-rectSize/2, -rectSize/2, rectSize, rectSize); 
     context.restore(); 
    } 
    } 

    frameCount = frameCount + 1; 
    requestAnimationFrame(draw); 
}; 

window.addEventListener('resize', function() { 
    setTimeout(function() { 
    resizeCanvas(); 
    }, 500); 
}, false); 

function resizeCanvas() { 
    canvas.width = window.innerWidth; 
    canvas.height = window.innerHeight; 

    draw(); 
} 

// count the calls of draw() per second -> it's increasing on window.resize 
function drawCalls() { 
    setTimeout(function() { 
    console.log("draw() called " + count + " times"); 
    count = 0; 
    drawCalls(); 
    }, 1000) 
} 
drawCalls(); 

// start the loop 
resizeCanvas(); 

Wie kann ich die alten Draw verhindern kann() Anrufe weiterhin ihre rekursive Ausführung auf Resize ?

ist hier ein codepen mit dem gleichen Problem: http://codepen.io/Sebkasanzew/pen/GZGZVP

+1

Wenn Sie Ihre Schleife nicht aufhören, warum tun Sie Call-Draw in der Größenänderung Ereignis? BTW resize Ereignis wird wahrscheinlich mit höherer Rate als rAF auslösen. [gegabelter Stift] (http://codepen.io/anon/pen/QNxEMN) – Kaiido

+0

Das Aufrufen von draw() außerhalb des resize-Ereignisses löst das Problem. Aber dann wird die Erstellung der gezeichneten Objekte nicht erneut ausgeführt, oder? Aber das löst zumindest das Problem für dieses Beispiel, danke. Gibt es keinen anderen Weg? – SebKas

+1

für eine für immer laufende Animation, würde ich es in zwei separaten Schritten tun: eine App ein Update und eine Zeichnung eins. Bei der Größenänderung rufen Sie einfach das App-Update auf, setzen alle Variablen zurück und Ihre Zeichenfunktion verbraucht nur die Variablen in jedem Frame. – Kaiido

Antwort

3

Sie vergessen die setTimeout() abzubrechen - ich würde folgendes vorschlagen:

var timer; 

window.addEventListener('resize', function() { 
    cancelAnimationFrame(timer);     // cancel previous request 
    timer = requestAnimationFrame(function() { // create a new request 
    resizeCanvas(); 
    }) 
}); 
+0

Das ist, was ich gesucht habe. Vielen Dank! – SebKas

Verwandte Themen