Menacing Cloud

Canvas Generated Favicons & Touch Icons.

17th June 2013, by Edward Cant.

In short, it is possible to use the HTML canvas element to dynamically add these resources to the HTML head when it makes sense to do so.

Generated favicons have been around a while, but the potential to use the same technique to cover touch icons encourages an efficient approach, reducing requests and bandwidth requirements in the process.

Demo

Check out deletefacebook.com (disclosure, my site) for a favicon and touch icon production example.

A favicon as well as iPhone and iPad touch icons (with Retina variations) are generated in under 2KB of JavaScript. One source file, zero icon requests.

This article serves as a demo for the art direction use case. A cloud is generated using circles and gradients appropriate to the target icon size.

Screenshot of generated touch icons on an iPhone4

Benefits

  • Saves on server requests and bandwidth.
  • Possible to reuse image assets in the drawing process.
  • Opportunities for dynamic icons e.g. background colour changes for website sections.
  • No need to worry about image format or compression.

Disadvantages

  • Requires Canvas and JavaScript familiarity.
  • Icons not present without JavaScript and Canvas support.

How It Works

  • Icons are drawn to a background canvas at appropriate sizes.
  • A data URI representation of each icon is created and then injected via a link tag.

The demos are built within the context of my own app engine, but the code is simple enough to modify for your own purposes.

The genImage(); function referenced initialises a canvas, draws the icon and returns a data URI via canvas.toDataURL(); of the image for insertion into the document head.

That part is up to you to implement as you see fit.

// Favicon, standard icons. //-------------------------- this.icon = function(width, height, drawFunc) { var d = document, img = this.genImage(width, height, drawFunc); // Insert into head var l = d.createElement('link'); l.rel = 'icon'; l.href = img; l.sizes = width + 'x' + height; d.head.appendChild(l); }; // Touch icon //------------ this.touch = function(width, height, drawFunc) { var d = document, img = this.genImage(width, height, drawFunc); // Insert into head var l = d.createElement('link'); l.rel = 'apple-touch-icon-precomposed'; // Precomposed to support Android l.href = img; l.sizes = width + 'x' + height; d.head.appendChild(l); };

Example Usage

It's possible to optimise further by narrowing devices down by screen width or device pixel ratio, as demonstrated in the code from deletefacebook.com

// 16 x 16 icon //-------------- fE.icon.icon(16, 16, function() { draw(16); }); // Touch icons //------------- if(scrWidth < 569) { // iPhone fE.icon.touch(114, 114, function() { draw(114); }); } else if(scrWidth < 1025) { // iPad fE.icon.touch(144, 144, function() { draw(144); }); } // Draw icon (from deletefacebook.com) //------------------------------------- var draw = function(size) { var ctx = fE.icon.c.ctx; var linearGradient = ctx.createLinearGradient(0, 0, 0, size); linearGradient.addColorStop(0,'#f33'); linearGradient.addColorStop(1,'#b11'); ctx.fillStyle = linearGradient; // Background gradient ctx.fillRect(0, 0, size, size); // Stripe ctx.lineWidth = size / 8; ctx.strokeStyle = '#fee'; ctx.beginPath(); ctx.moveTo(0.75 * size, 0.25 * size); ctx.lineTo(0.25 * size, 0.75 * size); ctx.closePath(); ctx.stroke(); // Gloss ctx.fillStyle = 'rgba(255, 255, 255, 0.125)'; ctx.fillRect(0, 0, size, size / 2); };

Icon Reference

Icons

  • Favicon. 16 x 16. (32 x 32 for high-dpi desktop browsers).
  • Opera Speed Dial. 114 x 114 (minimum). 256 x 160 (maximum).

Touch icons

  • iPhone. 57 x 57.
  • iPhone Retina. 114 x 114. Upped to 120 x 120 as of iOS7.
  • iPad. 72 x 72.
  • iPad Retina. 144 x 144. Upped to 152 x 152 as of iOS7.

Windows 8 Pinned Sites

I had hoped that this technique would make pinned icon generation easy. Sadly, I could not get IE to play ball.

Tips

A blank favicon is present in the site root directory for really old browsers.

I've generated icons for the demos, but you could just draw an image onto the canvas. The image could be one that is already on your website, thereby avoiding any extra requests.

Consider the benefits of generated graphics. Gradients, noise, tiling, shadows can all be used without the cost of transferring them via an image file.

References

Follow the author on Twitter.

ProtoFluid. ‘Effortless responsive web design testing’.

Previous Articles

Canvas Generated Icons. Read more.

Targeting Windows 8 Snap Mode. Read more.

CSS @viewport rule or viewport meta tag? Read more.

The Responsive Viewport. Missing piece of the responsive web design puzzle? Read more.

Getting the Viewport Scale.
Read more.

Hiding the iPhone Address Bar.
Read more.

Orientation Correct Screen Width.
Read more.

iPhone Title Modification.
Read more.

Optimising for High Pixel Density Displays.
Read more.

CSS3 Media Query Prototyping With ProtoFluid.
Read more.

AJAX Kill Switch. Version 2.
Read more.

URI Processing With JavaScript.
Read more.

Source Code

All source code is provided for free.

A standard disclaimer of warranty and limitation of liability applies.