Quick update: Thanks for the endorsement Mr. doob! I’m honored
Here is a web site with a cool Javascript effect by Mr. doob, recently posted on HN & Reddit. I’m trying to get better at my Javascript so here’s my dissection of this interesting effect, if you’re interested in learning how this is done.
First, create a HTML 5 canvas element (highly recommended short read about canvas here). Make its width and height the same size as window.innerWidth and window.innerHeight so that it fills up the content area of the browser window. Append the canvas element to the document body.
var canvas = document.createElement( 'canvas' ); canvas.width = window.innerWidth; canvas.height = window.innerHeight; canvas.style.display = 'block'; document.body.appendChild( canvas );
As of now, there’s only a 2D context to pick from. In future, there might be a 3D context based on OpenGL ES (quote). So just get the context with getContext, and then create the image element.
var context = canvas.getContext( '2d' ); var image = document.createElement( 'img' );
Now let’s add an event handler to the image for when the image loads. ‘this’ refers to the image element itself. bitmapWidthHalf and bitmapHeightHalf is exactly what it means: half the length of the image’s width and height respectively. Math.floor is used to round the result of the division down to the nearest integer.
Then comes the fun part. When the image is done loading in the browser, it sets the document object’s onmousemove event to draw the bitmap on the canvas. event is passed into the function, so that you can access event.clientX and event.clientY, which are respectively the mouse’s X and Y coordinates relative to the upper-left corner of the window.
The reason why drawImage() is given the mouse coordinates minus half the length of the image’s width and height is so that the image will always be centered on your cursor.
The reason for the false in line 11 is to indicate that this event is set to fire during the bubbling phase (really good explanation of event handling here).
image.addEventListener('load', function() {
var bitmap = this,
bitmapWidthHalf = Math.floor( this.width / 2 ),
bitmapHeightHalf = Math.floor( this.height / 2 );
document.addEventListener( 'mousemove', function ( event ) {
context.drawImage( bitmap, event.clientX - bitmapWidthHalf, event.clientY - bitmapHeightHalf );
}, false );
The following lines are actually not necessary for this effect to work in browsers on desktops and laptops. The following lines are there to support ‘touch’ devices, e.g. iPad, Android, etc. As you can see, it’s very similar to the code above, except the event is touchstart and touchmove. touchstart is when a finger first touches the screen. touchmove is when the finger (already touching the screen) now moves on the screen.
I’m actually not entirely sure what the for loop is for A kind reader commented below that event.touches.length is the number of fingers simultaneously touching the screen. Thus, each iteration of the for loop draws the image (which in this case is the bitmap) for each finger touching the screen. Thanks Guillaume!
document.addEventListener( 'touchstart', function ( event ) {
event.preventDefault();
for ( var i = 0; i < event.touches.length; i++ ) {
context.drawImage( bitmap, event.touches[i].pageX - bitmapWidthHalf, event.touches[i].pageY - bitmapHeightHalf );
}
}, false );
document.addEventListener( 'touchmove', function ( event ) {
event.preventDefault();
for ( var i = 0; i < event.touches.length; i++ ) {
context.drawImage( bitmap, event.touches[i].pageX - bitmapWidthHalf, event.touches[i].pageY - bitmapHeightHalf );
}
}, false );
}, false );
Last but not least, set the image element's source — and you're done
image.src = "ie6.png";
Update 1: I just discovered the reason why the canvas's display = block
@mrdoob Change the canvas to display:block so clicking and dragging doesn’t cause a little white space on the bottom.
Hope you enjoyed this short write up. I found 'Learning JavaScript' by Shelley Powers helpful when I was learning Javascript from basically scratch.
p.s. this is actually a Windows effect, not an IE effect. Either way, drop IE already! Use Google Chrome
Tags: cool site of the day, how it works, html5, javascript
