키보드 입력을 통해 카메라 이동을 이용하여 공간 떠다니기 - eventListener와 연동하여 움직임 주기
eventListener 적용해서 키보드 입력(W, S) 적용하기
import { THREE, GLTFLoader, GenerateCanvas } from "./study/settings";
const canvas = GenerateCanvas();
let camera, scene, renderer, mesh;
let originPosition;
function init() {
renderer = new THREE.WebGLRenderer({
antialias: true,
canvas,
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
0.1,
3000
);
camera.position.set(0, 0, 0);
// gamma
renderer.gammaFactor = 2.2;
scene = new THREE.Scene();
scene.background = new THREE.Color(0x000000);
// add new group
const group = new THREE.Group();
group.position.copy(camera.position);
group.rotation.copy(camera.rotation);
scene.add(group);
group.add(camera);
// add gltf model
const loader = new GLTFLoader();
loader.load("/gltf/move.glb", function (gltf) {
mesh = gltf.scene;
mesh.position.set(0, 0, 0);
const ratio = 0.1;
mesh.scale.set(ratio, ratio, ratio);
scene.add(mesh);
// set default camera position to gltf camera
const cam = gltf.cameras[0];
// multiply by ratio
camera.position.set(
cam.position.x * ratio,
cam.position.y * ratio,
cam.position.z * ratio
);
camera.rotation.set(cam.rotation.x, cam.rotation.y, cam.rotation.z);
originPosition = camera.position.clone();
// change child material
mesh.traverse((child) => {
if (child.isMesh) {
if (child.name == "light") {
child.material = new THREE.MeshBasicMaterial({
color: 0xffffff,
});
// double sided
child.material.side = THREE.DoubleSide;
} else {
child.material = new THREE.MeshStandardMaterial({
color: 0xffffff,
roughness: 0.5,
});
}
}
});
render();
});
// add point light
const pointLight = new THREE.PointLight(0xffffff, 1);
pointLight.position.set(0, 0, 0);
scene.add(pointLight);
// hemi light
const hemiLight = new THREE.HemisphereLight(0x000000, 0xffffff, 0.3);
hemiLight.position.set(1, 0, 1);
scene.add(hemiLight);
}
function render() {
animate();
renderer.render(scene, camera);
requestAnimationFrame(render);
}
// window resize event
window.addEventListener("resize", onWindowResize);
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
// ** type below
// 01. make variables
//키가 눌려 있는지 체크하기 위한 Object type 변수 - 기본값은 false
const keyPressed = {
forward: false,
backward: false,
}
// 02. add events
//키보드에 관련된 이벤트를 설정할 때는 keydown(처음 눌렀을 때)과 keyup(누르고 키를 뗐을 때)에 대해서 둘 다 설정해야함
window.addEventListener("keydown", event => {
if(event.code == "KeyW") keyPressed.forward = true;
if(event.code == "KeyS") keyPressed.backward = true;
})
window.addEventListener("keyup", event => {
if(event.code == "KeyW") keyPressed.forward = false;
if(event.code == "KeyS") keyPressed.backward = false;
})
// 03. make movement
function animate() {
// a. checking key pressed
if(keyPressed.forward == true){
camera.position.z -= 5;
}
if(keyPressed.backward == true){
camera.position.z += 2;
}
console.log(camera.position.z) //z가 -45지점에 흰 네모에 도달 -> 카메라의 처음 위치(z값이 1934)로 되돌아가기
// 움직임의 범위 제한하기
if(camera.position.z < -45) {
camera.position.z = 1934;
}
if(camera.position.z > 1934){
camera.position.z = 1934;
}
}
// ** end
init();
애니메이션 결과
'3D Project > 3D 인터랙티브 웹' 카테고리의 다른 글
[3D 인터랙티브 웹] 스크롤 인터랙션/애니메이션 적용하기 (1) | 2024.01.14 |
---|---|
[3D 인터랙티브 웹] Three.js에서 회전 애니메이션 적용시키기 - 3D 시계 모델링 (0) | 2024.01.14 |
[3D 인터랙티브 웹] glTF, glb 모델 불러오기, 애니메이션 불러오기 (0) | 2024.01.13 |
[3D 인터랙티브 웹] Three.js 기초 - 실시간 조명 세팅하기, 3D Scene에 이미지 적용하기 (0) | 2024.01.13 |
[3D 인터랙티브 웹] 3D 구 모델링하기, OrbitControls(카메라 컨트롤러) (0) | 2024.01.12 |