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 listeners—Javascript 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.
|