What is the best way to adjust the THREE.js view to match the size of the canvas

I am trying to implement dragging and dropping an element to the mouse position by synchronizing THREE.js space with the canvas size, where the coordinates {0,0} are located at the center of the screen. If my element has a width of 500px, dropping it at a mouse coordinate x = 500 should translate to the object's x coordinate being x = 250. Currently, I am using a PerspectiveCamera for this functionality.

To achieve this, I referred to a tutorial on understanding scale and the perspective camera and calculated the field of view (fov) based on the z position of the camera. The goal was to have the fov boundaries intersect the boundaries of the green line, which represents the canvas width in my case.

Here is the code snippet I have developed so far to calculate the fov based on the z position of the camera (employing Pythagorean theorem).

  calculateFOV(z:number){
    const b = z;
    const a = this.width / 2;
    const c = Math.sqrt((a**2) + (b**2));
    const cosa =  a / c;
    let angle = (Math.acos(cosa) * (180 / Math.PI));
    let resAngle = 180 - 90 - angle
    return (resAngle * 2);
  }

...

const zPosition = 40;
const fov = this.calculateFOV(zPosition);
this.camera = new THREE.PerspectiveCamera( fov, this.width / this.height, 10,  zPosition);

However, the implementation is not functioning as expected. Any assistance or further details required would be greatly appreciated.

Answer №1

Imagine if your model has a width of W and a height of H.
Picture the camera positioned at Z.
Visualize a canvas with a width of w and a height of h.
In THREE.js, the field of view (fov) is determined by the height.

Your task is to assess the aspect ratio of the model compared to the canvas.

If ((W/H) < (w/h)), then the fov = 2*atan2(H/2, Z);
Else, the fov = 2*atan2(W*h/w/2, Z);

(It's worth noting that THREE.js camera fov is measured in degrees)

(This calculation gives me a sense of accomplishment:)

If the canvas aspect ratio is 4/3, with H=30, W<40, and Z=100, then:  
  (W/H) < (4/3) and fov = 2*atan2(30/2, 100);  
If the canvas aspect ratio is 4/3, with W=40, H<30, and Z=100, then:  
  (W/H) > (4/3) and fov = 2*atan2(40*3/4/2, 100);

Answer №2

This solution was successful for me:

  adjustFieldOfView(z:number){
    const b = z;
    //scaling mid base of fov triangle to aspect ratio
    const a = ((this.width / 2 ) / (this.width / this.height));
    //pythagorean theorem
    const c = Math.sqrt((a**2) + (b**2));
    //cosine of angle
    const cosa = a / c;
    //convert cosine to degrees
    const angle = Math.acos(cosa) * (180 / Math.PI);
    //multiply angle by 2 to get final result
    let resAngle = (90 - angle) * 2
    return (resAngle);
  }

and setting z = this.width

Although I don't fully understand the logic behind it, adjusting the mid base to the aspect ratio did the trick.

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

Troubleshooting asynchronous problems with rxjs chaining within ngrx effects

@Effect({ dispatch: false }) public setJwtDataParcoursPage = this.actions$.pipe( ofType(INIT_FORM_SUCCESS_ACTION), map((action: InitFormSuccessAction) => action.payload), withLatestFrom(this.store.select(this._apiHeadersSelector.getJwt) as Observa ...

Navigating an Array in Typescript

Angular is linked to node.js, which interacts with mongodb to fetch data successfully. However, I am now faced with the challenge of mapping variables in my typescript component to the backend node.js. When viewing the data structure in the browser consol ...

methods for extracting JSON key values using an identifier

Is it possible to extract the Type based on both the file number and file volume number? [ { ApplicantPartySiteNumber: "60229", ManufacturerPartySiteNumber: "1095651", FileVolumeNumber: "E312534.2", Type: "Manufacturer", FileNumber ...

How can you craft a single type that encompasses both the function signature and an array with the same structure?

In this scenario, I am facing a specific dilemma. type fnArgs = [string, number]; function test(a: string, b: number): void {} const x: fnArgs = ['a', 2]; test(...x); What I find interesting is that the values being passed to the test functio ...

Unable to build due to TypeScript Firebase typings not being compatible

This is what I have done: npm install firebase --save typings install npm~firebase --save After executing the above commands, my typings.json file now looks like this: { "ambientDevDependencies": { "angular-protractor": "registry:dt/angular-protract ...

Working with a function in the stylesheet of TypeScript in React Native allows for dynamic styling

When attempting to use variables in my StyleSheet file, I encounter a type error even though the UI works fine. Any suggestions on how to resolve this issue? type buttonStyle = (height: number, width: string, color: string) => ViewStyle; export type St ...

Retrieve all exports from a module within a single file using Typescript/Javascript ES6 through programmatic means

I aim to extract the types of all module exports by iterating through them. I believe that this information should be accessible during compile time export const a = 123; export const b = 321; // Is there a way to achieve something similar in TypeScript/ ...

Using the TypeScript NextPage function along with the getInitialProps static method and @typescript-eslint/unbound-method

After enabling typescript-eslint with its recommended settings, I encountered an issue in my code. I came across this helpful post on Stack Overflow: Using getInitialProps in Next.js with TypeScript const X: NextPage = props => {/*...*/} X.getInitialP ...

Getting the Angular component class reference within a triggered Highcharts selection event callback - what's the best approach?

It seems like I'm facing a common javascript closure issue, but let me illustrate it with a specific example as I'm struggling to grasp it in an Angular context. In my Angular component, I'm using the Highcharts library to visualize data. W ...

Can three.js be executed in Jupyter's ijavascript kernel?

Seeking assistance in integrating my library built with three.js into an ijavascript (jupyter + ijavascript) notebook environment. Any insights on whether this is achievable? It seems like three.js is compatible when using require('three'), but ...

I am attempting to retrieve custom cellRendererParams within the CustomCellRenderer class

I'm currently working with Ag-Grid in my angular application and am trying to implement a custom cell renderer. The tutorial I followed uses ICellRendererParams for the parameter type passed to the init event. agInit(params: ICellRendererParams): void ...

Utilize Lodash to iterate through functions in a loop and retrieve the first matching result

I am looking to iterate through an array of objects and call a method on them. If the result of that method meets certain conditions, I want to immediately return that result. The current implementation is as follows: public getFirstMatch(value: string, a ...

Implementing a NestJs application on a microcomputer like a Raspberry Pi or equivalent device

I'm facing a challenge in trying to find a solution for what seems like a simple task. I am aware that using the Nest CLI, I can utilize the command "nest build" to generate a dist folder containing the production files of my project. However, when I ...

Can HTML variables be accessed in lines of code before they are declared in HTML?

In line 1 of my code, I am trying to access the rowData variable which is declared in the second HTML line. However, I keep getting the error message "Property 'rowData' does not exist on type 'AppComponent'" for that line. Strangely, t ...

Dealing with a Typescript challenge of iterating over a tuple array to extract particular values

I am struggling with writing a function that extracts names from an array of tuples, where each tuple includes a name and an age. My current attempt looks like this: type someTuple = [string, number] function names(namesAndAges: someTuple[]) { let allNa ...

Error in TypeScript: Gulp + Browserify combination is not yielding the expected type

I keep encountering an error whenever I try to run this script. The error message I receive is: -> % gulp compile-js [22:18:57] Using gulpfile ~/wwwdata/projects/site/gulpfile.js [22:18:57] Starting 'compile-js'... events.js:141 th ...

Simple solutions for creating Typescript declaration files effortlessly

Recently, I created a Javascript library using Typescript and I am seeking guidance on how to include a Declaration file in the distribution package. Can anyone recommend helpful tools available in Visual Studio 2015 for this purpose? ...

An effective approach to automatically close an Expansion Panel in an Angular Mat when another one is opened

I am attempting to implement functionality where one expansion panel closes when another is opened. By default, the multi attribute is set to "false" and it works perfectly when using multiple expansion panels within an accordion. However, in this case, I ...

Typescript: The type 'X' does not correspond with the signature '(prevState: undefined): undefined' in any way

My React Native app, which is written in TypeScript, has been giving me a hard time with an error lately. The issue revolves around a Searchable List feature. This list starts off with an Array of values and gets updated when users type into a search bar. ...

The type 'string[]' is missing the required property 'label', resulting in a typescript error

Within my codebase, I've defined a type called Person that looks like this : type Person = { value?: string[]; label?: string[]; }; Additionally, there is a promise function in my project: async function main(): Promise<Person> { const fo ...