fix(B07): CAD 그림 그리기의 y 뒤집기 누락 수정 — 도각 로고·서명이 화면에 안 보이던 원인
- screenCanvas.drawController.drawImage 가 worldToTarget 결과를 그대로 써서 그림이 거울상 자리(캔버스 밖)에 놓였음. 선·글자처럼 canvasSize.y - y 로 뒤집고 회전 부호도 반대로 - vitest 추가: 그림 중심의 뒤집힌 y 자리, 회전 부호·원상 복구 - 검증(공용 브라우저, 종단면도): 로고 상자 비배경 픽셀 0 → 14708(파랑 11661), 서명 상자 498 → 2810(빨강 852). 뷰는 187% 로 정확히 복귀
This commit is contained in:
@@ -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]);
|
||||
});
|
||||
});
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user