'How do I confine a dragged cube within boundaries smoothly?
How can I confine a cube that can be dragged using the mouse within the boundaries of a plane smoothly so that if my cursor leaves the plane, the cube is still dragged but only so that it doesn't leave the plane?
First off, here is my code:
import { BoxBufferGeometry, DirectionalLight, Mesh, MeshStandardMaterial, PerspectiveCamera, PlaneBufferGeometry, Raycaster, Scene, Sprite, SpriteMaterial, Vector2, WebGLRenderer } from "three";
import { degToRad } from "three/src/math/MathUtils";
const renderer = new WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.append(renderer.domElement);
// Setup the scene
const scene = new Scene();
const ground = new Mesh(new PlaneBufferGeometry(5, 5, 5), new MeshStandardMaterial());
ground.rotateX(degToRad(-90));
scene.add(ground);
const box = new Mesh(new BoxBufferGeometry(), new MeshStandardMaterial({ color: "green" }));
scene.add(box);
const spriteMaterial = new SpriteMaterial({ color: "red" });
spriteMaterial.depthTest = false;
const pointingObj = new Sprite(spriteMaterial);
pointingObj.scale.set(0.05, 0.05, 0.05);
scene.add(pointingObj);
const camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight);
camera.position.set(0, 3, 3);
camera.lookAt(ground.position);
const light = new DirectionalLight("white", 0.5);
camera.add(light);
scene.add(camera);
// Do the raycasting
const raycaster = new Raycaster();
let boxIsGrabbed = false;
document.addEventListener("mousedown", () => {
const intersections = raycaster.intersectObject(box);
if (intersections.length > 0)
boxIsGrabbed = true;
});
const pointer = new Vector2();
document.addEventListener("mousemove", event => {
// Normalize the coordinates in range -1 to +1
pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(pointer, camera);
const intersections = raycaster.intersectObject(ground);
if (intersections.length > 0) {
pointingObj.position.copy(intersections[0].point);
if (boxIsGrabbed)
box.position.copy(intersections[0].point);
}
});
document.addEventListener("mouseup", () => {
boxIsGrabbed = false;
});
renderer.setAnimationLoop(() => {
renderer.render(scene, camera);
});
If you run it, it looks like this:

It works well overall but if you drag the cube out of the plane, it abruptly stops moving the cube and it looks rather ugly.
The way I want it to look is like this:
https://i.imgur.com/6pDExEb.mp4 (this is simulated and doesn't actually work)
This is smooth and still moves the cube in some way, but not outside the boundaries. How can I do it like that? I'm honestly not sure where to start.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
