Transforming a 3D coordinate into a 2D screen coordinate [r69!]

I am seeking Three.js code that can convert 3D object coordinates to 2D coordinates within a 'div' element, allowing me to place text labels in the correct positions without them scaling, moving, or rotating along with the 3D movement. Unfortunately, all the examples I have attempted thus far appear to employ outdated functions and techniques. Currently, I am working with version r69 of Three.js.

One example of an 'older' technique that consistently generates errors for me can be found here:

Three.js: converting 3d position to 2d screen position

In contrast, I recently discovered a snippet of what appears to be newer code, but due to lack of context, I have not been able to make it work effectively:

https://github.com/mrdoob/three.js/issues/5533

Answer №1

In my recent project, I have crafted a function that takes in an instance of THREE.Object3D and a camera as parameters to determine the position on the screen.

function toScreenPosition(obj, camera)
{
    var vector = new THREE.Vector3();

    var widthHalf = 0.5*renderer.context.canvas.width;
    var heightHalf = 0.5*renderer.context.canvas.height;

    obj.updateMatrixWorld();
    vector.setFromMatrixPosition(obj.matrixWorld);
    vector.project(camera);

    vector.x = ( vector.x * widthHalf ) + widthHalf;
    vector.y = - ( vector.y * heightHalf ) + heightHalf;

    return { 
        x: vector.x,
        y: vector.y
    };

};

Subsequently, I instantiated a THREE.Object3D solely for the purpose of storing the div's position (linked to a mesh in the scene). Whenever necessary, this object can be easily converted to a screen position utilizing the toScreenPosition function to update the coordinates of the div element.

var proj = toScreenPosition(divObj, camera);

divElem.style.left = proj.x + 'px';
divElem.style.top = proj.y + 'px';

Check out this demo on JSFiddle.

Answer №2

To transform a 3D position into screen coordinates, you can utilize the following method:

var point = new THREE.Vector3();
var surface = renderer.domElement;

point.set(4, 5, 6);

// convert to normalized device coordinate (NDC) space
point.project(camera);

// map to 2D screen space
point.x = Math.round((point.x + 1) * surface.width / 2);
point.y = Math.round((-point.y + 1) * surface.height / 2);
point.z = 0;

Version: three.js r.69

Answer №3

Here is a helpful function that I have successfully used with Three.js version 69:

function generateCoordinates(x, y, z, camera, screenWidth, screenHeight) {
        var point = new THREE.Vector3(x, y, z);
        var calculatedVector = point.project(camera);

        calculatedVector.x = (calculatedVector.x + 1) / 2 * screenWidth;
        calculatedVector.y = -(calculatedVector.y - 1) / 2 * screenHeight;

        return calculatedVector;
    }

Answer №4

In response to @meirm's query, this code snippet provides additional information on how the .getContext() method is utilized in the latest version of THREE.js. It also includes adjustments for the canvas offset, which may be necessary when a canvas is nested within another user interface.

const calculateScreenPosition = function(obj, camera){
    let vector = new THREE.Vector3();
    let widthHalf = 0.5 * renderer.getContext().canvas.width;
    let heightHalf = 0.5 * renderer.getContext().canvas.height;
    obj.updateMatrixWorld();
    vector.setFromMatrixPosition(obj.matrixWorld);
    vector.project(camera);
    vector.x = (vector.x * widthHalf) + widthHalf + $(scenecanvas).offset().left;
    vector.y = -(vector.y * heightHalf) + heightHalf + $(scenecanvas).offset().top;
    return {
        x: vector.x,
        y: vector.y
    };
};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to generate a complete PDF of a webpage using pdfmake?

I'm currently developing a web application and facing the task of converting an HTML page, which contains multiple tables and datatables, to a PDF format. To achieve this, I've chosen to utilize the library pdfmake. Below is the script that I ha ...

How to properly load components in React?

I've been diving into building a simple app in React using ES6 and Babel. While working on it, I encountered an issue. I decided to incorporate the react-notifications package from https://github.com/minhtranite/react-notifications Following the docu ...

Executing a shell command prior to the ENTRYPOINT in the dockerfile: Tips and guidelines

My nodejs project includes the following file: FROM node:boron # Create app directory RUN mkdir -p /usr/src/app WORKDIR /usr/src/app # Install app dependencies COPY package.json /usr/src/app/ RUN npm install # Bundle app source COPY . /usr/src/app # ...

AJAX-enhanced knockout for throttling updates

I am in the process of developing an HTML form that dynamically updates its values based on the selection made in a dropdown menu. The structure of my view model is as follows: function RoomViewModel() { var self = this; self.companyOptions = @Ht ...

Initializing multiple instances of vue-chartNote: The unique text

I am looking to implement multiple vue-chart.js graphs, each refreshing (adding a new data point) every 5 seconds. The data comes from a sensor and is passed using props (I am developing the UI for a node-red application, but this detail may not be relevan ...

Run JavaScript code after the completion of loading a generic handler in ASP.NET

I am facing a challenge with a gridview that contains a list of pdf files. Whenever a user clicks on a pdf, it should display the file inline on the page. I have been trying to execute some javascript after the pdf has finished loading, but I'm encoun ...

Having trouble installing Angular 4 with npm?

After installing Angular, I encountered an error when trying to use the command line "ng -v". Please refer to the attached jpeg file. My node version is 6.10.3. Does anyone have a solution? https://i.sstatic.net/ZQ69k.png ...

Converting a JSON object to an array with the help of JavaScript

Looking for help with converting and pushing data from a jQuery ajax request in json format into an array. Thanks in advance. [{"Day":"Nov 03","Saavor Kitchen":null,"Home Kitchen":2,"Restaurant":null}, {"Day":"Nov 06","Saavor Kitchen":null,"Home Kitchen": ...

Utilize jQuery to convert text to lowercase before adding Capitalize CSS styling

I have encountered a situation where I need to change the HTML link values from UPPERCASE to LOWERCASE and then apply a capitalization style. The problem lies in the fact that the links arrive in uppercase, so I had to come up with a workaround: The given ...

Is there a way to transform these into five columns within a single row using the Material-UI Grid system?

I'm trying to align 5 columns in one row, but I'm struggling to achieve the desired layout. Here is what I currently have: https://i.stack.imgur.com/d3z3n.png Any tips on how to make all columns appear in a single row? You can also view my att ...

Developing a JavaScript library that utilizes flow type annotations and provides access to various data types

I am currently developing a library intended for use by third parties. I have opted to utilize flowtype as the typing system for specific reasons within my organization. This library presents React components with annotations. The library itself is annota ...

One possible solution to the error of being unable to set headers after they have already been sent to the client is to ensure that the response is returned

Currently, I am working with expressJS and the following is a snippet of my code in the controller: Within the file readstream, there is a condition check that needs to be met for proper data format. If this condition is not satisfied, I do not want to co ...

Initiate a connection to the cloud management system

I am utilizing the following library to establish a connection with the cloud controller https://github.com/prosociallearnEU/cf-nodejs-client const endpoint = "https://api.mycompany.com/"; const username = "myuser"; const password = "mypass"; const Clou ...

Issues with _gaq.push functionality in Google Analytics

Alright, I've been struggling to get _gaq.push to function properly for quite some time now. Below is the code snippet I'm working with: var ext_id = localStorage.ext_id; var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-xxx ...

Troubleshooting problem with Z-Index conflict in Flash animation

I am facing an issue with two HTML divs - one containing a flash movie and the other simple text. I want to place the textual div on top of the flash movie div, but no matter how I set their positions in CSS or adjust their Z-Index values, the text keeps ...

Steps for adding an HTML string to a div element using Ajax

I am facing some major challenges with Ajax, especially when it comes to appending HTML code to a div. I am attempting to append this HTML string to <div id="content-loader"></div> PHP function getLogo(){ $logo = '<div class="bg- ...

Loading text with a remote web font has been successfully initiated in Fabric.js

Currently, I am immersed in developing a large custom application using Fabric JS and thus far, my progress has been commendable. However, I have encountered an issue concerning the initialization of loaded text objects that utilize web fonts. When the fo ...

What is the best way to send an object from the front end to the backend using res.send?

In my current project, I am establishing communication between the frontend and backend. The process involves the backend sending an expression to the frontend for computation, after which the computed answer needs to be sent back to the backend. For exam ...

Service Worker in Workbox with Background Sync functionality

For the past few days, I have been utilizing Workbox and ensuring that I am setting it up correctly to generate a service worker from a source instead of letting Workbox do it for me. While everything seemed to be working fine, I recently attempted to int ...

IE presenting problems with JQuery content loaded via Ajax

I operate a website that showcases various products, each with a corresponding link to a fancybox displaying detailed information about the product (detailed.php file). <a class="fancy fancy'.$_GET['type'].'" href="detail.php?id=&ap ...