HTML5 캔버스에서 확대/축소(zoom)를 구현할 때 가장 중요한 개념은 원점(origin)입니다. 캔버스는 항상 현재 원점을 기준으로 크기가 조절되며, 기본 원점은 [0, 0], 즉 좌측 상단 모서리입니다.
원점 변경하기: translate()
만약 특정 지점을 기준으로 확대/축소하고 싶다면, 먼저 ctx.translate(desiredX, desiredY)를 호출하면 됩니다. 이 메서드는 캔버스의 원점(0, 0) 위치를 지정한 좌표로 다시 매핑(remap)해 주므로, 그 이후의 변형은 새로운 원점을 기준으로 적용됩니다.
- translate() — 캔버스 좌표계의 (0, 0) 위치를 재설정합니다.
- scale() — 현재 그려진 내용을 확대하거나 축소합니다.
마우스 커서 기준 줌의 핵심 로직
마우스가 가리키는 지점을 기준으로 줌인·줌아웃하려면, 단순히 scale()만 호출해서는 안 됩니다. 오프셋(offset)만큼 컨텍스트를 이동시키려면 다음 순서를 따라야 합니다.
- 먼저
translate(pt.x, pt.y)로 원점을 마우스 포인터 위치로 이동 scale(factor, factor)로 확대 또는 축소 적용- 마지막으로
translate(-pt.x, -pt.y)를 호출해 반대 방향으로 되돌림
이 과정을 코드로 표현하면 다음과 같습니다.
ctx.translate(pt.x, pt.y); ctx.scale(factor, factor); ctx.translate(-pt.x, -pt.y);
동작 원리 요약
이 세 단계의 트랜스폼(transform) 조합은 "마우스 포인터 아래의 점은 고정된 채로 화면 전체가 늘어나거나 줄어드는" 효과를 만듭니다. 첫 번째 translate가 대상 지점을 원점으로 가져오고, scale이 그 지점을 중심으로 크기를 변경한 뒤, 두 번째 translate가 좌표계를 원래 위치로 복원하기 때문입니다.
마우스 휠 이벤트와 결합하면, factor 값을 휠 방향에 따라 1보다 크거나 작게 설정하여 부드러운 줌 인/아웃 인터랙션을 손쉽게 구현할 수 있습니다.