카메라를 쉽게 컨트롤 하기 위해 Controls 객체를 사용하여 시야를 컨트롤 한다.
미리 만들어져서 사용이 쉽지만, 특정 기능을 추가하기엔 까다로울 수 있다.
-> (이 경우 커스텀을 위해 기본적으로 제공하는 controls 기능에 추가로 기능을 구현할 것인지, 새롭게 control을 하는 객체를 만들 것인지 결정해야 함)
✔ 타겟 대상을 중심으로 카메라를 여러 방향으로 회전시킬 수 있다.
new OrbitControls(object: Camera(필수), domElement: HTMLDOMElement)
➡ 첫 번째 매개변수로 컨트롤을 할 카메라 오브젝트를 전달하고, 두 번째 인자로는 이벤트 리스너를 적용할 HTML DOM 엘리먼트(=three.js 캔버스)를 전달한다.
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
const controls = new OrbitControls( camera, renderer.domElement );
controls.enableDamping = true;
controls.enableZoom = false;
controls.maxDistance = 10;
controls.minDistance = 3;
controls.minPolarAngle = Math.PI / 4; //45deg
controls.maxPolarAngle = THREE.MathUtils.degToRad(45);
camera.position.set( 0, 20, 100 );
controls.update();
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
}
컨트롤을 정의한 후 갱신이 생기면 update()메서드를 적용해주어야 한다.
.target.set(x, y, z)
.enableDamping
: boolean.enableZoom
: boolean.maxDistance
: number.minDistance
: number.minPolarAngle
: number.maxPolarAngle
: numberTHREE.MathUtils.degToRad(45);
-> 45도그 외의 속성들은 필요에 따라 공식 문서: OrbitControls 에서 확인할 수 있다.
✔ OrbitControls와 유사하게 동작한다.
.enableDamping
속성이 이미 적용된 것 처럼 부드럽게 동작한다.import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls';
const controls = new TrackballControls(camera, renderer.domElement);
controls.maxDistance = 120;
controls.minDistance = 5;
.target.set(x, y, z)
.maxDistance
: number.minDistance
: number✔ 게임처럼 방향키를 이용해서 화면을 컨트롤 할 수 있게 도와준다.
import { FlyControls } from 'three/examples/jsm/controls/FlyControls';
const controls = new FlyControls(camera, renderer.domElement);
controls.rollSpeed = 0.5;
controls.movementSpeed = 1;
controls.dragToLook = true;
const clock = new THREE.Clock();
function draw() {
const delta = clock.getDelta();
controls.update(delta);
renderer.render(scene, camera);
renderer.setAnimationLoop(draw);
}
draw();
.rollSpeed
: number.movementSpeed
: number.dragToLook
: boolean✔ FlyControls의 대체 구현 버전으로, FlyControls에 몇 가지 기능을 추가하거나 수정해서 다시 내놓은 버전이다.
따라서 FlyControls와 대부분의 동작이 유사하다.
컨트롤에 사용되는 키도 FlyControls와 동일하고, update시에 delta 값을 전달해야 하는 것도 동일하다.
.activeLook
: boolean.lookSpeed
: number.autoForward
: boolean✔ 특정 이벤트 발생 시에 Controls를 활성화 시킬 수 있다.
import { PointerLockControls } from 'three/examples/jsm/controls/PointerLockControls';
const controls = new PointerLockControls(camera, renderer.domElement);
controls.domElement.addEventListener('click', () => {
controls.lock();
});
controls.addEventListener('lock', () => {
console.log('lock!');
});
controls.addEventListener('change', () => {
console.log('움직이는 중');
});
controls.addEventListener('unlock', () => {
console.log('unlock!');
});
.moveForward(distance:Number)
: xz평면과 평행하게 앞, 뒤로 움직인다. distance 값을 음수로 주면 뒤로 이동한다..moveRight(distance:Number)
: xz평면과 평행하게 좌, 우로 움직인다. distance 값을 음수로 주면 왼쪽으로 이동한다.✔ 드래그앤드롭 인터랙션을 제공하는 Controls.
DragControls( objects : Array, camera : Camera, domElement : HTMLDOMElement )
import { DragControls } from 'three/examples/jsm/controls/DragControls';
// Mesh
const geometry = new THREE.BoxGeometry(1, 1, 1);
const meshes = [];
let mesh;
let material;
for (let i = 0; i < 20; i++) {
material = new THREE.MeshStandardMaterial({
color: `rgb(
${ 50 + Math.floor(Math.random() * 205) },
${ 50 + Math.floor(Math.random() * 205) },
${ 50 + Math.floor(Math.random() * 205) }
)`
});
mesh = new THREE.Mesh(geometry, material);
mesh.position.x = (Math.random() - 0.5) * 5;
mesh.position.y = (Math.random() - 0.5) * 5;
mesh.position.z = (Math.random() - 0.5) * 5;
mesh.name = `box-${i}`;
scene.add(mesh);
meshes.push(mesh);
}
// Controls
const controls = new DragControls(meshes, camera, renderer.domElement);
controls.addEventListener('dragstart', e => {
console.log(e.object.name);
});
mesh 생성 시에 name을 설정하고, addEventListener에서 drag가 시작될 때 타겟 mesh의 name을 출력하도록 하는 코드이다.
dragstart
: 드래그 시작 시drag
: 드래그 중dragend
: 드래그 후hoveron
: 마우스 커서가 타겟 3d 오브젝트(혹은 타겟 3d 오브젝트의 자식요소) 위에 올라갈 때hoveroff
: 마우스 커서가 타겟 3d 오브젝트 위에서 나올 때