When TransformControls is behind the object you want it to stay the same size no matter if the user zoom in or out. At the moment when I zoom in or out the size changes from small to enormous. The camera is a PerspectiveCamera
. Not sure if it is the camera’s problem or the scaling but I have attempted on keeping it the same size:
// Calculate the scale based on the object's size and the camera's distance
const objectSize = bounds.getSize(new THREE.Vector3());
// const objectDistance = camera.position.distanceTo(theeBox.position);
// const scale = objectSize.length() / objectDistance;
// console.log(objectSize)
transformControls.scale.set(objectSize.x - 3.6, objectSize.y - 3.6, objectSize.z - 3.6);
Note: I added the -3.6
because I also liked the Controls to be a bit away from the object.
But that doesn’t affect the scaling much as I have this:
or this:
How can TransformControls stay at object size?
MRC
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js';
const boxGeometry = new THREE.BoxGeometry(5, 5, 5);
// Load wood texture using the provided URL
const woodTexture = new THREE.TextureLoader().load('https://cdn.glitch.global/364206c7-9713-48db-9215-72a591a6a9bd/pexels-fwstudio-129733%20(1).jpg?v=1658926492448');
const theeBoxMaterial = new THREE.MeshBasicMaterial({ map: woodTexture });
const theeBox = new THREE.Mesh(boxGeometry, theeBoxMaterial);
const renderer = new THREE.WebGLRenderer();
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
0.1,
1000
);
const gridHelper = new THREE.GridHelper(30);
scene.add(gridHelper);
// Adjust the initial position of the cube to be above the grid helper
theeBox.position.set(0, 2.6, 0);
scene.add(theeBox);
const orbitControls = new OrbitControls(camera, renderer.domElement);
const transformControls = new TransformControls(camera, renderer.domElement);
transformControls.traverse(e => {
if (e.material) {
e.material.depthTest = true;
}
});
let transformAnchor = new THREE.Object3D();
scene.add(transformAnchor);
let bounds = new THREE.Box3().setFromObject(theeBox);
transformAnchor.position.copy(bounds.min);
transformAnchor.attach(theeBox);
transformControls.attach(transformAnchor);
transformControls.setMode('translate');
const gizmo = transformControls._gizmo.gizmo;
[83, 86, 89, 91, 92, 93, 94].forEach(axis => {
const obj = gizmo.translate.getObjectById(axis);
obj.visible = false;
obj.layers.disable(0);
});
scene.add(transformControls);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera.position.set(50, 30, 20);
camera.lookAt(0, 0, 0);
let isDragging = false;
// TODO: Make the cube to be above the grid helper by default
// TODO: Prevent the arrows from shrinking when zooming
// TODO: Add degree rotating arrows
transformControls.addEventListener('dragging-changed', function (event) {
orbitControls.enabled = !event.value;
isDragging = event.value;
});
function animateTheeBox() {
if (!isDragging && !orbitControls.enabled) {
rayCasters.setFromCamera(mousePos, camera);
const intersect = rayCasters.intersectObjects([theeBox]);
if (intersect.length === 0) {
const moveSpeed = 0.1;
camera.position.x += (mousePos.x - 0.5) * moveSpeed;
camera.position.y += (mousePos.y - 0.5) * moveSpeed;
camera.lookAt(0, 0, 0);
}
}
// Calculate the scale based on the object's size and the camera's distance
// const objectSize = bounds.getSize(new THREE.Vector3());
// const objectDistance = camera.position.distanceTo(theeBox.position);
// const scale = objectSize.length() - objectDistance;
// console.log(objectSize)
// transformControls.scale.set(objectSize.x - 3.6, objectSize.y - 3.6, objectSize.z - 3.6);
renderer.render(scene, camera);
}
renderer.setAnimationLoop(animateTheeBox);
Note: I commented my attempt because it was not working…