Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 修改后将画布重置为上一张图片_Javascript_Html_Canvas_Drawing - Fatal编程技术网

Javascript 修改后将画布重置为上一张图片

Javascript 修改后将画布重置为上一张图片,javascript,html,canvas,drawing,Javascript,Html,Canvas,Drawing,假设我有一个简单的画布元素,在上面画一幅复杂的、资源密集型的图片。然后我在图片上画了一些简单的线。是否有一种方法可以“保存”画布的状态(在绘制线条之前),然后重新绘制状态以删除任何进一步的更改。我确实在save()和restore()中尝试过这一点,但我认为它的状态不包括画布上的当前形状。请参阅下面的演示 var canvas=document.getElementById(“canvas”); var context=canvas.getContext('2d'); 函数init(){ //

假设我有一个简单的画布元素,在上面画一幅复杂的、资源密集型的图片。然后我在图片上画了一些简单的线。是否有一种方法可以“保存”画布的状态(在绘制线条之前),然后重新绘制状态以删除任何进一步的更改。我确实在
save()
restore()
中尝试过这一点,但我认为它的状态不包括画布上的当前形状。请参阅下面的演示

var canvas=document.getElementById(“canvas”);
var context=canvas.getContext('2d');
函数init(){
//这是一些计算密集型绘图,我们不想重复
context.fillStyle=“rgb(150,29,28)”;
fillRect(40,40,255,200);
context.fillStyle=“rgb(150,83,28)”;
context.fillRect(10,10,50,50);
context.fillStyle=“rgb(17,90,90)”;
fillRect(51000220);
context.fillStyle=“rgb(22120,22)”;
fillRect(2002009090);
//现在我们保存状态,以便可以返回到它
saveState();
}
功能行(){
//这是一些我们将要做的画,然后想摆脱它
context.beginPath();
上下文。moveTo(125125);
lineTo(150,45);
lineTo(200200);
closePath();
stroke();
}
函数saveState(){
//将数据复制到某个变量中
}
函数loadState(){
//从变量加载数据并应用到画布
}
init()
#画布{
边框:1px实心#000;
}

画图
还原
您可以创建一个

#画布{
边框:1px实心#000;
}

画图
还原
您可以创建一个

#画布{
边框:1px实心#000;
}

画图

还原
您可以轻松地将画布复制到新画布上

// canvas is the canvas you want to copy.
var canvasBack = document.createElement("canvas");
canvasBack.width = canvas.width;
canvasBack.height = canvas.height;
canvasBack.ctx = canvasBack.getContext("2d");
canvasBack.ctx.drawImage(canvas,0,0);
您可以将新画布视为另一个图像,并使用

ctx.drawImage(canvasBack,0,0);
渲染图像是在硬件中完成的,因此每帧可以轻松地实时执行多次。因此,您可以将画布视为图层(如photoshop),并使用globalCompositeOperation创建范围广泛的可调整效果

您可以转换为dataURL,但这是一个慢得多的过程,并且对于实时渲染来说不够快。此外,保留DataURL字符串的副本,然后将其解码为图像,这将给内存带来更大的压力,而不仅仅是创建画布副本(base64每4个字符编码3个字节(24位)。由于JS字符长度为16位,因此在base64中存储数据的效率非常低(64位内存用于存储24位)


另一种方法是使用ctx.getImageData将画布存储为类型化数组,但这也非常缓慢,无法处理实时需要。

您可以轻松地将画布复制到新的画布

// canvas is the canvas you want to copy.
var canvasBack = document.createElement("canvas");
canvasBack.width = canvas.width;
canvasBack.height = canvas.height;
canvasBack.ctx = canvasBack.getContext("2d");
canvasBack.ctx.drawImage(canvas,0,0);
您可以将新画布视为另一个图像,并使用

ctx.drawImage(canvasBack,0,0);
渲染图像是在硬件中完成的,因此每帧可以轻松地实时执行多次。因此,您可以将画布视为层(如photoshop),并使用globalCompositeOperation创建范围广泛的可调效果

您可以转换为dataURL,但这是一个慢得多的过程,并且速度不够快,无法进行实时渲染。此外,保留dataURL字符串的副本,然后将其解码为图像将比仅创建画布副本对内存造成更大的压力(base64编码3个字节(24位)由于JS字符长度为16位,所以在base64中存储数据的效率非常低(64位内存用于存储24位)


另一种方法是使用ctx.getImageData将画布存储为类型化数组,但这也非常慢,无法处理实时需要。

回答得好。关于提问者的怀疑:是的,
context.save&restore
只影响上下文属性——它们不会保存/还原画布内容(图纸)。回答得好。关于提问者的怀疑:是的,
context.save&restore
只影响上下文属性——它们不会保存/还原画布内容(图形)。当所有内容都合并到画布上的像素(就地)时,您需要跟踪两者之间的每个状态。创建一个简单的撤消-重做堆栈(或在此处尝试我的:)。当所有内容都合并到画布上的像素(就地)时,您需要跟踪之间的每个状态。创建一个简单的撤消重做堆栈(或在此处尝试我的:)。