3 posts on Canvas

Chainvas: Make APIs chainable, enhance the canvas API

1 min read 0 comments Report broken page

It’s definitely not the first time someone writes a script to make the canvas API chainable, as a quick Google search will confirm.

However, I think my attempt has merit, because it’s not really focused in chaining canvas methods, but just about every API you use it on and because it’s super small, only 1KB!

You can find it here: chainvas


CSS.coloratum: Convert and share CSS colors

2 min read 0 comments Report broken page

Whenever I wanted to convert a CSS named color to RGB, I used to open the CSS3 colors spec in a new tab, search in the page and copied the values. Every time it felt even more tedious. I didn’t want to search in long tables, I wanted to type the color somewhere and get the values back, in an easy to copy format. So, after yet another color lookup earlier today, I decided to scratch my own itch and do it myself.

Of course, I didn’t plan to include a whole database of CSS colors in the website. My idea was much simpler: Use the named color to draw a rectangle in a <canvas> and then read the R,G,B values through ctx.getImageData().

I got the core functionality done in under 10 minutes, so I started adding stuff. I added a hex and HSL representation, I used canvas.toDataURL() to get a data URI of the rectangle and use it as a dynamic favicon*, I made the colors sharable and bookmarkable by using an old-fashioned hash. Also, I realized it actually supports any CSS supported color represenation by design, not just named colors.

Regarding the color conversions themselves, I took extra care to avoid redundancy. So values < 1 don’t have leading zeroes (.5 instead of 0.5) and when the hex color is in the format #xxyyzz it gets converted to #xyz. When it’s an RGBA color, it still converts it to hex, since those values will be supported in CSS4.

Since it’s for developers, I didn’t bother at all with fallbacks.

Cool stuff used:

  • HTML5: canvas, autofocus, output, oninput event, hashchange event
  • CSS3: gradients, media queries, box-sizing, background-clip, border-radius, shadows, RGBA
  • ES5: Array#map()
  • Selectors API

The reason the input’s border appears weird on Webkit is this long standing Webkit bug. Also, for some reason my nice dynamic favicons don’t display on Firefox, although they display fine in Webkit and Opera.

Enjoy: CSS.coloratum

Happy color sharing! Let me know of any problems or suggestions you may have.

PS: In case you’re wondering about the domain, I’ve had it for ages for another project and I thought it was quite fitting.

*Thanks to @milo for giving me the idea of using a dynamic favicon

Cross browser, imageless linear gradients

2 min read 0 comments Report broken page

I have to write a color picker in the near future and I wanted it to have those little gradients on top of the sliders that show you the effect that a slider change will have on the selected color. Consequently, I needed to create imageless gradients, in order to easily change them. My very first thought was creating many div or span elements in order to show the gradient. I rejected it almost instantly, for ovbious reasons (*cough* performance *cough*). My second thought was SVG for the proper browsers, and gradient filters for IE. As it turned out, inline SVG was too much of a hassle and I didn’t want to use Data URIs. My final thought was canvas for the proper browsers and gradient filters for IE.

Since I consider such a script very entertaining, I didn’t google it at all, I started coding right away. Time to have fun! :D After finishing it though, I googled it just out of curiosity and didn’t like the other solutions much (either the solution itself, or the code), so I decided to post it in case it helps someone. I also made a little test page, so that you may test out how it works. :)

The script is a class for the creation of linear 2-color gradients in any browser. It’s used like this:

var g = new Gradient(200, 100, '#000000', '#ff1166', true);

You can create and manipulate the Gradient object at any point (during or after DOM parsing) but you have to insert the element somewhere in the DOM after the DOM has finished parsing (which is common sense).

All the parameters in the constructor are optional and can be manipulated later. Their order is width, height, startColor, endColor, vertical.

Some notes:

  • Its object oriented and doesn’t throw any strict warnings
  • Tested in IE6, IE7, IE8, Firefox 3, Safari 4b and Opera 9.6. Probably works with older versions of Firefox, Opera and Safari as well (as long as they support <canvas>), I’m just not able to test in them currently.
  • All it’s methods return the object, so they can be chained.
  • You can modify it to support RGBA as well, but you’d have to use a different format for IE (extended hex) and a different one for the proper browsers. I didn’t need that and it would make the script unnecessarily complex, so I didn’t implement it.

Limitations (all these limitations are enforced by IE’s gradient filter):

  • Only does linear gradients
  • The gradient can be either vertical or horizontal. No other angles.
  • The only color format supported is #RRGGBB.


canvas (HTMLElement)

The HTML Element that is being used to render the gradient. Either a <canvas> or a <span>. You have to use it at least once, in order to insert the element in the DOM. I preferred not to do this automatically, since it would be too restrictive.

startColor (String)

The current start color of the gradient.

endColor (String)

The current end color of the gradient.

vertical (Boolean)

True if the gradient is vertical, false if it’s horizontal.

width (Number)

The width of the gradient in pixels

height (Number)

The height of the gradient in pixels


paint(startColor, endColor, vertical)

Used to change the colors and/or the orientation of the gradient. All parameters are optional.

resize(width, height)

Used to change the size of the gradient. Both parameters are optional.


Reverses the gradient (swaps endColor with startColor)


Rotates the gradient by 90 degrees clockwise (should I add CCW too?)


Hope you find it useful :)