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

The second click on ng-click does not seem to be functioning properly

Hello, I am new to AngularJS. I have managed to fetch the required data, but I'm facing an issue where clicking doesn't work for the second time. I have tried multiple solutions but none seem to be working. Could someone please help me solve this ...

Winning opportunities created by using credits in the slot machine

**Greetings, I have created a slot machine using JavaScript, but I am looking to enhance the player's chances based on their credits. Can anyone guide me on how to achieve this? Essentially, I want the player's odds to increase proportionally wit ...

My locale NUXT JavaScript files are being blocked by Content Security Policy

I've been working on implementing CSP headers for my website to ensure data is loaded from trusted sources. However, I'm facing an issue where CSP is blocking my local JS files. Here's a snippet from my nuxt.config.js: const self = 'lo ...

What steps do I need to take to develop a syntax similar to Vue.js using only plain JavaScript?

<div id=""> <span>{{msg}}</span> </div> Assume that {{msg}} is a variable in JavaScript. Now, I aim to locate the parent tag of {{msg}} and replace its content with a new value using innerHTML, where {{msg}} serves as an identi ...

What's causing the error "is not a function" to appear?

I am currently facing an issue while attempting to develop an angular service. Here is the code snippet for the service: var app = angular.module('plunker', []); // Filter Service that returns records with crdamt positive: app.factory('Fil ...

Tips on traversing a JSON array in AngularJS using the ng-repeat directive

My service returns the following JSON data: {"categories":[{"category_id":"20","name":"Desktops"}, {"category_id":"18","name":"Laptops &amp;"},{"category_id":"25","name":"Components"}, {"category_id":"57","name":"Tablets"}, {"category_id":"17","name": ...

What is the best way to ensure my <h5> element fits perfectly inside its parent div vertically?

Currently facing an issue with finding a solution to my problem. The challenge involves having a header tag nested within multiple divs. Below is the structure: <div class="card"> <div class="layout-left"> <div class="card-header"> ...

Converting an image to a byte array in JavaScript

Does anyone know how to manipulate binary files in Javascript similar to C? I'm currently facing a critical scenario where I need to create a flipped image. Unfortunately, I don't have access to CSS, canvas, HTML, or the DOM - so I need to accomp ...

I am looking to personalize a Material UI button within a class component using TypeScript in Material UI v4. Can you provide guidance on how to achieve this customization?

const styling = { base: { background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)', border: 0, borderRadius: 3, boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)', color: 'white', height: 48, ...

The getJSON API functions properly on a local machine but encounters issues when deployed on a

I have a vision to create a web application that can display the weather of any city based on user input. I've divided my project into three files - index.html for collecting user input, index2.html for retrieving and displaying the data, and a CSS fi ...

Determining the orientation of an image in JavaScript

Currently, I am attempting to determine the orientation of images using JavaScript in order to apply a specific class to them. This process seems to be functioning correctly on Firefox, but is presenting challenges on other browsers. It appears to work bet ...

What strategies are typically employed to prevent falling into the callback hell trap when working with error-back asynchronous functions in Node.JS?

As a new Node user, I've been practicing pure Node scripting without relying on third-party npm packages. However, I quickly ran into the issue of my code becoming nested with callbacks inside callbacks, making it difficult to follow. This can lead to ...

Struggling with my jQuery Ajax call, need some help

I am attempting to create an ajax request that will update the content of my select element. Below is the code for my request : $(function() { $("#client").change(function() { type: 'GET', url: "jsonContacts. ...

Tips for verifying if two passwords match during registration and displaying an error message if they do not match

How can I ensure that the passwords entered in a registration form match and how do I validate the entire form to be correct? <form id="registerForm" method="POST" action="/register" class="form2"> ...

unable to insert logo into HTML

I am customizing an HTML template, but the dimensions of the logo in the template are smaller than my logo. Despite adding my logo to the template, it is not showing up. @media (max-width: 673px) { #logo { margin-left: 20px; } } #header #logo ...

Implementing fetch within a custom hook to display a loader within a return function

customFetch hook: import React, { useState, useEffect } from 'react'; const customFetch = (url, options) => { const [response, setResponse] = useState(null); const [error, setError] = useState(null); useEffect(() => { (async () ...

What are the issues surrounding Node.js when it comes to handling Cyrillic encoding?

If we consider the most basic and simplest example from the Node website: var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hell ...

Struggling to make jQuery code function properly in Wordpress, despite attempting to use noConflict

I have created a custom image grid gallery in WordPress using HTML and CSS, complete with popups and sliders. I had to code it myself because I couldn't find a suitable plugin that matched my design preferences. I have tested the functionality on my ...

Mastering the art of nesting loops and conditions in React: A comprehensive guide

I am fetching data in React using the following method: const data = [ { header: 'my header1', copy: [ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 'Etiam et risus quam. Pr ...

nextJS does not recognize the term 'Window'

I'm encountering the error "window is not defined" in my NextJS project. The variable isMobile determines whether the window size is less than 767.98 to handle the hamburger menu functionality. This code worked in ReactJS but seems to be causing issue ...