728x90
반응형
마우스 이벤트를 위해서 canvas 상에서 돌아가는 event listener를 알아보자.
canvas.addEventListener('click', e=>{
console.log(e.clientX, e.clientY);
});
mouse 클릭 이벤트를 통해 클릭 포인터를 알 수 있다.
window.addEventListener('resize', setSize);
canvas.addEventListener('click', e=>{
mouse.x = e.clientX / canvas.clientWidth * 2 - 1;
mouse.y = -(e.clientY / canvas.clientHeight * 2 - 1);
console.log(mouse);
});
현재 canvas화면 비율에 맞춰 중심을 0,0으로 하고 2차원 좌표계로 표현할 수 있다.
y의 경우 위가 (-)이고, 아래가 (+)로 처리되어있어, (-)로 부호를 바꿔주어야한다.
function checkIntersects(){
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(meshes);
for(const item of intersects) {
console.log(item.object.name);
break;
}
// other method
// if(intersects[0]){
// console.log(intersects[0].object.name);
// }
}
...
// event
window.addEventListener('resize', setSize);
canvas.addEventListener('click', e=>{
mouse.x = e.clientX / canvas.clientWidth * 2 - 1;
mouse.y = -(e.clientY / canvas.clientHeight * 2 - 1);
checkIntersects();
});
checkIntersects라는 함수를 통해서 클릭한 방향으로 raycast를 쏘고, 감지할 수 있다.
raycaster는 쏘는 시작 origin이 중요한데, setFromCamera를 통해 camera에서 raycaster를 쏠 수 있다.
raycaster가 감지하는 오브젝트는 여러개 일 수 있어서, 만약 처음 감지한 하나만 뽑고 싶다면 intersectObjects 중에서 가장 먼저 감지된 것만을 보는 방법을 사용한다.
클릭 이벤트는 드래그를 한 후에 마우스를 떼는 것도 클릭 이벤트로 감지된다. 이는 별도로 처리해주어야한다.
canvas.addEventListener('click', e=>{
mouse.x = e.clientX / canvas.clientWidth * 2 - 1;
mouse.y = -(e.clientY / canvas.clientHeight * 2 - 1);
checkIntersects();
});
let mouseMoved;
let clickStartX;
let clickStartY;
let clickStartTime;
canvas.addEventListener('mousedown', e=>{
clickStartX = e.clientX;
clickStartY = e.clientY;
clickStartTime = Date.now();
})
canvas.addEventListener('mouseup', e => {
const xGap = Math.abs(e.clientX - clickStartX);
const yGap = Math.abs(e.clientY - clickStartY);
const timeGap = Date.now() - clickStartTime;
if (xGap > 5 || yGap > 5 || timeGap > 500){
mouseMoved = true;
}
else{
mouseMoved = false;
}
})
마우스를 누를 때와 떼었을 때 좌표 변화가 얼마나 생겼는지를 이용해서, moseMoved라는 변수로 click과 drag를 구분할 수 있도록 한다.
또 마우스를 너무 오래 눌렀다 떼는 경우도 제외하기 위해서 clickStartTime을 체크하려 timeGap을 0.5초(500ms)로 설정한다.
// PreventDragClick.js
export class PreventDragClick{
constructor(elem) {
this.mouseMoved;
let clickStartX;
let clickStartY;
let clickStartTime;
elem.addEventListener('mousedown', e=>{
clickStartX = e.clientX;
clickStartY = e.clientY;
clickStartTime = Date.now();
})
elem.addEventListener('mouseup', e => {
const xGap = Math.abs(e.clientX - clickStartX);
const yGap = Math.abs(e.clientY - clickStartY);
const timeGap = Date.now() - clickStartTime;
if (xGap > 5 || yGap > 5 || timeGap > 500){
this.mouseMoved = true;
}
else{
this.mouseMoved = false;
}
})
}
}
click와 drag를 구분하는 코드를 위와 같이 모듈화한 다음
PreventDragClick(canvas)로 객체를 생성해서 사용할 수 있다.
728x90
반응형
'개발 · 컴퓨터공학' 카테고리의 다른 글
three.js 물리엔진 라이브러리 cannon.js (0) | 2022.10.14 |
---|---|
three.js glb / gltf 모델 load하여 애니메이션 적용하기 (0) | 2022.10.13 |
three.js Raycaster로 물체 감지하기 (0) | 2022.10.11 |
three.js HemisphereLight와 RectAreaLight (0) | 2022.10.10 |
three.js PointLight와 SpotLight (0) | 2022.10.07 |