"Utilizing three.js to smoothly move the camera forward with a left mouse click

I am currently working on a 3-D graphical website using three.js. The theme of the website is a universe filled with text. My goal is to make the camera move forward when the left mouse button is clicked and backward when the right mouse button is clicked.

In the past, the camera would zoom in or out based on the mouse scroll movement. However, I need to change this functionality to use the left and right mouse clicks instead.

If the user holds down the left mouse button, the camera should continuously move backward.

The previous code for zooming with the scroll looked like this:

document.addEventListener('wheel', onMouseWheel, false);
function onMouseWheel( event ) {
  camera.position.z += event.deltaY * 0.1; // move camera along z-axis
}

So, in reference to that code, I modified it as follows:

var hold = false;

document.addEventListener('contextmenu', onContextMenu, false);
document.addEventListener('mousedown', onMouseDown, false);
document.addEventListener('mouseup', onMouseUp, false);

function onContextMenu(event) { // Prevent right click
  event.preventDefault();
}

function onMouseDown(event) {
  hold = true;
  switch (event.which) {
    case 1: // if left click
      moveForward();
      break;
    case 3: // if right click
      moveBackward();
      break;
  }
}

function onMouseUp(event) {
  console.log('mouse up');
  hold = false;
}

function moveForward() {
  while (hold === true) {
    camera.position.z -= 0.1;
  }
}

function moveBackward() {
  while (hold === true) {
    camera.position.z += 0.1;
  }
}

This code allows the camera to move forward or backward depending on the value of the hold variable. However, when running this code, the browser becomes unresponsive. I am looking for a solution to smoothly move the camera forward/backward.

Is there a way to address this issue?

Answer №1

To add animation to the camera movement, you will need to update the camera position within the rendering loop. This way, every time the scene is rendered, the camera moves a step further.

var hold = -1;

document.addEventListener('contextmenu', onContextMenu, false);
document.addEventListener('mousedown', onMouseDown, false);
document.addEventListener('mouseup', onMouseUp, false);

function onContextMenu(event) { // Prevent right click
  event.preventDefault();
}

function onMouseDown(event) {
  hold = event.which;
}

function onMouseUp(event) {
  console.log('mouse up');
  hold = -1;
}

// Render Loop for Animation
function animate() {

  requestAnimationFrame(animate);

  switch(hold) {
    case 1:
      camera.position.z -= 0.1;
      break;
    case 3:
      camera.position.z += 0.1;
      break;
  }

  renderer.render(scene, camera);

}

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 sorting feature for isotopes is malfunctioning following the addition of a new div element

Isotope was utilized for sorting divs based on attribute values, however, a problem arises when a new div is added or an existing div is edited. The sorting functionality does not work properly in such cases, as the newly created or edited div is placed at ...

Struggling with making changes to a instantiated "this" object within a pseudo javascript class

If you scroll down to the bottom of this post, you'll find a workaround or possible solution. I've been grappling with understanding how pseudo classes work together to achieve the task I'm attempting (explained in the code below). It might ...

Problem with div selection and dynamic content in Rails 5

Currently, I am working on developing an application using Rails 5 and Ruby 2.4.0 with Bootstrap 4 Alpha 6 integration. The issue I am facing involves a dynamic select box that loads information about the selected item into a div below it. However, each t ...

Retrieve the specific array element from parsing JSON that includes a particular phrase

I need help filtering array values that contain the phrase 'Corp' Currently, all values are being returned, but I only want the ones with "Corp" var url = "/iaas/api/image-profiles"; System.debug("getImageProfiles url: "+url ...

Removing an individual HTML element within a form using JavaScript Fetch() in the presence of multiple components

The Situation Having a form that includes image components generated from a MySQL database with PHP, I've implemented javascript fetch() functionality on different pages of the website to enhance user experience. However, in cases where the functiona ...

Prevent redirection in JavaScript

My current script is designed to detect an Android device and then redirect the user to "android.html". Once on the "android.html" page, the user has the option to either download an app or click "CONTINUE" to proceed to "index.html". However, there seems ...

The React application is experiencing difficulty in rendering SVG images exclusively on Windows operating systems

My react app runs smoothly on OSX, but encounters issues on Windows due to SVG files: Module parse failed: Unexpected token (2:0) You may need an appropriate loader to handle this file type. <svg xmlns="http://www.w3.org/2000/svg" viewBox="..."> I ...

Is there a way to retrieve metadata from a web URL, like how Facebook automatically displays information when we share a URL in a status update?

Is there a way to fetch metadata such as title, logo, and description from a website URL using AngularJS or JavaScript? I am looking for a solution similar to Facebook's status update feature that automatically loads metadata when you paste a website ...

"An issue has been identified where Raycaster is unable to retrieve userData

Currently, I am utilizing the following code to obtain intersects and it successfully returns the correct objects. However, I have noticed that the userData:{} appears to be empty. var intersects = this.raycaster.intersectObjects(this.scene.children[8].chi ...

Filter prices (minimum and maximum) using a dropdown menu in asp.net core

Struggling to filter prices using javascript and asp.net core, I've written a lot of javascript code that isn't quite cutting it. I'm wondering if there's a simpler way to achieve this, perhaps with jquery or in c#? If anyone has any ...

create new Exception( "Invalid syntax, expression not recognized: " msg );

Can someone assist me in identifying the issue at hand? Error: There seems to be a syntax error, and the expression #save_property_#{result.id} is unrecognized. throw new Error( "Syntax error, unrecognized expression: " msg ); Here is the c ...

What is the process for activating an event when a window undergoes a change?

I created a window using the window.open method to display a form. Once the user submits the form, they are redirected to a page called success.html. Is there a way to trigger an event after success.html finishes loading? I attempted the following approach ...

Utilize Set.Attribute prior to entering the for loop

Could someone please clarify why I am unable to declare the var node before the for loop and then simply use appendChild(node) inside the loop? Why is it necessary to declare it for each iteration in order for it to affect all div elements? Otherwise, it w ...

Obtaining HTML elements from JSON using jQuery (i.e., the opposite of serializing with Ajax)

I am looking to extract values from a set of controls (INPUT, SELECT, TEXTAREA) within a DIV and send them as JSON via Ajax to a server. Utilizing jQuery's serializeArray makes this process easy. After sending the JSON data, I expect the server to re ...

Are there any creative methods for structuring Node.js Alexa code efficiently?

I'm looking for a more organized approach to managing my Node.js Alexa code. With the increasing number of intents in my interaction model, the lines of code in my lambda's index.js have become difficult to manage. Can someone provide an example ...

The following MongoDB errors unexpectedly popped up: MongoNetworkError: connect ETIMEDOUT and MongoServerSelectionError: connect ETIMEDOUT

I've been working on a React and NextJS App for about a month now, utilizing MongoDB as my database through MongoDB Atlas. I'm currently using the free version of MongoDB Atlas. For the backend, I rely on NextJS's api folder. Everything wa ...

To utilize the span and input text increment functionality, simply use the required input type number and hold either the up or down arrow

Is it possible to increment the value of an input type number by 1 when holding down on a mobile device? <input type="text" id="number" value="1"> <span id="upSpan"> Up </span> $('#upSpan').on('touchstart', function ...

Is it better to verify the data from an ajax request or allow JavaScript to generate an error if the data is empty

Is it better to check if the necessary data is present when handling success data in jQuery, like this? success: function (data) { if (data.new_rank !== undefined) { $('._user_rank').html(data.new_rank); } } Or should you just l ...

Vue 2 draggable does not maintain reactivity when the v-model value consists of a parent tag's iterable

Utilizing Vue 2 alongside Vuex, the incoming object gets organized into distinct sub-objects according to the classCategory value. Could it be failing because the v-model value in draggable is a key sourced from the parent tag object? <div class="c ...

Creating an expo apk using eas buildWould you like a tool for generating

Following an update to Expo, the process of building apk files using expo build:android -t apk is no longer supported. Instead, it now recommends using eas builds with the command eas build -p android --profile preview. However, this resulted in building a ...