From 1250cabe71dfae701854e2285542928da0fe0d17 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Wed, 2 Sep 2026 12:24:26 +0900 Subject: [PATCH] =?UTF-8?q?fix(B07):=20CAD=20=EA=B7=B8=EB=A6=BC=20?= =?UTF-8?q?=EA=B7=B8=EB=A6=AC=EA=B8=B0=EC=9D=98=20y=20=EB=92=A4=EC=A7=91?= =?UTF-8?q?=EA=B8=B0=20=EB=88=84=EB=9D=BD=20=EC=88=98=EC=A0=95=20=E2=80=94?= =?UTF-8?q?=20=EB=8F=84=EA=B0=81=20=EB=A1=9C=EA=B3=A0=C2=B7=EC=84=9C?= =?UTF-8?q?=EB=AA=85=EC=9D=B4=20=ED=99=94=EB=A9=B4=EC=97=90=20=EC=95=88=20?= =?UTF-8?q?=EB=B3=B4=EC=9D=B4=EB=8D=98=20=EC=9B=90=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - screenCanvas.drawController.drawImage 가 worldToTarget 결과를 그대로 써서 그림이 거울상 자리(캔버스 밖)에 놓였음. 선·글자처럼 canvasSize.y - y 로 뒤집고 회전 부호도 반대로 - vitest 추가: 그림 중심의 뒤집힌 y 자리, 회전 부호·원상 복구 - 검증(공용 브라우저, 종단면도): 로고 상자 비배경 픽셀 0 → 14708(파랑 11661), 서명 상자 498 → 2810(빨강 852). 뷰는 187% 로 정확히 복귀 --- .../screenCanvas.drawController.test.ts | 39 +++++++++++++++++++ .../screenCanvas.drawController.ts | 10 +++-- 2 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 B07_DesignDetail/openwebcad/src/drawControllers/screenCanvas.drawController.test.ts diff --git a/B07_DesignDetail/openwebcad/src/drawControllers/screenCanvas.drawController.test.ts b/B07_DesignDetail/openwebcad/src/drawControllers/screenCanvas.drawController.test.ts new file mode 100644 index 00000000..bad08fe9 --- /dev/null +++ b/B07_DesignDetail/openwebcad/src/drawControllers/screenCanvas.drawController.test.ts @@ -0,0 +1,39 @@ +import { Point } from '@flatten-js/core'; +import { describe, expect, it } from 'vitest'; +import { ScreenCanvasDrawController } from './screenCanvas.drawController'; + +/** translate·drawImage 인자만 기록하는 최소 2d 컨텍스트. */ +function recordingContext() { + const calls: { translate: number[][]; rotate: number[]; image: number[] } = { + translate: [], + rotate: [], + image: [], + }; + const context = { + translate: (x: number, y: number) => calls.translate.push([x, y]), + rotate: (a: number) => calls.rotate.push(a), + drawImage: (_img: unknown, ...rest: number[]) => calls.image.push(...rest), + } as unknown as CanvasRenderingContext2D; + return { context, calls }; +} + +describe('ScreenCanvasDrawController.drawImage', () => { + it('그림 중심은 선·글자와 같은 뒤집힌 y 자리에 놓인다', () => { + const { context, calls } = recordingContext(); + const controller = new ScreenCanvasDrawController(context); + controller.setCanvasSize(new Point(800, 600)); + controller.setScreenOffset(new Point(0, 0)); + // 세계 (10,-20)~(42,-4) 상자 — 도각 로고 자리처럼 원점 아래. + controller.drawImage({} as HTMLImageElement, 10, -20, 32, 16, 0); + const center = controller.worldToTarget(new Point(26, -12)); + expect(calls.translate[0]).toEqual([center.x, 600 - center.y]); + expect(calls.image).toEqual([-16, -8, 32, 16]); + }); + + it('회전은 y 뒤집기에 맞춰 부호를 바꾸고 원상 복구한다', () => { + const { context, calls } = recordingContext(); + const controller = new ScreenCanvasDrawController(context); + controller.drawImage({} as HTMLImageElement, 0, 0, 4, 2, 0.5); + expect(calls.rotate).toEqual([-0.5, 0.5]); + }); +}); diff --git a/B07_DesignDetail/openwebcad/src/drawControllers/screenCanvas.drawController.ts b/B07_DesignDetail/openwebcad/src/drawControllers/screenCanvas.drawController.ts index efaa8a31..4facbdbd 100644 --- a/B07_DesignDetail/openwebcad/src/drawControllers/screenCanvas.drawController.ts +++ b/B07_DesignDetail/openwebcad/src/drawControllers/screenCanvas.drawController.ts @@ -603,11 +603,13 @@ export class ScreenCanvasDrawController implements DrawController { const screenHeight = height * this.screenScale; const screenCenter = this.worldToTarget(new Point(xMin + width / 2, yMin + height / 2)); const screenCenterX = screenCenter.x; - const screenCenterY = screenCenter.y; + // 다른 그리기와 같이 y 를 뒤집는다 — worldToTarget 은 수학 좌표(위가 +y)라 그대로 + // 쓰면 그림이 거울상 자리(캔버스 밖)에 놓여 화면에 안 보인다(2026-09-02 도각 로고). + const screenCenterY = this.canvasSize.y - screenCenter.y; - // Rotate and translate context + // Rotate and translate context (y 를 뒤집었으니 회전 방향도 반대) this.context.translate(screenCenterX, screenCenterY); - this.context.rotate(angle); + this.context.rotate(-angle); // Draw image this.context.drawImage( @@ -619,7 +621,7 @@ export class ScreenCanvasDrawController implements DrawController { ); // Reset context - this.context.rotate(-angle); + this.context.rotate(angle); this.context.translate(-screenCenterX, -screenCenterY); }