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); }