Hello everyone!
I am trying to scale a sphere based on mouse drag. In my current implementation I can resize the sphere just fine. However there are some issues with the direction in which the scaling takes place. I want to enlarge the sphere when the mouse drag is away from the center of the sphere and shrink the sphere when the mouse drag is towards its center. This behavior is not always exhibited in my code.
Any help will be greatly appreciated. I am also open to suggestions on better ways to deal with resizing a 3D object using mouse click and drag events. Thanks!
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
scene.background = new THREE.Color('skyblue');
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const geometry = new THREE.SphereGeometry( 15, 32, 16 );
const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
const sphere = new THREE.Mesh( geometry, material ); scene.add( sphere );
scene.add( sphere );
camera.position.z = 25;
const controls = new OrbitControls( camera, renderer.domElement );
controls.update();
let isResizing = false;
let initialScale;
const mouse = new THREE.Vector2();
document.addEventListener('mousedown', onMouseDown);
document.addEventListener('mouseup', onMouseUp);
document.addEventListener('mousemove', onMouseMove);
function onMouseDown(event) {
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObject(sphere);
if (intersects.length > 0) {
isResizing = true;
initialScale = sphere.scale.clone();
}
}
function onMouseUp() {
isResizing = false;
}
function onMouseMove(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
if (isResizing) {
const scaleFactor = 1 + (mouse.x - initialScale.x) * 0.5;
const delta = new THREE.Vector2(event.movementX, event.movementY);
sphere.scale.set(
initialScale.x * scaleFactor,
initialScale.y * scaleFactor,
initialScale.z * scaleFactor
);
}
}
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
}
animate();