2016-04-06 9 views
0

Ich habe eine Arbeits Leinwand hier zu verwenden: http://codepen.io/lexbi/pen/KzZKzeeine Leinwand-Animation konvertieren request schafft Endlosschleife Animation

Obwohl ich versuche, es zu konvertieren von setTimeout mit requestAnimationFrame stattdessen zu verwenden.

Als einen kurzen Überblick über das, was ich zu erreichen versuche, habe ich ein Bild auf einem Canvas-Element in mehrere Blöcke aufgeteilt, ich möchte dann diese Blöcke einzeln animieren, um das "vollständige" Bild neu zu erstellen. (Der Codepen mit setTimeout funktioniert perfekt).

Es scheint einen Teil durch die Animation zu bekommen, und einige der Positionen des Blocks werden aktualisiert, ABER, Sie sehen die Animation nicht wirklich.

Ich glaube, dass die Schleife, die ich für das Objekt activeBlocks erstellt habe, früh beendet wird. Was bedeutet, es wird auf die else in dieser bedingten bevor die Animation (welche es sollte nicht) beendet ist:

if((blocks[blocks.length-1].x != blocks[blocks.length-1].toX)){ 
     updateAndRender = true; 
    }else{ 
     updateAndRender = false; 
     window.cancelAnimationFrame(requestId); 
    } 

jemand könnte vermuten lassen, was ich hier falsch mache?

Sehen als es keinen Sinn, eine codepen in einfügen (weil es abstürzt), hier ist mein bester Versuch, es zu konvertieren:

var canvas = document.getElementById("canvas"), 
    context = canvas.getContext("2d"), 
    img = new Image(), 
    rowPieces = 10, 
    columnPieces = 10, 
    totalPieces = rowPieces*columnPieces, 
    workingPiece = 0, 
    blocks = [], 
    activeBlocks = [], 
    minWait = 10, 
    lastTime = +new Date(), 
    updateAndRender = true, 
    requestId; 

img.src = "http://lastresistance.com/wp-content/uploads/2014/09/ATT-fat-cat.jpg"; 

// // set height & width 
canvas.width = window.innerWidth; 
canvas.height = window.innerHeight; 

img.onload = function(){ 

    function theLoop(){ 
    var loopCount = 0; 
    for(var colCount=0;colCount<columnPieces;colCount++){ 
     for(var rowCount=0;rowCount<rowPieces;rowCount++){ 
     blocks.push(
      new Block(
      (canvas.width/rowPieces), // w 
      (img.width/rowPieces), // sWidth 
      (canvas.height/columnPieces), // h 
      (img.height/columnPieces), // sHeight 
      ((img.width/rowPieces)*rowCount), //sx 
      ((canvas.width/rowPieces)*rowCount), //x 
      (canvas.width/rowPieces), // fromX 
      ((canvas.width/rowPieces)*rowCount), // toX 
      ((img.height/columnPieces)*colCount), // sy 
      ((canvas.height/columnPieces)*colCount), // y 
      (canvas.height/columnPieces), // fromY 
      ((canvas.height/columnPieces)*colCount), // toY 
      loopCount // Loop count, starting on 0 
     ) 
     ); 
     loopCount++; 
     } 
    } 

    } 

    theLoop(); 

    function Block(w, sWidth, h, sHeight, sx, x, fromX, toX, sy, y, fromY, toY, loopCount){ 
    this.w = w; 
    this.sWidth = sWidth; 
    this.h = h; 
    this.sHeight = sHeight; 
    this.sx = sx; 
    this.x = -x; 
    this.fromX = fromX; 
    this.toX = toX; 
    this.sy = sy; 
    this.y = -y; 
    this.fromY = fromY; 
    this.toY = toY; 
    this.i = loopCount; 
    } 

    Block.prototype.update = function(){ 
    // so if the increment is NOT enlarged by "1" the position could final up being offset 
    if(this.y < this.toY){ 
     this.y+=40; 
    } 
    //reset the y pos 
    if(this.y > this.toY){ 
     this.y = this.toY; 
    } 
    // so if the increment is NOT enlarged by "1" the position could final up being offset 
    if(this.x < this.toX){ 
     this.x+=40; 
    } 
    // reset the x pos 
    if(this.x > this.toX){ 
     this.x = this.toX; 
    } 
    }; 

    Block.prototype.render = function(){ 
    context.drawImage(img, this.sx, this.sy, this.sWidth, this.sHeight, this.x, this.y, this.w, this.h); 
    }; 

    //draw the screen 
    function animate() { 

     // This stops active blocks from growing larger than intended 
     if(activeBlocks.length <= blocks.length){ 
     activeBlocks.push(blocks[workingPiece]); 
     if(workingPiece <= totalPieces){ 
      workingPiece = workingPiece+1; 
     }else{ 
      workingPiece = 0; 
     } 
     } // endif 

     context.clearRect(0,0,canvas.width, canvas.height); 

     for(var ei = 0; ei < activeBlocks.length; ++ei){ 
     if((blocks[blocks.length-1].x != blocks[blocks.length-1].toX)){ 
      updateAndRender = true; 
     }else{ 
      updateAndRender = false; 
      window.cancelAnimationFrame(requestId); 
     } 
     if(updateAndRender == true){ 
      // For some reason this still fires for 70 loops, not sure why, though this undefined IF at least stops errors in the console 
      if("undefined" !== typeof activeBlocks[ei]){ 
      activeBlocks[ei].update(); 
      activeBlocks[ei].render(); 
      requestId = window.requestAnimationFrame(animate); 
      } 
     } // endif 
     } // for 

    }; 
    requestId = window.requestAnimationFrame(animate); 
} 

Antwort

0

Ok, damit ich diese in die falsche Richtung näherte, dieser Artikel hat mir geholfen verstehen, einen besseren Weg, damit umzugehen: http://creativejs.com/resources/requestanimationframe/

Insbesondere folgt aus:

var fps = 15; 
function draw() { 
    setTimeout(function() { 
     requestAnimationFrame(draw); 
     // Drawing code goes here 
    }, 1000/fps); 
} 

im Wesentlichen wurde die Aktualisierung ich die requestAnimationFrame(draw) in der falscher Ort, sollte es innerhalb der animate Funktion gewesen sein.