Understanding the concept of inertia within the OrbitControls feature of ThreeJS

I have implemented THREE.OrbitControls to rotate my objects in a project. Yet, I am interested in incorporating some inertia for the camera rotation so that it gradually comes to a stop after the user stops moving the mouse. What would be the best approach to achieve this effect?

Answer №1

If you're looking to introduce inertia into OrbitControls.js, there's a quick and easy method to achieve this:

Towards the end of the update function (specifically around Lines 271-272), you'll come across two variables that are currently set to zero:

thetaDelta = 0;
phiDelta = 0;

All you need to do is modify them so that instead of immediately resetting to zero, they gradually decrease over time like so:

thetaDelta /= 1.5;
phiDelta /= 1.5;

That's all there is to it!

Answer №2

Attention to all fellow developers who have found themselves here: in the current year of 2019 and with the latest version r111 of three.js, it is worth noting that the OrbitControls now come equipped with built-in inertia, known as damping (though the reasoning behind this name remains a mystery). If you are curious about how to utilize this feature, be sure to check out this informative answer.

Answer №3

To achieve this effect, I implemented a quick and simple coding method -

Within the OrbitControls.js file, insert the following function within the main declaration (or any suitable location) -

this.inertiaFunction = function()
{
    scope.rotateLeft( ( 2 * Math.PI * rotateDelta.x / PIXELS_PER_ROUND * scope.userRotateSpeed )/dividingFactor);
scope.rotateUp( ( 2 * Math.PI * rotateDelta.y / PIXELS_PER_ROUND * scope.userRotateSpeed )/dividingFactor);
dividingFactor+=0.5;
}


Incorporate the following line at the beginning of the onMouseDown(event) function -

 dividingFactor = 1;

(to reset the factor each time the mouse is clicked)


At the start of the onMouseUp(event) function, include these lines -

dragging2=false;
timer = setTimeout(function(){dragging=false;}, 500);

dragging and dragging2 serve as flags in the requestAnimFrame function to determine if the mouse has been lifted and if 500 milliseconds have not yet passed.


Add the following snippet within your main animate() or requestAnimationFrame() function -

if(dragging && !dragging2){ controls.inertiaFunction(); }


This condition ensures that if the mouse has been lifted and 500ms have not elapsed, the inertiaFunction() of the controls object (which is an instance of THREE.OrbitControls) will be called. To handle cases where the user clicks within 500ms of lifting the mouse, the setTimeout is canceled using the timer object.
In your onMouseDown function, add the following line -

if(dragging)
{
    clearTimeout(timer);
}


Remember to declare dragging, timer, dragging2, and dividingFactor as global variables. Experiment with the dividingFactor and the 500ms in the setTimeout() to adjust the distance traveled and duration of the inertial motion.

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

Guide for transferring information from JavaScript to PHP on the same page

My dilemma lies in transferring data from my JavaScript script to PHP code for use within a query. Despite numerous attempts, I have been unsuccessful in achieving this. Below is my script for uploading files using an input type: file, where the URL is sto ...

React Router integration problem with Semantic UI React

Just diving into ReactJS and encountering a problem with using "Menu.Item" (from Semantic UI React) and React Router. I won't include my imports here, but rest assured they are all set up correctly. The constructor in my "App.jsx" looks like this: ...

During my JavaScript coding session, I encountered an issue that reads: "Uncaught TypeError: $(...).popover is not a function". This

Encountering an issue while trying to set up popovers, as I am receiving this error: Uncaught TypeError: $(...).popover is not a function. Bootstrap 5 and jQuery links are included in the code, but despite that, the functionality is still not operational. ...

Is it possible to verify age on a date field in vanilla JavaScript?

How can I validate the age on a date input field? If someone is 18 or older, they will be valid. Otherwise, an error message should be displayed. Can you help me with this? ...

Exploring the differences between JavaScript destructuring and assignment

In my code, I initially used this line: const availableDays = status.availableDays; However, a suggestion was made to replace it with this line: const { availableDays } = status; Both options achieve the same result in one line of code, but I am curious ...

Triggering jQuery Submit Form when Form is Modified

I need help with automatically submitting a form using jQuery when an input changes. The specific input I am working with is a date picker, and I want the form to be submitted as soon as a user makes a selection. <form id="select_date" name="select_da ...

What is the best approach: Loading all database results at once or making multiple requests?

Looking to refine a vast database with these specific columns: Name - Maximum Height - Minimum Height - Range - Maximum Angle - Minimum Angle The goal is to filter the data based on user-inserted criteria, such as if a user inputs a maximum height of 80c ...

Using moment.js to perform addition of time does not yield the desired outcome

Every time I try to ---- make changes ---- var someMoment = moment('6:30 PM', ["h:mm A"]); ---- end changes ---- someMoment.add(30, 'minutes') I am not getting any desired outcome. console.log(start); -- Moment {_isAMomentObject: ...

Emulate clicking a radio button (using PHP and JS)

For the past week, I've been struggling to solve this issue with no luck. I admit that I am new to this area, so I ask for your patience. My current problem involves using TastyIgniter, an online food ordering system. In order to add items to the car ...

The most effective method for calculating overhead is through the utilization of synchronous techniques

I'm currently developing a nodeJS app that heavily relies on synchronous methods, particularly for file operations and spawning child processes. I am looking to assess the impact of these blocking main thread activities in terms of overhead. What woul ...

I'm confused about what I did wrong with Node.js. The server.js is up and running, but I'm unable to view the

I have made some progress so far and I am currently running this code on Putty. var http = require('http'); var fs = require('fs'); const PORT = 8080; http.createServer(function(request, response) { var url = request.url; switc ...

Utilizing JQuery to select list items for pagination purposes

I am currently working on a pagination script and everything seems to be functioning well, except for one minor issue. I am struggling with triggering an action when the page number (li) is clicked. The pagination data is being retrieved via ajax and disp ...

Easiest method for combining elements made in Angular with D3

Exploring various methods to combine D3 and Angular for learning purposes, seeking advice on the approach: The client application is fed a JSON array of nodes and edges from the server. The main component is a graph visualization using D3 force-directed l ...

Encountering issue: Unrecognized parameter "id" in the "user" field of type "Query" [GraphQL, Relay, React]

We are currently setting up a query in relay. Our user database is structured like this: function User(id, name, description) { this.id = id.toString() this.name = name this.description = description } var users = [new User(1, 'abc', &a ...

Unable to insert an array within a function

I've searched for the answer but couldn't find it - my array is not pushing to datahasil. How can I push the array hasil into datahasil...?? const data1 = await JadwalBooking.aggregate([{ $project: { "keterangan": "$keterangan", ...

"Implementing Notifications in Mongoose: A Step-by-Step Guide

My current user schema is set up as follows: const Schema = mongoose.Schema; const bcrypt = require("bcryptjs"); const userSchema = new Schema( { email: { type: String, required: true, index: { unique: true } }, ...

Using JavaScript, create a function that accepts an HTML element as a parameter

I have a script with two functions. One function generates a lengthy HTML string, and the other function processes this string as a parameter. function myFirstFunction() { // Generate HTML content return myHTML; } var myHTML = myFirstFunction(); ...

Using jQuery and Ajax to dynamically populate a select input with items upon page initialization

I am facing an issue with 2 <select> inputs: <select id="country"> <option value="" selected>Choose</option> <option value="usa">USA</option> <option value="uk">UK</option> </select> <select ...

What steps should be taken to prepare data for transmission to a server in a Next.js environment?

I'm in the process of creating a website that requires authentication. I am using Next (React) and typescript for web development. My objective is to make most pages ServerSideRendered or StaticHTML. However, I encountered an issue right at the begin ...

Having trouble getting my Win and Lose Divs to display in my IF statement within the Card Game

Currently, I am developing a card game where players are presented with a card generated by the computer. The player has to decide whether the next card will be higher, lower, or equal to the current one by clicking corresponding buttons. if ((playerChoic ...