두 요소가 겹쳐져 있어 배경 이미지는 클릭 이벤트가 발생할 수 없다. 하지만 이미지 위치를 조정하기 위해선 이미지에 드래그 이벤트를 발생시켜야 한다.
최상위 컨테이너 요소에 마우스 클릭 이벤트가 발생하면 배경 이미지에 드래그 이벤트를 발생시키면 될 것 같았다.
찾아보니 자바스크립트는 커스텀 이벤트를 생성하고 수동으로 이벤트를 발생시킬 수 있다. 🧐
드래그 이벤트를 생성해 준다. 이때 이벤트 객체도 직접 넣어줘야 한다.
이미지 위치를 옮기기 위해서 필요한 값들을 마우스(터치) 이벤트 객체에서 뽑아내서 전달했다.
const createCustomDragEvent = (
event: MouseEvent | DragEvent | TouchEvent,
eventType: 'dragstart' | 'dragover' | 'drop',
dataTransfer: DataTransfer,
) => {
let clientY;
let clientX;
if (event instanceof MouseEvent) {
// 마우스 이벤트인 경우
clientY = event.clientY;
clientX = event.clientX;
} else {
// 터치 이벤트인 경우
const touch = event.touches[0] || event.changedTouches[0];
clientY = touch?.clientY;
clientX = touch?.clientX;
}
return new DragEvent(eventType, {
bubbles: true,
cancelable: true,
clientY,
clientX,
dataTransfer,
});
};
const dataTransfer = new DataTransfer();
dropzone.addEventListener('mousedown', (e) => {
const dragStartEvent = createCustomDragEvent(
e,
'dragstart',
dataTransfer,
);
draggableImage.dispatchEvent(dragStartEvent);
});
draggableImage.addEventListener('dragstart', handleDragStart);
컨테이너 요소(=dropzone)에 mousedown 이벤트가 발생하면 draggableImage 요소에 dragStart 이벤트가 발생한다.
이미지를 이동하기 위해 dragstart, dragover, drop 이렇게 세 가지 이벤트를 사용해야 해서 동일한 방법으로 커스텀 이벤트를 수동으로 발생시켰다.
// PC를 위한 마우스 이벤트
dropZone.addEventListener('mousedown', (e) => {
const dragStartEvent = createCustomDragEvent(
e,
'dragstart',
dataTransfer,
);
draggableImage.dispatchEvent(dragStartEvent);
});
document.addEventListener('mousemove', (e) => {
const dragOverEvent = createCustomDragEvent(e, 'dragover', dataTransfer);
dropZone.dispatchEvent(dragOverEvent);
});
document.addEventListener('mouseup', (e) => {
const dropEvent = createCustomDragEvent(e, 'drop', dataTransfer);
dropZone.dispatchEvent(dropEvent);
});
// 모바일을 위한 터치 이벤트
dropZone.addEventListener(
'touchstart',
(e) => {
if (e.target === dropZone || dropZone.contains(e.target as Node)) {
e.preventDefault();
}
const dragStartEvent = createCustomDragEvent(
e,
'dragstart',
dataTransfer,
);
draggableImage.dispatchEvent(dragStartEvent);
},
{ passive: false },
);
document.addEventListener(
'touchmove',
(e) => {
if (e.target === dropZone || dropZone.contains(e.target as Node)) {
e.preventDefault();
}
const dragOverEvent = createCustomDragEvent(
e,
'dragover',
dataTransfer,
);
dropZone.dispatchEvent(dragOverEvent);
},
{ passive: false },
);
document.addEventListener('touchend', (e) => {
const dropEvent = createCustomDragEvent(e, 'drop', dataTransfer);
dropZone.dispatchEvent(dropEvent);
});
//이미지 위치를 이동하는 드래그 이벤트
draggableImage.addEventListener('dragstart', handleDragStart);
dropZone.addEventListener('dragover', handleDragOver);
dropZone.addEventListener('drop', handleDrop);