Search code examples
matrixthree.jsquaternions

Aligning 3D position and orientation of a HTML div with an animated Three.js plane Object3D


Trying to align HTML content over a Threejs background where I need to match a div with a 3d plane.

Following this post I was able to get the div to follow the plane position, but i m still having trouble with the orientation even following advices from this post

So far this is my code:

screenPlane.updateWorldMatrix()
screenPlane.getWorldPosition(tempV)
screenPlane.getWorldQuaternion(tempQuat)
tempRotationV3.copy(screenPlane.up ).applyQuaternion(tempQuat)
tempV.project(camera)
const x = (tempV.x *  .5 + .5) * container.clientWidth
const y = (tempV.y * -.5 + .5) * container.clientHeight
div.style.transform = `translate(-50%, -50%) translate(${x}px,${y}px) `
div.style.transform += ` rotateX(${tempRotationV3.x}rad) rotateY(-${tempRotationV3.y}rad) rotateZ(${tempRotationV3.z}rad)`

Position is good but orientation is clearly broken:

enter image description here

Here is a jsfiddle demo of the position only

Any help would be much appreciated.


Solution

  • Thanks to @Marquizzo comment i was able to fix the fiddle example using CSS3DRenderer

    var div = document.getElementById('overlay');
    var cssScene = new THREE.Scene();
    var cssObject = new CSS3DObject(div);
    // we reference the same position and rotation 
    cssObject.position.set(plane.position.x, plane.position.y, plane.position.z);
    cssObject.rotation.set(plane.rotation.x, plane.rotation.y, plane.rotation.z);
    // add it to the css scene
    cssScene.add(cssObject);
    
    var cssRenderer = new CSS3DRenderer();
    cssRenderer.setSize( window.innerWidth, window.innerHeight );
    cssRenderer.domElement.style.position = 'absolute';
    cssRenderer.domElement.style.top = 0;
    document.body.appendChild( cssRenderer.domElement );
    window.div = cssObject
    

    Note that CSS3DRenderer is not deprecated by ThreeJS but it is shipped separately in order to keep the main library lighter. So make sure you import it separately:

    import { CSS3DRenderer, CSS3DObject } from 'https://threejs.org/examples/jsm/renderers/CSS3DRenderer.js';