Files
Aislo/resources/tester/helper_383_2_key_nudge.cjs
T
eomsangdonandClaude Opus 5.5 e0abf8c5bf feat(383-2): 평면 교각점 방향키 — 화면 축 0.1 m · Shift ×10 · 뗄 때 한 걸음(스냅이면 맞춤 + 실제 이동 · 함께 밀린 IP)
- 새 파일 B05_Profile_UI_RouteEdit_Keys.ts(창 keydown 가로채기 · 마지막 누름 평면 안 · 고정 · 입력칸 제외 · 하한 검사) + logic/KeyNudge
- 평면을 누른 뒤 방향키는 평면이 삼킴 — 종단 ▲▼ · 횡단 조정창으로 안 샘
- B06 Panel_Base lastPointerWithin 넓힘 · Pointer.ts 걸기 한 줄

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ji4nuyLVHcxrXWHTdb5nRD
2026-10-17 15:11:46 +09:00

79 lines
2.6 KiB
JavaScript

/* 383-2 교각점 방향키 — `logic/B05_Profile_RouteEdit_KeyNudge.ts` 를 Node 로 돌려 JSON 한 줄을 냄
* (`test_383_2_route_keys.py` 가 판정). `.cjs` = 루트 package.json 이 "type": "module" 이라서.
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const ROOT = path.join(__dirname, "..", "..");
const cache = new Map();
function loadTs(file) {
const full = path.resolve(file);
if (cache.has(full)) return cache.get(full);
const js = ts.transpileModule(fs.readFileSync(full, "utf8"), {
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) =>
request.startsWith(".")
? loadTs(path.join(path.dirname(full), `${request}.ts`))
: require(request);
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
const nudge = loadTs(path.join(ROOT, "B05_Profile", "logic", "B05_Profile_RouteEdit_KeyNudge.ts"));
// 화면 → 도면: 1 px = 0.5 m · 화면 y 아래 = 도면 y 위로 뒤집힘 · 지도 30° 돌림
const turn = (Math.PI / 180) * 30;
const plain = (x, y) => [x * 0.5, -y * 0.5];
const rotated = (x, y) => {
const [mx, my] = plain(x, y);
return [mx * Math.cos(turn) - my * Math.sin(turn), mx * Math.sin(turn) + my * Math.cos(turn)];
};
const keys = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"];
const steps = (metricAt, shift) =>
Object.fromEntries(keys.map((key) => [key, nudge.arrowStep(key, shift, metricAt)]));
const before = [
[0, 0],
[50, 0],
[100, 20],
[150, 0],
];
const snapped = [
[0, 0],
[50.8, 0],
[100, 20.6],
[150, 0],
];
const stayed = [
[0, 0],
[50.02, 0],
[100, 20],
[150, 0],
];
const merged = [
[0, 0],
[50.4, 0],
[150, 0],
];
const out = {
plain: steps(plain, false),
shift: steps(plain, true),
rotated: steps(rotated, false),
arrows: keys.map(nudge.isArrowKey).concat(nudge.isArrowKey("Enter")),
snapped: nudge.nudgeReport(before, snapped, 1, [50, 0], [50.3, 0]),
stayed: nudge.nudgeReport(before, stayed, 1, [50, 0], [50.3, 0]),
merged: nudge.nudgeReport(before, merged, 1, [50, 0], [50.3, 0]),
messages: {
snapped: nudge.nudgeMessage({ movedM: 0.8, pushed: 1 }, true),
stayed: nudge.nudgeMessage({ movedM: 0.02, pushed: 0 }, true),
free: nudge.nudgeMessage({ movedM: 0.3, pushed: 0 }, false),
},
};
process.stdout.write(JSON.stringify(out));