I think punching things would be awesome. Sadly, I was not born with the punching physique. Thus the only punching I do is with Html5 canvas, a technique that has an effect on approximately 0/100 bros. Fortunately we are in the realm of webdesign, where being able to punch with a browser technology is more valuable than it might be at one of those bars where you throw your peanut shells on the floor.
Punchout allows you to dynamically add and animate images behind type using Html5 canvas. Unlike most of the work here, Punchout is remotely practical, so I will be a little more detailed about how to use it and design with it. Afterwards I will talk a bit more about how it works.
using punchout
Like most of the code on this site, Punchout is written in plain Javascript, so you may use any library. If you are planning on using webfonts, I recommend using a library like jquery or prototype, as it is essential that you have a method of waiting for the DOM to finish loading before you execute. If you are using hosted type, you will probably need to work with a callback function. If you are using Typekit, I have a great example over at Cluster
Punchout uses a typography to canvas utility function I wrote called Shellac, which targets preexisting text and renders it. This allows you to design your page as normal, with the headline type in the right size and font. Once you have things looking correctly, you can load an image and fire Punchout. If you had an html element like this:
<h1 id="to_cluster"> Chrissy Totally Punched that Bro!</h1>
You could target it with this:
punchout.image = "/url-to-my/image.jpg"
punchout.down = -750 // image starting point
punchout.interval = 1 // the speed to move down
punchout.animate = true //defaults to true
punchout.init('to_cluster')
Punchout does not automatically remove the text for semantic purposes. There are a couple things you can do with it using css. The first is to simply hide it using text-indent:
#to_punch {
text-indent: -9999px;
}
Another would be to physically line up the text with the canvas, and then use independent transparency to ghost the text. This gives the illusion that the text is highlightable.
#to_punch {
color: rgba(0,0,0,0)
}
Canvas, to me, is an image. A fancy image, perhaps, but I still prefer to treat it as we do with all other images. Thus, in my work, I use the first example.
how it works
Placing an image behind type in canvas is quite easy. All you need to do is load the image, and place it on top of the canvas text with a composite type of source-atop.
var img = new Image();
img.src = 'url-to-image'
img.onload = function() {
context.globalCompositeOperation = 'source-atop'
context.drawImage(img,0,0)
}
The image can be animated using a setTimeout function. In this example, I’ve created a bit of easing in the animation, which I do by adding 0.2 ms to the interval after each repetition of the setTimeout function.
var down = -750, anim, interval = 1 function animate() { down = down + that.rate context.drawImage(img,0,down) if(down < 0) { setTimeout(animate,interval) interval = interval + 0.2 } }var img = new Image(); img.src = 'url-to-image' img.onload = function() { context.globalCompositeOperation = 'source-atop' window.setTimeout(animate,interval) }
This version is a little oversimplified. A more bulletproof execution should actually re-render the type with each pass using getImageData and putImageData in order to be compatible with Firefox. Please download the source and check out my live example if you want to replicate the process.