요청: EV렌더러-라이브드래그
- 날짜: 2026-07-21 12:30:38
- 작업 경로: /Users/ef/crowny-ev/public
요청 본문
EV 뷰포트를 CAD 렌더러 패턴(포인터 드래그+RAF+SVG속성 직접변이)으로 실시간 움직이게. 실루엣 파라미터 드래그 슬라이더화
관련 산출
개요
EV 실루엣 파라미터(루프 높이·지상고·휠·사이드 덕트) 4종을 +/− 스테퍼(→innerHTML 전체 리페인트) 방식에서 design.crowny.org(Crowny CAD) 렌더러 패턴(svgPointFromEvent/onViewportMove/updatePreview, rAF 스로틀+SVG 속성 직접변이)을 그대로 이식한 드래그 슬라이더로 전환. 서버(:9616)는 정적파일이라 무수정, index.html만 수정.
CAD 패턴 이식 매핑
svgPointFromEvent(svg,e)→ 이번 작업은 SVG 좌표 변환이 아니라 트랙 pointer→값 매핑(_sliderValueFromEvent)이라 getScreenCTM 대신getBoundingClientRect()사용(슬라이더 트랙은 1D 값이라 SVG 좌표계 불필요).onViewportDown→_sliderDown(e,key,lo,hi,trackEl)(pointerdown 위임에서 호출).onViewportMove(this._moveRaf 가드) →_onDragMove(e)(this._dragRaf 가드, requestAnimationFrame 스로틀).updatePreview(기존 엘리먼트 속성만 setAttribute) →_applyDragFrame()(ev-body/ev-glass/ev-roofline/ev-duct/ev-hilite/ev-headlight/ev-taillight/ev-split/ev-fin-N/ev-wheel-N-{tire,rim,hub,caliper} + 슬라이더 thumb/fill + 값 라벨 텍스트만 직접 변이, innerHTML 재작성 없음).- pointerup 커밋 시 CAD와 동일하게 1회
this.render()로 전체 동기화(가격·항속·검수 등 파생 라벨 재계산).
무엇을 했는지
EvApp.prototype.computeCarGeom(st)신규 — 기존computeVals()안에 인라인이던 측면 car 지오메트리 계산부(bodyD/glassD/roofLineD/ductD/hlD/hiliteD/splitD/duckD/difFins/wheels)를 순수함수로 분리.computeVals()는var car = self.computeCarGeom(st);로 호출(회귀0, node로 원본 수식과 문자열 diff 확인 — PASS).- 측면 SVG(svgSide) 엘리먼트에 안정 id 부여:
ev-body ev-glass ev-duct ev-hilite ev-headlight ev-taillight ev-roofline ev-split ev-fins/ev-fin-N ev-wheel-{0,1} ev-wheel-{0,1}-{tire,rim,hub,caliper}. - 우측 패널 실루엣 파라미터 4행(루프 높이·지상고·휠·사이드 덕트)에 기존 +/− 스테퍼 아래 드래그 트랙(
.ev-slider-track+.ev-slider-fill+.ev-slider-thumb) 추가.paramDefs→params에 key/lo/hi/step/pct 필드 추가. - 드래그 핸들러 6종 신규:
_sliderValueFromEvent_sliderDown_onDragMove_applyDragFrame_onDragEndbindDrag.bindDrag()를 DOMContentLoaded 부트스트랩에app.bindDrag()로 연결(bindDom/bindKeys와 병렬). - 한선씨 동반:
EV엔진.한선에 §9 측면 뷰 지오메트리 스칼라(geom_wheelR_x10/geom_rimR_x10/geom_botY_x10/geom_roofY_x10/geom_dxDuct_x10/geom_archR_x10 + geom_자가검사) ×10 고정소수점으로 추가 — SVG 경로 문자열 조립·pointer 드래그·DOM setAttribute 자체는 VM에 DOM이 없어 이식 불가(브라우저 전용, 파일 상단 기존 주석과 동일 전제)이므로 산식 핵심(수치)만 동반.
node 검증 결과
node --check(스크립트 추출) SYNTAX OK.- computeCarGeom 회귀: 기본상태 bodyD/glassD/roofLineD/wheels 문자열이 리팩터 전 원본 인라인 수식과 완전 동일(PASS).
- 반응성 diff: gc=95 vs 135 → bodyD 다름(true), roofH=1160 vs 1240 → bodyD 다름(true), wheelIn=19 vs 21 → wheels 다름(true, tireR 37→39.8 rimR 26.5→29.3), ductS=0 vs 100 → ductD 다름(true).
- 6뷰(side/front/color/spec/order/parts) 전부 render() 무예외 + panel-{id} 보존 확인(jsdom 없이 vm+stub root로 innerHTML 캡처).
hanseonc_high EV엔진.한선컴파일 exit 0,geom_자가검사()실행 결과 1(PASS) — wheelR20×10=384, rimR20×10=279, botY115×10=3194, roofY1201×10=1999, dxDuct60×10=380 (JS 대조 38.4/27.9/319.4/199.9/38.0, 정수화 오차 0~1).- curl로 :9616 라이브 서빙 확인 — 응답 바이트가 로컬 파일과 diff -q 일치,
id="ev-body"등 신규 마크업 그대로 반영(서버 무수정, 정적파일 즉시 반영).
관련 파일
/Users/ef/crowny-ev/public/index.html— computeCarGeom(197~239행), computeVals car 호출부, svgSide id 부여, panel-side 슬라이더 마크업, 드래그 핸들러 6종(1165~1273행), bindDrag 부트스트랩 연결./Users/ef/crowny-ev/EV엔진.한선— §9 측면 뷰 지오메트리 스칼라(geom_ 함수, 916행 이후 추가).- 참조 정본:
/Users/ef/crowny-cad/앱.html(494~571행 svgPointFromEvent/onViewportDown/updatePreview/onViewportMove),/Users/ef/Downloads/design_handoff_crowny_ev/Crowny EV.dc.html(EV 스펙 정본).
잔여 이슈
- 육안(브라우저 실제 드래그 동작·손맛)은 미검증 — node로는 DOM pointer 이벤트·rAF 렌더 타이밍을 실측할 수 없음. 사용자가 crowny://ev 또는 https://ev.crowny.org에서 직접 확인 필요.
- splitter/diffuser 토글 ON 상태에서 드래그 시
ev-split/ev-fin-N은 갱신되지만, 스포크·랩핑(투톤루프/스트라이프) 등 부차 장식은 드래그 중 실시간 갱신 대상에서 제외(mouseup 시 full render로 동기화) — 의도적 축소(지시문 "과하면 핵심 car+파라미터라벨만"). - 슬라이더 트랙은 마우스/터치 겸용 pointer 이벤트 사용(pointerdown/pointermove/pointerup) — 구형 브라우저 폴리필 미고려(사내 크롬 기준 문제없음 가정).
- computeCarGeom 산식과 EV엔진.한선 geom_ 함수는 별도 구현(중복)이라 향후 산식 변경 시 양쪽 동시 갱신 필요(EV엔진.한선 파일 상단 기존 관례와 동일한 트레이드오프).