Tutorial 2: Listening for Events  
Author: Tony Parisi tparisi@mediamachines.com  
Last updated: October 11, 2006  

Live Example Demonstration - 3D world opens in a seperate window.
Try The Demo

Example Files - displayed as text files, open in a seperate window.
index.html
ajax3d.js
tutorial2.js
ajax3dlogo.x3d

Example Files - download as ZIP
ajax3dlogo.zip

This tutorial illustrates how to listen to events coming from an X3D world, a capability that is fundamental for building dynamic applications which respond to user input.  

Setup: Embed an empty X3D world in the page. In index.html, we see the X3D viewer embedded using an EMBED tag with the following parameter values (explained below):  

<embed WIDTH="640" HEIGHT="480" NAME="FLUX" SRC=" " TYPE="model/x3d" DASHBOARD="0" BGCOLOR="0xFFFFFF">  

Parameter name

Description

NAME

Used by the HTML DOM to identify this particular embedded object

SRC

The X3D source file to be loaded by the FLUX Player; in this case empty because we will load the world dynamically (see below)

TYPE

The MIME content type of the object; required to tell the web browser which control to use for viewing this content (in this case, FLUX Player)

DASHBOARD

FLUX-specific parameter to turn off the built-in navigation dashboard controls

BGCOLOR

FLUX-specific parameter to set the X3D window background color, in this case to match the HTML page background

 

    Step 1: Create a browser listener object. In the file ajax3d.js, we have defined a function initAjax3d(). initAjax3D() is called when the page is loaded. This function sets up a browser listener as follows:  

listener = new Object();         
listener.browserChanged = browserChanged;         
browser.addBrowserListener(listener);  

The browser listener is an object with a specially named callback function (“browserChanged”) that is called by the X3D browser when interesting events happen, such as when a new file is loaded.  

We want to know when the X3D file is completely loaded, because only then can we be sure that we can get handles to nodes using the getNode() method of the ExecutionContext object. If, for example, we tried to call context.getNode() in response to the web page onLoad event, the call might fail. Why? Because the web browsers operate asynchronously, i.e. they do not guarantee the order in which the X3D viewer component is loaded and the onLoad handler for the page is called. We get around this by loading an empty scene, setting up the browser listener, and then asking the browser to load the named file (see next step).  

Note that, with the file ajax3d.js, we have now introduced the beginnings of a general-purpose framework for building Ajax3D applications. At the moment this file is quite simple; it has just 3 functions defined to help the application connect to the X3D world. We will be building on this framework in upcoming tutorials.

  Step 2: Dynamically load a world file. Now that we have set up a browser listener, we can ask the browser to load a specific file, and the application will be notified when it is fully loaded:              

browser.loadUrlS (filename);  

This call loads the file ajax3dlogo.x3d, which has a nicely modeled Ajax3D logo using extruded text geometry. The function browserChanged() will be called when the world is fully loaded:  

function browserChanged(evt)
{   
  
          if (evt == 0)      // BROWSER_INITIALIZED               
{               
context = browser.getExecutionContext();               

   setupListeners();                } }  

Step 3: Create field listener objects.  

browserChanged() calls out to a helper function, setupListeners(), which is defined specifically for this application. The file tutorial2.js contains the application-specific code for this tutorial:  

function setupListeners()
{   
 
if (context == null)   
         
return;        

// Get a handle to the nodes    
  
timeSensor = context.getNode("Timer");      
AjaxTextMaterial = context.getNode("AjaxTextMaterial");
     
X3DTextMaterial = context.getNode("X3DTextMaterial");     

    // Set up the observers that detect mouse clicks on the geometry    
  
touchObserver1 = setListenerObserver("TouchSensor1", "touchTime", sensor1Touched);  
    
touchObserver1 = setListenerObserver("TouchSensor2", "touchTime", sensor2Touched); }  

The code first tucks away handles to nodes this application is interested in: a TimeSensor node for starting/stopping time-based animations, and two Material nodes for controlling the color of the two pieces of geometry that comprise the Ajax3D logo.   setupListeners() calls a helper function in our new framework,

setListenerObserver(). This function creates field listenersJavascript objects with callback functions that are called when the values of a node’s fields change. In this example, the fields being listened to are from TouchSensor nodes: objects that respond when a piece of geometry is clicked.  

Step 4: Respond to the events.   Once the field listeners are set up, we can now respond to clicks on the geometry.  

Click on the “ Ajax ” geometry and you will see two things: i) the color of the geometry will change, and the contents of the containing web page will be updated with a text message. The former happens by setting the green component (‘g’ property) of the Material node’s diffuse color (color that reflects light) to 50% green. The latter behavior actually illustrates a typical (2D) Ajax programming trick: using the ‘innerHTML’ property of the web page to provide additional user feedback without reloading the page.  

Click on the “3D” geometry and three things happen: i) the color of the geometry changes; ii) the logo starts spinning by setting the start time of the animation, and iii) once again, the message in the web page is updated.  


Copyright © 2006 Ajax.org All Rights Reserved.