For general information about using <canvas>
see the canvas topic page.
Getting the amount of pixels of a certain colour in a Canvas
The following function will return the amount of pixels in canvas that have the RGB colour 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, c.width, c.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 colour 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
Class to give jQuery-style chained access to 2D context methods and properties.
<html xmlns="https://www.w3.org/1999/xhtml"> <head><title></title></head> <body> <canvas id="canvas" width="1800" height="1800"></canvas> <script type="text/javascript"> function Canvas2DContext(c) { if (typeof c === 'string') { c = document.getElementById(c); } if (!(this instanceof Canvas2DContext)) { return new Canvas2DContext(c); } this.context = this.ctx = c.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']; var gmethl, propl; for (var i = 0, methl = methods.length; i < methl; i++) { var m = methods[i]; Canvas2DContext.prototype[m] = (function (m) {return function () { this.ctx[m].apply(this.ctx, arguments); return this; };}(m)); } for (i = 0, gmethl = getterMethods.length; i < gmethl; i++) { var gm = getterMethods[i]; Canvas2DContext.prototype[gm] = (function (gm) {return function () { return this.ctx[gm].apply(this.ctx, arguments); };}(gm)); } for (i = 0, propl = props.length; i < propl; i++) { var p = props[i]; Canvas2DContext.prototype[p] = (function (p) {return function (value) { if (typeof value === 'undefined') { return this.ctx[p]; } this.ctx[p] = value; return this; };}(p)); } }; var c = document.getElementById('canvas'); var ctx = Canvas2DContext(c).strokeStyle("rgb(30,110,210)"). transform(10, 3, 4, 5, 1, 0).strokeRect(2, 10, 15, 20).context; // Use context to get access to underlying context //alert(ctx); var strokeStyle = Canvas2DContext(c).strokeStyle("rgb(50,110,210)").strokeStyle(); // Use property name as a function (but without arguments) to get the value // alert(strokeStyle); </script> </body> </html>
The following snippets can only be used from privileged code (extensions, in particular).
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); }
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 oCanvas = document.createElement("canvas"), oCtx = oCanvas.getContext("2d"); function loadImageFile (sURL, fCallback) { var oImage = new Image(); oImage.src = sURL; oImage.onload = function () { oCanvas.width = this.width; oCanvas.height = this.height; oCtx.clearRect(0, 0, this.width, this.height); oCtx.drawImage(this, 0, 0); fCallback.call(this, oCanvas.toDataURL()); }; }
Usage:
loadImageFile("myimage.jpg", function(string64) { alert(string64); });
If you want to get instead the base64 content of a local file using the file {{ HTMLElement("input") }} element, you must use the FileReader
object.
{{ languages( { "fr": "fr/Extraits_de_code/Canvas", "ja": "ja/Code_snippets/Canvas", "pl": "pl/Fragmenty_kodu/Canvas" } ) }}