Tutorial 3
From NaviWiki
Contents |
Tutorial 3 - "Transparency is Beautiful"
A Navi is basically a browser window rendered to a texture. This browser window is normally opaque and so we must use 'alpha-masks' and/or 'color-keying' to achieve the look we want.
The overall opacity of a Navi
The easiest and simplest way to start getting transparent is by changing the overall opacity of a certain Navi. You can achieve this by invoking Navi::setOpacity. Here's an example of how to make a Navi half-transparent (50% opacity):
myNavi->setOpacity(0.5);
Alpha-Masking is fun!
Changing the overall opacity is great and all but we still have a rectangle/square for a Navi. What do we do if we wanted something rounder, for example.. a circle?
The answer is Alpha-Masks. An alpha-mask is an image (usually the same exact size as your Navi) with an alpha channel. If you give a Navi an Alpha-Mask image, it will use the alpha channel of that image to 'mask' your Navi.
Let's use Navi::setMask to apply an alpha-mask "my_alphamask.png" to a Navi:
myNavi->setMask("my_alphamask.png");
Note: Alpha-Mask images must either be the same size or bigger than the Navi it is applied to. Alpha-Mask images that are larger will not be scaled, instead they will be cropped.
A really smart technique is using an image as both the background to your Navi and as the alpha-mask at the same time. If you've seen the NaviDemo, every Navi on-screen was using this technique. This is really only possible with '.png' images.
The Dark Art of Color-Keying
What if you wanted some opaque text on a transparent/semi-transparent background? Or maybe you have some fancy Javascript animation that moves some images around and you want the background to be transparent? Obviously we can't use a static mask for such things, so what can we do?
Color-Keying is your best friend in this situation. What is color-keying you ask? Well basically you have a certain color (say #FF00FF, pure magenta) called your 'Key Color' that you dynamically replace with a 'Fill Color' with custom opacity.
So for example, say you want to key out all of the yellow (#ffff00) pixels on your Navi with a half-transparent green (#00c000). This is how you could do it:
myNavi->setColorKey("#ffff00", 0.5, "#00c000");
Fuzzy Color-Keying
Color-Keying usually has a problem with anti-aliased text/rounded corners. In the browser, the background color of a page/element is used as the matte for anti-aliasing text and also with .gif's and .png's. Because color-keying usually only uses a single key-color, it doesn't catch these slightly-different-colored pixels.
Fuzzy Color Keying was implemented in v1.2 of the NaviLibrary and was written specifically to combat this problem.
You may set a 'fuzziness' level in Navi::setColorKey (the fourth parameter). A 'fuzziness' level of 0.0 is the default and uses the exact key color. Increasing this level (the max is 1.0) by arbitrary amounts increases the range of colors that will be keyed out.
All pixels that are keyed out will have their color replaced with the fill color. However, the keyed-out pixels' opacity will be calculated based on the color distance to the key color. So if you had a 'pure magenta' key color and a 'black' fill color and an opacity of 0.0, all 'pure magenta' pixels will be replaced with a transparent black color.. but a slightly-darker 'magenta' pixel will be replaced with a black with opacity of maybe 10%.
I know this sounds a little confusing and so I put together a little video for you:
Fuzzy-Color Keying and Animated Dock Example Video (XVID codec)
The Future
Alpha-Masks and Color-Keying are both techniques that take care of something that should already work without the need for intervention.
Purportedly, the upcoming release of Mozilla XULRunner (Gecko) 1.9 will allow us to render to a true transparent surface complete with a real alpha channel. If all goes as planned and we successfully port to this new release (no easy task by any means-- they've re-written most of the underlying graphics engine), the above two techniques should be rendered obsolete.

