angularthree.js

Three Js when rotation and Scalling then mesh object psotion changes


When I object rotation or Scalling with that control then why its change's position also, See below Video

https://drive.google.com/file/d/1SZ26GRon5ko8cHAG8taeeN6pP8i0xb1Z/view

I want to below video result in my current code

https://drive.google.com/file/d/1iy3216DTpsDREuXIvGG4JpD5iqRN-lQc/view

In older packager version its perfect working but new version not work

Older Version: "^0.96.0" Newer Version: "^0.167.1",

This is my three js environment setup code

// canvas initialization
  async init() {
    await this.addScene();
    await this.addRenderer();
    await this.addCamera();
    await this.addLight();
    await this.addGridHelper();
    await this.addControl();
    await this.addTransformControl();
    await this.addDragControl();
  }

  addScene() {
      this.scene = new THREE.Scene();
  }

  addRenderer() {
      this.renderer = new THREE.WebGLRenderer({
          antialias: true,
          canvas: this.canvas,
          alpha: true,
      });
      // this.renderer.setClearColor(0xffffff, 1);
      this.renderer.setPixelRatio(window.devicePixelRatio);
      this.renderer.setSize(this.canvas.clientWidth, this.canvas.clientHeight);
  }

  addCamera() {
      const aspectRatio = this.getAspectRatio();
      this.camera = new THREE.PerspectiveCamera(45, aspectRatio, 0.1, 2000);
      this.camera.position.set(0, 4, 6);
      this.camera.lookAt(0, 0, 0);

  }

  addLight() {
    var light;
    this.scene.add(new THREE.AmbientLight(0x666666));
    
    var lightobjgeo = new THREE.SphereGeometry(0.3, 4, 2);
    var material = new THREE.MeshPhongMaterial({
        color: new THREE.Color().setHSL(Math.random(), 1, 0.75),
        flatShading: true,
        specular: 0x111111,
        shininess: 0
    });
    
    this.lightobj = new THREE.Mesh(lightobjgeo, material);
    this.lightobj.position.set(2, 8, 4);
    this.lightobj.name = 'light';

    light = new THREE.DirectionalLight(0xdfebff, Math.PI * 2);
    light.position.copy(this.lightobj.position);
    light.castShadow = true;
    light.shadow.mapSize.width = 1500;
    light.shadow.mapSize.height = 1500;
    light.shadow.camera.near = 0.5;
    light.shadow.camera.far = 500;

    this.lightobj.add(light);
    this.scene.add(this.lightobj);
    this.updateObjectList();
  }
  copyValue(tmp) {
    var dummy = document.createElement("input");
    document.body.appendChild(dummy);
    dummy.setAttribute("id", "dummy_id");
    document.getElementById("dummy_id").setAttribute('value', tmp);
    dummy.select();
    document.execCommand("copy");
    document.body.removeChild(dummy);
    this.utils.showSuccess('Copied', false, 2000);
  }
  addGridHelper() {
      this.ground = new THREE.GridHelper(40, 40);
      this.ground.name = "ground";
      this.scene.add(this.ground);
  }

  addControl() {
      this.orbitcontrols = new OrbitControls(this.camera, this.renderer.domElement);
      this.orbitcontrols.rotateSpeed = 1;
      this.orbitcontrols.zoomSpeed = 2;
      this.orbitcontrols.panSpeed = 1;
      this.orbitcontrols.minDistance = 1;
      this.orbitcontrols.maxDistance = 100;
      this.orbitcontrols.enableKeys = false;
      this.orbitcontrols.update();

      this.orbitControlChangeRef = this.renderCanvas.bind(this);
      this.orbitcontrols.addEventListener('change', this.orbitControlChangeRef);
  }

  addTransformControl() {
    this.transformcontrols = new TransformControls(this.camera, this.renderer.domElement);
    this.transformcontrols.addEventListener('change', this.renderCanvas.bind(this));

    this.transformcontrols.addEventListener('mouseDown', () => {
        this.orbitcontrols.enabled = false;
    }); 
    this.transformcontrols.addEventListener('mouseUp', () => {
        this.orbitcontrols.enabled = true;
        this.getObjectPosition();
        this.getObjectRotation();
        this.getObjectScale();
    });

    this.scene.add(this.transformcontrols);
  }

  addDragControl() {
    // Filter only Mesh objects from the scene
    const meshObjects = this.objects.filter(obj => obj instanceof THREE.Mesh);
  
    // Initialize DragControls with filtered mesh objects
    this.dragControls = new DragControls(meshObjects, this.camera, this.renderer.domElement);
  
    this.dragControls.deactivate();
    this.dragControls.activate();
  
    // Add event listeners for hover effects
    this.dragControls.addEventListener('hoveron', (e) => {
      // Only apply wireframe effect if the object has material and is a Mesh
      if (e.object instanceof THREE.Mesh && e.object.material) {
        this.onHoverObject(e); // Call your custom hover logic
      }
    });
  
    // Disable DragControls while TransformControls are active
    this.transformcontrols.addEventListener('dragstart', () => {
      this.dragControls.enabled = false;
    });
  
    this.transformcontrols.addEventListener('dragend', () => {
      this.dragControls.enabled = true;
    });
  }

  renderCanvas() {
      this.renderer.render(this.scene, this.camera);
  }

This is my Object Load From the API Code

 loadStl(path) {
    return new Promise(resolve => {
      var that = this;
      var loader = new STLLoader();
      loader.load(path, function (geometry) {
        geometry.center();
        var material = new THREE.MeshPhongMaterial({ color: 0xff5533, specular: 0x111111, shininess: 100,flatShading: true });
        var mesh = new THREE.Mesh(geometry, material);
        mesh.name = "stl";
        mesh.position.set(0, 0, 0);
        mesh.rotation.set(0, 0, 0);
        mesh.castShadow = true;
        that.scene.add(mesh);
        that.updateObjectList();
        that.renderCanvas();  
        resolve(null);
      });
    });
  }

This is my Hover Object Code

  onHoverObject(event) {
    this.delayHideTransform();
    this.transformcontrols.attach(event.object);
    this.activatedObject = event.object;
    this.resetPanel();
    this.isAttached = true;
    // to get position rotation and scale value of hovered object
    this.getObjectPosition();
    this.getObjectRotation();
    this.getObjectScale();
    this.getMaterial();
    if (this.activatedObject.name == 'text') {
      this.getTextGeometry();
      this.textEditor = true;
    }
    this.cancelHideTransorm();
  }

This is my Rotation and Scalling Code


  getObjectPosition() {
    console.log("object Position Changes");
    if (this.activatedObject) {
      var x: number = Number(parseFloat(this.activatedObject.position.x).toFixed(1));
      var y: number = Number(parseFloat(this.activatedObject.position.y).toFixed(1));
      var z: number = Number(parseFloat(this.activatedObject.position.z).toFixed(1));
      this.posX = Math.round(x * 10);
      this.posY = Math.round(y * 10);
      this.posZ = Math.round(z * 10);
      if (this.posX > 200 || this.posX < -200) {
        this.changePosition();
      }
      if (this.posY > 200 || this.posY < -200) {
        this.changePosition();
      }
      if (this.posZ > 200 || this.posZ < -200) {
        this.changePosition();
      }
    }
  }

  getObjectRotation() {
    console.log("Object Rotation Changes");
    if (this.activatedObject) {
      var x: number = Number(parseFloat(this.activatedObject.rotation.x).toFixed(1));
      var y: number = Number(parseFloat(this.activatedObject.rotation.y).toFixed(1));
      var z: number = Number(parseFloat(this.activatedObject.rotation.z).toFixed(1));
      this.degX = Math.round(x * 10);
      this.degY = Math.round(y * 10);
      this.degZ = Math.round(z * 10);
      if (this.degX > 63 || this.degX < -63) {
        this.changeRotation();
      }
      if (this.degY > 63 || this.degY < -63) {
        this.changeRotation();
      }
      if (this.degZ > 63 || this.degZ < -63) {
        this.changeRotation();
      }
    }
  }

  getObjectScale() {
    if (this.activatedObject) {
      var x: number = Number(parseFloat(this.activatedObject.scale.x).toFixed(1));
      var y: number = Number(parseFloat(this.activatedObject.scale.y).toFixed(1));
      var z: number = Number(parseFloat(this.activatedObject.scale.z).toFixed(1));
      this.scaleX = Math.round(x * 10);
      this.scaleY = Math.round(y * 10);
      this.scaleZ = Math.round(z * 10);
      if (this.scaleX > 100 || this.scaleX < 1) {
        this.changeScale();
      }
      if (this.scaleY > 100 || this.scaleY < 1) {
        this.changeScale();
      }
      if (this.scaleZ > 100 || this.scaleZ < 1) {
        this.changeScale();
      }
    }
  }



This is my Changes Translate to Rotate and Scalling

HTML

 <div class="three-display-row">
                  <div class="three-display-flex">
                    <p class="three-display-p">Movements :</p>
                    <svg role="img" *ngIf="transformMode == 'move'" xmlns="http://www.w3.org/2000/svg"
                      viewBox="0 0 576 512" class="three-display-eye" id="mvmnt" (click)="setTransformMode('move')">
                      <path fill="#61B1FF"
                        d="M572.52 241.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400a144 144 0 1 1 144-144 143.93 143.93 0 0 1-144 144zm0-240a95.31 95.31 0 0 0-25.31 3.79 47.85 47.85 0 0 1-66.9 66.9A95.78 95.78 0 1 0 288 160z">
                      </path>
                    </svg>
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" class="three-display-eye" id="mvmnt"
                      (click)="setTransformMode('move')" *ngIf="transformMode != 'move'">
                      <path fill="white"
                        d="M320 400c-75.85 0-137.25-58.71-142.9-133.11L72.2 185.82c-13.79 17.3-26.48 35.59-36.72 55.59a32.35 32.35 0 0 0 0 29.19C89.71 376.41 197.07 448 320 448c26.91 0 52.87-4 77.89-10.46L346 397.39a144.13 144.13 0 0 1-26 2.61zm313.82 58.1l-110.55-85.44a331.25 331.25 0 0 0 81.25-102.07 32.35 32.35 0 0 0 0-29.19C550.29 135.59 442.93 64 320 64a308.15 308.15 0 0 0-147.32 37.7L45.46 3.37A16 16 0 0 0 23 6.18L3.37 31.45A16 16 0 0 0 6.18 53.9l588.36 454.73a16 16 0 0 0 22.46-2.81l19.64-25.27a16 16 0 0 0-2.82-22.45zm-183.72-142l-39.3-30.38A94.75 94.75 0 0 0 416 256a94.76 94.76 0 0 0-121.31-92.21A47.65 47.65 0 0 1 304 192a46.64 46.64 0 0 1-1.54 10l-73.61-56.89A142.31 142.31 0 0 1 320 112a143.92 143.92 0 0 1 144 144c0 21.63-5.29 41.79-13.9 60.11z"
                        class=""></path>
                    </svg>
                  </div>
                  <div class="three-display-flex">
                    <p class="three-display-p">Rotations :</p>
                    <svg role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class="three-display-eye"
                      id="rotation1" (click)="setTransformMode('rotate')" *ngIf="transformMode == 'rotate'">
                      <path fill="#61B1FF"
                        d="M572.52 241.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400a144 144 0 1 1 144-144 143.93 143.93 0 0 1-144 144zm0-240a95.31 95.31 0 0 0-25.31 3.79 47.85 47.85 0 0 1-66.9 66.9A95.78 95.78 0 1 0 288 160z">
                      </path>
                    </svg>
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" class="three-display-eye" id="rotation1"
                      (click)="setTransformMode('rotate')" *ngIf="transformMode != 'rotate'">
                      <path fill="white"
                        d="M320 400c-75.85 0-137.25-58.71-142.9-133.11L72.2 185.82c-13.79 17.3-26.48 35.59-36.72 55.59a32.35 32.35 0 0 0 0 29.19C89.71 376.41 197.07 448 320 448c26.91 0 52.87-4 77.89-10.46L346 397.39a144.13 144.13 0 0 1-26 2.61zm313.82 58.1l-110.55-85.44a331.25 331.25 0 0 0 81.25-102.07 32.35 32.35 0 0 0 0-29.19C550.29 135.59 442.93 64 320 64a308.15 308.15 0 0 0-147.32 37.7L45.46 3.37A16 16 0 0 0 23 6.18L3.37 31.45A16 16 0 0 0 6.18 53.9l588.36 454.73a16 16 0 0 0 22.46-2.81l19.64-25.27a16 16 0 0 0-2.82-22.45zm-183.72-142l-39.3-30.38A94.75 94.75 0 0 0 416 256a94.76 94.76 0 0 0-121.31-92.21A47.65 47.65 0 0 1 304 192a46.64 46.64 0 0 1-1.54 10l-73.61-56.89A142.31 142.31 0 0 1 320 112a143.92 143.92 0 0 1 144 144c0 21.63-5.29 41.79-13.9 60.11z"
                        class=""></path>
                    </svg>
                  </div>
                  <div class="three-display-flex mb-1">
                    <p class="three-display-p">Scale :</p>
                    <svg role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class="three-display-eye"
                      id="scale1" (click)="setTransformMode('scale')" *ngIf="transformMode == 'scale'">
                      <path fill="#61B1FF"
                        d="M572.52 241.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400a144 144 0 1 1 144-144 143.93 143.93 0 0 1-144 144zm0-240a95.31 95.31 0 0 0-25.31 3.79 47.85 47.85 0 0 1-66.9 66.9A95.78 95.78 0 1 0 288 160z">
                      </path>
                    </svg>
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" class="three-display-eye" id="scale1"
                      (click)="setTransformMode('scale')" *ngIf="transformMode != 'scale'">
                      <path fill="white"
                        d="M320 400c-75.85 0-137.25-58.71-142.9-133.11L72.2 185.82c-13.79 17.3-26.48 35.59-36.72 55.59a32.35 32.35 0 0 0 0 29.19C89.71 376.41 197.07 448 320 448c26.91 0 52.87-4 77.89-10.46L346 397.39a144.13 144.13 0 0 1-26 2.61zm313.82 58.1l-110.55-85.44a331.25 331.25 0 0 0 81.25-102.07 32.35 32.35 0 0 0 0-29.19C550.29 135.59 442.93 64 320 64a308.15 308.15 0 0 0-147.32 37.7L45.46 3.37A16 16 0 0 0 23 6.18L3.37 31.45A16 16 0 0 0 6.18 53.9l588.36 454.73a16 16 0 0 0 22.46-2.81l19.64-25.27a16 16 0 0 0-2.82-22.45zm-183.72-142l-39.3-30.38A94.75 94.75 0 0 0 416 256a94.76 94.76 0 0 0-121.31-92.21A47.65 47.65 0 0 1 304 192a46.64 46.64 0 0 1-1.54 10l-73.61-56.89A142.31 142.31 0 0 1 320 112a143.92 143.92 0 0 1 144 144c0 21.63-5.29 41.79-13.9 60.11z"
                        class=""></path>
                    </svg>
                  </div>
                </div>


TS

 setTransformMode(type) {
    switch (type) {
      case 'move':
        this.transformMode = type;
        this.transformcontrols.setMode("translate");
        break;
      case 'rotate':
        this.transformMode = type;
        this.transformcontrols.setMode("rotate");
        break;
      case 'scale':
        this.transformMode = type;
        this.transformcontrols.setMode("scale");
        break;
    }
  }


Solution

  • You probably forgot to deactivate your DragControls. You should deactivate them when you want your TransformControls to be able to transform the geometry without dragging it around at the same time.