diff --git a/B07_DesignDetail/openwebcad/src/drawControllers/screenCanvas.drawController.ts b/B07_DesignDetail/openwebcad/src/drawControllers/screenCanvas.drawController.ts index 8b0d6a17..0d2032d7 100644 --- a/B07_DesignDetail/openwebcad/src/drawControllers/screenCanvas.drawController.ts +++ b/B07_DesignDetail/openwebcad/src/drawControllers/screenCanvas.drawController.ts @@ -107,13 +107,14 @@ export class ScreenCanvasDrawController implements DrawController { * This function takes the deltaY from the mouse wheel event and zooms the screen in or out * The location of the mouse in world space is preserved * @param deltaY + * @param strength 한 번에 얼마나 확대할지(휠 한 칸 = 1). 트랙패드의 잔 델타용. */ - public zoomScreen(deltaY: number) { + public zoomScreen(deltaY: number, strength = 1) { const worldMouseLocationBeforeZoom = this.getWorldMouseLocation(); const oldScreenScale = this.getScreenScale(); const newScreenScale = - oldScreenScale * (1 - MOUSE_ZOOM_MULTIPLIER * (deltaY / Math.abs(deltaY))); + oldScreenScale * (1 - MOUSE_ZOOM_MULTIPLIER * strength * (deltaY / Math.abs(deltaY))); this.setScreenScale(newScreenScale); // now get the location of the cursor in world space again diff --git a/B07_DesignDetail/openwebcad/src/inputController/input-controller.ts b/B07_DesignDetail/openwebcad/src/inputController/input-controller.ts index 55c0592a..f5c8de0a 100644 --- a/B07_DesignDetail/openwebcad/src/inputController/input-controller.ts +++ b/B07_DesignDetail/openwebcad/src/inputController/input-controller.ts @@ -67,13 +67,25 @@ export class InputController { canvas?.addEventListener('mousedown', (evt: MouseEvent) => this.handleMouseDown(evt)); canvas?.addEventListener('mousemove', (evt: MouseEvent) => this.handleMouseMove(evt)); canvas?.addEventListener('mouseup', (evt: MouseEvent) => this.handleMouseUp(evt)); - canvas?.addEventListener('wheel', (evt: WheelEvent) => this.handleMouseWheel(evt)); + // passive:false — 핀치·휠의 브라우저 기본 확대/스크롤을 막아야 한다. + canvas?.addEventListener('wheel', (evt: WheelEvent) => this.handleMouseWheel(evt), { + passive: false, + }); canvas?.addEventListener('mouseout', () => this.handleMouseOut()); canvas?.addEventListener('mouseenter', () => this.handleMouseEnter()); // Stop the context menu from appearing when right-clicking canvas?.addEventListener('contextmenu', (evt) => { evt.preventDefault(); }); + // 캔버스 밖(리본·패널) 위에서의 트랙패드 핀치도 브라우저를 확대시키지 않는다. + // ctrl이 없는 휠은 그대로 둬서 패널 스크롤은 살린다. + document.addEventListener( + 'wheel', + (evt: WheelEvent) => { + if (evt.ctrlKey) evt.preventDefault(); + }, + { passive: false } + ); } public draw(drawController: ScreenCanvasDrawController) { @@ -214,13 +226,19 @@ export class InputController { * @param evt */ public handleMouseWheel(evt: WheelEvent) { + // 확대는 도면만 — 트랙패드 핀치(ctrl+휠)가 브라우저 전체를 키우던 것을 막는다. + evt.preventDefault(); if (Math.abs(evt.deltaY) === 0) { return; // We can't zoom by zero delta } const drawController = getScreenCanvasDrawController(); + // 휠 한 칸(deltaY 100, 줄 단위면 3)을 세기 1로 본다. 트랙패드는 잔 델타를 + // 초당 수십 번 보내므로 세기를 델타에 비례시켜야 한 번에 튀지 않는다. + const notch = evt.deltaMode === 0 ? 100 : 3; + const strength = Math.min(1, Math.max(0.12, Math.abs(evt.deltaY) / notch)); // 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(-evt.deltaY, strength); } public handleMouseDown(evt: MouseEvent) {