0

I can display a full page view of graphical objects with three.js and use mouse click on object to select an object.

But if I try to display three.js graphics in a small viewport within an html page I get problems. To compute viewport coordinates of mouse click position from screen coordinates requires me to know value of pixel offsets of the viewport left border and viewport top border.

Then I can use a coordinate conversion algorithm such as ( modified from http://stemkoski.github.com/Three.js/Mouse-Tooltip.html) :-

mouse.x =   ( (event.clientX - viewport_OffsetLeft_X) / viewport_Width) * 2 - 1;
mouse.y = - ( (event.clientY- viewport_OffsetTop_Y) / viewport_Height ) * 2 + 1;

But my question is:- how do I obtain the values of the viewport Offsets? Note I need to do this at runtime not by inspecting values from a debugger and then hard-wiring them into code.

Any suggestions gratefully received!

steveOw
  • 879
  • 12
  • 41
  • See if this helps: http://stackoverflow.com/questions/13542175/three-js-ray-intersect-fails-by-adding-div/ . If not, you are going to have to show how you set up your page and define your viewport. – WestLangley Sep 05 '13 at 01:33
  • There is also a JQuery "offset" property that you can use if you happen to already have jQuery in your project(s). – GuyGood Sep 05 '13 at 08:47
  • Hi Guys and thanks for your responses (which I only just saw as I am not getting notified by StackOverflow for some reason). – steveOw Sep 06 '13 at 15:44
  • I put something together which works OK using the techniques you both suggested. Boy was it tricky! I think this problem needs a neat full example somewhere. Here for benefit of anyone desperate in the meantime is mine. [link](http://www.zen226082.zen.co.uk/PONGO_SUB.html)[/link]. – steveOw Sep 06 '13 at 15:52

2 Answers2

2

There are two basic ways of finding out the offsets of your canvas from the screen origin.

The following code from West Langley illustrates:- Method 1 For the following method to work correctly, set the canvas position static; margin > 0 and padding > 0 are OK

mouse.x = ( ( event.clientX - renderer.domElement.offsetLeft ) / renderer.domElement.width ) * 2 - 1; mouse.y = - ( ( event.clientY - renderer.domElement.offsetTop ) / renderer.domElement.height ) * 2 + 1;

Method 2 For this alternate method, set the canvas position fixed; set top > 0, set left > 0; padding must be 0; margin > 0 is OK

mouse.x = ( ( event.clientX - container.offsetLeft ) / container.clientWidth ) * 2 - 1; mouse.y = - ( ( event.clientY - container.offsetTop ) / container.clientHeight ) * 2 + 1;

But you need to be careful about padding and margins. A way to reduce this trouble is by filling the screen and then accessing the resulting html page from an iframe in another html page.

steveOw
  • 879
  • 12
  • 41
0

My code looks like this

var x, y, top = 0, left = 0, obj = document.getElementById('canvas');
        var objWebGl = document.getElementById('canvas');

        while (obj && obj.tagName !== 'BODY') {

            top += obj.offsetTop;
            left += obj.offsetLeft;
            obj = obj.offsetParent;
        }

        left += window.pageXOffset;
        top -= window.pageYOffset;

        x = ((event.clientX - left) / objWebGl.clientWidth) * 2 - 1;
        y = -((event.clientY - top) / objWebGl.clientHeight) * 2 + 1;

        var vector = new THREE.Vector3(x, y, 0.5);
Sergey
  • 43
  • 1
  • 9