feat(B07): 트랙패드 두 손가락 팬 + 확대를 델타 비례로
확대가 이벤트 1회당 10% 고정이라 트랙패드처럼 잔 델타를 초당 수십 번 보내는 입력에서 튀었고, 두 손가락 이동은 팬이 아니라 확대로 먹혔다. - zoomScreen을 부호 기반에서 델타 비례 지수식 exp(-delta*지수)로 변경. 마우스 휠 한 칸(deltaY 100)은 종전과 같은 10%, 트랙패드 잔 델타는 그만큼만 - 트랙패드 두 손가락 이동은 panScreen으로 — 마우스 휠은 한 칸이 100/120px로 딱 떨어지고 가로 델타가 없다는 성질로 기기를 가른다 - 핀치(ctrl+휠)는 기기 무관 확대, 전용 지수로 천천히 - deltaMode(줄·쪽 단위) 픽셀 환산 추가 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,11 @@ import {
|
||||
CANVAS_INPUT_FIELD_TEXT_COLOR,
|
||||
CANVAS_INPUT_FIELD_WIDTH,
|
||||
HIGHLIGHT_ENTITY_DISTANCE,
|
||||
PINCH_ZOOM_EXPONENT,
|
||||
SNAP_POINT_DISTANCE,
|
||||
WHEEL_LINE_PX,
|
||||
WHEEL_PAGE_PX,
|
||||
WHEEL_ZOOM_EXPONENT,
|
||||
} from '../App.consts.ts';
|
||||
import { MouseButton } from '../App.types.ts';
|
||||
import type { ScreenCanvasDrawController } from '../drawControllers/screenCanvas.drawController.ts';
|
||||
@@ -228,13 +232,30 @@ export class InputController {
|
||||
public handleMouseWheel(evt: WheelEvent) {
|
||||
// 확대는 도면만 — 트랙패드 핀치(ctrl+휠)가 브라우저 전체를 키우던 것을 막는다.
|
||||
evt.preventDefault();
|
||||
if (Math.abs(evt.deltaY) === 0) {
|
||||
const drawController = getScreenCanvasDrawController();
|
||||
// deltaY 단위를 픽셀로 맞춘다 — 브라우저에 따라 줄(1)·쪽(2) 단위로 오기도 한다.
|
||||
const unitPx = evt.deltaMode === 1 ? WHEEL_LINE_PX : evt.deltaMode === 2 ? WHEEL_PAGE_PX : 1;
|
||||
const deltaX = evt.deltaX * unitPx;
|
||||
const deltaY = evt.deltaY * unitPx;
|
||||
|
||||
// 핀치(ctrl+휠)는 기기와 무관하게 확대.
|
||||
if (evt.ctrlKey) {
|
||||
if (deltaY !== 0) drawController.zoomScreen(-deltaY, PINCH_ZOOM_EXPONENT);
|
||||
return;
|
||||
}
|
||||
|
||||
// 트랙패드 두 손가락 이동은 팬 — 문서를 스크롤하듯 화면이 손가락 반대로 간다.
|
||||
if (!isMouseWheel(evt)) {
|
||||
drawController.panScreen(-deltaX, deltaY);
|
||||
return;
|
||||
}
|
||||
|
||||
if (deltaY === 0) {
|
||||
return; // We can't zoom by zero delta
|
||||
}
|
||||
const drawController = getScreenCanvasDrawController();
|
||||
// Aislo: wheel direction is inverted on purpose - pulling the wheel zooms in, pushing
|
||||
// zooms out, matching the B04/B05 maps and the B06 cross sections (2026-08-02).
|
||||
drawController.zoomScreen(-evt.deltaY);
|
||||
drawController.zoomScreen(-deltaY, WHEEL_ZOOM_EXPONENT);
|
||||
}
|
||||
|
||||
public handleMouseDown(evt: MouseEvent) {
|
||||
@@ -540,3 +561,15 @@ export class InputController {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 마우스 휠인지 트랙패드인지 가른다. 마우스 휠은 한 칸이 정해진 크기(Chrome 100px,
|
||||
* 일부 브라우저 120px)로 딱 떨어지고 가로 델타가 없다. 트랙패드는 손가락이 움직인
|
||||
* 만큼 잔 델타를 보내고 가로 델타도 함께 온다. 줄·쪽 단위(deltaMode≠0)는 휠뿐이다.
|
||||
*/
|
||||
function isMouseWheel(evt: WheelEvent): boolean {
|
||||
if (evt.deltaMode !== 0) return true;
|
||||
if (evt.deltaX !== 0) return false;
|
||||
const step = Math.abs(evt.deltaY);
|
||||
return step !== 0 && (step % 100 === 0 || step % 120 === 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user