What is the best way to achieve a seamless camera movement effect similar to lerping using Three.js?

I am currently working on implementing smooth camera movement using Three.js. The current setup allows me to click, hold, and drag to move around the scene with the camera following. However, I want to achieve a smoother movement similar to the acceleration and deceleration effect seen on this website: . At the moment, when I release the click after dragging, the camera abruptly stops. I aim to replicate the dampening effect of Three.js's OrbitalControls.

import * as THREE from "three";

export default class Experience {
    constructor(options = {}) {
        this.camera = new Camera();
        this.renderer = new Renderer(this.canvas);
        this.drag = new THREE.Vector2();


        this.animate();
        this.onMouseDrag();
    }

    updateCamera(event) {
        if (event.movementX > 0) {
            this.drag.x -= event.movementX * 0.01;
        } else {
            this.drag.x -= event.movementX * 0.01;
        }
        if (event.movementY > 0) {
            this.drag.y -= event.movementY * 0.01;
        } else {
            this.drag.y -= event.movementY * 0.01;
        }
        this.camera.position.x = this.drag.x;
        this.camera.position.z = this.drag.y;
    }

    onMouseDrag() {
        let holder = this.updateCamera.bind(this);

        window.addEventListener("mousedown", () => {
            window.addEventListener("mousemove", holder);
        });
        window.addEventListener("mouseup", () => {
            window.removeEventListener("mousemove", holder);
        });
    }


    animate() {
        requestAnimationFrame(this.animate.bind(this));
        this.renderer.render(this.scene, this.camera);
    }
}

My attempted solution so far involves adjusting the camera position based on mouse movements but results in jittery movements. Once the mouse is released, the camera smoothly transitions to its target position. To address the issue of jerky movement, I have made some adjustments:

constructor(options = {}) {
    this.cameraTargetPosition = new THREE.Vector3(0, 20, 12); //added starting position
    // ...
}
updateCamera(event) {
    if (event.movementX > 0) {
        this.cameraTargetPosition.x -= event.movementX * 0.01; //changed these from "this.drag"
    } else {
        this.cameraTargetPosition.x -= event.movementX * 0.01;
    }
    if (event.movementY > 0) {
        this.cameraTargetPosition.y -= event.movementY * 0.01;
    } else {
        this.cameraTargetPosition.y -= event.movementY * 0.01;
    }
}

animate() {
    this.camera.position.lerp(this.cameraTargetPosition, 0.4); //added this
    //...
}

Answer №1

After some troubleshooting, I discovered that the issue was caused by extra code interfering with my system. The solution I shared successfully achieves the desired damping "lerping" effect.

constructor(options = {}) {
    this.cameraTargetPosition = new THREE.Vector3(0, 20, 12); //initial position added
    // ...
}
updateCamera(event) {
    if (event.movementX > 0) {
        this.cameraTargetPosition.x -= event.movementX * 0.01; //modified from using "this.drag"
    } else {
        this.cameraTargetPosition.x -= event.movementX * 0.01;
    }
    if (event.movementY > 0) {
        this.cameraTargetPosition.y -= event.movementY * 0.01;
    } else {
        this.cameraTargetPosition.y -= event.movementY * 0.01;
    }
}

animate() {
    this.camera.position.lerp(this.cameraTargetPosition, 0.4); //newly added line
    //...
}

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

Issues with transmitting data from client to server through Socket.io

Experiencing a communication glitch between the client and server when using socket.io. Sending JSON object: loginInfo = { email: 'username', password: 'password' } Client side code: socket.emit('user:login', loginInfo); ...

Locate and eliminate all occurrences of "<br />" within a webpage using jQuery

I am currently working on a project using the Cargo Collective platform and I have noticed that it automatically includes unnecessary <br /> tags in the body of my document. Is there a way to use jQuery to scan for all instances of <br /> tags ...

Techniques to dynamically insert database entries into my table using ajax

After acquiring the necessary information, I find myself faced with an empty table named categorytable. In order for the code below to function properly, I need to populate records in categoryList. What should I include in categoryList to retrieve data fro ...

Guidelines for Establishing a JavaScript Development Environment

Currently, I am working on a JavaScript framework that consists of N modules. Each module has its own GitHub repository. ModuleA is dependent on ModuleB, so whenever there is an update in ModuleB, the following steps need to be taken: Commit changes to ...

Achieving full content height with sticky footer

Revise I have made updates to a JSFiddle demo for users to test out. @Aspiring Aqib has offered a working solution using javascript, but CSS solutions are still encouraged. Original Request I successfully implemented a sticky footer following the guidel ...

Exploring the Differences Between Using CPU and GPU for Transformations in WebGL

I've just started exploring WebGL, and I'm curious about whether using JavaScript or a shader would be faster for transformations like rotation, translation, scale, etc. Can anyone shed some light on this? ...

The selected value from a dropdown list may occasionally come back as text

I am facing an issue with a dropdown list on my form that has Integer Values set to display text. The problem arises when I run the code to show the value and associated text, as the text is being displayed as the value itself. Is there any workaround avai ...

Utilizing the output of a callback function to execute res.render in a NodeJS application

Currently, I am utilizing oracledb for node in order to retrieve data from the database. Once the data is fetched, my goal is to transmit it to the client side using render() in express JS. Below is an example of the code structure: config.js module.expo ...

Error - Oops! It seems like there was a TypeError that occurred because the property 'innerHTML' cannot be set for something that

I keep encountering this issue in my code. Uncaught TypeError: Cannot set property 'innerHTML' of undefined Despite trying various suggestions from other posts with similar errors like Uncaught TypeError: Cannot set property 'innerHTML&apos ...

Using Angular ng-token-auth to post to an incorrect localhost address

I have a Node.js server running on http://localhost:3000/, and a React Frontend running on http://localhost:8000/. I am setting up the user authentication feature with JWT. However, when posting the token, it goes to the incorrect localhost address: http ...

Extracting JavaScript OnClick button using Selenium

I'm having trouble extracting the email address from the following URL: https://www.iolproperty.co.za/view-property.jsp?PID=2000026825 that is only visible after clicking on the "Show email address" button. However, every time I attempt to click and r ...

At times, Mongoose may return null, while other times it returns data frequently

I have designed a unique mongoose schema for managing contacts, with a custom defined ID. Here is the schema structure: const mongooseSchema = new mongoose.Schema({ _id:{ type:String, unique:true, required:true }, firstN ...

Load the scripts only if they have not already been loaded, and proceed to utilize them

Currently, I have a situation where I must load 4 javascript libraries if they have not been loaded already, and then proceed to utilize their functions. However, I am encountering an issue with Uncaught ReferenceError: sbjs is not defined. Even though th ...

Trapped in the dilemma of encountering the error message "Anticipated an assignment or function: no-unused expressions"

Currently facing a perplexing issue and seeking assistance from the community to resolve it. The problem arises from the code snippet within my model: this.text = json.text ? json.text : '' This triggers a warning in my inspector stating: Ex ...

Unable to retrieve blobs from a directory using the Node.js SDK

I'm experiencing an issue while trying to download blobs from a blob container in Azure. I am able to successfully download files when they are located in the root container, but I encounter errors when trying to download files from inside a folder. ...

Ensuring Typescript returns the accurate type depending on given parameters

i am working with a code example that looks like the following interface BaseQuestionType { label?: string } export type RadioQuestionType = BaseQuestionType & { radio: boolean } export type TextQuestionType = BaseQuestionType & { text: strin ...

Trouble with tab switching across multiple cards

I have been working on an app that generates multiple cards with 3 tabs on each card. However, I am facing an issue with tab switching. The tab switching works fine on the first card, but when I try to switch tabs on other cards, it still affects the tabs ...

Go all the way down to see the latest messages

I have developed a messaging system using Vue. The latest messages are displayed from bottom to top. I want to automatically scroll to the end of a conversation when it is clicked and all the messages have been loaded via axios. Conversation Messages Comp ...

Using Selenium to interact with a Modal Dialog window

When trying to navigate to a page in IE9 using Selenium, a certificate error message appears on the page. By using AutoIT, I am able to click within the browser, TAB twice, and hit enter without any issues. However, after this step, an error for a "Modal d ...

Switch the style sheets after the content

How can I create a toggle effect on the :after property, switching between + and - each time the link is clicked? I've attempted to achieve this using JavaScript, CSS, and HTML, but the code only changes + to - and doesn't switch back when the l ...