Hi guys.
I am creating a interior design project with three.js.I need these different controls And I have added all of them but after some time working with them, my app will slow down. I see some lags.
Do you know the reason? especially in dragging
Lets check my code
Select
const selectMode = () => {
console.log('selectMode')
selectMODE.current=true
orbitRef.current.enabled = true
transformControlRef.current.detach();
transformControlRef.current.enabled = false
if (dragControlRef.current) {
dragControlRef.current.enabled = false;
dragControlRef.current = ""
}
}
function onMouseClick(event) {
console.log('event', event.target)
if(selectMODE.current){
const rect = canvasRef.current.getBoundingClientRect();
// Calculate mouse position in normalized device coordinates
mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
// Set the raycaster
raycaster.setFromCamera(mouse, cameraRef.current);
if (isPlacing && modelToPlace) {
// If we're in placing mode, place the model at the intersection point
const intersects = raycaster.intersectObjects(sceneRef.current.children, true); // Assuming floor is your ground plane or surface
if (intersects.length > 0) {
const intersectPoint = intersects[0].point;
modelToPlace.position.copy(intersectPoint); // Place the model at the clicked location
isPlacing = false; // Exit placing mode
modelToPlace = null; // Clear the model to place
}
} else {
// Normal object selection logic (if not placing a model)
const intersects = raycaster.intersectObjects(sceneRef.current.children, true);
if (intersects.length > 0) {
selectedGroup = intersects[0].object;
console.log('Intersection found:', selectedGroup);
if (selectedGroup.isMesh && selectedGroup.material) {
const originalColor = selectedGroup.material?.color?.clone(); // Store original color
// If another timeout is active, clear it
if (activeTimeout) {
clearTimeout(activeTimeout);
if (selectedObject.current) {
selectedObject.current.material?.color?.copy(originalColor); // Reset immediately
}
}
// Change the color to green temporarily
selectedGroup.material?.color?.set(0x354E37);
selectedObject.current = selectedGroup;
if(transformControlRef.current.enabled){
transformControlRef.current.attach(selectedObject.current)
}
// Set a new timeout to revert the color after 100ms
activeTimeout = setTimeout(() => {
selectedGroup.material?.color?.copy(originalColor);
activeTimeout = null;
}, 100);
}
} else {
console.log('No object selected');
}
}
}
console.log('selectedObject raycast', selectedObject.current)
}
next part is dragging that I think maybe this part has performance issues:
const dragMode = () => {
console.log('dragmode', draggableObjects)
selectMODE.current=false
transformControlRef.current.enabled = false
transformControlRef.current.detach();
if (dragControlRef.current) dragControlRef.current.enabled = true;
dragControlRef.current = new DragControls(draggableObjects, cameraRef.current, renderer.current.domElement);
// dragControlRef.current.transformGroup = true;
// dragControlRef.current.transformRoot=true
let originalMaterial;
const dragMaterial = new THREE.MeshBasicMaterial({ color: 0xD6A218, transparent: true, opacity: 0.5 });
// Add event listeners for dragging
dragControlRef.current.addEventListener('dragstart', function (event) {
console.log('dragstart name >>>', event.object.name)
orbitRef.current.enabled = false
originalMaterial = event.object.material
event.object.material = dragMaterial;
const draggedObject = event.object;
previousPosition.copy(draggedObject.position);
});
dragControlRef.current.addEventListener('drag', function (event) {
orbitRef.current.enabled = false
});
dragControlRef.current.addEventListener('dragend', function (event) {
console.log('Drag ended: ', event.object);
orbitRef.current.enabled = true
event.object.material = originalMaterial;
});
}
next one is transform Control mode for selected object:
const transformMode = () => {
console.log('transformMode', selectedObject.current)
selectMODE.current=false
if (dragControlRef.current) dragControlRef.current.enabled = false
transformControlRef.current.reset()
transformControlRef.current.enabled = true
if(selectedObject.current.name.includes("LOCK")===false){
transformControlRef.current.attach(selectedObject.current)
sceneRef.current.add(transformControlRef.current.getHelper())
transformControlRef.current.addEventListener('mouseDown', () => {
orbitRef.current.enabled = false;
});
transformControlRef.current.addEventListener('mouseUp', () => {
orbitRef.current.enabled = true;
});
transformControlRef.current.addEventListener('objectChange', () => {
constrainPosition(selectedObject.current, minLimit, maxLimit);
});
window.addEventListener('keydown', (event) => {
switch (event.key) {
case 'r': // Press 'r' to switch to rotation mode
transformControlRef.current.setMode('rotate');
break;
case 's': // Press 's' to switch to scale mode
transformControlRef.current.setMode('scale');
break;
case 't': // Press 't' to switch to translate mode
transformControlRef.current.setMode('translate');
break;
}
});
}
else{
console.log('you ant to change a lock object')
}
}
and orbit mode can be enable with other modes at the same time
const orbitMode = () => {
console.log('orbitMode', transformControlRef.current)
orbitRef.current.enabled = true
transformControlRef.current.detach();
transformControlRef.current.enabled = false
if (dragControlRef.current) {
dragControlRef.current.enabled = false;
dragControlRef.current = ""
}
}