Hi All, I am trying to overlay DOM objects (<li>
s) which track the position of objects in my 3D scene (reasoning explained below) and have found that the .project(camera) method of Vector3 gives wildly different results when it is called during inital loading and after onCameraUpdate (without significantly moving the camera).
I have one function to create and position the <li>
s which is run as the scene is loaded, and another function to update the position of the <li>
s onCameraUpdate. Both of these functions call the same positionMarker() function and pass in the same Object3D in order to calculate the position to which to set the <li>
s. This works perfectly for positioning the <li>
s on the X-axis, but the Y-axis position it gives is wrong. When the positionMarker() function is called during the initial loading, the Y-axis value is almost but not exactly double the value it should be. When it is called again onCameraUpdate, it is much closer to desired value, but still wrong and — more importantly — different to the result given during initial loading. It is also not half the value given during initial loading. This second value — while not precisely where I want it — is close enough to where it needs to be for me to be able to work with it, but I cannot live with the wildly wrong Y-axis positions upon first load.
I have made a simple jsfiddle version of my project to explain what I am talking about: DOM object positioned over Three.JS scene - JSFiddle - Code Playground. There you can see the red boxes positioned away from the red spheres when you first run the code. When you move the camera, the red boxes snap to a different position over the red spheres. Note that the red squares should be positioned with their bottom left corner in the middle of the sphere.
I know from logging out “vector.y” before and after it is projected using .project() that the problem is during that step. In my jsfiddle example, on initial load, the vector.y before projection = 1.5 and after projection = -0.6516126864206032. After onCameraUpdate, the vector.y before projection is still equal to 1.5 but the value after projection changes to -0.00010623945071439685. This accounts for the change in placement, but has left me scratching my head as to why this is happening and what to do about it.
A potentially related issue is that when you move the camera quickly, both the X and Y axis positions scatter away from where they should be. While it is very obvious in my jsfiddle example, it is less noticeable — but still present — when I view it outside of jsfiddle. I mention this because it may help diagnose the main issue and because fixing it would be nice, but I can live with this issue if need be.
My reasoning for wanting to position <li>
s over my 3D scene is twofold. The first and main reason is for accessibility; I want the labels on my page to be real HTML text that can be resized by the user and fall-back to an ordered list for those who can’t see the 3D scene. Secondarily, using raycasting to identify when I am hovering over a marker seems unnecessarily expensive and complicated when :hover in my css does everything I need it to.
Any help tracking down what is going on, whether it is a mistake in my code, a bug in that method, or a technical limitation would be very much appreciated. Similarly, if any of you have an alternative means of achieving the same objective which doesn’t rely on the .project(camera) method then I’d love to hear it.
Many thanks in advance.