2012-07-12 32 views
3

我畫了一個圓角矩形的網格,我需要填充它們的圖像背景。最終我會有很多圖像背景,但現在,我試圖讓它與其中一個一起工作。我很接近,我的矩形繪製,但填充做一些有點怪異的東西 - 它重疊自己,並殺死我的模式(邊緣除外),基本上填充整個畫布與圖像。我試圖「剪輯」我的路徑,但這隻會導致只填充一個矩形。我不確定我做錯了什麼,我希望畫布專家能夠發現它?爲什麼我的畫布填充圖案自身重複/重疊?

/* build rounded rectangle */ 
var roundedRect=function(ctx,x,y,width,height,radius,fill,stroke) 
{ 

ctx.save(); // save the context so we don't mess up others ctx.beginPath(); 

// draw top and top right corner ctx.moveTo(x+radius,y); 
ctx.arcTo(x+width,y,x+width,y+radius,radius); 

// draw right side and bottom right corner 
ctx.arcTo(x+width,y+height,x+width-radius,y+height,radius); 

// draw bottom and bottom left corner 
ctx.arcTo(x,y+height,x,y+height-radius,radius); 

// draw left and top left corner 
ctx.arcTo(x,y,x+radius,y,radius); 
ctx.clip(); 

if(fill){ ctx.fill(); } 

if(stroke){ ctx.stroke(); } 

ctx.restore(); // restore context to what it was on entry 
} 

/* onload, fill canvas with pattern of rounded rectangles separated by 2px */ 
window.onload = function() { 
var canvas = document.getElementById("canvas"); 
/* rounded filled rectangle pattern */ 
var canvasWidth=530; 
    var canvasHeight=530; 
    var recWidth=42; 
    var recHeight=42; 
    var grout=2; 
    var radius=2; 
    var cols=canvasWidth/(recWidth+grout); 
    var rows=canvasWidth/(recHeight+grout); 


    /* loop through each row/column to build pattern */ 
    alert("rows" + rows + " & cols " + cols); 
    for (i=1; i<rows; i++){ 
     for (j=1; j<cols; j++){ 
      var ctx = canvas.getContext("2d"); 
      /* fill pattern */ 
      var img=document.getElementById("poppy"); 
      var pat=ctx.createPattern(img,"repeat"); 
      ctx.fillStyle=pat; 
      roundedRect(ctx,(j*grout + (j-1)*recWidth),(i*grout + (i-1)*recHeight),recWidth,recHeight,radius,true,false);  

       } 
      } 
}; 

回答

2

讓我們假設你的問題在這個JSFiddle中複製:http://jsfiddle.net/hBEwr/。 (如果不是這種情況下,這個答案的其餘〜鋪位,請編輯以滿足您的具體問題。)

  1. 如果我們從公式中刪除該模式中,我們可以看到,它是不直接責怪。
    http://jsfiddle.net/hBEwr/1/
    取而代之的是,圓角矩形不會在它們之間留下必要的水泥漿。

  2. 由於一切都在彼此運行,我們然後將填充顏色更改爲低不透明的藍色。有趣!
    http://jsfiddle.net/hBEwr/2/
    我們看到許多路徑被一次又一次地繪製。這種洞察導致我們更仔細地看待roundedRect()的實現,並注意到我們從未稱之爲beginPath()。的確,在你上面的問題的代碼中,似乎已經被評論所吃掉了。如果沒有這個調用,每次調用roundedRect()會將附加矩形添加到不斷增長的路徑中,而不是重新開始。

  3. 添加呼叫beginPath()回來,我們看到,我們是通往成功的道路上:
    http://jsfiddle.net/hBEwr/3/

  4. 現在我們可以在模式加回(有一些輕微的變化),實現輝煌的勝利:
    http://jsfiddle.net/hBEwr/4/
    Poppies! Poppies! Poppies!

其他小的調整的一些注意事項我做:

  • 確保你總是var本地變量:

    for (i=0; i<10; i++)  // Oops! i is a global variable 
    for (var i=0; i<10; i++) // Much better 
    
  • 這是低效重新得到ctximg,併爲每個區塊的格局。在上面的最終代碼中,我將這些代碼移到了循環外部以簡化和加快速度。

  • 使用console.log而不是alert進行調試通常要容易得多。 (打開開發人員控制檯查看輸出。)

  • 我在灰色列的最後一行/列中添加了列計算,以確保其中包含空間。使用或不如你喜歡。

+0

你是如此超越真棒,我不知道該說些什麼,除非是一個非常豐盛的謝意。我很欣賞這個額外的特別迴應,以確定這一點。吃過的beginpath只是跛腳,需要檢查我的眼睛! – littlered 2012-07-13 04:17:07