delphic.me.uk Navigate

Controlling the Cursor

Preventing cursor changing on drag

When creating games using the canvas element there's few cases where the default cursor behaviour is unlikely to be what you want, here's how to get the cursor to behave itself.

Normally if you click and then move the mouse - something you tend to do a lot of in games - your cursor changes to the text selection cursor. This isn't exactly desired behaviour if you're not selecting text, but stopping this easy if you know how. All we need to do add an event lisenter that passes the useCapture parameter as true. Your JavaScript should look something like that below:

window.onload = function() {
	// Set variable to the canvas
	var canvas = document.getElementById("myCanvas");
	// Listen for mouse down on our canvas event, capturing the event
	canvas.addEventListener("mousedown", handleClick, true);
};

var handleClick = function() {
	// Handle Click!
};

So no more horrible text cursor! You'll probably also want to handle mouse move and mouse up events as part of your game.

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 default browser context menu appears, not so great! The event capture on the mouse down event in the previous section isn't enough to prevent this from happening. Instead you need to override the oncontextmenu event on the element in question as below:

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

Note that capturing the event in JavaScript, that is canvas.addEventListener("contextmenu", handleContextMenu, true), will not prevent the default context menu from appearing.

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. The MDN cursor page contains a demo and images for all supported cursor types.

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 if more powerful to use the canvas or WebGL to draw a custom cursor. Before you draw your own cursor you need to hide the default cursor.

#myCanvas { cursor: none; }

You also need to calculate the mouse position relative to your canvas, the following code does so adjusting for the canvas element's offset and scale.

window.onload = function() {
	var canvas = document.getElementById("myCanvas");
	canvas.addEventListener("mousemove", handleMouseMove);
};

var handleMouseMove = function(event) {
	var canvas = event.target;
	// calculate mouse position in canvas pixel coordinates space where (0,0) is top left
	mouseX = Math.floor(canvas.width * (event.clientX - canvas.offsetLeft) / canvas.clientWidth);
	mouseY = Math.floor(canvas.height * (event.clientY - canvas.offsetTop) / canvas.clientHeight);
};

This calculates the mouse position in pixel coordinates, which is very helpful if you're using 2D canvas, if you're using WebGL you may want to forego multiplying the values by canvas dimensions and get it in screen-space instead.

I hope this tutorial was helpful, if you have any comments or feedback you can contact me via twitter @_delph.