우선 Orbit Controls
은 three.js core 의 일부가 아니고 add-on 이다.
또한 three.js 에는 여러 컨트롤러들이 존재한다.
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100)
camera.position.z = 2
camera.lookAt(0.5, 0.5, 0.5)
const controls = new OrbitControls(camera, renderer.domElement)
// controls.target.set(.5, .5, .5)
카메라 객체에는 lookAt()
메서드가, 컨트롤 객체에는 .set()
이 존재한다.
이때, 컨트롤의 기본 값은 (0, 0, 0) 이다. 따라서 만약 카메라 초기값만 세팅해주고 컨트롤의 초기값을 카메라 초기값과 다르게 설정하면 의도한 바와는 다르게 동작된다.
하지만 lootAt()
메서드를 사용하여 세팅하기보단 더 간단하게 컨트롤 객체의 update()
함수를 사용하는 것이 더 좋다.
왜냐하면 lookAt()
은 control 을 위해 나온 함수가 아니기 때문에 더 콘크리트한 코드를 작성하고 싶다면 컨트롤 함수를 사용하여 Control 객체를 조절하는 것이 좋다.
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100)
camera.position.z = 2
// camera.lookAt(0.5, 0.5, 0.5)
const controls = new OrbitControls(camera, renderer.domElement)
controls.target.set(.5, .5, .5)
// animation 함수에서 실행해줘야함.
controls.update()
const controls = new OrbitControls(camera, renderer.domElement)
controls.addEventListener('start', () => console.log("Controls Start Event"))
controls.addEventListener('change', () => console.log("Controls Change"))
controls.addEventListener('end', () => console.log("Controls End Event"))
start: 마우스, 터치를 누를 때
change: 마우스, 터치를 하여 욺직일 때
end: 마우스, 터치를 땔 때
controls.autoRotate = true
controls.autoRotateSpeed = 10
자동으로 돌아가도록 하는 속성 값이며 반드시 animate 함수안에 controls.update()
가 있어야 매 프레임 마다 적용되어 동작한다.
controls.enableDamping = true
controls.dampingFactor = .01
사용자가 회전 후 관성으로 조금 더 나아가도록 부드럽게 설정하는 설정 값이다.
controls.listenToKeyEvents(window)
controls.keys = {
LEFT: 'KeyA', // default 'ArrowLeft'
UP: 'KeyW', // default 'ArrowUp'
RIGHT: 'KeyD', // default 'ArrowRight'
BOTTOM: 'KeyS' // default 'ArrowDown'
}
controls.mouseButtons = {
LEFT: THREE.MOUSE.ROTATE,
MIDDLE: THREE.MOUSE.DOLLY,
RIGHT: THREE.MOUSE.PAN
}
controls.touches = {
ONE: THREE.TOUCH.ROTATE,
TWO: THREE.TOUCH.DOLLY_PAN
}
키보드를 사용하여 카메라 위치를 옮길 수 있다. 또한 화살표로 되어있는 키를 다른 키로 매핑할 수 있다.
또한 마우스, 터치를 고려하려 키와 해당 이벤트를 매핑할 수 있다.
controls.screenSpacePanning = false
마우스 오른쪽 클릭 즉, pan 이벤트가 마우스 휠 이벤트 즉, zoom in, out 이벤트로 바뀐다.
// 상하
controls.minPolarAngle = 0
controls.maxPolarAngle = Math.PI
// 좌우
controls.minAzimuthAngle = 0
controls.maxAzimuthAngle = Math.PI / 2
// 줌 in, out 의 최대, 최소 거리
controls.maxDistance = 4
controls.minDistance = 1.5
controls.enabled = false
controls.enablePan = false
controls.enableRotate = false
controls.enableZoom = false
import './style.css'
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import Stats from 'three/addons/libs/stats.module.js'
const scene = new THREE.Scene()
const gridHelper = new THREE.GridHelper()
gridHelper.position.y = -0.5
scene.add(gridHelper)
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100)
camera.position.z = 2
const renderer = new THREE.WebGLRenderer({antialias: true})
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
})
const info = document.createElement('div')
info.style.cssText = 'position:absolute;bottom:10px;left:10px;color:white;font-family:monospace;font-size: 17px;filter: drop-shadow(1px 1px 1px #000000);'
document.body.appendChild(info)
const controls = new OrbitControls(camera, renderer.domElement)
// camera.lookAt(0.5, 0.5, 0.5)
// controls.target.set(.5, .5, .5)
// controls.update()
controls.addEventListener('change', () => {
info.innerText =
'Polar Angle : ' +
((controls.getPolarAngle() / -Math.PI) * 180 + 90).toFixed(2) +
'°\nAzimuth Angle : ' +
((controls.getAzimuthalAngle() / Math.PI) * 180).toFixed(2) +
'°'
})
// controls.addEventListener('start', () => console.log("Controls Start Event"))
// controls.addEventListener('end', () => console.log("Controls End Event"))
// controls.autoRotate = true
// controls.autoRotateSpeed = 10
// controls.enableDamping = true
// controls.dampingFactor = .01
// controls.listenToKeyEvents(window)
// controls.keys = {
// LEFT: 'KeyA', // default 'ArrowLeft'
// UP: 'KeyW', // default 'ArrowUp'
// RIGHT: 'KeyD', // default 'ArrowRight'
// BOTTOM: 'KeyS' // default 'ArrowDown'
// }
// controls.mouseButtons = {
// LEFT: THREE.MOUSE.ROTATE,
// MIDDLE: THREE.MOUSE.DOLLY,
// RIGHT: THREE.MOUSE.PAN
// }
// controls.touches = {
// ONE: THREE.TOUCH.ROTATE,
// TWO: THREE.TOUCH.DOLLY_PAN
// }
// controls.screenSpacePanning = false
// controls.minAzimuthAngle = 0
// controls.maxAzimuthAngle = Math.PI / 2
// controls.minPolarAngle = 0
// controls.maxPolarAngle = Math.PI
// controls.maxDistance = 4
// controls.minDistance = 1.5
// controls.enabled = false
// controls.enablePan = false
// controls.enableRotate = false
// controls.enableZoom = false
const geometry = new THREE.BoxGeometry()
const material = new THREE.MeshNormalMaterial({ wireframe: true })
const cube = new THREE.Mesh(geometry, material)
scene.add(cube)
const stats = new Stats()
document.body.appendChild(stats.dom)
function animate() {
requestAnimationFrame(animate)
controls.update()
renderer.render(scene, camera)
stats.update()
}
animate()