What is the best way to prevent camera rotation with mouse movement in three.js while using OrbitControls?

My current setup involves using orbit controls to rotate the camera in my three.js project.

const controls = new THREE.OrbitControls(camera, renderer.domElement);

controls.dampingFactor = 0.07;
controls.rotateSpeed = 0.07;
controls.enableZoom = false;
controls.screenSpacePanning = false;
controls.minDistance = 250;
controls.maxDistance = 350;
controls.minPolarAngle = 1.2;
controls.maxPolarAngle = 1.2;

In addition, I have set a fixed position for the camera as follows -

camera.position.x = 308;
camera.position.y = 135;
camera.position.z = 130;

Everything works smoothly when I use left-click mouse movement to navigate around my object. However, I encounter an issue when I try to use right-click mouse movement as it unexpectedly moves the camera away from the object. I have attempted to disable this functionality by utilizing event listeners on the document, but have not been successful in finding a solution yet.

document.addEventListener("mousedown", function(event){
  console.log(event.button);
  if(event.button == 2){
    rightmousemove = true;
    return false;
  } 
});
document.addEventListener("mousemove", function(event){
  if(rightmousemove === true){
    event.preventDefault();
    event.stopPropagation();
  }
});

Answer №1

If you want to stop the panning effect, you can use this code:

controls.enablePan = false;

Visit this link for more information on disabling panning in Three.js controls.

Answer №2

To prevent panning, you can easily disable it by using controls.enablePan = false;, as mentioned in another response.

I'd like to explain why your initial code wasn't functioning correctly. The issue lies within event bubbling, where events such as mousemove originate from a child element and travel upwards to the parent.

https://i.sstatic.net/8dsqV.png

For example, if a click or mouse movement is initiated on a button element, it will ascend to the container div, then to the document, and finally reach the window level.

In the source code of OrbitControl.js, you'll notice that the mouse movement is bound to

document.addEventListener( 'mousemove', onMouseMove, false );
.

Both of you have attached this behavior to the document object, rendering stopPropagation ineffective since it halts propagation to the parent, yet both actions are registered on the same entity.

To overcome this, consider binding the event to a more specific element or employing event.stopImmediatePropagation(). This method interrupts subsequent handlers from executing and hinders the event's upward traversal through the DOM structure.

View JSFiddle code with stopImmediatePropagation

Answer №3

let control = new OrbitControls(camera, container); // Let's create a new control object
control.mouseButtons = {
    // LEFT: THREE.MOUSE.ROTATE,
    MIDDLE: THREE.MOUSE.DOLLY,
    // RIGHT: THREE.MOUSE.PAN
}
control.update(); // Update the controls

If you want to customize mouse controls, simply uncomment the lines as shown in the code snippet above.

Reference Link:

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

What is the best approach for looping through this JSON data?

After retrieving the following JSON data from a database using ajax: {"route":[{"latitude":-27.38851,"longitude":153.11606},{"latitude":-27.47577,"longitude":153.01693}]} What is the best approach for iterating over it to extract latitude and longitude p ...

Error: XYZ has already been declared in a higher scope in Typescript setInterval

I've come across an interesting issue where I'm creating a handler function and trying to set the current ref to the state's value plus 1: const useTimer = () => { const [seconds, setSeconds] = useState(0); const counterRef = useRef(n ...

Calculate the date difference in Nuxt by leveraging the @nuxtjs/moment module

I'm a Nuxt newbie facing an issue with calculating the difference between two dates (user input date and current date). The code I am using works fine in most cases, but when the input date is '2020-03-31' or '2020-01-30', the cons ...

What is the best way to connect click events with ExtJS template elements?

Is there a way to assign a click event to each link tag without directly embedding onclick=.... in the XTemplate code? new Ext.XTemplate( '<ul>', '<tpl for="."><li><a href="#{anchor}">{text}</a></li& ...

Establishing a limit on the maximum number of classes that can be selected/activated when clicking on multiple divs or IDs

Working on a talent tree, I encountered an interesting issue. Currently, the code allows users to select up to 4 talents. However, when duplicating the talent tree for a second hero or party member, the same limit is shared across all trees. Attempts have ...

Enhance toolbox information upon clicking and revert text to its original state when the mouse is moved off

Within my component, I have a property that serves as the tooltip text: @property() copyText = 'Click to copy'; I've managed to create a function using the @click expression to update the text, and also figured out how to revert it back to ...

JS Issue with Countdown functionality in Internet Explorer and Safari

I am having an issue with a JavaScript countdown not working on Internet Explorer and Safari, despite being tested on Windows 7. It works fine on Chrome and Firefox. I am unable to switch to a jQuery countdown due to certain restrictions on the website, so ...

Submission method of a stateless component in Redux form

Should I keep this component stateless or should I convert it to a stateful component? import React from "react"; import { Field, reduxForm } from "redux-form"; import { connect } from "react-redux"; import RaisedButton from 'material-ui/RaisedButton ...

What is the reason behind allowing JavaScript to perform mathematical operations with a string type number?

let firstNum = 10; let secondNum = "10"; console.log(firstNum * secondNum); // Result: 100 console.log(secondNum * secondNum); // Result: 100 ...

Incorporate a single file into the source code using React just once

I am looking to add a JavaScript script to the body when a React Component renders, but I only want it to happen once. Here is the current code I have: const MyComponent: React.FC = () => { const script = document.createElement('script'); ...

Having trouble locating the search bar element on Walmart's website?

I'm currently working on a bot that needs Selenium to interact with the search bar on Walmart's website, where it will input the name of a specific product and perform a search. However, I've encountered an issue where no matter what method ...

Having trouble with shipit.js deployment: Error encountered - git checkout undefined

I have been using shipit.js to deploy my nodejs application on an Ubuntu 16.04 server successfully. However, I recently encountered the following error: ./node_modules/shipit-cli/bin/shipit production deploy start Running 'deploy:init' task... ...

Struggling with getting my JQuery show function to execute properly

I'm new to javascript and I'm facing some challenges. My goal is to display an overlay div using jquery. Below is my code snippet: $("#loginbutton").click(function() { alert('Hello'); $('#overlay').show(); return ...

Nextjs has a tendency to transform my personalized components into div elements

Why do my components (ElementTile) on my page change into divs when viewed in the browser? The CSS rules that apply to "ElementTile" also do not work, which is expected because they are converted to divs. Is there a way to change this behavior? Thanks in ...

CSS for aligning to baseline grid

Update: I am seeking advice on how to align text to a baseline using different font sizes within a div. Despite my efforts, I have not found a satisfactory solution online. It seems impossible to achieve without the use of a Javascript framework or css pre ...

Keypress-triggered function for reading lines in Word - Word Addin

I am currently working on developing an addin for Microsoft Word that can read the entire line of text in a Word document and compare it to a dictionary on each keypress event. The goal is to capture the text input by the user, save it to a variable, and s ...

Combine two arrays in MongoDB where neither element is null

Issue I am looking to generate two arrays of equal length without any null elements. Solution I have managed to create two arrays, but they contain some null values. When I remove the null values, the arrays are no longer of equal length. aggregate([ ...

Trouble displaying custom markers in VueJS using Google Maps API

I have integrated vue2-google-maps to display a map and add markers on specific locations. Here is the code snippet showing the map components along with the props passed to it. <gmap-map id="map" :center="center" :zoom="5" ...

Enhance your deletion process by utilizing Ajax for smooth communication and incorporating a

When a user clicks on the delete ImageButton, I want to display a confirmation message. If they select 'Ok', then the deletion will proceed. If 'Cancel' is clicked, nothing will happen. <asp:ImageButton ID="ImageButton1" runat="serv ...

Strange Behavior of ngIf and @Input in Angular 2

Despite console indicating false, NgIf appears to always evaluate as true. The issue stems from the component's HTML below: <product-component-tree itemSku="{{item.itemSku}}" selectable="false" classes="col-md-12 col-xs-12"></product-compo ...