What is the best way to smoothly transition between quaternions for a camera object in three.js?

I'm confused as to why my camera isn't smoothly moving back. Upon refreshing the page, it moves back once with a smooth slerp animation. However, after that initial movement, it doesn't respond to any mousewheel input. I expect it to smoothly slerp forward and backward (as I scroll up and down) between the x quaternions.

export default class Experience {
    constructor(options = {}) {
    //...
        this.camera = new Camera();
        this.renderer = new Renderer(this.canvas);
        this.scrollTargetPosition = new THREE.Quaternion();
        this.scrollTargetPosition.setFromAxisAngle(new THREE.Vector3(0, 0, 1),0);

        this.onMouseScroll();
        this.animate();
    }

    onMouseScroll() {
        window.addEventListener("wheel", (event) => {
            if (event.wheelDelta > 0) {
                this.scrollTargetPosition.x = 0;
            } else {
                this.scrollTargetPosition.x = Math.PI / 2;
            }
        console.log("Target: " + this.scrollTargetPosition.x); //Images provided below
        console.log("Camera: " + this.camera.quaternion.x);
        });
    }

    animate() {
        this.camera.quaternion.slerp(this.scrollTargetPosition, 0.9);
        requestAnimationFrame(this.animate.bind(this));
        this.renderer.render(this.scene, this.camera);

    }
}

If I continuously scroll up multiple times, this is what the console logs show: https://i.sstatic.net/1aD5t.png

and when scrolling down:

https://i.sstatic.net/U3QWT.png

Answer №1

The issue lies in the mistaken assumption that a Quaternion can be treated like Euler angles, when in reality, they are two very different concepts.

It's important to understand that Quaternion.x does not represent the x-axis rotation in radians. Quaternions consist of a 4-dimensional combination of imaginary and real numbers, so it's best to avoid manipulating their x, y, z, w properties directly. Instead, utilize utility methods designed for specific tasks. The following method demonstrates how to set the x-axis rotation to either 0 or 90 degrees:

onMouseScroll() {
    let xAxis = new THREE.Vector3(1, 0, 0);

    window.addEventListener("wheel", (event) => {
        if (event.wheelDelta > 0) {
            this.scrollTargetPosition.setFromAxisAngle(xAxis, 0);
        } else {
            this.scrollTargetPosition.setFromAxisAngle(xAxis, Math.PI / 2);
        }
    });
}

Once this adjustment is made, you should be able to perform spherical interpolation as intended. However, it is advisable to replace the value of 0.9 with a smaller number like 0.1 to ensure smoother transition:

this.camera.quaternion.slerp(this.scrollTargetPosition, 0.9);

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 Vue/Vuetify wrapper component does not automatically pass on the `hide-details` parameter to the input component

I recently crafted a custom wrapper for the v-select input using Vuetify. Along with custom properties, I utilized the v-bind="$props"attribute to inherit all props. Upon testing, I observed that while this method applies to most props, it doesn ...

Each time I open my modal (Select Dynamic), my ajax query is triggered repetitively

Currently, I am developing a project in Laravel and focusing on the CRUD operations, specifically working on the Update functionality. I have a button within a modal that allows me to edit dates, including a dynamic select option. The table with the butto ...

What is the process for appending a file extension to a Next.js URL?

For instance, I am attempting to redirect the URL : https://example.com/data/publications to this : https://example.com/data/publications.json I made an attempt using Next.js redirection, but encountered difficulty when trying to add a string that does no ...

Securing page access for unlogged users using VueJS: A guide

As I continue to hone my skills in VueJs, I am experimenting with creating sample applications. Currently, I am working on a straightforward app that features a login page where users input their credentials to access their profile. However, I am strugglin ...

The perspective shifts as the windows.location is redirected to a new URL, yet the elements (objects) remain connected to the previous destination

When it comes to redirecting to a URL on PhoneGap for iOS, I have been using the following JavaScript code: function pedirTaxi(){ var direccion = $('#txtDireccion').val(); alert(direccion); window.location.href = "loading.html"; ...

Using JavaScript within WordPress to achieve a seamless scrolling effect

I am seeking to implement a Smooth Scroll effect on my website located at . The site is built on WordPress and I am facing difficulty in connecting JavaScript/jQuery in WordPress. I have come across various WordPress plugins, but they either do not meet my ...

Using either JavaScript or jQuery to capture the first second of a video file as a snapshot

Is it possible to use JavaScript or jQuery to capture the first second of a video (in any format like flv, mpg, mp4) and show it in an HTML page? ...

Retrieve JSON data sent via AJAX request in a Rails controller

I recently sent an ajax post request to receive json data, but I'm struggling to access that data in my rails controller. How can I properly retrieve this information? Below is the code snippet of how I posted the data using ajax: jQuery.ajax({ ...

How to extract styles from a string using PHP

There is a string that contains some inline styles within <P><span><font> tags <p style='color:red; font-size:21px'><span style='color:blue;'><font style='font-family:Arial'>This is a ...

Reduce numerical values within tables

How can I shorten the numbers displayed on json / datatable? I have extracted json data from a website, but the figures shown in the json are too detailed. For instance, instead of displaying 408.43324032, I simply want to show 408 or 408x. https://i.ss ...

Having trouble making a successful API call with an Authorization Token in Angular

I've been struggling to make an API call to retrieve current user details while attaching a token in the Authorization header. Unfortunately, every time I try, it fails with a 500 error response. The strange thing is, the same API call works perfectl ...

Open multiple accordion sections simultaneously

In my current setup, I have a paginated loop of elements that contains an accordion. The accordion is implemented using angular-ui-bootstrap. <div data-ng-repeat="m in results"> <div class="stuff_in_the_middle"> <accordion id="a ...

Using Jquery to toggle visibility and position of a button when clicked

I'm new to using Jquery and I've been able to create a button that shows a div and moves the button to the right when clicked. I have looked at similar questions about toggling visibility, but I also need to move the button back when it's cl ...

Optimal method for adjusting URL parameters using JavaScript

I am currently exploring different methods to modify URL parameters, but I haven't found the perfect solution yet. Initially, I attempted to achieve this using the following code: window.location.href = window.location.href + '?test'; Unf ...

It seems that the Bootstrap 4 Modal Pop up window is having difficulty closing

I recently completed a project on creating a matching game. After all the cards are successfully matched and the game finishes, a congratulatory modal pops up. However, I encountered an issue where the modal would not close after clicking the "Play Again" ...

Checkbox in Meteor always returns false after the template has been rendered

I've created a navigation bar with 2 options. One option is a checkbox and the other is a dropdown with a button (code provided below). The checkbox has the ID "inputMode" and the button has the ID "addNewObject" <div class="collapse navbar-colla ...

Encountering the error "Cannot read property 'header' of undefined" while conducting tests on Nodejs using supertest

In my server.js file, I have set up my express app. I tried to run a demo test in my test file using express, but unfortunately, the test did not run successfully. const request = require('supertest'); const express = require('express' ...

Issue with Discord.js (14.1) - Message Handling Unresponsive

After developing a sizable Discord Bot in Python, I decided to expand my skills and start learning JS. Despite thoroughly studying the documentation and comparing with my original Python Bot regarding intents, I am facing difficulties getting the message ...

Enhance the information within the textextjs plugin by incorporating additional data

I am attempting to invoke a function within the textextjs method- //my function function GetAreaTags() { return "some text"; } //textext initialization $('#territory').textext({ plugins: 'tags prompt focus autocomplete ajax', ...

JavaScript capable of storing vast quantities of data

Currently, I am receiving file chunks in byte format from my server and combining them into one variable on my frontend for downloading later. Unfortunately, I am unable to modify the server setup which sends files sliced into chunks. The issue arises whe ...