Merge pull request '[2296-2] 모듈 이동 시 モジュール間離隔(간격) 미검증 수정 + 입력창 Del키 막힘(preventDefault) 수정' (#938) from dev into dev-deploy
Reviewed-on: #938
This commit is contained in:
commit
00499c8692
@ -113,6 +113,9 @@ export function useModule() {
|
|||||||
|
|
||||||
const moduleMove = (length, direction) => {
|
const moduleMove = (length, direction) => {
|
||||||
const selectedObj = canvas.getActiveObjects() //선택된 객체들을 가져옴
|
const selectedObj = canvas.getActiveObjects() //선택된 객체들을 가져옴
|
||||||
|
// [MOVE-CLEARANCE 2026-07-01] 경고 후 선택 해제 상태에서 재시도 시 selectedObj[0] undefined 크래시 방지
|
||||||
|
// (형제 함수 moduleMultiMove 와 동일한 선택 없음 가드)
|
||||||
|
if (selectedObj.length === 0) return
|
||||||
const selectedIds = selectedObj.map((obj) => obj.id) // selectedObj의 ID 추출
|
const selectedIds = selectedObj.map((obj) => obj.id) // selectedObj의 ID 추출
|
||||||
if (selectedObj[0].circuit) {
|
if (selectedObj[0].circuit) {
|
||||||
swalFire({
|
swalFire({
|
||||||
@ -144,7 +147,9 @@ export function useModule() {
|
|||||||
|
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
|
|
||||||
if (isOverlapOtherModules(module, isSetupModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, setupSurface)) {
|
// [MOVE-CLEARANCE 2026-07-01] 이동 시 モジュール間離隔 검증 추가 (isTooCloseToOtherModules)
|
||||||
|
const _tooClose = isTooCloseToOtherModules(module, isSetupModules, setupSurface)
|
||||||
|
if (isOverlapOtherModules(module, isSetupModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, setupSurface) || _tooClose) {
|
||||||
isWarning = true
|
isWarning = true
|
||||||
module.set({ fill: 'red' })
|
module.set({ fill: 'red' })
|
||||||
}
|
}
|
||||||
@ -222,7 +227,13 @@ export function useModule() {
|
|||||||
module.setCoords()
|
module.setCoords()
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
|
|
||||||
if (isOverlapOtherModules(module, otherModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
// [MOVE-CLEARANCE 2026-07-01] 행/열 이동 시 モジュール間離隔 검증 추가
|
||||||
|
if (
|
||||||
|
isOverlapOtherModules(module, otherModules) ||
|
||||||
|
isOverlapObjects(module, objects) ||
|
||||||
|
isOutsideSurface(module, moduleSetupSurface) ||
|
||||||
|
isTooCloseToOtherModules(module, otherModules, moduleSetupSurface)
|
||||||
|
) {
|
||||||
isWarning = true
|
isWarning = true
|
||||||
module.set({ fill: 'red' })
|
module.set({ fill: 'red' })
|
||||||
}
|
}
|
||||||
@ -1052,6 +1063,47 @@ export function useModule() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [MOVE-CLEARANCE 2026-07-01] 이동 시 モジュール間離隔(縦 moduleIntvlVer / 横 moduleIntvlHor) 미검증 보완.
|
||||||
|
// isOverlapOtherModules 는 실제 겹침만 보므로, 이동으로 모듈을 인접 모듈에 30/3mm 미만으로 붙여도 통과한다.
|
||||||
|
// 같은 열(X-range 겹침)→세로 간격>=Ver, 같은 행(Y-range 겹침)→가로 간격>=Hor 요구.
|
||||||
|
//
|
||||||
|
// ⚠ 간격은 반드시 stroke 를 뺀 실제 폴리곤 정점(getCurrentPoints)으로 잰다.
|
||||||
|
// getBoundingRect 는 strokeWidth 를 포함해 모듈이 실제보다 커 보이고(1606→1609mm),
|
||||||
|
// 정상 격자(정확히 30/3mm)도 측정 간격이 축소돼 위반 오판 → 모든 방향 이동 차단(회귀) 발생.
|
||||||
|
const isTooCloseToOtherModules = (module, otherModules, surface) => {
|
||||||
|
if (!otherModules || otherModules.length === 0) return false
|
||||||
|
const gapVer = Number(surface?.trestleDetail?.moduleIntvlVer ?? 0) / 10 // mm → canvas unit
|
||||||
|
const gapHor = Number(surface?.trestleDetail?.moduleIntvlHor ?? 0) / 10
|
||||||
|
if (gapVer <= 0 && gapHor <= 0) return false
|
||||||
|
const EPS = 0.05 // 0.5mm — 좌표 반올림 잔차(±0.02) 흡수, 의미있는 위반은 통과 못함
|
||||||
|
const bboxOf = (o) => {
|
||||||
|
const pts = o.getCurrentPoints ? o.getCurrentPoints() : null
|
||||||
|
if (pts && pts.length) {
|
||||||
|
const xs = pts.map((p) => p.x)
|
||||||
|
const ys = pts.map((p) => p.y)
|
||||||
|
return { l: Math.min(...xs), r: Math.max(...xs), t: Math.min(...ys), b: Math.max(...ys) }
|
||||||
|
}
|
||||||
|
const r = o.getBoundingRect(true, true)
|
||||||
|
return { l: r.left, r: r.left + r.width, t: r.top, b: r.top + r.height }
|
||||||
|
}
|
||||||
|
const mb = bboxOf(module)
|
||||||
|
return otherModules.some((o) => {
|
||||||
|
if (o.id === module.id) return false
|
||||||
|
const nb = bboxOf(o)
|
||||||
|
const overlapX = mb.l < nb.r - EPS && nb.l < mb.r - EPS
|
||||||
|
const overlapY = mb.t < nb.b - EPS && nb.t < mb.b - EPS
|
||||||
|
if (overlapX) {
|
||||||
|
const vGap = mb.t >= nb.b ? mb.t - nb.b : nb.t >= mb.b ? nb.t - mb.b : 0
|
||||||
|
if (vGap < gapVer - EPS) return true
|
||||||
|
}
|
||||||
|
if (overlapY) {
|
||||||
|
const hGap = mb.l >= nb.r ? mb.l - nb.r : nb.l >= mb.r ? nb.l - mb.r : 0
|
||||||
|
if (hGap < gapHor - EPS) return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const isOverlapObjects = (module, objects) => {
|
const isOverlapObjects = (module, objects) => {
|
||||||
return !checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects)
|
return !checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -372,6 +372,12 @@ export function useCanvasEvent() {
|
|||||||
* https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values
|
* https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values
|
||||||
*/
|
*/
|
||||||
const handleKeyDown = (e) => {
|
const handleKeyDown = (e) => {
|
||||||
|
// [INPUT-GUARD 2026-07-01] 입력창/텍스트에어리어 포커스 중에는 캔버스 단축키 처리를 건너뛴다.
|
||||||
|
// Delete/Backspace 케이스가 switch 에 매칭돼 아래 preventDefault 까지 도달, 필드 내 문자삭제를 막던 버그.
|
||||||
|
// (QContextMenu wrappedKeyup 과 동일한 편집요소 가드)
|
||||||
|
const el = document.activeElement
|
||||||
|
if (el && (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA' || el.isContentEditable)) return
|
||||||
|
|
||||||
const key = e.key
|
const key = e.key
|
||||||
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user