I have a Javascript project which applies Matrix4 transformations to Three.js objects. The transformations are acting awry, what’s wrong with my code?

As stated in the title of this post, whenever I try to apply any of the below transformations to each of the cubes created in the addGUIControls() function they act in unexpected ways. When I apply makeScale() in the applyScalingCube() function it stretches the cube but also changes its position as well as oscillating in the scaling it does rather than in a linear fashion in accordance with the sliders in the GUI. I’ll attach a picture for each of the other awry transformations to give an idea. If any of you need to see how the rest of the scene was set up let me know. I ask this question since this is a project and some of my classmates have done the code in a similar way and theirs works. I don’t know if it’s because my environment (I’m using webstorm) isn’t set up properly. Before posting this I reset it to its default settings but it didn’t fix the issues. I also want to add I have separate inverse functions of each of the transformations which also are acting entirely awry but I want the first four transformations addressed. They do not affect the state of the initial normal functions unless the inverse buttons are toggled.

function applyScaling(cube, { scaleX, scaleY, scaleZ }) {
  const scaleMatrix = new THREE.Matrix4().makeScale(scaleX, scaleY, scaleZ);
  cube.matrix.identity();
  cube.applyMatrix4(scaleMatrix);
  render();
}

Scaled cube overscaled

Scaled Cube and Translated(unexpected behavior, it shouldn’t move)

function applyTranslation(cube, { translateX, translateY, translateZ }) {
  const translationMatrix = new THREE.Matrix4().makeTranslation(translateX, translateY, 
  translateZ);
  cube.matrix.identity();
  cube.applyMatrix4(translationMatrix);
  render();
}

Compounded Translation

(Translation seems to stack and not adhere to a linear mode of movement in alignment with the slider.)

function applyRotation(cube, { rotateY, rotateZ }) {
  const rotationYMatrix = new THREE.Matrix4().makeRotationY(rotateY);
  const rotationZMatrix = new THREE.Matrix4().makeRotationZ(rotateZ);
  cube.matrix.identity();
  cube.applyMatrix4(rotationYMatrix);
  cube.applyMatrix4(rotationZMatrix);
  render();
}

Unexpected Rotation Behavior

(It appears to rotate around the origin rather than its center and it also seems to compound rather than stop at the bounds of the slider)

function applyShear(cube, { shearX, shearY }) {
  const shearMatrix = new THREE.Matrix4().set(
        1, shearX, 0, 0,
        shearY, 1, 0, 0,
        0, 0, 1, 0,
        0, 0, 0, 1
  );
  cube.matrix.identity();
  cube.applyMatrix4(shearMatrix);
  render();
}

Unexpected Shear Behavior

(Also appears to compound the shear of the cube)

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


function addGUIControls() {
gui = new GUI();

cubes.forEach((cube, index) => {
  const cubeFolder = gui.addFolder(`Cube ${index + 1}`);
  const transform = {
    scaleX: 1,
    scaleY: 1,
    scaleZ: 1,
    translateX: 0,
    translateY: 0,
    translateZ: 0,
    rotateY: 0,
    rotateZ: 0,
    shearX: 0,
    shearY: 0
  };

  // Scaling Controls
  cubeFolder.add(transform, 'scaleX', 0.5, 3).name('Scale X').onChange(() => applyScaling(cube, transform));
  cubeFolder.add(transform, 'scaleY', 0.5, 3).name('Scale Y').onChange(() => applyScaling(cube, transform));
  cubeFolder.add(transform, 'scaleZ', 0.5, 3).name('Scale Z').onChange(() => applyScaling(cube, transform));

  // Inverse Scale
  cubeFolder.add({ inverseScale: () => applyInverseScaling(cube) }, 'inverseScale').name('Inverse Scale');

  // Translation Controls
  cubeFolder.add(transform, 'translateX', -5, 5).name('Translate X').onChange(() => applyTranslation(cube, transform));
  cubeFolder.add(transform, 'translateY', -5, 5).name('Translate Y').onChange(() => applyTranslation(cube, transform));
  cubeFolder.add(transform, 'translateZ', -5, 5).name('Translate Z').onChange(() => applyTranslation(cube, transform));

  // Inverse Translation
  cubeFolder.add({ inverseTranslation: () => applyInverseTranslation(cube) }, 'inverseTranslation').name('Inverse Translation');

  // Rotation Controls
  cubeFolder.add(transform, 'rotateY', 0, Math.PI * 2).name('Rotate Y').onChange(() => applyRotation(cube, transform));
  cubeFolder.add(transform, 'rotateZ', 0, Math.PI * 2).name('Rotate Z').onChange(() => applyRotation(cube, transform));

  // Inverse Rotation
  cubeFolder.add({ inverseRotation: () => applyInverseRotation(cube) }, 'inverseRotation').name('Inverse Rotation');

  // Shear Controls
  cubeFolder.add(transform, 'shearX', -1, 1).name('Shear X').onChange(() => applyShear(cube, transform));
  cubeFolder.add(transform, 'shearY', -1, 1).name('Shear Y').onChange(() => applyShear(cube, transform));

  // Inverse Shear
  cubeFolder.add({ inverseShear: () => applyInverseShear(cube) }, 'inverseShear').name('Inverse Shear');

  cubeFolder.open();
});
}