Announcing Faviconist

faviconist screenshot

I have made a new Favicon generator, Faviconist. Since most favicons are just a letter with some colour theme, I found it crazy to have to open up a photo editor every time I wanted a new favicon. Or alternatively, it’s easy enough to convert an image with ImageMagick, but most images don’t scale down nicely to a tiny icon! So the aim here is not an editor as such, but a true “favicon generator”.

Using Faviconist

To create a favicon, it’s as simple as typing the first letter of your website. But you probably don’t want the default colour scheme, so it’s easy enough to tweak. Under the covers, Favicon has a concept of a “FillStyle” and both foreground and background are instances of FillStyle, so they have the same flexibility. You can have a solid fill style (just a single colour), a linear gradient, or a radial gradient.

For simplicity, Linear gradients don’t have stops (it’s just a linearly increasing spectrum from start to finish), though you can choose the direction. And in the same sprit of simplicity, radial gradients may only begin at some points, and their span is fixed. The guiding principle here is “YAGNI” – You Ain’t Gonna Need It. I’m catering for the 95% of people who don’t want to micro-design their icons; the rest will still need to resort to PhotoShop et al.

The preview images are PNGs, which can easily be downloaded directly. However, another gripe of mine is the whole thing of downloading to hard drive and uploading back to a server somewhere else. Hot-linking, aka “bandwidth theft”, is rightly a problem for the original image host…but it’s a shame the only way we can deal with it is to silo everything. (A parallel vision of the web, which might have almost succeeded and still might, saw it more as embedded content than a collection of copies and links.) In this case, it’s only favicons, so I’ll just say hot-link and be merry. When you click “Save Favicon”, it saves the icons on my server and you can just cut-and-paste into your own project.

I hope this is useful for quick hacks and hackathons, where favicons are often forgotten! These days Favicons are more useful than here. Of many reasons to use a favicon, things one might forget are: they’re used on third party sites like Google Plus, tabbed browsing is super-popular these days; if you don’t provide favicons, you’ll get 404s in your log files.

And here’s a little tip for you – don’t just use letters. Try special characters, and don’t just limit yourself to ASCII. You have the entirety of Unicode at your disposal!

How Favicon Works

Buzzword Bingo time. There are a number of technologies at work here:

  • HTML5 Canvas In the past, a site like this would have to be powered by the server – every change would require a long wait for the server to generate a new image. But now, we can do it in real-time, in the browser, using Canvas. The only server interaction is conversion to “.ico”; unfortunately, Canvas will output to PNG, but not ICO. And while a JavaScript ICO encoder is certainly a possibility, no-one has yet written one.

  • Canvas Text To draw text, Faviconist uses Canvas’s fillText method. e.g. context = canvas.getContext('2d'); context.fontStyle = '25px arial'; context.fillText('Yo!'). When Ace Editor effort got started (called Bespin), in the early days of canvas, text support was patchy. But now it’s very well supported.

  • MeasureText Library I thought Faviconist would be easy because I thought there would be simple metrics for fonts. Turns out canvas’s measureText() returns a “TextMetrics” object, and guess what TextMetrics contains:

interface TextMetrics {
  readonly attribute double width;
};

Huh? We can only find the text’s width, not its height. And as a I went down the path, I learned you can’t just say “draw this text with its top-left at (0,0)”. To center the font, as we do in Faviconist, we actually need to determine text offset as well – left and top.

So I built the MeasureText library. It works as a drop-in replacement (~shim) for the built-in HTML5 Canvas MeasureText mechanism, and also provides a new convenience function not requiring an existing canvas. It works by drawing the text and scanning the resulting bitmap to get a true representation of the metrics. Using this, and with a little geometry, it’s possible to center text.

  • Favicon Library Figured it would be cool to show a preview of the favicon by changing the site’s actual favicon! For which I used ye olde Favicon library, which I originally created via this blog and I’ve now officially moved to Faviconist.com. The library also incorporates a new “badge” feature, so you can show number of pending emails, etc. Go try the demo!

  • Font Selection You can choose fonts, with the fonts coming from the Google Font Directory. It wasn’t feasible load all fonts, so they’re loaded dynamically, but I wanted to show previews … so there’s a script to build a 38,000 pixel sprite map! It’s loaded after the page loads, with a canvas-based check to see if it loaded successfully (since it doesn’t work on Firefox). To show it in a dropdown, I used a fork of the Chosen library, a fork which retains the class of each option in the select list.

  • Chrome Frame Didn’t want to support IE6-IE8, so introduced Google Chrome Frame, based on the code in HTML Boilerplate, but increasing the version check from 6 to 8.

  • JavaScript Libraries Faviconist uses several useful libraries: jQuery, Underscore, Backbone, and jQuery Tools. And just to say, jQuery Tools is the very picture of Developer Experience heaven. Great explanations, many easy-to-follow demos, lots of options…and a CDN for the libraries.

  • NodeJS, Connect, Express The server is NodeJS running the Express-Connect stack. Considering that the app is almost all client-side, I spent a ton of time getting up to speed with this stack, partly due to performance optimisatins, and partly due to the next point …

  • Jade, Stylus, Kaffeine Being a fan of DRY, I’m very happy to be using higher-level abstractions of HTML, CSS, and JavaScript. I certainly am happy with Jade, with the exception of dropping in raw HTML script snippets. And Stylus is absolutely awesome. Kaffeine makes JavaScript much easier, though I’ve found it difficult to incorporate everywhere because the ecosystem is very much geared around CoffeeScript. e.g. Connect comes with a default CS compiler, Nodemon (a node watch-and-run-tool by Remy Sharp) supports CS, there’s a ton of doco about getting CS working with things. So that was really the biggest challenge. I mainly wanted Kaffeine because I’m not such a fan of significant whitespace, but the ecosystem’s preference for CoffeeScript did present challenges.

I hope you enjoy Faviconist. It’s a work in progress, so please leave feedback if you have suggestions.

Ajax/Javascript: 8 Ways to Create Graphics on the Fly

<a href='http://digg.com/programming/Ajax_Javascript_8_Ways_to_Create_Graphics_on_the_Fly'>Ajax/Javascript: 8 Ways to Create Graphics on the Fly &#8211; digg this</a>

The ability to create rich graphics on the fly is one of the critical gaps in Ajax. There are indeed techniques to do it, albeit far from perfect, and some are do-able today if you take a pragmatic view of things and keep graceful degradation in mind.

Here I list all the techniques I can think of to create graphics and images dynamically when you’re creating an Ajax/DHTML/Javascript web app, with varying degrees of portability and usability. Starting with the obvious and ending with the obscure. Please submit any other techniques you’re aware of!!!

  1. Use SVG. Current versions of Firefox, Opera, and Safari (nightly builds) support SVG natively, but with IE and older versions, users need to install a plugin. SVG is an old W3C standard that creates images based on XML. Being a vector format, it stores the image at a high level (curves, lines, etc), so it scales better than a plain bitmap. Here’s an SVG circle (adapted from W3CSchools:

    1. <svg width="100%" height="100%" version="1.1"
    2. xmlns="http://www.w3.org/2000/svg">
    3. <circle cx="25" cy="25" r="30" stroke="black"
    4. stroke-width="2" fill="green"/>
    5. </svg>

    You could build up the XML string in the code or pull it down from the server with a remote request. However, you don’t actually have to specify the XML as a literal string message; you can create a blank SVG document object model (DOM) and manipulate it to build up an image. In this example, we create a circle of radius 25 (adapted from this tutorial):

    javascript

    1. var svgDocument = evt.target.ownerDocument;
    2. var shape = svgDocument.createElementNS(svgns, "circle");
    3. shape.setAttributeNS(null, "cx", 25);
    4. shape.setAttributeNS(null, "cy", 25);
    5. shape.setAttributeNS(null, "r",  20);
    6. shape.setAttributeNS(null, "fill", "green");
  2. Use Canvas. Canvas was introduced in Safari and now in Firefox and Opera too. No sign of life in IE, but this there’s a fantastic adaptor hack (via Ajaxian) that emulates Canvas using IE’s native VML support (more on VML below), and it’s now been rolled into an open-source project, ExplorerCanvas by some Googlers.

    Where SVG is about things, Canvas is about actions. SVG documents represent images. Canvas tags include code to build up an image, a bit like moving a turtle in the Logo language. So you set a colour, draw something, change the fill style, draw something else, etc. You manipulate a Canvas tag like this:

    javascript

    1. var canvas = document.getElementById('tutorial');
    2.   if (canvas.getContext){
    3.     var ctx = canvas.getContext('2d');
    4.     ctx.fillRect(25,25,100,100);
    5.     ctx.clearRect(45,45,60,60);
    6.     ctx.strokeRect(50,50,50,50);
    7.   }

    (BTW Canvas uses the dreaded term, “Context”, to refer to what should really be called “paintbrush”, “pen”, or “turtle” … more concrete terms than “Context” which imply some sort of metaphor. But wouldn’t an imperfect metaphor be easier to grok than the generic “Context”? Alas, it’s a common idiom in graphics programming and will be around for a while.)

  3. Load dynamic images from the server. Once you have an image tag (either in the initial HTML or created on the fly with document.createElement(“img”), you can set its source to any URL, even external to your domain (though cross-domain “hot-linking” should generally be done only with permission). This is standard DHTML/Ajax stuff and works with any browser.
    javascript

    1. button = document.createElement("img");
    2. button.src = "http://example.com/livechart.gif?interval=15"
    On the server, the image need not be a static image file. It can be a server-side script that happens to output a binary image with the appropriate header, and furthermore, the script can accept CGI parameters, so a unique image can be generated on the fly. Of course, performance will probably suffer if you rely on the server to create images on the fly, and you can only generate them once a second or so. The various Ajax image manipulation tools do something like this.
  4. Use Vector Markup Language (VML). VML is effectively the MS equivalent of SVG, and as such works in IE, and only in IE. As with SVG, you use XML to specify an image.
    1. <v:oval style="position:absolute; left:0; top:0;
    2.               width:100pt; height:50pt"
    3.               fillcolor="red">
    4. </v:oval>
    Fortunately, the Canvas-on-VML hack mentioned earlier means you can take advantage of VML without committing to IE-specific code, though it’s (obviously) not a perfect emulation by any means.
  5. Introduce a Richer Plugin, most likely Flash, to beef up the browser’s multimedia capabilities.
  6. Rely on plain old CSS and the DOM. You can do some impressive-looking things with just CSS and the DOM, e.g. the CSS graphs library. And of course it’s easy enough to make it fully portable too.
  7. Create an image and set its src to a data: resource. Firefox and Opera only. From Dive Into GM:
    javascript

    1. var logo = document.createElement('img');
    2. logo.src = 'data:image/gif;base64,R0lGODlhDQAOAJEAANno6wBmZgAAAAAAACH5BAAAAAAA'+    'LAAAAAANAA4AQAIjjI8Iyw3GhACSQecutsFV3nzgNi7SVEbo06lZa66LRib2UQAAOw%3D%3D';
    3. document.body.insertBefore(logo, document.body.firstChild);
  8. Embed an XBM file. Yes, some browsers can display XBM images. Works on IE and Firefox, but not Safari or Opera. Unfortunately, XBM has the rather major constraint that it’s black-and-white. However, it does have the virtue of being a plain-text format which, like the data: protocol, you can assign an image source to.

    If you get your image data in that format in a string (complete with the n after each of the #define lines), then you can make any image’s SRC attribute be:
    “javascript:'”+xbmimagestring+”‘”

    XBM’s not used often, but there are some nice examples: Wolfenstein 5K, most notably, as well as this bitmap editor and a sparklines library.

(Off-topic: I’ve just updated my blog page, I prefer the 2-column sidebar because: (a) there are now 20 monthly archives links; (b) I wanted to add a ton of chicklets; (c) I wanted to add more bio info. BTW If you have a blog, here’s a quick exercise: Place yourself in the mind of a new visitor for twenty seconds, and decide if this person could work out who you are, what you do, and how to contact you. Around 90% of blogs fail this test on the grounds it’s impossible or way too hard.)