From e59988488834fea7d59d765b6bbbf6ffab4259ec Mon Sep 17 00:00:00 2001 From: umsangdon Date: Sun, 30 Aug 2026 14:43:46 +0900 Subject: [PATCH] =?UTF-8?q?feat(B07):=20=EA=B7=B8=EB=A6=BD=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EA=B3=A0=EC=B9=98=EA=B3=A0,=20=EC=9D=8C=EC=88=98?= =?UTF-8?q?=C2=B7=EA=B7=B9=EC=A2=8C=ED=91=9C=EB=A5=BC=20=EB=B0=9B=EA=B3=A0?= =?UTF-8?q?,=20=ED=8E=B8=EC=A7=91=EB=B6=84=EC=9D=84=20=EC=9E=83=EC=A7=80?= =?UTF-8?q?=20=EC=95=8A=EB=8A=94=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 조사표 8~13절 검토에서 "기본 기능"으로 고른 것을 반영한다. - 좌표 입력: 절대·상대 좌표가 양수만 받아 `@-100,50`을 거부했다. 부호를 허용하고 극좌표 `@거리<각도`·`거리<각도`를 더했다. `-`·`+`가 확대·축소 단축키로 먼저 잡혀 음수의 첫 글자를 먹고 있어 그 두 단축키를 뺐다(줌은 휠·뷰 막대·명령). - 그립 편집: 선택 객체에 그립을 그리고 집어서 옮긴다. 선 끝점·중점, 폴리선 정점, 사각형 모서리, 원 중심·반지름, 문자·점 기준점. 폴리선은 세그먼트 중점을 끌면 정점이 늘고 정점 위 Ctrl+클릭이면 준다. 형상 필드가 private이라 공개 생성자로 다시 만들어 바꿔 끼우고 id·도면층·색·그룹을 물려받는다. - 자동 백업·복구: 5초 디바운스로 복구 전용 키에 저장하고, 시작할 때 백업이 있으면 눌러서 되살리는 안내를 띄운다. 저장(QSAVE)에 성공하면 백업을 지운다. - 선택 순환: 같은 자리를 다시 클릭하면 겹친 후보를 차례로 돌린다. - 상태막대: `극좌표 추적` 버튼이 `직교`와 같은 onClick이라 같은 일을 하고 있었다. 각각 45°·90°를 켜고 끄도록 고치고, 스냅 추적 토글과 F3·F7·F8·F10을 붙였다. - 문자 굵게·기울임을 캔버스·SVG·JSON·스타일 패널에 연결했다. - 조사표: 이미 되어 있던 5건의 표기를 정정하고, 출력·내보내기(9절)는 결재창 이후 PDF·DXF·DWG로 반영할 것이라 보류(P)로 구분해 사유를 남겼다. Co-Authored-By: Claude Opus 5 (1M context) --- B07_DesignDetail/openwebcad/src/App.consts.ts | 3 + .../openwebcad/src/commands/commands.file.ts | 18 +- .../src/components/RibbonWidgets.tsx | 18 +- .../openwebcad/src/components/StatusBar.tsx | 22 +- .../src/drawControllers/DrawController.ts | 2 + .../screenCanvas.drawController.ts | 6 +- .../src/drawControllers/svg.drawController.ts | 2 +- .../openwebcad/src/entities/TextEntity.ts | 9 + .../openwebcad/src/helpers/autosave.ts | 83 ++++++++ .../calculate-angle-guides-and-snap-points.ts | 12 +- .../openwebcad/src/helpers/draw-functions.ts | 44 +++- .../openwebcad/src/helpers/draw.ts | 103 ++++----- .../src/helpers/find-closest-entity.ts | 21 +- .../openwebcad/src/helpers/get-draw-guides.ts | 4 +- .../openwebcad/src/helpers/grips.ts | 199 ++++++++++++++++++ .../src/inputController/input-controller.ts | 129 ++++++++---- B07_DesignDetail/openwebcad/src/main.tsx | 8 +- B07_DesignDetail/openwebcad/src/state.ts | 14 +- B07_DesignDetail/openwebcad/src/tools.ts | 1 + .../openwebcad/src/tools/grip-edit-tool.ts | 115 ++++++++++ .../src/tools/select-tool.helpers.ts | 72 ++++++- .../openwebcad/임시_AutoCAD_리본_기능_조사.md | 43 ++-- 22 files changed, 779 insertions(+), 149 deletions(-) create mode 100644 B07_DesignDetail/openwebcad/src/helpers/autosave.ts create mode 100644 B07_DesignDetail/openwebcad/src/helpers/grips.ts create mode 100644 B07_DesignDetail/openwebcad/src/tools/grip-edit-tool.ts diff --git a/B07_DesignDetail/openwebcad/src/App.consts.ts b/B07_DesignDetail/openwebcad/src/App.consts.ts index 7f4c9292..8e517983 100644 --- a/B07_DesignDetail/openwebcad/src/App.consts.ts +++ b/B07_DesignDetail/openwebcad/src/App.consts.ts @@ -65,6 +65,9 @@ export const HIGHLIGHT_ENTITY_DISTANCE = 15; * The size of the snap point indicator shapes that are shown on active snap points */ export const SNAP_POINT_SIZE = 15; +/** 그립 사각형의 화면 크기(px)와 색 — 선택 객체의 편집점 */ +export const GRIP_SIZE = 8; +export const GRIP_COLOR = '#3aa0ff'; /** * How long you need to hover over a snap point to make it a marked snap point that will show angle guides diff --git a/B07_DesignDetail/openwebcad/src/commands/commands.file.ts b/B07_DesignDetail/openwebcad/src/commands/commands.file.ts index 71c1c3a8..a1bc7986 100644 --- a/B07_DesignDetail/openwebcad/src/commands/commands.file.ts +++ b/B07_DesignDetail/openwebcad/src/commands/commands.file.ts @@ -1,11 +1,12 @@ /** 빠른 실행 도구막대 · 출력 탭 명령 (파일 수명주기) */ import { toast } from 'react-toastify'; -import type { CadCommand } from './command.types'; +import { clearRecovery, restoreRecovery } from '../helpers/autosave'; import { exportEntitiesToJsonFile } from '../helpers/import-export-handlers/export-entities-to-json'; import { exportEntitiesToLocalStorage } from '../helpers/import-export-handlers/export-entities-to-local-storage'; import { exportEntitiesToPngFile } from '../helpers/import-export-handlers/export-entities-to-png'; import { exportEntitiesToSvgFile } from '../helpers/import-export-handlers/export-entities-to-svg'; import { redo, undo } from '../state'; +import type { CadCommand } from './command.types'; export const FILE_COMMANDS: CadCommand[] = [ { @@ -15,10 +16,23 @@ export const FILE_COMMANDS: CadCommand[] = [ glyph: '💾', hint: '현재 도면을 브라우저에 저장한다', run: () => { - void exportEntitiesToLocalStorage().then(() => toast.success('도면을 저장했습니다.')); + void exportEntitiesToLocalStorage().then(() => { + clearRecovery(); + toast.success('도면을 저장했습니다.'); + }); return '도면 저장'; }, }, + { + id: 'RECOVER', + label: '백업 복구', + glyph: '⟲', + hint: '자동 백업된 마지막 편집을 되살린다', + run: () => { + void restoreRecovery(); + return '백업 복구'; + }, + }, { id: 'EXPORT', label: 'JSON 내보내기', diff --git a/B07_DesignDetail/openwebcad/src/components/RibbonWidgets.tsx b/B07_DesignDetail/openwebcad/src/components/RibbonWidgets.tsx index 1b05d47a..fe8ece4a 100644 --- a/B07_DesignDetail/openwebcad/src/components/RibbonWidgets.tsx +++ b/B07_DesignDetail/openwebcad/src/components/RibbonWidgets.tsx @@ -1,5 +1,6 @@ /** 리본 안에 들어가는 위젯 패널 — 특성(색·굵기·선종류), 도면층, 문자 스타일 */ import type { FC } from 'react'; +import { runCommandInput } from '../commands/run-command'; import type { Entity } from '../entities/Entity'; import { EntityName } from '../entities/Entity'; import type { TextEntity } from '../entities/TextEntity'; @@ -19,7 +20,6 @@ import { setActiveTextStyle, setEntities, } from '../state'; -import { runCommandInput } from '../commands/run-command'; export const LINE_TYPES: { value: string; label: string; dash: number[] | undefined }[] = [ { value: 'solid', label: '실선', dash: undefined }, @@ -178,6 +178,22 @@ export const TextStyleWidget: FC = () => { }} /> + +