您最好的方法是使用既存储绘图命令又执行绘图的代理。
由于浏览器对 Proxy 的支持很差(目前只有 FF),你必须自己构建 Proxy,要么使用 nosuchmethod,要么构建一个全新的全新 WatchedContext 类Context2D。
我为这个简短的演示采用了最后一个解决方案(WatchedContext 类):
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 调用或类似方法将它们远程存储在服务器上。