简体   繁体   中英

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.
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?

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.
I took the last solution (WatchedContext Class) for this short demo :

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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