Search code examples
x3dx3dom

X3DOM Custom Navigation


Does X3DOM have a proper way of implementing custom camera navigation? I would like to zoom when the user drags a zoom slider and pan when the user drags across the screen. Does X3DOM have an API for calling pan(), zoom(), or rotate() funcitons?

So far I could think of three workarounds, which are not ideal solutions:

  1. Change viewpoint attributes manually:

    document.getElementById("the_viewpoint").setAttribute("orientation", "some numbers here");

  2. Keep the viewpoint fixed and change the position/rotation of a <transform>, which contains the whole 3d world

  3. Reroute events. For example, when a user slides the zoom slider, fire a mousewheel event to zoom.


Solution

  • Looks like this functionality was added fairly recently, but has yet to be properly documented

    The PR includes this example:

    var d = function(selector) { return document.querySelector(selector)}
    
    x3dom.runtime.ready = function() {
        var x3d = d('x3d');
        var viewpoint = d('viewpoint');
        var x3dCanvas = x3d.runtime.canvas;
    
        var _onMouseWheel = x3dCanvas.onMouseWheel;
    
        x3dCanvas.onMouseWheel = function(event) {
            if(event.altKey) {
                var offset = .01
                var fov = parseFloat(viewpoint.getAttribute('fieldofview')) || 1.571;
    
                if(event.wheelDelta < 0) offset = -offset;
                fov = Math.min(2, Math.max(0, fov+offset));
    
                viewpoint.setAttribute('fieldofview', fov)
    
            } else {
                _onMouseWheel.call(this, event);
            }
        }
    
        x3dCanvas.canvas.removeEventListener('mousewheel', _onMouseWheel); // unable to unbind when handler is anonymous function 
        x3dCanvas.canvas.addEventListener('mousewheel', x3dCanvas.onMouseWheel);
    }