Turns out it's pretty easy to do a gradient favicon in svg:
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg">
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
<linearGradient y2="1" x2="1" y1="0" x1="0" id="favicon">
<stop stop-color="#ff0000" offset="0"/>
<stop stop-color="#ffff00" offset="1"/>
<rect id="svg_1" height="16" width="16" y="0" x="0" stroke="#7f0000" fill="url(#favicon)"/>
It would mean no canvas library needed. Just use same random color code tied to a templatized version of above.
Only downside is doesn't work in all browsers for true tab favicon, but that seems minor since it works on wiki pages.
Course some sort of pluggable system would be ideal for png, gravatar, svg, etc.
This is the current gradient generator:
Light, dark and angle are the three values that would need to be substituted into a templatized version. Also, a server would need to remember the values of these three random variables so that a gradient can be reproduced once chosen. Would this be as simple as producing favicon.svg as a substitute for favicon.png?
I remember looking into this but just happened to get the server side png generator working first.
Yes, exactly. I've got it working in concept, I just need to extract out the random color/angle logic from the favicon.coffee Nick created, then have a favicon.png.coffee and a favicon.svg.coffee with some logic to select which to use to create.
Can we put the favicon color data in the status local-identity.json? Seems logical but I dunno.
I did the template in jade because I have a designer that makes it easy to test, but we can switch it to haml if you like (assuming haml supports arbitrary tags).
I need to do some more testing, but it looks we could just ignore the file extension on the web requests and ask for http://mysite/favicon and then it sends the mime type and the browser figures it out. There's a lot of references to favicon.png scatter all over the place that would need to be cleaned up.
BTW - One other options is to have the favicon on the wiki pages be a div tag and set it's style via css and it could be either png image or css defined gradient. This might be cleaner anyway so we can use a css class rather than have all those hard-coded favicon.png's floating around.
I'll check something into my branch soon and you can take a look...
I've been looking over all this, and I think i'd like to stick with png. Most browsers don't seem to support svg favicons, and I think browser support of the favicons is a surprisingly important factor in browseability.
All the canvas code should be there in the current favicon.coffee, we just need to browserify it a bit, and add the logic to get it when there is a 404 for /favicon.png and and to upload the favicon when it's done.
It makes the server side code lighter for all implementations, especially node removing the node-canvas requirement. While only adding a few lines to the client, and also maintains all the functionality we have already.
There was a time before favicon.rb when new servers used the same default icon still available in default-data. There was a test for this but I updated it to expect generated icons with this commit: 6445bd5.
I suggest Nick adopt the default icon strategy and either ignore the failing test or find some way to make it pass with either approach. (Does the test fail? It looks pretty permissive right now.)
Once we have a clear notion of site ownership we can provide a utility for choosing a new icon from a collection of client-side generated icons. Richard Dawkins entertained many geeks with a program called Biomorphs. I'd like to see his "evolutionary" approach used to offer a site owner a simple mechanism for finding a likable icon that still adheres to the family resemblance goals I have for federated sites.
So the server get for /favicon returns the image in /status, but is totally decouple from favicon image creation and doesn't know/care how it got there?
Marty -- Yes, that is what I am suggesting, except that the server needs to go to some modest effort to make sure that there is a /favicon even if it is a brand new server. I'm suggesting that the node implementation just copy the favicon from default-data if it doesn't find one where it belongs.
(I did this for a while but it got too confusing when I made a server farm and all the sites there had the same favicon. That's when I added the random generated favicons.)
I would like to prototype a favicon picker coded as a federated wiki plugin. My strategy will be to:
Generate random gradient parameters (like in favicon.rb, or better).
Use these parameters to create many small canvas objects from which one will be picked.
Convert the chosen canvas to png by using canvas.toDataURL("image/png").
Send the converted image/png to the server to be the new favicon for the site.
I haven't done this yet so I don't know that it is actually possible. I would be pleased to see working code snippets, especially for the part about converting canvas to png and saving that on the server in a normal .png file.
Right now favicon stuff is working within spec on the express server. The main problem is that it has a very heavy requirement on the server install for the node-canvas library, which includes cairo and some other stuff. Which is a pain on linux installs and possibly impossible to install on other operating systems.
My theory on this is the same as yours Ward, except I hadn't envisioned a nice picking scheme. I think this should work fine, if we gave the favicon link an id of favicon:
or something along those lines. I think I can implement this with a few minor changes to client.coffee and a bit of browserification of favicon.coffee.
You might want to grab something like http://jscolor.com/ and let people choose there own colors.
Here's a library for creating .png from canvas: http://www.nihilogic.dk/labs/canvas2image/ (you may not even need that, just use canvas.toDataURL() and post that in a json object to the server)
The approach in the existing code doesn't take advantage of the built in gradient methods. Much easier to just do:
var canvas = $('#myCanvas');
var context = canvas.getContext('2d');
var gradient = context.createLinearGradient(0,0,32,32); //control direction here.
gradient.addColorStop(0, 'yellow'); //name, hex, rgb, rgba - all ok
context.fillStyle = gradient
context.fillRect(0, 0, 32, 32);
Great tips. Thanks.
We now have a "clear notion of site ownership" so it is a good time to move forward with some owner focused site customization plugins.
see #84 for a step to allow site-customisation
I'm going to move forward on this in the next couple of days if no one has yet. My plan so far is to make a plugin that gets downloaded when the favicon returns 404, generates an image based on the same criteria we have been using so far, and then uploads it back to the server. We can add a slick ui later, I just want to get the node-canvas dependency gone on the server side.
I'll look forward to seeing this. Thanks for taking it on.