Adjusting the THREE.js function to accommodate a new starting rotation angle

I am currently in the process of converting the code from into an AFRAME component.

Everything works fine when the initial rotation is '0 0 0', but I am now attempting to set a different initial rotation.

Thanks to @Piotr, who created a fiddle for me

Essentially, my goal is to define that initial rotation and then have the object rotate on click and drag using the remaining function.

AFRAME.registerComponent('drag-rotate',{
    schema : { 
      mouseSpeed : {default:1},
      touchSpeed : {default:2},
      rotation   : {type: 'vec3'},
      disabled: {default: false}
    },
    windowHalfX: window.innerWidth / 2,
    windowHalfY: window.innerHeight / 2,
    targetRotationX:0,
    targetRotationOnMouseDownX:0,
    targetRotationY:0,
    targetRotationOnMouseDownY: 0,
    mouseX:0,
    mouseXOnMouseDown:0,
    mouseY: 0,
    mouseYOnMouseDown: 0,
    init : function(){
      this.ifMouseDown = false
      document.addEventListener('touchstart',this.onTouchStart.bind(this))
      document.addEventListener('touchend',this.onTouchEnd.bind(this))
      document.addEventListener('touchmove',this.onTouchMove.bind(this))
      document.addEventListener('mousedown',this.OnDocumentMouseDown.bind(this))
      window.addEventListener( 'resize', this.onWindowResize.bind(this) )
    },
    update: function (oldData) {
      if(!AFRAME.utils.deepEqual(oldData.rotation, this.data.rotation)){
        this.el.setAttribute('rotation',  this.data.rotation)
        this._targetRotation = this.el.object3D.rotation.clone()
        this.targetRotationX = this._targetRotation.x
        this.targetRotationY = this._targetRotation.y
      }
    },
    remove: function() {
      
      document.removeEventListener('touchstart',this.onTouchStart.bind(this))
      document.removeEventListener('mousedown',this.OnDocumentMouseDown.bind(this))
      window.removeEventListener( 'resize', this.onWindowResize.bind(this))
    },
    onWindowResize: function () {
      this.windowHalfX = window.innerWidth / 2
      this.windowHalfY = window.innerHeight / 2
    },
    OnDocumentMouseDown : function(event){

      this.ifMouseDown = ['A-SCENE', 'CANVAS'].includes(event.target?.tagName)

      if(this.ifMouseDown){
        document.addEventListener('mouseup',this.OnDocumentMouseUp.bind(this))
        document.addEventListener('mousemove',this.OnDocumentMouseMove.bind(this))
        this.mouseXOnMouseDown = event.clientX - this.windowHalfX
        this.targetRotationOnMouseDownX = this.targetRotationX

        this.mouseYOnMouseDown = event.clientY - this.windowHalfY
        this.targetRotationOnMouseDownY = this.targetRotationY
      }

    },
    OnDocumentMouseUp : function(){
      this.ifMouseDown = false
      document.removeEventListener('mouseup',this.OnDocumentMouseUp.bind(this))
      document.removeEventListener('mousemove',this.OnDocumentMouseMove.bind(this))
    },
    OnDocumentMouseMove : function(event)
    {
      if(this.ifMouseDown){
        this.mouseX = event.clientX - this.windowHalfX;
        this.mouseY = event.clientY - this.windowHalfY;

        this.targetRotationY = this.targetRotationOnMouseDownY + (this.mouseY - this.mouseYOnMouseDown) * this.data.mouseSpeed/1000
        this.targetRotationX = this.targetRotationOnMouseDownX + (this.mouseX - this.mouseXOnMouseDown) * this.data.mouseSpeed/1000
      }
    },
    onTouchStart: function(event){  

      if (event.touches.length == 1) {
        this.ifMouseDown = ['A-SCENE', 'CANVAS'].includes(event.target?.tagName)
        this.x_cord = event.touches[ 0 ].pageX
        this.y_cord = event.touches[ 0 ].pageY

        document.addEventListener('touchend',this.onTouchEnd.bind(this))
        document.addEventListener('touchmove',this.onTouchMove.bind(this))
        this.mouseXOnMouseDown = event.touches[ 0 ].pageX - this.windowHalfX
        this.targetRotationOnMouseDownX = this.targetRotationX
        this.mouseYOnMouseDown = event.touches[ 0 ].pageX - this.windowHalfY
        this.targetRotationOnMouseDownY = this.targetRotationY

      }
    },
    onTouchMove: function(event){
      if(this.ifMouseDown){
        this.mouseX = event.touches[ 0 ].pageX - this.windowHalfX;
        this.mouseY = event.touches[ 0 ].pageY - this.windowHalfY;

        this.targetRotationY = this.targetRotationOnMouseDownY + (this.mouseY - this.mouseYOnMouseDown) * this.data.touchSpeed/1000
        this.targetRotationX = this.targetRotationOnMouseDownX + (this.mouseX - this.mouseXOnMouseDown) * this.data.touchSpeed/1000
      }  
    },
    onTouchEnd: function(event){
      document.removeEventListener('touchend',this.onTouchEnd.bind(this))
      document.removeEventListener('touchmove',this.onTouchMove.bind(this))
      this.ifMouseDown = false
    },
    tick: function(){

      if(this.data.disabled)
        return
 
     this.el.object3D.rotation.y += ( this.targetRotationX - this.el.object3D.rotation.y ) * 0.1

     this.finalRotationY = (this.targetRotationY - this.el.object3D.rotation.x)
    
     if (this.el.object3D.rotation.x  <= 1 && this.el.object3D.rotation.x >= -1 ) 
      this.el.object3D.rotation.x += this.finalRotationY * 0.1
        
     if (this.el.object3D.rotation.x  > 1 ) 
      this.el.object3D.rotation.x = 1
        
     if (this.el.object3D.rotation.x  < -1 ) 
      this.el.object3D.rotation.x = -1
      
    },
  });

The angle I initially established with AFRAME in the update function differs from the one set here – specifically, when this component is disabled

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

With it enabled

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

If I zero these values as in the example code, then the rotation becomes '0 0 0' and functions normally.

    this.el.setAttribute('rotation',  this.data.rotation)
    this._targetRotation = this.el.object3D.rotation.clone()
    this.targetRotationX = 0
    this.targetRotationY = 0

Answer №1

Wow, this incredible spell did the trick!

 With a flick of my wand, I added some magic to the rotation of this object: 
 this.el.object3D.rotation.y += ( (this._targetRotation.y + this.targetRotationX) - this.el.object3D.rotation.y ) * 0.1
 I marveled as the finalRotationY emerged from the mystical energy: ((this._targetRotation.x + this.targetRotationY) - this.el.object3D.rotation.x)

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

JavaScript code to enforce a 100% page zoom setting

After developing a small game in Canvas, I encountered an issue. Some users with their default zoom level set to something other than 100% are unable to view the entire game page. I attempted to resolve this by using the following CSS: zoom: 100%; This ...

JavaScript in fullscreen mode for Internet Explorer

I'm trying to make sure that this code snippet... $('#gatewayDimmer').width($('html').width()); $('#gatewayDimmer').height($('html').height()); $('#gatewayDimmer').css('display','block& ...

What is the best way to implement an Angular application within the child routes of another Angular application?

Is it possible to load an Angular app using lazy-loading (when a specific route is hit by users) into another Angular app without compiling the first one for use in the second? This is the Routing-Module of the app to nest into an Angular app: const upgr ...

Performing array reduction and summation on objects in JavaScript

Data Analysis: dataSet: [], models: [ { id: 1, name: "samsung", seller_id: 1, count: 56 }, { id: 1, name: "samsung", seller_id: 2, count: 68 }, { id: 2, name: "nokia", seller_id: 2, count: 45 }, { id: 2, name: "nokia", seller_id: 3, count: ...

Encountering a Nuxt error where properties of null are being attempted to be read, specifically the 'addEventListener' property. As a result, both the default

Currently, I am utilizing nuxt.js along with vuesax as my UI framework. I made particular adjustments to my default.vue file located in the /layouts directory by incorporating a basic navbar template example from vuesax. Subsequently, I employed @nuxtjs/ ...

Unlock the secrets of recovering deleted data from a text area in Kendo UI Angular

Currently working with Kendo UI for Angular, I need to capture deleted content and remove it from another text area within the same component. My project is using Angular-13. I'm stuck on how to accomplish this task. Any suggestions would be greatly ...

Exploring the use of properties in JavaScript

I recently began learning Vue.js 2, but I encountered an issue when passing props to a child component. Here's the code snippet where I pass the prop: <div class="user"> <h3>{{ user.name }}</h3> <depenses :user-id="user.id"&g ...

Caution: It is not possible to make changes to a component (`App`) during the rendering of another component (`History

I am currently in the process of creating a tic tac toe game, but I'm encountering an error that is preventing me from updating the history. Despite following a tutorial on skillshare.com and mirroring the steps exactly, the error persists. I must men ...

Developing a custom logging middleware with morgan

I am trying to develop a middleware using morgan. I have attempted to export the middleware function and then require it in app.js. However, I am facing an issue where it is not working as expected. Middleware: const morgan = require('morgan&apos ...

Unable to perform dynamic query with $in operator in Mongoose find method

I am currently utilizing Node.js along with Mongoose version 5+ to create a dynamic query in my database. The variable filterField represents the field name, while filterValues is an array. Here is an example of how my code looks: if (req.currentUser.acti ...

Dealing with multiple parameters using React Router

I work with two main components: the AddList component and the DetailList component. The functionality I have set up involves a list of AddList components, each containing a button in every li element. When a user clicks on any button, the corresponding ID ...

Sharing the outcome of a $.get request with another function for optimal results

I am facing an issue with the callback function of the jquery $.get() ajax function. Currently, I am working with the DataTables plugin and attempting to implement the "expanding row to see children details" example from (https://www.datatables.net/exam ...

Which specific transitionend (or animationend) event should I use for this application?

I'm feeling a bit lost when it comes to using transitionend (or if I should be using animationend in this scenario). I'm not sure whether to utilize var, node, or box. Essentially, I am a complete beginner in this case. My goal is to have my div ...

What is the best way to ensure that navigation takes up the full width of the screen in pixels when

Trying to use jQuery to set a specific pixel width for my Bootstrap navbar that spans the entire width of the browser window. However, encountering some bugs as the width needs to be recalculated whenever the browser is resized. Currently, I have this cod ...

Combining multiple HTML elements onto a single page with just one function

I am trying to dynamically import specific HTML content into a new page, rather than the entire page itself. The issue I am encountering is that I have to create a document load function for each individual item I want to import. Is there a more efficient ...

What are the advantages of retrieving a complete category tree, including all categories and sub-categories, versus retrieving only the necessary branches as required?

My query is not centered around terminology accuracy, but rather on the goal of presenting a tiered structure consisting of categories, sub-categories, and sub-subcategories. In total, there are approximately 100 different categories and their respective ...

Issue with React and JavaScript: Object is displayed on the console briefly before disappearing

I am having an issue with my sign up page where the console log of the two fields disappears after a second. I would appreciate any assistance on this matter. Below is the code for the sign-up form: export default function SignUp() { const [firstNam ...

Storing repeated inputs in local storage multiple times

I am working on a feature where I need to store data in local storage multiple times using a dropdown menu and some input fields. Currently, I am able to retrieve all the values from the input fields and see them in the console log. My goal is to save thes ...

Encountering a post AJAX issue in Spring JAVA

I have successfully implemented MVC spring and now I want to consume it with SAPUI5 (javascript) using AJAX. However, I encountered an error "415 (Unsupported Media Type)". I have used swagger in spring to test CRUD operations. In swagger, I was able to in ...

Strategies for retaining additional fields added via JavaScript when the page is refreshed

var newField = document.createElement("lastExp"); newField.innerHTML = 'insert new form field HTML code here'; document.getElementById("lastExp").appendChild(newField); I have a button that adds an additional form field with a simple click. ...