Please note, this is a STATIC archive of website developer.mozilla.org from November 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Наши волонтёры ещё не перевели данную статью на Русский. Присоединяйтесь к нам и помогите закончить эту работу!

For general information about using <canvas> see the canvas topic page.

Code usable from Web content

Getting the number of pixels of a certain color in a canvas

The following function will return the number of pixels in a canvas that have the RGB color of r, g and b. This can be very useful to compare for example if a user has painted over another area as explained in this blog post.

function getpixelamount(canvas, r, g, b) {
  var cx = canvas.getContext('2d');
  var pixels = cx.getImageData(0, 0, canvas.width, canvas.height);
  var all = pixels.data.length;
  var amount = 0;
  for (i = 0; i < all; i += 4) {
    if (pixels.data[i] === r &&
        pixels.data[i + 1] === g &&
        pixels.data[i + 2] === b) {
      amount++;
    }
  }
  return amount;
};

Getting the color of a pixel in a canvas

This following snippet returns an object with the RGBA values of the pixel at position x and y of the canvas. This can be used to determine if the mouse cursor is inside a certain shape or not.

function getpixelcolour(canvas, x, y) {
  var cx = canvas.getContext('2d');
  var pixel = cx.getImageData(x, y, 1, 1);
  return {
    r: pixel.data[0],
    g: pixel.data[1],
    b: pixel.data[2],
    a: pixel.data[3]
  };
}

Chaining methods

This class provides jQuery-style chained access to 2D context methods and properties.

function Canvas2DContext(canvas) {
  if (typeof canvas === 'string') {
    canvas = document.getElementById(canvas);
  }
  if (!(this instanceof Canvas2DContext)) {
    return new Canvas2DContext(canvas);
  }
  this.context = this.ctx = canvas.getContext('2d');
  if (!Canvas2DContext.prototype.arc) {
    Canvas2DContext.setup.call(this, this.ctx);
  }
}
Canvas2DContext.setup = function () {
  var methods = ['arc','arcTo','beginPath','bezierCurveTo','clearRect','clip',
    'closePath','drawImage','fill','fillRect','fillText','lineTo','moveTo',
    'quadraticCurveTo','rect','restore','rotate','save','scale','setTransform',
    'stroke','strokeRect','strokeText','transform','translate'];

  var getterMethods = ['createPattern','drawFocusRing','isPointInPath','measureText', // drawFocusRing not currently supported
    // The following might instead be wrapped to be able to chain their child objects
    'createImageData','createLinearGradient',
    'createRadialGradient', 'getImageData','putImageData'
  ];

  var props = ['canvas','fillStyle','font','globalAlpha','globalCompositeOperation',
    'lineCap','lineJoin','lineWidth','miterLimit','shadowOffsetX','shadowOffsetY',
    'shadowBlur','shadowColor','strokeStyle','textAlign','textBaseline'];

  for (let m of methods) {
    let method = m;
    Canvas2DContext.prototype[method] = function () {
      this.ctx[method].apply(this.ctx, arguments);
      return this;
    };
  }

  for (let m of getterMethods) {
    let method = m;
    Canvas2DContext.prototype[method] = function () {
      return this.ctx[method].apply(this.ctx, arguments);
    };
  }

  for (let p of props) {
    let prop = p;
    Canvas2DContext.prototype[prop] = function (value) {
      if (value === undefined)
        return this.ctx[prop];
      this.ctx[prop] = value;
      return this;
    };
  }
};

var canvas = document.getElementById('canvas');

// Use context to get access to underlying context
var ctx = Canvas2DContext(canvas)
  .strokeStyle("rgb(30,110,210)")
  .transform(10, 3, 4, 5, 1, 0)
  .strokeRect(2, 10, 15, 20)
  .context;

// Use property name as a function (but without arguments) to get the value
var strokeStyle = Canvas2DContext(canvas)
  .strokeStyle("rgb(50,110,210)")
  .strokeStyle();

Code usable only from privileged code

These snippets are only useful from privileged code, such as extensions or privileged apps.

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 returns a promise which resolves when the file has been completely saved.

function saveCanvas(canvas, path, type, options) {
    return Task.spawn(function *() {
        var reader = new FileReader;
        var blob = yield new Promise(accept => canvas.toBlob(accept, type, options));
        reader.readAsArrayBuffer(blob);

        yield new Promise(accept => { reader.onloadend = accept });

        return yield OS.File.writeAtomic(path, new Uint8Array(reader.result),
                                         { tmpPath: path + '.tmp' });
    });
}

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 = "https://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(255,255,255)");
    ctx.restore();
};

Usage:

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

Convert image files to base64 strings

The following code gets a remote image and converts its content to Data URI scheme.

var canvas = document.createElement("canvas");
var ctxt = canvas.getContext("2d");
function loadImageFile (url, callback) {
  var image = new Image();
  image.src = url;
  return new Promise((accept, reject) => {
    image.onload = accept;
    image.onerror = reject;
  }).then(accept => {
    canvas.width = this.width;
    canvas.height = this.height;
    ctxt.clearRect(0, 0, this.width, this.height);
    ctxt.drawImage(this, 0, 0);
    accept(canvas.toDataURL());
  });
}

Usage:

loadImageFile("myimage.jpg").then(string64 => { alert(string64); });

If you want to get instead the base64 content of a local file using the file <input> element, you must use the FileReader object.

Метки документа и участники

Метки: 
 Внесли вклад в эту страницу: jsx, Drako, SlawomirRodak, kmaglione, fscholz, wbamberg, Sheppy, codepo8, fusionchess, Brettz9, Taw, Nickolay, MarkFinkle, Ripounet, Mgjbot, Bowmanmc, Ptak82, Chbok, Enn
 Обновлялась последний раз: jsx,