/** * 직교(337 마 · H8) — F8 이면 기준점에서 가로 · 세로로 늘 내림(커서 · 누름 · 거리 숫자 방향) · * Shift 누른 동안 뒤집음(오토캐드 임시 우선 키 · 마우스 사건 shiftKey 로 · keyup 안 씀) · * 객체 스냅 점 · 친 좌표 · 각도 잠금은 안 덮음. 직교인 동안 극 추적 가이드 점은 스냅으로 안 침. */ import { Point } from '@flatten-js/core'; import { compact } from 'es-toolkit'; import { SNAP_POINT_DISTANCE } from '../App.consts.ts'; import { type SnapPoint, SnapPointType } from '../App.types.ts'; import { getClosestSnapPointWithinRadius } from '../helpers/get-closest-snap-point.ts'; import { getAngleStep, getScreenCanvasDrawController, getSnapPoint, getSnapPointOnAngleGuide, } from '../state.ts'; let shiftHeld = false; /** 마우스 사건마다 Shift 상태를 적어 둠(커서 미리보기 · 거리 숫자 방향이 읽음) */ export const noteShift = (evt: { shiftKey?: boolean }): void => { shiftHeld = !!evt.shiftKey; }; /** 직교 켬 = F8(각 간격 90) XOR Shift */ export const orthoOn = (shift: boolean = shiftHeld): boolean => (getAngleStep() === 90) !== shift; /** 기준점에서 가로 · 세로 중 커서에 가까운 쪽으로 내림 */ export const orthoPoint = (base: Point, point: Point): Point => Math.abs(point.x - base.x) >= Math.abs(point.y - base.y) ? new Point(point.x, base.y) : new Point(base.x, point.y); /** 그 자리에서 누르면 잡힐 스냅 점(누름과 같은 셈 · 반경 = 화면 픽셀) */ export function snapAt(world: Point): SnapPoint | null { return getClosestSnapPointWithinRadius( compact([getSnapPoint(), getSnapPointOnAngleGuide()]), world, SNAP_POINT_DISTANCE / getScreenCanvasDrawController().getScreenScale() ); } /** 스냅 점이 직교를 막는가 — 극 추적 가이드 점은 직교 중엔 안 막음 */ export const isObjectSnap = (snap: SnapPoint | null): boolean => !!snap && snap.type !== SnapPointType.AngleGuide;