2013-03-23 39 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

除了缓冲区画布以外,您都可以使用翻译。将第一个画布拖到缓冲区时也存在问题。您可以绘制包括白色区域在内的所有内容(因为第一个画布内的矩形由白色“边框”包围),这使得红色区域更小。 –