Adjusted position of the viewport if the DOM element containing the renderer is not located at the top of the display

I've come across an issue with a three.js scene within an Angular custom directive in the view. At the top, there's a navigation bar for switching between views (pretty standard so far). I set up a simple scene with a cube and basic camera rotation, but when trying to interact with the object on mouse down, it seems like my coordinate system is off – starting from the top of the page. Here's a screenshot for better understanding: http://prntscr.com/6r6pnu. It looks like the object's actual mesh has shifted upwards slightly while rendering.

Here's how I've set up the renderer:

renderer.setSize(window.innerWidth, window.innerHeight);
    element[0].appendChild(renderer.domElement);

where element[0] represents my custom directive

<input-dir> <canvas> </input-dir>

And here's the raycaster setup:

var vector = new THREE.Vector3();
      vector.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
      vector.unproject( camera );

      raycaster.ray.set( camera.position, vector.sub( camera.position ).normalize());

Any help would be greatly appreciated. Thank you!

Answer №1

It seems like the issue lies in how the mouse coordinates are being interpreted relative to the browser viewport, rather than the canvas where the THREE.js scene is displayed. The coordinate (0, 0) corresponds to the top left corner of the browser viewports, while ideally it should align with the top left corner of the canvas. This discrepancy may be due to the presence of a navbar, which requires adjustments to accurately capture the mouse position on the screen.

To calculate the offset between the canvas and the viewport edge, you can utilize the canvas.getBoundingClientRect() method. This function provides information about the canvas size and its position within the viewport.

To access the canvas rendered by THREE.js renderer, you can use renderer.domElement. Alternatively, you can assign a custom canvas to the renderer during initialization using a designated canvas element.

var canvas = document.getElementById("canvasID");
renderer = new THREE.WebGLRenderer({ canvas: canvas });

Subsequently, you can employ the following function to determine the mouse coordinates relative to the canvas:

function getMousePos(canvas, evt) {
    var rect = canvas.getBoundingClientRect();
    return {
      x: evt.clientX - rect.left, 
      y: evt.clientY - rect.top 
    };
}

This function enables retrieval of accurate mouse position data with respect to the canvas.

If necessary, please consider sharing the code snippet used for obtaining mouse positions to facilitate better assistance. Remember to include relevant code when seeking help on platforms like stack overflow.

EDIT: For optimal results, ensure that the mouse coordinates are captured immediately before usage. Modify the capturing code as follows:

var vector = new THREE.Vector3();
var mousePos = getMousePos(canvas, event);
vector.set( ( mousePos.x / window.innerWidth ) * 2 - 1,
 - ( mousePos.y / window.innerHeight ) * 2 + 1, 0.5 );
vector.unproject( camera );

If passing the canvas as an argument poses challenges, consider making the renderer globally accessible. Update the function call accordingly:

var mousePos = getMousePos(renderer.domElement, event);

Following successful testing, explore methods to obtain canvas elements without relying on global variables, enhancing code structure and optimization.

Proceed by utilizing DOM techniques to retrieve the canvas based on identifiers or alternative approaches. Best wishes for resolving this issue!

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

When res.write is called before res.send, an error occurs

I'm struggling to figure out why I am getting an error with the following code. app.get("/", (req, res) => { res.write("Hello"); res.send(" World!"); }) // Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers afte ...

Encountering an HTTP parsing failure while sending XML through Angular 5's HttpClient

Struggling to access a local webservice through XML: Take a look at the code below: const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'text/xml', 'Accept': 'text/xml', 'Response- ...

Optimizing the JSON date structure

After receiving a datetime value in JSON with the format: Created "/Date(1335232596000)/" I developed a JavaScript function to display this value on the front end. Here's the code snippet: return new Date(parseInt(date.substr(6))); However, the c ...

I am trying to organize a list of blog post tags in Eleventy using Nunjucks based on the number of posts that each tag contains. Can you help me figure out

I currently manage a blog using Eleventy as the static site generator, with Nunjucks as the templating language. One of the features on my site is a page that displays all the tags assigned to my posts in alphabetical order along with the number of posts ...

Sending a massive video file to a node.js server and saving it in AWS S3 with ReactJS

I am currently in the process of creating an OTT platform, but I have encountered a problem while attempting to upload large files to the server. I initially attempted to store the file in a temporary folder using multer and then utilize aws-sdk s3.upload. ...

Prevent unexpected page breaks in <tr> elements on Firefox (Could JavaScript be the solution?)

Wondering if there are any ways, possibly through JavaScript or CSS, to avoid having page breaks within <tr> elements specifically in Firefox. Given that FF does not yet fully support page-break-inside, I assume this might need to be addressed using ...

Stop the sudden jump when following a hashed link using jQuery

Below is the code snippet I am working with: $( document ).ready(function() { $( '.prevent-default' ).click(function( event ) { event.preventDefault(); }); }); To prevent the window from jumping when a hashed anchor ...

Update the directory path for Angular ui-bootstrap templates

Currently, I am attempting to utilize ui-bootstrap.min.js in conjunction with external templates. An issue has arisen where the error message reads as follows: http://localhost:13132/Place/template/timepicker/timepicker.html 404 (Not Found) I desire fo ...

Comparison between on() delegation and delegate()

When using <strong>$(document).on('click', '#target')</strong> versus <strong>$('body').delegate('click', '#target');</strong> It seems like both options achieve the desired outcome ...

What is the reason for the Express middleware using parenthesis syntax, whereas custom-made middleware does not?

What is the reason behind Express inbuilt middleware using a parenthesis syntax like app.use(express.json()) while custom-made middleware does not use parentheses like app.use(logger)? It seems to throw an error with parentheses. I'm uncertain if th ...

Unable to install android application due to duplicated code

I created a hybrid app for Android using Ionic v1 and Angular 1 which is currently running smoothly. I have already uploaded it to the Play Store. Now, I have copied the same code to create a new app, changed the name and package path. However, I am facin ...

"Troubleshooting async/await issue with Node.js Sequelize and configuring the connection

function credential(secretFromVault) { const creddetails = new ClientSecretCredential(clientId, tenantId, clientSecret); // Build the URL to reach your key vault const url = `https://<vaultName>.vault.azure.net/`; // Lastly, create our secre ...

Using Node.js and Express to import a simple JavaScript file as a router

Can anyone help me understand how to import the user.json json file into my user.js? I want the json file to be displayed when typing /user but I'm struggling with the new version of Node. index.js import express from 'express'; import body ...

Developing a standard jQuery function for adding event listeners

Attempting to replicate the functionality of Google Maps' addListener using jQuery listeners for clicks, keypresses, etc. In Moogle Maps, you can use .event.addListener(map, 'click', function()... or switch 'click' with 'drag ...

Is there a way to set table column headers in ngGrid using values from another array?

The JSON I am working with is organized into 'headers' and 'rows'. For example: { "headers": ["id","timestamp from","blah1","blah2"], "rows": [["69517737","1416932540011285849","104220.00","170968251000.000: ...

What is the process for integrating a Browserify library module into a project as a standard file?

I have successfully developed a JavaScript library module with browserify --standalone, passing all tests using npm test. Now, I am working on creating a demo application that will utilize this library module in a browser setting. When I run npm update, th ...

Scrolling Down on a Jquery Login Page

I am currently utilizing JQuery version 1.4.2. My objective is to allow the user to scroll down to the login form by clicking on the 'login' option in the top menu, similar to Twitter's design. The implementation works impeccably with insert ...

What is the method for assigning a class name to a child element within a parent element?

<custom-img class="decrease-item" img-src="images/minus-green.svg" @click="event => callDecreaseItem(event, itemId)" /> Here we have the code snippet where an image component is being referenced. <template&g ...

Ways to automatically close browser tab upon successful submission of a form

I have an old file that has been updated. One of the requirements for this file/project modification is to have the current browser window close when the user clicks OK to submit the form. I am curious if this can be done using plain/vanilla JavaScript? ...

The dropdown menu is malfunctioning when accessed within the mobile view of a jQuery

Take a look at this code snippet on Fiddle: https://jsfiddle.net/rizwanali98601/ngofhc24/12/. The table below contains a dropdown inside a jQuery Datatable. When the button is clicked, an option is supposed to be added to the dropdown. However, in mobile ...