Limits on zooming with THREE.js Orbit controls

I've encountered an interesting limit while using Orbit controls.

The zooming functionality is tied to the radius of the spherical coordinates of the camera in relation to the orbiting axis. Here's how it functions:

Whenever the user scrolls, the scale value changes based on the zoom speed:

(if zooming in)

scale *= Math.pow(0.95, scope.zoomSpeed)

(or if zooming out)

scale /= Math.pow(0.95, scope.zoomSpeed)

Subsequently, the radius value is updated like this: spherical.radius *= scale

Afterwards, the scale is reset to its default value scale = 1 to prevent further changes to the radius

The spherical.radius value dictates the proximity to the camera's focal point, creating a limit when zooming in due to the shrinking radius.

The issue arises when attempting to zoom in a direction where the spherical.radius is at its minimum, making it impossible to zoom further.

Therefore, my query is about achieving the behavior of zooming up or down when at the radius limit using Orbit controls.

P.S. This code is located in OrbitControl.js of the THREE.js library, specifically within the this.update() function. You can access the code on the github repo

Answer №1

Big thanks to pailhead for helping me crack this one!

I made a breakthrough by updating the this.update() function within OrbitControls.js.

Here's how I obtained the vector representing the camera's direction:

var cameraWorldDir = new THREE.Vector3();
scope.object.getWorldDirection(cameraWorldDir);

The key revelation:

if (spherical.radius <= 2) {
    scope.target.add(cameraWorldDir.multiplyScalar(0.4));
}

Essentially, when approaching the center, I adjust the target by pushing it back along the lookAt vector.

For the complete discussion, check out the thread on the threejs forum here

Answer №2

If the terminology used in OrbitControls has you feeling perplexed, you're not alone.

In the world of cameras, what we typically refer to as "zoom" is actually known as "dolly." For those unfamiliar, a dolly is a device utilized to create smooth camera movements. You can learn more about dollies by visiting this link: https://en.wikipedia.org/wiki/Camera_dolly

When we talk about "zooming a camera" in reality, we are discussing a completely different concept. This involves adjusting the focal length of the lens to either widen or narrow the field of view, affecting how much of the world is captured on screen from the same perspective. For additional insights on zooming in filmmaking, check out: https://en.wikipedia.org/wiki/Zooming_(filmmaking)

Upon reaching the minZoom value, it's essential to recognize that no actual zooming has occurred. Instead, you've simply approached the closest distance possible to your orbit center.

If you find yourself wanting to disable the "zoom" or dolly functions on the OrbitControls and prefer to handle zooming independently, consider crafting your own controller that focuses solely on adjusting the camera.fov parameter.

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

Retrieve the thousand separator for numbers using Angular in various languages

When using the English locale, numbers appear as follows: 111,111,222.00, with a comma as the thousand separator and a point as the decimal separator. In languages like German, the same number would be represented as 111.111.222,00, reversing the positions ...

Having trouble getting the items to show up on the canvas

I have been struggling to implement JavaScript on a canvas in order to display mice in the holes using the mouse coordinates. Despite trying many different methods and spending close to a month on this project, I still can't seem to get it to work acr ...

There was an issue with rendering: "TypeError: Unable to access the 'name' property of an undefined object" [Vue alert]

I encountered the following error message: TypeError: Cannot read property 'name' of undefined Here's the snippet from the Vue file where the error occurred: <tr v-for="user in fields.data" :key="user.id"> <td>{{ user.id ...

Design an interactive quarter-circle using CSS styling

My goal is to create this element using CSS, however, the content inside needs to be dynamic. I initially attempted to use border-radius, but realized it is unable to achieve the desired outcome. If anyone has a solution or can offer assistance, I would g ...

Exploring the concept of making nested API requests within a route using Node.js and

Being a newbie in the world of coding, I'm excited to make my first post here. My current learning project involves developing a website that utilizes an external CRM for storing client data received from web forms. The storage functionality is up an ...

What is the best way to identify different directives within the same $scope?

When it comes to calling directive functions from controllers, I follow this approach: function myControllerFunction = function () { $scope.highlight(); } The highlight() function is defined within the directive itself. But what if there are two dif ...

When incorporating MDX and rehype-highlight on a next.js site to display MD with code snippets, a crash occurs due to Object.hasOwn

I'm encountering an issue with my setup that is based on examples from next.js and next-mdx-remote. Everything was working fine until I added rehypeHighlight to the rehypePlugins array, which resulted in this error. Any thoughts on why this could be h ...

I'm seeking assistance with a frontend script problem. I'm curious if there are alternative approaches to coding this script that may be more effective. Can anyone offer guidance on this?

As a frontend developer specializing in script injection, I have been utilizing Adobe Target to inject scripts. However, this method presents several challenges: 1. It is difficult to debug code errors as my HTML and CSS are wrapped inside ' ' a ...

Is it possible to combine ng-class with conditional expression and ng-class with string syntax in a single statement?

To assign classes based on the ngRepeat index, I am using ng-init="myIndex = $index". With this setup, I can apply classes like color-0, color-1, color-2, etc. by using ng-class='"color-" + myindex'. Furthermore, I need to add a different class ...

Using JSON object as an argument in React functional component

Currently, I'm trying to assign a JSON object to a const variable. I've been successful with using vars in the past, like so: {this.props.user.map(function(user){... However, when it comes to stateless consts, I'm encountering some confusi ...

Issue with Angular ui-select causing repeated $http requests in ui-select-choices

I'm currently working on integrating ui-select into my project, and this time I need to pass a controller function as options to ui-select-choices. Here's how it's set up: HTML: <ui-select ng-model="selectedItem" theme="selectize" ng-di ...

Parallax Effect Slows Down When Scrolling In Web Page

Currently in the process of creating a website with a scrolling parallax effect using Stellar.js on the header and three other sections. However, I'm experiencing lag when scrolling, especially at the top of the page. I've attempted to reduce la ...

I'm curious, what is the optimal method for arranging a json object based on an index contained in each of its properties?

I'm working with an array of objects, looking like this myArray = [ { id: 3, data: foo }, { id: 7, data: bar } ] However, I would like to transform it into the following structure transformedArray = { 3: ...

Customized placement of form fields on an HTML grid determined by the user

My goal is to organize input elements on a grid based on user preferences. After researching, I stumbled upon CSS grids, which seem promising. I am considering creating a CSS grid with r rows and c columns, then using JavaScript to assign input elements t ...

Is it possible to obtain the impending exception handling protocol in advance?

In upcoming scenarios, unhandled promise rejections will lead to the termination of the Node.js process using a non-zero exit code. Despite encountering issues, my pipeline erroneously passed and deployed a faulty version that crashes upon launch. If Node ...

Display checkboxes on all TableRow elements as soon as one of them is checked

I've incorporated a material-ui Table into my project and have successfully implemented multi-select functionality. Here are the requirements I've fulfilled so far: Checkboxes are initially hidden - COMPLETED Hovering over a row reveals its che ...

Master the art of navigating the Windows Sound Recorder with the power of JavaScript

I am creating a project that involves controlling the Windows sound recorder for tasks such as starting, stopping, and saving recordings. Is there a way to do this without displaying the recorder window? I would appreciate any assistance in solving this. ...

Adjust the size of the leaflet popup with Vue2Leaflet's l-popup component

I've been working on programming a web application and incorporating leaflet to showcase a map. I've set up markers and popups that show up when the markers are clicked. However, I've noticed that the popups look a bit odd right now – the ...

The function message.react in Discord.js is throwing an error

I have a Discord bot set up for reaction roles. I use IDs to cache the messages that need reactions and make sure the bot reacts with the appropriate emojis before further action. Here is my process for caching the messages: const guild = await client.guil ...

Easy Registration Page using HTML, CSS, and JavaScript

In the process of creating a basic login form using HTML and CSS, I'm incorporating Javascript to handle empty field validations. To view my current progress, you can find my code on jsfiddle My goal is to implement validation for empty text fields ...