2013-03-23 40 views
3

嘗試獲取畫布的繪圖並在稍後將其重新繪製到同一個畫布上會產生意外的行爲。例如,參見Jsfiddle畫布意外的結果/行爲使用drawImage/putImageData

的邏輯是相當簡單:

  • 鑑於翻譯在畫布上的圖像,並以中心(我用一個矩形來證明)。
  • 剪下圖像的一部分。我只是在示例中複製整個「圖像」。
  • 可能做操作。
  • 清除後粘貼回同一個畫布。重點是在給定點處剪裁一段寬度/高度的原始圖像,並稍後進行修改並粘貼。

var c=document.getElementById("cvs1"), 
    ctx = c.getContext("2d"), 
    bufferCvs = document.createElement('canvas'), 
    bufferCtx = bufferCvs.getContext('2d'); 


bufferCvs.width = c.width; 
bufferCvs.height = c.height; 

ctx.translate(c.width/2, c.height/2); 
ctx.fillStyle="#FF0000"; 
ctx.fillRect(-75, -50 ,150,100); 

//Image data experiment 
//Set the buffer width/height same size as rectangle 
bufferCvs.width = 150; 
bufferCvs.height = 100; 
//Draw the "image" from the first context to the buffer by clipping the first, and pasting to 0,0 width the same "image" dimensions. 
bufferCtx.drawImage(c, -75, -50, 150, 100, 0, 0, 150, 100); 
//clear out old canvas drawing 
ctx.save() 
ctx.setTransform(1,0,0,1,0,0,1,0,0); 
ctx.clearRect(0, 0, c.width, c.height); 
ctx.restore(); 

ctx.drawImage(bufferCvs, -75, -50, 150, 100); 

由於我保持完全相同的座標/尺寸,預計產量將是什麼最初是在畫布上開始。但是,只有左上角的一部分被繪製(請參閱小提琴)。我使用的drawImage爲efficiency reasons,但我用get/putImageData具有相同的結果。寬度和高度的定義均與上述相同,以修復other strange behaviors

你將如何去確保存儲在緩衝區畫布中的所有內容都被繪製,而不僅僅是頂角?

編輯: 爲了解決我的問題以及我相信正在發生的行爲,我會發布一些屏幕。

第1步: 將上下文1翻譯爲中心,繪製矩形以表示圖像。

ctx.translate(c.width/2, c.height/2); 
ctx.fillStyle="#FF0000"; 
ctx.fillRect(-75, -50 ,150,100); 

Translate/Add Rect

步驟2: 使用的drawImage從-75,-50點「剪輯」和使用該寬度150切出只是矩形,100。這應該被繪製到畫布緩衝區,但它不是

bufferCvs.width = 150; 
bufferCvs.height = 100; 
//Draw the "image" from the first context to the buffer by clipping the first at -75, -50 (the start of the image), and pasting to 0,0 width the same "image" dimensions. 
bufferCtx.drawImage(c, -75, -50, 150, 100, 0, 0, 150, 100); 

我希望緩衝畫布看起來像這樣(這是不是):

Expected buffer canvas

但是,如果我改變的drawImage到

bufferCtx.drawImage(c, 0, 0, 150, 100, 0, 0, 150, 100); 

我得到的白色空間緩衝的預期量(最後的drawImage回沒有問題的情況下)

步驟3:清除從第一個環境中排除舊的「形象」。這不應該改變翻譯,因爲我在執行清除後恢復上下文狀態。(這工作正常)

ctx.save() 
ctx.setTransform(1,0,0,1,0,0,1,0,0); 
ctx.clearRect(0, 0, c.width, c.height); 
ctx.restore(); 

步驟4:簡單地採取什麼是在緩衝區畫布繪製到原始上下文的地方開始恢復這樣的:

Translate/Add Rect

的想法是要更多地「剪輯」原始區域,清除舊圖像,並將新剪切區域粘貼回原始上下文。我曾看過MDN's example,但drawImage的剪輯部分未按預期執行。

回答

0

主要問題是繪製在bufferCvs上的第一個畫布未繪製在您期望的位置。爲了證明這一點的最簡單的方法是將bufferCvs到DOM樹:http://jsfiddle.net/CdWn6/4/

我想這是你在找什麼:http://jsfiddle.net/CdWn6/6/

var c=document.getElementById("cvs1"), 
    c2 = document.getElementById("cvs2"), 
    bufferCvs = document.createElement('canvas'), 
    bufferCtx = bufferCvs.getContext('2d'), 
    ctx = c.getContext("2d"), 
    ctx2 = c2.getContext("2d"); 

bufferCvs.width = c.width; 
bufferCvs.height = c.height; 

ctx.translate(c.width/2, c.height/2); 
ctx.fillStyle="#FF0000"; 
ctx2.translate(c.width/2, c.height/2); 
ctx2.fillStyle="#FF0000"; 

bufferCtx.translate(c.width/2, c.height/2); 

ctx.fillRect(-75, -50 ,150,100); 
ctx2.fillRect(-75, -50 ,150,100); 

//Image data experiment 
bufferCtx.drawImage(c, -135, -110, 270, 220); 

ctx.save() 
ctx.setTransform(1,0,0,1,0,0,1,0,0); 
ctx.clearRect(0, 0, c.width, c.height); 
ctx.restore(); 

//Draw background to demonstrate coordinates still work 
ctx.fillStyle="#00FF00"; 
//ctx.fillRect(-75, -50 ,150,100); 

ctx.drawImage(bufferCvs, -75, -50, 150, 100); 
+0

不知道這是完全是我要找的。保存/恢復部分的要點僅僅是清除現有的畫布。即使在這個例子中,最終的drawImage仍然只畫出了我所期望的一小部分。 –

+0

是的,問題出現在'bufferCvs'看看編輯。 –

+0

除了緩衝區畫布以外,您都可以使用翻譯。將第一個畫布拖到緩衝區時也存在問題。您可以繪製包括白色區域在內的所有內容(因爲第一個畫布內的矩形由白色「邊框」包圍),這使得紅色區域更小。 –