I am a fan of Three.js, it is fun, simple and there are a plethora of examples out there but it lacks a proper documentation with tutorials and simple examples. This is a severe handicap for anyone who wants to build something using Three.js and does not want to spend hours skimming through examples. That being said I did learn quite a bit about Three.js and even JavaScript, while skimming through those examples.  There are some tutorials but they don’t cover everything. I want to help by covering those pot holes in the documentation by creating simple tutorials that anyone with a decent knowledge of JavaScript can fallow.

Why mouse events? Mouse events have always been a pet peeve of mine, people always assume you know how to handle them and so don’t bother to explain; this is especially true for Three.js. That being said this is what you will need to know for this tutorial:

–         JavaScript (duh!)

–         JavaScript editor (there are plenty of online editors, I will be using jsfiddle)

–         Some basic understanding of Three.js

I will be using this http://jsfiddle.net/mand/gzuwg/ , a template I created for the tutorial. Before I proceed, let me say I won’t venture too deep into the mechanics of detecting a mouse event in 2d space and translating that into 3d coordinates.

http://jsfiddle.net/mand/gzuwg/#base

If you are not a fan of reading than skip to the finished project and come back for explanations: http://jsfiddle.net/mand/gzuwg/7/

STEP 1: Setting up

Setting up, you are welcome to fork the template above and that should take care of setting up. If you don’t want to use jsfiddle just copy and paste the code from the template and we are ready to go. Of course check if it is running properly, you should see a dark green sphere on a white background when you run the script.

STEP 2:  Creating variables

Creating variables, we will be using some global variables, and here is a list of them and their purpose. You want to place these variables outside the init() function.

The projector will be responsible for unprojecting the mouse vector with the camera. If you have a bit of knowledge on vector math, than this will make some sense to you, otherwise don’t worry about it, just be happy it works!

var projector = new THREE.Projector();

The mouse_vector is a vector object with three notable values (x, y, z) that will hold the mouse coordinates and we will be passing this variable to the projector.

var  mouse_vector = new THREE.Vector3();

This is a custom object that will hold the mouse coordinates that we receive from the browser. Why use two different objects to hold the mouse coordinate? Projector only takes THREE vectors and it also changes the vector we pass to it.

var mouse = { x: 0, y: 0, z: 1 };

The ray will be the Raycaster object, which is the centerpiece of mouse events in THREE. You will only need one Raycaster that you will have to reset its values via the set() method every mouse event but for now we will give it some dummy vectors.

ray = new THREE.Raycaster( new THREE.Vector3(0,0,0), new THREE.Vector3(0,0,0) ),

The intersects variable will hold the array that ray will return when we ask it if the mouse event intersected/touched any objects. Why does it return an array and what is in the array? This has a lot to do with how THREE handles mouse events, the Raycaster creates a beam or ray that extends outwards, away from the camera, on the point where the mouse click occurred. Every object that beam intersects is added to the array, as well as the coordinates where it occurred, distance and some other info. Remember we are working with 3d space where there are three axes, while our browser can only display two, so objects who share two axes can be layered behind each other. Anyway, what you have to remember is the first object the beam intersects is the first element in the array that the Raycaster returns.

var intersects = [];

STEP 3: Creating the event handler

Creating an event handler, we will create function to handle mouse down events because that is what people commonly think of as mouse events.* If you are familiar with handling mouse events in JavaScript than you know when a mouse event occurs the browser passes the mouse handler an object with mouse coordinates, which button was pressed and some other relevant information. Once we get those mouse coordinates we are going to do a bit of arithmetic to them to transform them into THREE coordinates.



//we will get the mouse coordinates and other information from event_info

function onMouseDown( event_info ) {

//stop any other event listener from receiving this event

event_info.preventDefault(); 

//this is where we begin to transform the mouse coordinates to THREE

//coordinates the mouse coordinates as you will notice will become much smaller

//and will range between -1 and 1, why? I have no idea but it works! :D

mouse.x = ( event_info.clientX / window.innerWidth ) * 2 – 1;

mouse.y = – ( event_info.clientY / window.innerHeight ) * 2 + 1;

//here is our THREE vector and we will pass it to the projector

 mouse_vector.set( mouse.x, mouse.y, mouse.z );

//the final step of the transformation process, basically this method call

//creates a point in 3d space independent of the camera where the mouse click

//occurred, this does change the mouse_vector object

projector.unprojectVector( mouse_vector, camera );

//what this statement is basically doing is creating a direction for the beam I was

//writing about earlier, the direction will be used to create the beam and gives us

//other objects which the mouse click might have also intersected

var direction = mouse_vector.sub( camera.position ).normalize();

//we pass the raycaster we created a new camera position/origin for

//the beam and direction for the beam, why is the camera position the origin

//of the beam? We are always viewing THREE scenes from the perspective of the

//camera so any action we take with the mouse is done from the perspective of

//the camera and the camera position becomes the origin of the ray

ray = ray.set( camera.position, direction );

//we use the intersectObject method of the raycaster to see if the ray

//intersected any objects, this will return an array with the first element being the

//object the mouse event occurred on and also the closet object to the camera the

//ray intersected, the last element in the array is furthest object from the camera

intersects = ray.intersectObject( sphere );

//the ray will return an array with length of 1 or greater if the mouse click

//does touch an object, any number other than 0 is true and we will see an

//annoying dialog celebrating our successful use of raycasting if there is an

//intersection

    if( intersects.length ) {

        alert( “hit” );

    }

}

STEP 4: Adding the event handler

Adding the event handler, in THREE event listeners are added to the renderer which creates the dom element we will be drawing the scene to and therefore click on. You can place this statement where ever you want, I usually put it in the init() function.

//we add the even listener function to the domElement

renderer.domElement.addEventListener( ‘mousedown’, onMouseDown );

Here is the finished product, with a bit less comments:

http://jsfiddle.net/mand/gzuwg/7/

NOTES*:

You can add more event listeners to the render, here are the other usual suspects:

renderer.domElement.addEventListener( ‘mouseup’, onMouseUp );

renderer.domElement.addEventListener( ‘mousemove’, onMouseMove);

A comprehensive list of events and browser support can be found here:

http://help.dottoro.com/larrqqck.php

I don’t know if all of these work with THREE but they should since they are events for dom elements regardless of what library you use.

Feel free to comment and make corrections.

Next , a drag and drop tutorial, until than, peace.