When the mouse is clicked, rotate the object along its axis using OBJ Loader in THREE.js

I am looking to add a feature where my object rotates on its axis when the mouse is dragged. The challenge I am facing is that I can only access my skull object within the function, which limits where I can place a rotation increment inside render().

Could anyone guide me on how to update the rotation of my object based on the variables mouseX and mouseY?

var loader = new THREE.OBJLoader();
    loader.load(
        'images/SKULL.obj',
        function(object) {
            var skull = object;
            scene.add(skull);
           skull.position.y = -50;
           skull.rotation.y += mouseY;
           skull.rotation.x += mouseX;




            skull.traverse(function (child) {
                //console.log(child);
                if (child instanceof THREE.Mesh) {
                    child.material = chrome;
                }
            });



        },
        function(xhr) {
            var loaded = (xhr.loaded / xhr.total * 100);
            loadPercentageText.innerHTML = parseInt(loaded) + "%";
            //console.log(loaded + " % loaded");
            if (loaded == 100) {
                document.body.classList.remove("loading");
                animate();
            }
        },
        function (error) {
            //console.log("Error");
        }
    );

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


   function onDocumentMouseMove( event ) {
        mouseX = ( event.clientX - windowHalfX ) / 2;
        mouseY = ( event.clientY - windowHalfY ) / 2;

      }



    function animate(obj) {
        requestAnimationFrame( animate );
        renderer.render( scene, camera );
    }

Answer №1

Make sure to adjust the mesh rotation and update the object matrix using Object3D.updateMatrix in this way:

function onDocumentMouseMove( event ) {
    var mouseX = window.innerWidth / 2 - event.clientX;
    var mouseY = window.innerHeight / 2 - event.clientY;
    mesh.rotation.y = Math.PI*2*mouseX/window.innerWidth;
    mesh.rotation.x = -Math.PI*2*mouseY/window.innerHeight;
    mesh.updateMatrix();
}

Take a look at the provided code snippet:

var renderer, camera, controls, scene;
var mesh;

function init(){
    renderer = new THREE.WebGLRenderer({canvas: document.getElementById('myCanvas'), antialias: true});   
    renderer.setClearColor(0x000044);        

    scene = new THREE.Scene();        
    camera = new THREE.OrthographicCamera(window.innerWidth/-2,window.innerWidth/2,window.innerHeight/-2,window.innerHeight/2, -1000, 1000);    
    
    resize();
    window.onresize = resize;

    var geometry = new THREE.BoxGeometry(100, 100, 1);
    var material = new THREE.MeshBasicMaterial({
        color: 0xFF1111,
    });
    mesh = new THREE.Mesh(geometry,material);
    scene.add(mesh);

    document.addEventListener( 'mousemove', onDocumentMouseMove, false );
}

function resize() {
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
}

function onDocumentMouseMove( event ) {
    var mouseX = window.innerWidth / 2 - event.clientX;
    var mouseY = window.innerHeight / 2 - event.clientY;
    mesh.rotation.y = Math.PI*2*mouseX/window.innerWidth;
    mesh.rotation.x = -Math.PI*2*mouseY/window.innerHeight;
    mesh.updateMatrix();
}   

function render() {    
    requestAnimationFrame( render );
    renderer.render( scene, camera );
}

init(); render();
<script src="https://threejs.org/build/three.min.js"></script>
<canvas id="myCanvas"></canvas>

Answer №2

In one of my past projects, I implemented a similar approach to handling object rotation. Here is an overview of how I did it:

To manage movement data, I created a variable called mouseRotationData:

var mouseRotationData = {
    startX : 0,
    startY : 0,
    endX : 0,
    endY : 0,
    x : 0,
    y : 0
};

Within the onDocumentMouseMove() function, I included the following code snippet:

mouseRotationData.endX = event.clientX;
mouseRotationData.endY = event.clientY;
mouseRotation();
mouseRotationData.startX = event.clientX;
mouseRotationData.startY = event.clientY;

Lastly, within the mouseRotation() function, I handled the actual object rotation logic:

var lim = 360;
var rFactor = lim / window.innerWidth;

mouseRotationData.y = (mouseRotationData.endX - mouseRotationData.startX) * rFactor;
mouseRotationData.x = (mouseRotationData.endY - mouseRotationData.startY) * rFactor;

var rot_x = mouseRotationData.x * (Math.PI / 180); // in radians
var rot_y = mouseRotationData.y * (Math.PI / 180);

This implementation provides the rotation values for both the x and y axes.

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 tool tip feature is not recognizing line breaks

I've encountered an issue with the tooltip in my project. Despite trying various solutions found on stackoverflow, I am still unable to resolve it. In my ReactJS application, I am dynamically creating elements using createElement and applying the too ...

Reduce the density of x-axis labels in highcharts

Do you have any input on Highcharts? This chart belongs to me: https://i.sstatic.net/OAjJJ.png I am looking to reduce the density of x-axis labels, similar to the y-axis. Your assistance is greatly appreciated. Edit: for instance, take a look at this ...

Notifying with Jquery Alert after looping through routes using foreach loop

I am trying to create a jQuery alert message that displays after clicking on a dynamically generated button in the view using a foreach loop. The issue I am facing is that only the first button in the loop triggers the alert, while the subsequent buttons ...

Expansive image coverage

My footer design includes a rounded left image, a repeating middle section, and a rounded right image. How can I ensure that it scales perfectly responsively without overlapping? Ideally, the solution would involve adjusting the width of the middle section ...

What is the most effective method for implementing a debounce effect on a field in React or React Native?

Currently, I am working on implementing a debounce effect in my useEffect. The issue is that the function inside it gets called as soon as there is a change in the input value. useEffect(() => { if (inputValue.length > 0) { fn(); ...

Having trouble with React testing-library: Why is the file upload empty when testing a PDF file?

While testing file upload with react-testing-library, I encountered an issue where the log indicated that the file was empty (even though it worked in the browser). After researching various docs and bugs, I discovered that since tests run on Node.js, the ...

Preventing unauthorized access to files in ExpressJS public directories

Is there a way to conceal files served by the Node server? Despite my attempts to redirect certain files and directories, Express 4.X does not seem to cooperate. I have also experimented with sending 4XX HTTP responses when specific files are requested, bu ...

How can I add header and footer elements in dot.js template engine?

My understanding was that all I needed to do (as per the documentation on GitHub) was to insert {{#def.loadfile('/snippet.txt')}} into my template like this: <!DOCTYPE html> <html> <head> <meta charset=&a ...

Refreshing the page causes JavaScript to fail loading

Recently, I encountered a puzzling error. Upon visiting this link The carousel fails to load properly near the bottom of the page. However, if you click on the logo or navigate back to the home page, it works fine. Additionally, performing a command + r ...

Navigating through the elements of the DOM

Here is a function that deletes people from a list when you click on a certain part of the form: function ParticipantsDeleteClick(model, url) { for (i in model.Participants) { $("#delete" + i).click(function () { $.ajax({ url: url, ...

Error encountered when attempting to resolve Angular UI Router provider

Having difficulty with integrating a resolve into a state using Angular UI router. Strangely, it works perfectly fine in another section of my code. I've organized my code into different component areas structured like this: /app /component-dashbo ...

Is it considered poor form to use res.locals in Node.js with Express?

Is it considered bad practice to use res.locals as shown in this code example? Are there potential issues that could arise from using it in this manner? app.use((req, res, next) => { const session = req.cookies.session if (session) { db. ...

What is the method for extracting the value of a JavaScript variable using the .Net framework or C# programming language?

Looking at the code snippet below, I am trying to extract the values of title and videoId. These elements are part of the session, which is nested within units. I am unsure how to retrieve their values using C# or the .Net framework. Can anyone help m ...

Switchable radio options

Currently, I am creating a form containing multiple options that are mutually exclusive. However, none of these options are mandatory. That is why I want to enable the user to uncheck a selected radio button by simply clicking on it again. This way, all th ...

Using Vue.js to make asynchronous API requests using Axios

I am facing an issue with two versions of code, where the second version is not functioning as expected. I suspect it may be due to a contextual problem that I am unable to pinpoint. The first version of the code works fine: // Fist version (it works) met ...

Having trouble with installing Angular JS on my computer

On my machine, I have successfully installed node.js version v0.12.0. However, when attempting to run sudo npm install, I encountered the following errors: npm ERR! install Couldn't read dependencies npm ERR! Darwin 14.0.0 npm ERR! argv "node" "/usr/ ...

Enable compatibility with high resolution screens and enable zoom functionality

My goal is to ensure my website appears consistent on all screen sizes by default, while still allowing users to zoom in and out freely. However, I've encountered challenges with using percentages or vh/vw units, as they don't scale elements prop ...

JQuery ID Media Queries: Enhancing responsive design with targeted

Is it possible to integrate a media query into the selection of an ID using JQuery? For example: $('#idname') $('@media (max-width: 767px) { #idname }') In essence, can you target the #idname with that specified media query in JQuery ...

Adjust Tinymce size automatically when a key is held down for a prolonged period of

Having trouble with tinymce not automatically resizing when certain characters are pressed repeatedly. However, the height adjusts after releasing the key. Is there a method to auto resize tinymce during the key down event? I am utilizing angularjs ui-tin ...

Guide on exporting member formModule in angular

After compiling my code in cmd, an error message is displayed: ERROR in src/app/app.module.ts(3,10): error TS2305: Module '"C:/Users/Amir_JKO/my-first-app/node_modules/@angular/forms/forms"' does not have an exported member 'formModul ...