Skip to main content

threejs-interaction

Three.js interaction - raycasting, controls, mouse/touch input, object selection. Use when handling user input, implementing click detection, adding camera controls, or creating interactive 3D experiences.

Zur Installation springen

Quellinformationen

Repository
muhammedadnank/Antigravity-Skills
Letzte Quellaktivität
6. Juni 2026 um 18:30
Erkannte Sprache von SKILL.md
Englisch
Sterne
13
Forks
1

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
threejs-interaction
description
Three.js interaction - raycasting, controls, mouse/touch input, object selection. Use when handling user input, implementing click detection, adding camera controls, or creating interactive 3D experiences.
risk
unknown
source
community
# Three.js Interaction ## When to Use - You need user interaction inside a Three.js scene. - The task involves raycasting, object picking, pointer handling, touch input, or camera controls. - You are building an interactive 3D experience rather than a passive render. ## Quick Start ```javascript import * as THREE from "three"; import { OrbitControls } from "three/addons/controls/OrbitControls.js"; // Camera controls const controls = new OrbitControls(camera, renderer.domElement); controls.enableDamping = true; // Raycasting for click detection const raycaster = new THREE.Raycaster(); const mouse = new THREE.Vector2(); function onClick(event) { mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; raycaster.setFromCamera(mouse, camera); const intersects = raycaster.intersectObjects(scene.children); if (intersects.length > 0) { console.log("Clicked:", intersects[0].object); } } window.addEventListener("click", onClick); ``` ## Raycaster ### Basic Raycasting ```javascript const raycaster = new THREE.Raycaster(); // From camera (mouse picking) raycaster.setFromCamera(mousePosition, camera); // From any origin and direction raycaster.set(origin, direction); // origin: Vector3, direction: normalized Vector3 // Get intersections const intersects = raycaster.intersectObjects(objects, recursive); // intersects array contains: // { // distance: number, // Distance from ray origin // point: Vector3, // Intersection point in world coords // face: Face3, // Intersected face // faceIndex: number, // Face index // object: Object3D, // Intersected object // uv: Vector2, // UV coordinates at intersection // uv1: Vector2, // Second UV channel // normal: Vector3, // Interpolated face normal // instanceId: number // For InstancedMesh // } ``` ### Mouse Position Conversion ```javascript const mouse = new THREE.Vector2(); function updateMouse(event) { // For full window mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; } // For specific canvas element function updateMouseCanvas(event, canvas) { const rect = canvas.getBoundingClientRect(); mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1; mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1; } ``` ### Touch Support ```javascript function onTouchStart(event) { event.preventDefault(); if (event.touches.length === 1) { const touch = event.touches[0]; mouse.x = (touch.clientX / window.innerWidth) * 2 - 1; mouse.y = -(touch.clientY / window.innerHeight) * 2 + 1; raycaster.setFromCamera(mouse, camera); const intersects = raycaster.intersectObjects(clickableObjects); if (intersects.length > 0) { handleSelection(intersects[0]); } } } renderer.domElement.addEventListener("touchstart", onTouchStart); ``` ### Raycaster Options ```javascript const raycaster = new THREE.Raycaster(); // Near/far clipping (default: 0, Infinity) raycaster.near = 0; raycaster.far = 100; // Line/Points precision raycaster.params.Line.threshold = 0.1; raycaster.params.Points.threshold = 0.1; // Layers (only intersect objects on specific layers) raycaster.layers.set(1); ``` ### Efficient Raycasting ```javascript // Only check specific objects const clickables = [mesh1, mesh2, mesh3]; const intersects = raycaster.intersectObjects(clickables, false); // Use layers for filtering mesh1.layers.set(1); // Clickable layer raycaster.layers.set(1); // Throttle raycast for hover effects let lastRaycast = 0; function onMouseMove(event) { const now = Date.now(); if (now - lastRaycast < 50) return; // 20fps max lastRaycast = now; // Raycast here } ``` ## Camera Controls ### OrbitControls ```javascript import { OrbitControls } from "three/addons/controls/OrbitControls.js"; const controls = new OrbitControls(camera, renderer.domElement); // Damping (smooth movement) controls.enableDamping = true; controls.dampingFactor = 0.05; // Rotation limits controls.minPolarAngle = 0; // Top controls.maxPolarAngle = Math.PI / 2; // Horizon controls.minAzimuthAngle = -Math.PI / 4; // Left controls.maxAzimuthAngle = Math.PI / 4; // Right // Zoom limits controls.minDistance = 2; controls.maxDistance = 50; // Enable/disable features controls.enableRotate = true; controls.enableZoom = true; controls.enablePan = true; // Auto-rotate controls.autoRotate = true; controls.autoRotateSpeed = 2.0; // Target (orbit point) controls.target.set(0, 1, 0); // Update in animation loop function animate() { controls.update(); // Required for damping and auto-rotate renderer.render(scene, camera); } ``` #### OrbitControls Programmatic Methods (r183) ```javascript // Programmatic camera movement controls.dolly(1.5); // Dolly in/out (zoom for perspective cameras) controls.pan(deltaX, deltaY); // Pan the camera controls.rotate(deltaAzimuth, deltaPolar); // Rotate around target // Cursor style (r183) controls.cursorStyle = { orbit: "grab", pan: "move", dolly: "zoom-in" }; ``` ### FlyControls ```javascript import { FlyControls } from "three/addons/controls/FlyControls.js"; const controls = new FlyControls(camera, renderer.domElement); controls.movementSpeed = 10; controls.rollSpeed = Math.PI / 24; controls.dragToLook = true; // Update with delta function animate() { controls.update(clock.getDelta()); renderer.render(scene, camera); } ``` ### FirstPersonControls ```javascript import { FirstPersonControls } from "three/addons/controls/FirstPersonControls.js"; const controls = new FirstPersonControls(camera, renderer.domElement); controls.movementSpeed = 10; controls.lookSpeed = 0.1; controls.lookVertical = true; controls.constrainVertical = true; controls.verticalMin = Math.PI / 4; controls.verticalMax = (Math.PI * 3) / 4; function animate() { controls.update(clock.getDelta()); } ``` ### PointerLockControls ```javascript import { PointerLockControls } from "three/addons/controls/PointerLockControls.js"; const controls = new PointerLockControls(camera, document.body); // Lock pointer on click document.addEventListener("click", () => { controls.lock(); }); controls.addEventListener("lock", () => { console.log("Pointer locked"); }); controls.addEventListener("unlock", () => { console.log("Pointer unlocked"); }); // Movement const velocity = new THREE.Vector3(); const direction = new THREE.Vector3(); const moveForward = false; const moveBackward = false; document.addEventListener("keydown", (event) => { switch (event.code) { case "KeyW": moveForward = true; break; case "KeyS": moveBackward = true; break; } }); function animate() { if (controls.isLocked) { direction.z = Number(moveForward) - Number(moveBackward); direction.normalize(); velocity.z -= direction.z * 0.1; velocity.z *= 0.9; // Friction controls.moveForward(-velocity.z); } } ``` ### TrackballControls ```javascript import { TrackballControls } from "three/addons/controls/TrackballControls.js"; const controls = new TrackballControls(camera, renderer.domElement); controls.rotateSpeed = 2.0; controls.zoomSpeed = 1.2; controls.panSpeed = 0.8; controls.staticMoving = true; function animate() { controls.update(); } ``` ### MapControls ```javascript import { MapControls } from "three/addons/controls/MapControls.js"; const controls = new MapControls(camera, renderer.domElement); controls.enableDamping = true; controls.dampingFactor = 0.05; controls.screenSpacePanning = false; controls.maxPolarAngle = Math.PI / 2; ``` ## TransformControls Gizmo for moving/rotating/scaling objects. ```javascript import { TransformControls } from "three/addons/controls/TransformControls.js"; const transformControls = new TransformControls(camera, renderer.domElement); scene.add(transformControls); // Attach to object transformControls.attach(selectedMesh); // Switch modes transformControls.setMode("translate"); // 'translate', 'rotate', 'scale' // Change space transformControls.setSpace("local"); // 'local', 'world' // Size transformControls.setSize(1); // Events transformControls.addEventListener("dragging-changed", (event) => { // Disable orbit controls while dragging orbitControls.enabled = !event.value; }); transformControls.addEventListener("change", () => { renderer.render(scene, camera); }); // Keyboard shortcuts window.addEventListener("keydown", (event) => { switch (event.key) { case "g": transformControls.setMode("translate"); break; case "r": transformControls.setMode("rotate"); break; case "s": transformControls.setMode("scale"); break; case "Escape": transformControls.detach(); break; } }); ``` ## DragControls Drag objects directly. ```javascript import { DragControls } from "three/addons/controls/DragControls.js"; const draggableObjects = [mesh1, mesh2, mesh3]; const dragControls = new DragControls( draggableObjects, camera, renderer.domElement, ); dragControls.addEventListener("dragstart", (event) => { orbitControls.enabled = false; event.object.material.emissive.set(0xaaaaaa); }); dragControls.addEventListener("drag", (event) => { // Constrain to ground plane event.object.position.y = 0; }); dragControls.addEventListener("dragend", (event) => { orbitControls.enabled = true; event.object.material.emissive.set(0x000000); }); ``` ## Selection System ### Click to Select ```javascript const raycaster = new THREE.Raycaster(); const mouse = new THREE.Vector2(); let selectedObject = null; function onMouseDown(event) { mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; raycaster.setFromCamera(mouse, camera); const intersects = raycaster.intersectObjects(selectableObjects); // Deselect previous if (selectedObject) { selectedObject.material.emissive.set(0x000000); } // Select new if (intersects.length > 0) { selectedObject = intersects[0].object; selectedObject.material.emissive.set(0x444444); } else { selectedObject = null; } } ``` ### Box Selection ```javascript import { SelectionBox } from "three/addons/interactive/SelectionBox.js"; import { SelectionHelper } from "three/addons/interactive/SelectionHelper.js"; const selectionBox = new SelectionBox(camera, scene); const selectionHelper = new SelectionHelper(renderer, "selectBox"); // CSS class document.addEventListener("pointerdown", (event) => { selectionBox.startPoint.set( (event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1, 0.5, ); }); document.addEventListener("pointermove", (event) => { if (selectionHelper.isDown) { selectionBox.endPoint.set( (event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1, 0.5, ); } }); document.addEventListener("pointerup", (event) => {
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen