Visit Mozilla.org

Code snippets:Canvas

From MDC

For general information about using <canvas> see the tutorial.

These snippets can only be used from privileged code (extensions, in particular).

[edit] Saving a canvas image to a file

The following function accepts a canvas object and a destination file path string. The canvas is converted to a PNG file and saved to the specified location. The function displays a download progress dialog, but the dialog can be removed.

function saveCanvas(canvas, destFile) {
  // convert string filepath to an nsIFile
  var file = Components.classes["@mozilla.org/file/local;1"]
                       .createInstance(Components.interfaces.nsILocalFile);
  file.initWithPath(destFile);

  // create a data url from the canvas and then create URIs of the source and targets  
  var io = Components.classes["@mozilla.org/network/io-service;1"]
                     .getService(Components.interfaces.nsIIOService);
  var source = io.newURI(canvas.toDataURL("image/png", ""), "UTF8", null);
  var target = io.newFileURI(file)
    
  // prepare to save the canvas data
  var persist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
                          .createInstance(Components.interfaces.nsIWebBrowserPersist);
  
  persist.persistFlags = Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
  persist.persistFlags |= Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
  
  // displays a download dialog (remove these 3 lines for silent download)
  var xfer = Components.classes["@mozilla.org/transfer;1"]
                       .createInstance(Components.interfaces.nsITransfer);
  xfer.init(source, target, "", null, null, null, persist);
  persist.progressListener = xfer;
  
  // save the canvas data to the file
  persist.saveURI(source, null, null, null, null, file);
}

[edit] Loading a remote page onto a canvas element

The following class first creates a hidden iframe element and attaches a listener to the frame's load event. Once the remote page has loaded, the remotePageLoaded method fires. This method gets a reference to the iframe's window and draws this window to a canvas object.

Note that this only works if you are running the page from chrome. If you try running the code as a plain webpage, you will get a 'Security error" code: "1000' error.

RemoteCanvas = function() {
    this.url = "http://developer.mozilla.org";
};

RemoteCanvas.CANVAS_WIDTH = 300;
RemoteCanvas.CANVAS_HEIGHT = 300;

RemoteCanvas.prototype.load = function() {
    var windowWidth = window.innerWidth - 25;
    var iframe;
    iframe = document.createElement("iframe");
    iframe.id = "test-iframe";
    iframe.height = "10px";
    iframe.width = windowWidth + "px";
    iframe.style.visibility = "hidden";
    iframe.src = this.url;
    // Here is where the magic happens... add a listener to the
    // frame's onload event
    iframe.addEventListener("load", this.remotePageLoaded, true);
    //append to the end of the page
    window.document.body.appendChild(iframe);
    return;    
};

RemoteCanvas.prototype.remotePageLoaded = function() {
    // Look back up the iframe by id
    var ldrFrame = document.getElementById("test-iframe");
    // Get a reference to the window object you need for the canvas
    // drawWindow method
    var remoteWindow = ldrFrame.contentWindow;

    //Draw canvas
    var canvas = document.createElement("canvas");
    canvas.style.width = RemoteCanvas.CANVAS_WIDTH + "px";
    canvas.style.height = RemoteCanvas.CANVAS_HEIGHT + "px";
    canvas.width = RemoteCanvas.CANVAS_WIDTH;
    canvas.height = RemoteCanvas.CANVAS_HEIGHT;
    var windowWidth = window.innerWidth - 25;
    var windowHeight = window.innerHeight;

    var ctx = canvas.getContext("2d");
    ctx.clearRect(0, 0,
                  RemoteCanvas.CANVAS_WIDTH,
                  RemoteCanvas.CANVAS_HEIGHT);
    ctx.save();
    ctx.scale(RemoteCanvas.CANVAS_WIDTH / windowWidth,
              RemoteCanvas.CANVAS_HEIGHT / windowHeight);
    ctx.drawWindow(remoteWindow,
                   0, 0,
                   windowWidth, windowHeight,
                   "rgb(0,0,0)");
    ctx.restore();
};

Usage:

var remoteCanvas = new RemoteCanvas();
remoteCanvas.load();