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

时间:2016-10-13 17:50:56

标签: javascript html5 canvas drawing

假设我有一个简单的画布元素,并在其上绘制一个复杂的资源密集型图片。然后我在图片上画了一些简单的线条。是否有办法“保存”画布的状态(在绘制线条之前),然后重绘状态以擦除所做的任何进一步更改。我确实尝试使用save()restore(),但我认为状态不包括画布上的当前形状。请参阅下面的演示。

var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');

function init() {
  // This is some computationally intensive drawing we don't want to repeat
  context.fillStyle = "rgb(150,29,28)";
  context.fillRect(40, 40, 255, 200);
  context.fillStyle = "rgb(150,83,28)";
  context.fillRect(10, 10, 50, 50);
  context.fillStyle = "rgb(17,90,90)";
  context.fillRect(5, 100, 200, 120);
  context.fillStyle = "rgb(22,120,22)";
  context.fillRect(200, 200, 90, 90);
  // Now we save the state so we can return to it
  saveState();
}

function lines() {
  // This is some drawing we will do and then want to get rid of
  context.beginPath();
  context.moveTo(125, 125);
  context.lineTo(150, 45);
  context.lineTo(200, 200);
  context.closePath();
  context.stroke();
}

function saveState() {
  //copy the data into some variable
}

function loadState() {
  //load the data from the variable and apply to canvas
}

init();
#canvas {
  border: 1px solid #000;
}
<canvas id="canvas" width="300" height="300"></canvas>
<button onClick="lines()">Draw over image</button>
<button onClick="loadState()">Restore</button>

2 个答案:

答案 0 :(得分:4)

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

// 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创建各种可调FX。

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

另一种方法是将画布存储为带有ctx.getImageData的类型化数组,但这也非常慢,无法满足实时需求。

答案 1 :(得分:0)

您可以创建public class MBILogin extends com.sterlingcommerce.woodstock.ui.servlet.MBILogin 元素,调用<img>将原始canvas.toDataURL()存储在canvas context.clearRect()saveState(), use canvas to clear context.drawImage(), canvas`

&#13;
&#13;
to restore saved
&#13;
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
var _canvas;
var img = new Image;
img.width = canvas.width;
img.height = canvas.height;

function init() {
  // This is some computationally intensive drawing we don't want to repeat
  context.fillStyle = "rgb(150,29,28)";
  context.fillRect(40, 40, 255, 200);
  context.fillStyle = "rgb(150,83,28)";
  context.fillRect(10, 10, 50, 50);
  context.fillStyle = "rgb(17,90,90)";
  context.fillRect(5, 100, 200, 120);
  context.fillStyle = "rgb(22,120,22)";
  context.fillRect(200, 200, 90, 90);
  // Now we save the state so we can return to it
  saveState(canvas);
}

function lines() {
  // This is some drawing we will do and then want to get rid of
  context.beginPath();
  context.moveTo(125, 125);
  context.lineTo(150, 45);
  context.lineTo(200, 200);
  context.closePath();
  context.stroke();
}

function saveState(c) {
  _canvas = c.toDataURL();
  //copy the data into some variable
}

function loadState() {
  //load the data from the variable and apply to canvas
  context.clearRect(0, 0, canvas.width, canvas.height);
  img.onload = function() {
    context.drawImage(img, 0, 0);
  }
  img.src = _canvas;
}


init();
&#13;
#canvas {
  border: 1px solid #000;
}
&#13;
&#13;
&#13;