1. html 코드
<div id="screen">
<img id="target" src="" style="transform: scale(1) translate(0px, 0px);">
</div>
2. JavaScript 코드
function touchInit(targetElement) {
zoomStatus = true;
let startX = 0, startY = 0;
let offsetX = 0, offsetY = 0;
let scale = 1; // 초기 스케일
let isDragging = false;
let initialDistance = 0;
let touchCenterX = 0, touchCenterY = 0; // 터치 중심점
const maxScale = 2; // 최대 확대 배율 설정
// 기준값 설정
const baseTranslateX = 270;
const baseTranslateY = 270;
// 요소의 위치 정보
const rect = targetElement.getBoundingClientRect();
const elementOffsetX = rect.left; // 요소의 X 위치
const elementOffsetY = rect.top; // 요소의 Y 위치
// 값 제한 함수
function clamp(value, min, max) {
return Math.max(min, Math.min(value, max));
}
// 거리 계산 함수
function getDistance(touches) {
const [touch1, touch2] = touches;
const deltaX = touch2.clientX - touch1.clientX;
const deltaY = touch2.clientY - touch1.clientY;
return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
}
// 터치 시작
targetElement.addEventListener('touchstart', (event) => {
if (event.touches.length === 2) {
// 핀치 줌 시작
initialDistance = getDistance(event.touches);
// 중심점 계산 (요소의 위치를 기준으로 보정)
const touch1 = event.touches[0];
const touch2 = event.touches[1];
touchCenterX = ((touch1.clientX + touch2.clientX) / 2) - elementOffsetX;
touchCenterY = ((touch1.clientY + touch2.clientY) / 2) - elementOffsetY;
} else if (event.touches.length === 1) {
// 드래그 시작
isDragging = true;
startX = event.touches[0].clientX - offsetX;
startY = event.touches[0].clientY - offsetY;
}
});
// 터치 이동
targetElement.addEventListener('touchmove', (event) => {
if (event.touches.length === 2) {
// 핀치 줌 동작
const currentDistance = getDistance(event.touches);
const zoomFactor = currentDistance / initialDistance;
// 스케일 업데이트 및 제한
scale = clamp(scale * zoomFactor, 1, maxScale); // 확대 범위 제한
initialDistance = currentDistance;
// 중심점 기준 확대 조정
offsetX = (scale - 1) * (baseTranslateX - touchCenterX);
offsetY = (scale - 1) * (baseTranslateY - touchCenterY);
// 이동 경계 제한 추가
const minOffsetX = -((scale - 1) * baseTranslateX);
const maxOffsetX = (scale - 1) * baseTranslateX;
const minOffsetY = -((scale - 1) * baseTranslateY);
const maxOffsetY = (scale - 1) * baseTranslateY;
offsetX = clamp(offsetX, minOffsetX, maxOffsetX);
offsetY = clamp(offsetY, minOffsetY, maxOffsetY);
// 변환 적용
targetElement.style.transform = `scale(${scale}) translate(${offsetX}px, ${offsetY}px)`;
} else if (event.touches.length === 1 && isDragging) {
// 드래그 동작
offsetX = event.touches[0].clientX - startX;
offsetY = event.touches[0].clientY - startY;
// 이동 경계 제한
const minOffsetX = -((scale - 1) * baseTranslateX);
const maxOffsetX = (scale - 1) * baseTranslateX;
const minOffsetY = -((scale - 1) * baseTranslateY);
const maxOffsetY = (scale - 1) * baseTranslateY;
offsetX = clamp(offsetX, minOffsetX, maxOffsetX);
offsetY = clamp(offsetY, minOffsetY, maxOffsetY);
// 변환 적용
targetElement.style.transform = `scale(${scale}) translate(${offsetX}px, ${offsetY}px)`;
}
});
// 터치 종료
targetElement.addEventListener('touchend', () => {
isDragging = false;
});
}