2013-10-24 61 views
0

我正在創建一個移動webapp遊戲,讓用戶在屏幕上輕掃以清除它。 我想寫一個智能函數,檢測幾乎整個畫布是透明的。canvas getImageData返回太多像素

我有一個間隔,每秒鐘下面調用函數來做檢查。 它應該工作的方式是,我需要一個20px寬的畫布部分,並且與畫布一樣高。

這個函數應該運行的很平滑,但由於某種原因,getImageData函數返回很多像素。我的扇區總是寬20px,並且高度相同,所以它應該每次都返回相同數量的像素。當然,由於getImageData返回的數字越來越高,我的循環變得越來越慢。

有誰知道是什麼原因造成的?我誤解了getImageData函數的工作方式嗎?

isCanvasTransparent: function (fromX, toX, currentIteration) { 

     if(currentIteration < this.clearedIterations) { // If a sector is already clear, we dont need to check it again 
      this.isCanvasTransparent(fromX + 20, toX + 20, currentIteration + 1); 
      return; 
     } else { 
      var data = this.context.getImageData(fromX, 0, toX, parseInt(this.canvas.style.width)).data; 
      var counter = 0; 
      var i = 0; 

      // For some reason, the length increases, but the diff between fromX and toX is always 20 
      console.log(data.length); 

      for(i=0;i<(data.length);i+=4) { 
       if(data[i+3]!==0){ 
        counter++; 
        // I stop iterating, since there are too many non transparent pixels 
        if(counter > 10) { 
         break; 
        } 
       } 
      } 

      // I accept that 10 pixels in each sector is not transparent 
      if((counter < 10) && !this.alerted) { 
       this.clearedIterations++; // Here we increase clearedIterations, since this sector is clear 

       // There are no more iterations, so we are done 
       if(currentIteration === this.maxIterations) { 
        // this is the interval that calls isCanvasTransparent(0, 20, 0) 
        // in the first place. The interval is called each second. But as soon the whole view 
        // is transparent, we clear it, so that isCanvasTransparent is no longer called 
        clearInterval(this.checkCanvasTimeout); 
        this.alerted = true; 
        TouchHelpers.removeTouchEvents(); 
        this.levelCompleted(); 
        return; 
       } else { 
        // this sector is clear, but we need to check the next one, since we are not at the end 
        this.isCanvasTransparent(fromX + 20, toX + 20, currentIteration + 1); 
       } 
      } 
     } 
    }, 

回答

2

不確定如何設置fromX/toX,但它看起來沒有給getImageData適當的參數。

context.getImageData具有這些參數:

  • X:起始X座標提取,
  • Y:開始y座標來提取,
  • 寬度:提取此許多像素寬的塊,
  • 高度:提取一個塊,這很多像素高

[加法:bas ED上的更多信息]

如果你想像素同等大小的數據塊,你的第一個電話是

var data=getImageData(0,0, 20, canvas.height).data; 

和你的第二個電話是:

// Note: the width arguement remains at 20, not increase to 40 

var data=getImageData(20,0, 20, canvas.height).data; 
+0

很抱歉,如果我還不清楚。我試着在你看到的清除間隔代碼中解釋這一點。但無論如何,我最初調用函數的方式是使用這些參數(0,0,20,的高度)。然後在下一次遞歸地向右移動20個像素。所以第二次(20,0,40,的高度)被調用。 – funkyfly

+0

有問題......你的第二個電話是s/b(20,0,20,canvas.height) - 第三個寬度的參數應該保持在20,而不是增加到40.乾杯! – markE

+0

啊......你說得對!現在我的功能非常順暢。我無法爲此感謝你!真的很感激它! :) – funkyfly