This repository has been archived by the owner. It is now read-only.

Use svg for default favicon (in node)? #77

Open
martypdx opened this Issue Jan 5, 2012 · 14 comments

Comments

Projects
None yet
4 participants
@martypdx

martypdx commented Jan 5, 2012

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/ -->
 <defs>
  <linearGradient y2="1" x2="1" y1="0" x1="0" id="favicon">
   <stop stop-color="#ff0000" offset="0"/>
   <stop stop-color="#ffff00" offset="1"/>
  </linearGradient>
 </defs>
 <g>
  <title>Smallest-Federated-Wiki favicon</title>
  <rect id="svg_1" height="16" width="16" y="0" x="0" stroke="#7f0000" fill="url(#favicon)"/>
 </g>
</svg>

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.

Thoughts?

@WardCunningham

This comment has been minimized.

Show comment Hide comment
@WardCunningham

WardCunningham Jan 5, 2012

Owner

This is the current gradient generator:

https://github.com/WardCunningham/Smallest-Federated-Wiki/blob/master/server/sinatra/favicon.rb

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.

Owner

WardCunningham commented Jan 5, 2012

This is the current gradient generator:

https://github.com/WardCunningham/Smallest-Federated-Wiki/blob/master/server/sinatra/favicon.rb

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.

@martypdx

This comment has been minimized.

Show comment Hide comment
@martypdx

martypdx Jan 6, 2012

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...

martypdx commented Jan 6, 2012

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...

@nrn

This comment has been minimized.

Show comment Hide comment
@nrn

nrn Jan 6, 2012

Collaborator

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.

My proposal would be this, if the browser requests the favicon for the local site, and gets a 404, it downloads a bit of javascript, renders the gradient to a 2d canvas element, sets that as favicon.png and attempts to upload it back to the server for future use.

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.

Collaborator

nrn commented Jan 6, 2012

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.

My proposal would be this, if the browser requests the favicon for the local site, and gets a 404, it downloads a bit of javascript, renders the gradient to a 2d canvas element, sets that as favicon.png and attempts to upload it back to the server for future use.

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.

@WardCunningham

This comment has been minimized.

Show comment Hide comment
@WardCunningham

WardCunningham Jan 6, 2012

Owner

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.

Owner

WardCunningham commented Jan 6, 2012

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.

@martypdx

This comment has been minimized.

Show comment Hide comment
@martypdx

martypdx Jan 6, 2012

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?

martypdx commented Jan 6, 2012

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?

@WardCunningham

This comment has been minimized.

Show comment Hide comment
@WardCunningham

WardCunningham Jan 6, 2012

Owner

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.)

Owner

WardCunningham commented Jan 6, 2012

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.)

@WardCunningham

This comment has been minimized.

Show comment Hide comment
@WardCunningham

WardCunningham Jan 6, 2012

Owner

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.

Owner

WardCunningham commented Jan 6, 2012

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.

@nrn

This comment has been minimized.

Show comment Hide comment
@nrn

nrn Jan 7, 2012

Collaborator

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:

$("#favicon").attr('href', ctx.canvas.toDataURL());

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.

Collaborator

nrn commented Jan 7, 2012

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:

$("#favicon").attr('href', ctx.canvas.toDataURL());

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.

@martypdx

This comment has been minimized.

Show comment Hide comment
@martypdx

martypdx Jan 7, 2012

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')[0];
console.log(canvas)
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 
gradient.addColorStop(1,   'red'); 
context.fillStyle = gradient
context.fillRect(0, 0, 32, 32);

martypdx commented Jan 7, 2012

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')[0];
console.log(canvas)
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 
gradient.addColorStop(1,   'red'); 
context.fillStyle = gradient
context.fillRect(0, 0, 32, 32);
@WardCunningham

This comment has been minimized.

Show comment Hide comment
@WardCunningham

WardCunningham Jan 7, 2012

Owner

Great tips. Thanks.

Owner

WardCunningham commented Jan 7, 2012

Great tips. Thanks.

@WardCunningham

This comment has been minimized.

Show comment Hide comment
@WardCunningham

WardCunningham Jan 8, 2012

Owner

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.

Owner

WardCunningham commented Jan 8, 2012

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.

@SvenDowideit

This comment has been minimized.

Show comment Hide comment
@SvenDowideit

SvenDowideit Jan 10, 2012

Contributor

see #84 for a step to allow site-customisation

Contributor

SvenDowideit commented Jan 10, 2012

see #84 for a step to allow site-customisation

@nrn

This comment has been minimized.

Show comment Hide comment
@nrn

nrn Jan 29, 2012

Collaborator

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.

Collaborator

nrn commented Jan 29, 2012

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.

@WardCunningham

This comment has been minimized.

Show comment Hide comment
@WardCunningham

WardCunningham Jan 29, 2012

Owner

I'll look forward to seeing this. Thanks for taking it on.

Owner

WardCunningham commented Jan 29, 2012

I'll look forward to seeing this. Thanks for taking it on.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.