Search code examples
javascriptpositioningthree.js

Compute top,left,width,height in Three.js projetion


I'm struggling with a problem: I need to position a DIV over a WebGL animation. I rotate a mesh, based on a PlaneGeometry to occupy a rectangular size, then I'd like top position there the DIV, so I need to know what is the X,Y coordinate and the rendered dimensions of the plane.

enter image description here

I've tried the THREE.Projection class, but didn't help, even if I projected the [0] verticle using .projectVector. It computed:

x: -0.1994540991160383
y: 0.17936202821347358
z: 0.9970982652556688

...which was little help to me.


Solution

  • I found the solution. The top left point is indeed the 0 index of the plane's vertices, but you have to take into account the already performed transformations as well.

    function calculateLayer()
    {
        // multiplyVector3 applies the performed transformations to the object's coordinates.
        var topLeft = tubeCard.matrixWorld.multiplyVector3( tubeCard.geometry.vertices[0].clone() );
        // index 24 is the bottom right, because the plane has 4x4 faces
        var bottomRight = tubeCard.matrixWorld.multiplyVector3( tubeCard.geometry.vertices[24].clone() );
        return {
                topLeft: convert3Dto2D( topLeft ),
                bottomRight: convert3Dto2D( bottomRight )
            }
    }
    
    function convert3Dto2D( positionVector )
    {
        var projector = new THREE.Projector();
        var pos = projector.projectVector( positionVector, camera );
    
        var xcoord = Math.round( (  pos.x + 1 ) * window.innerWidth  / 2 );
        var ycoord = Math.round( ( -pos.y + 1 ) * window.innerHeight / 2 );
    
        return { x: xcoord, y: ycoord };
    }
    

    So once you have the correct coordinates, applied with the transformations, you just have to use the 3d to 2d conversion thanks to WestLangley.