delphic.me.uk

Controlling the Cursor (for WebGL & HTML5)

First off I want to recommend LearningWebGL for anyone that wants to learn WebGL. I'm learning Javascript at the same time as WebGL (hopefully to make some interesting web games), so I'm falling into a few pit falls that more experienced people would probably avoid! So just in case you're someone else that's learning Javascript and WebGL at the same time, I'm going to post snippets / solutions to particular problems I encounter. The first is on the investigation I had to do to fix the cursor issues I was having!

Preventing cursor changing on drag

Normally if you click and then move the mouse - something you tend to do a lot of in games - your cursor changes the 'text' cursor (looks like an capital i). This isn't exactly desired behaviour, but stopping this easy if you know how. All we need to do is override / prevent the default behaviour by returning false in your handling of the mouse down event. Your JavaScript should look something like that below:

// Canvas Element
var canvas; 

document.onload { 
	// Set variable to the canvas
	canvas = document.getElementById("myCanvas"); 
	// Bind mouse down on our canvas event to our own function
	canvas.onmousedown = handleClick;  
}

function handleClick() {
	// Handle Click!
	// FYI - event.button = 0 left click, = 1 Middle Click, = 2 Right Click
	
	// Prevent the default action
	return false; 	
}

So no more horrible Text cursor! Obviously you'll also need handle mouse move and mouse up events as part of your game, but that's not for this article.

Preventing the right click menu

You might want to allow right click to be an input for your game, currently as soon as you release the right mouse button the context menu appears, not so great! The return false on the click event in the previous section isn't enough to prevent this from happening. Instead you need to return false on the oncontextmenu event, this can be done in JavaScript or on the element in question as below:

<canvas id="myCanvas" oncontextmenu="return false;"></canvas>

Setting your own cursor

Now we probably don't want to use the default cursor for our game so an easy way to change the cursor is the CSS cursor property. Which you can use to replace the cursor with an image of your choice:

#myCanvas { cursor: url(myCursor.gif), default; }

Remember to list a default cursor to be used in case the image can not be loaded. You can use "crosshair" cursor as the default if you prefer. Here's a set of examples which will show you all the cursor types.

Oh you want a more complicated cursor?

Of course the above method is only suitable for simple animated or static cursors. If you want to do something more complex, for example you might wish the cursor to be animated under certain circumstances, or to turn the cursor into a selection box when over selectable objects. You might be able to change the CSS on the fly with JavaScript but much better to use WebGL to draw a custom cursor (I won't cover how to draw one here). To draw your own cursor first you need to hide the default cursor, "Aha I know this!" you might think!

#myCanvas { cursor: none; } /* Wrong! */

Unfortunately not... this is not a standard cursor, it has been implemented in some browsers, but it isn't supported by Chrome. We want a solution that will work everywhere WebGL does (especially Chrome as it's very friendly to WebGL). You can instead use the url() method to set it to an almost transparent image (if you use a fully transparent image Chrome will 'helpfully' display a black square instead).

#myCanvas { cursor: url('data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto; }

Here we use a Data URI to specify the image to be used as the cursor inline, rather than as a separate file. If you use the CSS above you can change the cursor to be imperceptable and can draw your own on the canvas.

I hope this was helpful! Any comments welcome (@_delph).