I received a comp yesterday for a mobile ad unit where the user would see some "frost" on their screen and underneath the frost is the ad content. The user would use their finger to "wipe away" the frost to reveal the content.
I decided to use the Canvas element to accomplish this. With the use of canvas' composite operation, this actually turned out to be pretty easy (although it took me a long time to find it). First, take a look at this rudimentary demo in a mobile browser. Drag your finger around on the screen and you'll see that the frost layer is erased wherever you touch. Here's the relevant Javascript I used:
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var img = document.createElement('IMG');
img.onload = function () {
ctx.beginPath();
ctx.drawImage(img, 0, 0);
ctx.closePath();
ctx.globalCompositeOperation = 'destination-out';
}
img.src = "http://dl.dropbox.com/u/12501653/FROST.png";
function drawPoint(pointX,pointY){
var grd = ctx.createRadialGradient(pointX, pointY, 0, pointX, pointY, 50);
grd.addColorStop(0, "rgba(255,255,255,.6)");
grd.addColorStop(1, "transparent");
ctx.fillStyle = grd;
ctx.beginPath();
ctx.arc(pointX,pointY,50,0,Math.PI*2,true);
ctx.fill();
ctx.closePath();
}
canvas.addEventListener('touchstart',function(e){
drawPoint(e.touches[0].screenX,e.touches[0].screenY);
},false);
canvas.addEventListener('touchmove',function(e){
e.preventDefault();
drawPoint(e.touches[0].screenX,e.touches[0].screenY);
},false);
The sauce here is in the ctx.globalCompositeOperation setting. There are several options for this, and Mozilla provides a really good description of what each does. It takes a little bit of mental gymnastics to get a handle on the whole source and destination concept, but once you have that, it's not hard to figure out which function will work for what you need.
In my case, I wanted my new shape to be able to poke holes in the shape underneath it. Destination-out does just that. When you add the new shape, the portion of the existing shape it covers will be removed. By setting the transparency of the new shape to less than one, I get a nice blend that allows the content below to become progressively more opaque as the user runs over the same spot multiple times. In this case, I use a radial gradient for the drawing point to achieve a soft edge.
When I actually integrate this, I'll need to figure out the right way to make the content beneath the canvas clickable and usable, so I'm sure that will lead to various nightmares, but for now I'm stoked to be able to create this effect using pure HTML/Javascript/CSS.