Not Your Mother's Web3D:
Integrating X3DOM, jQuery and HTML5

by Sandy Ressler

National Institute of Standards and Technology

Web3D 2012, August 4-5, 2012

 

You can step through the slides with and

Hit the ESC for an overview of the slideset (be patient wait for assets to load)

Disclaimer

Any mention of commercial products within this presentation or NIST web pages is for information only; it does not imply recommendation or endorsement by NIST.

The views expressed in this presentation are solely those of the author and do not represent any official views of NIST or the US Government.

Follow Along!

http://math.nist.gov/~sressler/

x3dom/revealjs14/jQueryTut.html

Agenda

  • What is markup, DOM, jQuery, and X3DOM
  • Selecting DOM elements, events, moving around the DOM tree
  • jQuery
  • X3DOM
  • Dynamically generating Geometry and Making it Interactive
  • Dynamically generating UI Controls
  • Extending jQuery - Plugins for Dummies
  • Future

What is markup?

Markup is information that is embedded in the text of a document that is not intended for printing or display. It may consist of instructions to a printing device, commands for a Web browser, or comments to a coauthor. The form the markup takes is a function of the particular markup language used.

HTML important but not only markup language

XML

XHTML

CSS

SGML

I tend to use .xhtml because the browser (parsing) is way more informative about errors

Look Ma there's some 3D in my web pages!

What is the DOM?

  • DOM - Document Object Model
  • The structure of everything needed to render a page..and more!
  • Manipulating the DOM means you are manipulating page elements
  • Selecting elements of the DOM means you are selecting those elements of the page you wish to manipulate.

DOM Structure

dom structure

From http://www.iwein.co.uk/2006/05/30/dom-structure-visualized/

DOM Structure (simple document)

dom structure

From W3C http://www.w3.org/TR/2006/WD-DOM-Level-3-Events-20060413/events.html

DOM Events

dom events

From W3C http://www.w3.org/TR/2006/WD-DOM-Level-3-Events-20060413/events.html

DOM (HTML) Events

  • Web programming is "real time" programming
  • Actions are "event driven"
  • just like games!!
  • An event happens, you perform an action and (sometimes) you have a callback to maintain control, in an asyncronous manner
  • type of events: mouse, keyboard,

DOM Event Example

Inside a <box> element define an "onclick" attribute

<box > </box>
onclick = "alert('you hit the box');"
$('#dialog').html('You hit me');
jQuery dialogs lab

What is jQuery?

(and why should you care)

jQuery

robust, highly tested, interoperable, JavaScript framework to simplify your web development life

  • very powerful selection mechanism (selecting elements of the DOM)
  • jQuery utilizes CSS selection mechanism
    • $('#asphere') - select one particular sphere called 'asphere'
    • $('sphere') - select all of the elements of type <sphere>

What is jQuery? (more)

  • deals with many issues of browser interoperability
  • simplifies life with asyncronous issues (AJAX)
  • highly extensible (gazillions of plugins)
  • Selectorama

    jQuery selectors lab

    jQuery selectors

    Selections

    radius='0.0125' onclick="$('#dialog').dialog('open'); $('#dialog').html('<p> You just selected the '+ $(this).parent().parent().attr('description') + ' landmark. </p>'); $('#dialog') .dialog( {title: $(this) .parent() .parent() .attr('description') });

    select (pseudo english)

    for each element of the type (shape)

    do something fn()

    Method Chaining

     <transform id='lm0' description='Sellion'>
        <shape>
          <appearance>
            <material id='mat0' diffuseColor='0 0.9 0'></material>
          </appearance>
          <sphere id='asphere' radius='0.0125' ... 
          </sphere>
        </shape>
     </transform>
                

    $('#asphere').parent().parent().attr('description');

    similar to functional programming

    take the output of one function and feed it to the input of the next function and so on...

    similar to UNIX pipes: ls | fgrep "foo" | wc

    What is X3DOM

    x3dom is not rocket science

    Simply put: it's X3D in your web page

    So what is X3D?

    An ISO Standard ... ISO/IEC 19775

    A REAL STANDARD...not some pseudo standard wannabe!!

    X3DOM is a 3D Declarative Markup Lanaguage (for X3D)

    it puts X3D in your browser

    X3D/X3DOM - Scene Graph

    scene Graph

    X3D/X3DOM - Event Model

    Time (keeps on ticking)

    Typical use of time in X3D (or X3DOM) file:

    
                <TimeSensor id='TIMER' cycleInterval='15' loop='true'></TimeSensor>
                <OrientationInterpolator DEF='OI' key='0 0.5 1' keyValue='1 0 0 0, 1 0 0.5 3.14, 1 0 1.0 6.28'></OrientationInterpolator>
                <ROUTE fromNode='TIMER' fromField='fraction_changed' toNode='OI' toField='set_fraction'></ROUTE>
                <ROUTE fromNode='OI' fromField='value_changed' toNode='coneTrafo' toField='rotation'></ROUTE>
                    

    HTML/DOM Events are asynchronous (don't want to block browser)

    X3D/X3DOM - Interactivity

    time issues

    <TouchSensor> (not implemented)

    versus

    onclick events

    but X3D time <TimeSensor> does exists..needed for animations

    X3DOM - the id versus DEF issue

    • In X3D geometry or other elements are named via the DEF construct
    • <Transform translation="1 2 3" DEF="boxTrans" >
    • Later on we might refer to it via <Transform USE="boxTrans" >
    • but HTML, the DOM and JavasScript don't know anything about the DEF/USE constructs
    • X3DOM solution is:

    • If both id and DEF are set both attrubutes will have different values
    • if only DEF is set that id is left unset
    • if only id is set then DEF and id are set to the same value

    X3DOM code looke like this:

    
    <X3D xmlns="http://www.web3d.org/specifications/x3d-namespace"  width="400px" height="400px">
        <Scene>
        <navigationInfo type='"EXAMINE" "WALK" '></navigationInfo>
        <Transform DEF="coneTrafo" class="coneClass" translation="-4.5 0 0">
            <Shape DEF="coneShape">
            <Appearance>
            <Material diffuseColor="0 1 0" specularColor=".5 .5 .5" ></Material>
            </Appearance>
            <Cone DEF="cone" ></Cone>
            </Shape>
        </Transform>
        
        
        <Viewpoint centerOfRotation="0 0 0" position="0 0 15" orientation="0 1 0 0" ></Viewpoint>
        
        <TimeSensor id='TIMER' cycleInterval='15' loop='true'></TimeSensor>
        <OrientationInterpolator DEF='OI' key='0 0.5 1' keyValue='1 0 0 0, 1 0 0.5 3.14, 1 0 1.0 6.28'></OrientationInterpolator>
        <ROUTE fromNode='TIMER' fromField='fraction_changed' toNode='OI' toField='set_fraction'></ROUTE>
        <ROUTE fromNode='OI' fromField='value_changed' toNode='coneTrafo' toField='rotation'></ROUTE>
        </Scene>
    </X3D>
                

    A Simple Example

    
    <x3d xmlns="http://www.x3dom.org/x3dom">
      <scene>
        <viewpoint position='0 0 10' ></viewpoint>
        <transform id="exTrans">
          <shape>
            <appearance>
                <material id="mat" diffuseColor='0.603 0.894 0.909' ></material>
            </appearance>
            <box id='box' ></box>
         </shape>
         </transform>
      </scene>
    </x3d>
               
               

    JSBIN demos/examples

    NOT a special X3D editor!!

    jsbin

    Dynamically generating geometry

    defining a sphere template
    
     <sphere radius="0.0125" 
     onclick="$("#dialog").dialog("open"); 
          $(".timer").attr("cycleInterval","0");
          $("#clock1").attr("cycleInterval","2.0");
          $("#dialog").html("<p> You just selected the "+ $(this).parent().parent().attr("description") + " landmark. </p>");
          $("#dialog").dialog( {title: $(this).parent().parent().attr("description") });" 
     </sphere>
    
    
                    

    Dynamically generating geometry (2)

    code to clone the landmark (sphere)
    
    function cloneLandmarks(idstr, matstr) {
    for (var index = 0; index < OrigLandmarks[0].length; index++) {
        $(".ball").each(function(index) {
             newNum = new Number(index + 1);
             newElem = $("#"+idstr+"0").clone().attr("id", "idstr" + newNum); 
             newElem.attr("description", 
                OrigLandmarks[0][index].description);
             newElem.attr("translation", 
                OrigLandmarks[0][index].translation);
             //2nd child of shape is sphere
             //replace clock1 with correct clock id
             tmpObj = newElem.children().children(":nth-child(2)");
             tmpClickStr = tmpObj.attr("onclick");
             ntmpClickStr = tmpClickStr.replace(/clock1/i,"clock"+newNum);
             newElem.children().children(":nth-child(2)").attr("onclick",ntmpClickStr);
             newElem.children() //replace mat1 with mat id
                .children().children()
                .attr("id",matstr+newNum);
            $("#"+idstr+"0").after(newElem);  // place the new transform
           }
    };
              

    Dynamically generating geometry (3)

    Usage
    
                   cloneLandmarks('lm','mat');
                    

    Let's Generate that Geometry

    caesarX3DOM

    Making Geometry Interactive

    Using the HTML onClick Event

    
    		
         newElem = $('#lm0').clone().attr('id', 'lm' + newNum); 
        
         tmpObj = newElem.children().children(':nth-child(2)');
         tmpClickStr = tmpObj.attr('onclick');
         ntmpClickStr = tmpClickStr.replace(/clock1/i,"clock"+newNum);
    										
        

    x3dom.org onClick example

    Using X3D's Touch events

    (NOT IMPLEMENTED)

    This is a GOOD Thing (IMHO)

    We want the WEB WAY of creating interaction

    Integrating jQuery UI elements

    What's in jQuery UI

    jQuery UI Demos

    Dynamically generating user interface controls

    First some code to create some jQuery controls

    From x3dom site: jQuery Manipulation

    code for jQuery sliders manipulating 3D attributes

    (the HTML part)

    
              <X3D xmlns="http://www.web3d.org/specifications/x3d-namespace" id="spheres" showStat="true" x="0px" y="0px" width="400px" height="400px" style="float:left;">
            <Scene DEF='scene'>
                <Viewpoint position='0 0 10' />
    			<Background skyColor='1 1 1' />
                <Transform id='trans'>
                    <Shape>
                        <Appearance>
                            <Material diffuseColor='0 0 0' specularColor='.2 .2 .2' />
                        </Appearance>
                        <Box DEF='box'/>
                    </Shape>
                </Transform>
            </Scene>
        </X3D>
    
        <div id="ctrlContainer">
            <p>Change the color of the cube using the RGB sliders, which updates the "diffuseColor" attribute of the Material node using jQuery.</p>
            <div id="sliderContainer">
                <ul>
                    <li><label>Red</label><div id="redSlider" class="slider"/></li>
                    <li><label>Green</label><div id="greenSlider" class="slider"/></li>
                    <li><label>Blue</label><div id="blueSlider" class="slider"/></li>
                </ul>
            </div>
        </div>
    

    code for jQuery sliders manipulating 3D attributes

    
            $(document).ready(function(){
                // Create the sliders
                $(".slider").slider({min: 0, max: 1, step: 0.01, slide: function(e, ui) {
                    var newCol =   $("#redSlider").slider('option', 'value') + " " 
                                 + $("#greenSlider").slider('option', 'value') + " "  
                                 + $("#blueSlider").slider('option', 'value');              
                    $("Material").attr("diffuseColor", newCol);
                }});
            });
            

    Programmatically creating controls

    AnthroGloss

    Code for sphere selection and scale action

    code sphere

    controls associated with graphical objects

    sliders

    buttons

    function to clone a button

    
    function cloneViewpointButtons() {
      $('#nameClone').show(); // show the button to clone	
      var Viewpoints = $("viewpoint");  //select all viewpoint elements and place into array
      // original source of clone button code
      // http://charlie.griefer.com/blog/index.cfm/2009/9/17/jQuery--Dynamically-Adding-Form-Elements
      
      //iterate through all of the viewpoints
      $("viewpoint").each( function(index) { 
        newNum = new Number(index + 1);
        newElem = $('#nameClone').clone().attr('id', 'name' + newNum); //clones only the button 
        newElem.attr('class', 'viewbutts'); // assign a classname to allow deletion of all but first button
        newElem.attr('value', $(this).attr('description'));
        
        //use the animate visual effect and
        //create an anonymous function to execute when button is clicked      
        newElem.button().click(function() {
          $(this).animate({opacity: 0.5}, 1500);
          $(Viewpoints[index]).attr('set_bind','true');  // this must be an actual viewpoint
    
          var descrip = $(Viewpoints[index]).attr('description');
          var htmlStr = "Current Viewpoint: " + descrip + "";
          $('#currViewpoint').html(htmlStr);
    });; 
          $('#nameClone').before(newElem); // place the new button after the old div
        });
        $('#nameClone').hide(); // hide the button to clone
    };	
               

    The Viewpoints

    code viewpoints

    Some More Robust Examples

    CAESAR X3DOM

    caesarX3DOM

    Scanning Tunneling Microscope

    So you want to make a slide show

    (Another type of Web3D integration)

    slide show examples

    Let's Assemble a jQuery UI/X3DOM

    • Include jQuery & jQuery UI
    • Include the X3DOM library and CSS
    • start inluding X3DOM code
    • HTML
    • code: JavaScript
    • IMPORTANT you must run on a web server! (for included "inline" files)

    Annoying Integration Issues

    name space, name space, name space

    Several types of HTML elements appear in global DOM namespace, and these can interfere with each other

    • Button elements all treated as global; they must be distinguigshed (can assign class name to solve this)

    • <button class="mybutton">

    • $("button"); versus $(".mybutton");

    • Dialog popups also get confused as global

    The story of the "button integration bug"

    Once upon a time...there were a whole bunch of viewpoints

    Couldn't change the viewpoint element because it's an ELEMENT and we need it.

    But we can add a new class "flipvp" to name only those viewpoint elements that we want to play with for this page

    Extending jQuery - plugIns for Dummies

    jqPlugTest.xhtml

    This is all the code for a jQuery plug-in

    
    (function($) {
    	$.fn.X3DOMgeomButton = function(options) {
    	// Extend our default options with those provided.
      	// Note that the first arg to extend is an empty object -
      	// this is to keep from overriding our "defaults" object.
      	var opts = 
                $.extend({}, $.fn.X3DOMgeomButton.defaults, options);
    	// iterate  each matched element
      	return this.each(function() {
        	var base = $(this);
    		//var attribute = base.attr(opts);
    		var scaleOpt = opts.scale;
    		var onclickOpt = opts.onclick;
    		var diffuseColorOpt = opts.diffuseColor;
    		var translationOpt = opts.translation;
    				
    		if (scaleOpt) base.attr('scale',scaleOpt);
    		if (onclickOpt) base.attr('onclick',onclickOpt);
    		if (translationOpt) base.attr('translation',translationOpt);
    // base is the transform then -> shape -> appearance -> material
    		if (diffuseColorOpt) base.children().children().children().attr('diffuseColor',diffuseColorOpt);
    		});
    	};
    		  
    	$.fn.X3DOMgeomButton.defaults = {
    		scale: '10 10 10',
    		onclick: 'alert("I am hit");',
    		diffuseColor: '0 1 0'
    		// do not want a default translation because 
            //generally objects exist where they should
    	};
    })(jQuery);
    
                                

    This is how to use the jQuery plug-in

    
    $('#tr0').X3DOMgeomButton(
    	{ onclick : 'alert("You hit id0 object")',
    				 diffuseColor: '0.5, 1, 1',
    				translation: '5 0 0'});
                    
    $('#tr1').X3DOMgeomButton({ onclick : 'alert("You hit id1 object")',
    				diffuseColor: '0.8 0 0',
    				scale: '10 1 10'});
                    
    $('#tr2').X3DOMgeomButton({ onclick : 'alert("You hit id2 object")',
    				diffuseColor: '0.8 0 0.8',
    				scale: '5 1 5'});
                

    jQuery plug-in Example

    The Future

    Look at D3 and what it does for SVG

    X3DOM and X3D from https://gist.github.com/ZJONSSON

    modified X3DOM and d3.js

    Useful Links

    Acknowledgements

    Summary

    Markup

    jQuery

    X3DOM

    Dymanic UI and Dynamic Graphics

    Integration/Future

    Discussion

    THE END