简体   繁体   English

HTML5 Canvas-在Canvas上绘制,保存上下文并稍后还原

[英]HTML5 Canvas - Draw on Canvas, Save Context and Restore it later

Requirement: 需求:

Now: Draw on a Canvas, and hit Save (store Canvas state/drawing offline - but NOT as image). 现在:在画布上绘制,然后单击保存(存储画布状态/离线绘制-但不作为图像)。
Later: Open up the Canvas with previously saved drawing showing, and continue to draw again. 以后:打开画布并显示以前保存的图形,然后继续进行绘制。

For drawing we normally use code as follows: 对于绘制,我们通常使用如下代码:

canvas = document.getElementById('can');
ctx = canvas.getContext("2d");
...
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(currX, currY);
....

In order to restore Canvas state later - exporting to Image does not help. 为了以后恢复Canvas状态-导出到Image没有帮助。
I want to restore the Canvas to it's original state to continue editing the drawing at a later date. 我想将“画布”还原到其原始状态,以便以后继续编辑图形。

I guess, the Canvas context has to be exported and stored offline - how? 我猜想,Canvas上下文必须离线导出和存储-如何?

Your best shot here is to use a Proxy that will both store the draw commands and perform the drawings. 最好的选择是使用一个代理,它既可以存储绘制命令,也可以执行绘制。
Since the browser support for Proxy is very bad (only FF as of today), you'll have to build the Proxy yourself, either by using nosuchmethod , or by building a new brand new WatchedContext Class out of the Context2D. 由于浏览器对Proxy的支持非常糟糕(截至目前仅支持FF),因此您必须使用nosuchmethod或通过Context2D构建新的全新WatchedContext类来自行构建Proxy。
I took the last solution (WatchedContext Class) for this short demo : 对于这个简短的演示,我采用了最后一个解决方案(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);
    }
  }
}

Obviously you might need some other method (start/stop recording, clear, ...) 显然,您可能需要其他方法(开始/停止记录,清除等)

Just a small example of use : 只是一个小的使用示例:

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();

You can see here : 您可以在这里看到:

http://jsbin.com/gehixavebe/2/edit?js,output

That the replay does work, and the line is re-drawn as a result of replaying the stored commands. 重放确实起作用,并且由于重放了存储的命令,因此重新绘制了该行。

For storing offline you can either store the commands locally using localStorage or store them remotely on a server an use AJAX calls or similar. 对于脱机存储,您可以使用localStorage在本地存储命令,也可以使用AJAX调用或类似方法将它们远程存储在服务器上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM