2016-07-10 55 views
0

我想要做的是在畫布中繪製一個列表框。我試圖用clip()來隱藏不在列表框「視口」中的列表項。問題是沒有在列表框「視口」中的所有列表項都被正確隱藏,除了最後一個列表項。我注意到,如果我只調用一次requestAnimationFrame,最後的列表項將被正確剪裁。或者,如果在繪製列表項後調用beginPath,則最後的列表項將被正確剪裁。奇數帆布剪裁行爲

<canvas id="myCanvas" width="200" height="300" style="border:1px solid #000000;"></canvas> 

<script type="text/javascript"> 

    window.addEventListener("load", function() { 
     var c = document.getElementById("myCanvas"); 
     var ctx = c.getContext("2d"); 

     var colors = ["green", "yellow", "blue", "red"]; 

     var gameLoopCallbackWrapper = function() { 
      //Comment this line out to fix clipping anomaly 
      window.requestAnimationFrame(gameLoopCallbackWrapper); 

      if (ctx) { ctx.clearRect(0, 0, 200, 300); } 

      ctx.save(); 

      ctx.transform(1, 0, 0, 1, 100, 100); 

      //draw list box 
      ctx.lineWidth = 1; 
      ctx.strokeStyle = "white"; 
      ctx.rect(-26, -15, 52, 30); 
      ctx.stroke(); 

      ctx.clip(); 

      //draw list items 
      for (var key in colors) { 
       var color = colors[key]; 

       ctx.save(); 

       ctx.transform(1, 0, 0, 1, 0, 14 * key - 8); 

       ctx.fillStyle = color; 

       ctx.strokeStyle = "black"; 

       ctx.beginPath(); 
       ctx.rect(-25, -7, 50, 14); 
       ctx.stroke(); 
       ctx.fill(); 

       ctx.restore(); 

       //uncomment this line to see clipping anomally fixed 
       //ctx.beginPath(); 
      } 

      ctx.restore(); 
     }; 

     window.requestAnimationFrame(gameLoopCallbackWrapper); 
    }); 
</script> 

上面的代碼是我的代碼的簡化版本,只是爲了演示剪輯異常。它的當前形式不具有互動性,因此列表項不能上下拖動。

+1

你必須調用'beginPath'否則您的矩形將累積到最後繪製的路徑(即使通過clearRect清除) – Kaiido

+0

良好的通話;謝謝你。在開始繪製列表框之前,我把ctx.beginPath放在正確的位置,現在最後的列表項目已經被正確剪輯。你能告訴我是Canvas的新手嗎? ;-) – Meadock

回答

0

「你得叫beginPath方法在你的函數的開始,否則你的矩形將只累積到最後繪製的路徑(即使清除由clearRect)」 - Kaiido

「良好的通話,向你表示感謝。我把ctx.beginPath放在開始繪製列表框的時候,最後一個列表項目現在已經被正確剪輯了,你能告訴我是Canvas的新手嗎?;-)「 - Meadock