要求:
现在:在画布上绘图,然后点击保存(将画布状态/绘图离线存储 - 但不作为图像存储)。
稍后:使用先前保存的绘图显示“画布”,然后继续绘制。
对于绘图,我们通常使用如下代码:
canvas = document.getElementById('can');
ctx = canvas.getContext("2d");
...
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(currX, currY);
....
为了以后恢复Canvas状态 - 导出到Image无济于事 我想将Canvas恢复到原始状态,以便以后继续编辑绘图。
我想,Canvas上下文必须导出并离线存储 - 如何?
答案 0 :(得分:1)
这里最好的方法是使用一个能够存储绘图命令并执行绘图的代理
由于浏览器对Proxy的支持非常糟糕(仅限今天的FF),您必须自己构建代理,方法是使用 nosuchmethod ,或者构建一个全新的WatchedContext类在Context2D之外。
我为这个简短的演示采用了最后一个解决方案(WatchedContext Class):
function WatchedContext(hostedCtx) {
this.commands= [];
Context2dPrototype = CanvasRenderingContext2D.prototype;
for (var p in Context2dPrototype ) {
this[p] = function(methodName) {
return function() {
this.commands.push(methodName, arguments);
return Context2dPrototype[methodName].apply(hostedCtx, arguments);
}
}(p);
}
this.replay=function() {
for (var i=0; i<this.commands.length; i+=2) {
var com = this.commands[i];
var args = this.commands[i+1];
Context2dPrototype[com].apply(hostedCtx, args);
}
}
}
显然你可能需要一些其他方法(开始/停止录制,清除......)
只是一个小例子:
var cv = document.getElementById('cv');
var ctx=cv.getContext('2d');
var watchedContext=new WatchedContext(ctx);
// do some drawings on the watched context
// --> they are performed also on the real context
watchedContext.beginPath();
watchedContext.moveTo(10, 10);
watchedContext.lineTo(100, 100);
watchedContext.stroke();
// clear context (not using the watched context to avoid recording)
ctx.clearRect(0,0,100,1000);
// replay what was recorded
watchedContext.replay();
你可以在这里看到:
http://jsbin.com/gehixavebe/2/edit?js,output
重播确实有效,并且由于重播存储的命令而重新绘制线条。
对于离线存储,您可以使用localStorage在本地存储命令,也可以将它们远程存储在服务器上,使用AJAX调用或类似命令。