Compare commits

..

No commits in common. "d27fd25acaecd7c02de7e1ca08e8f2678c739c4f" and "1684d9254c4225f3d9d6ea0b5fe532570a3998cd" have entirely different histories.

3 changed files with 19 additions and 87 deletions

View File

@ -183,64 +183,29 @@ export const QLine = fabric.util.createClass(fabric.Line, {
return this return this
}, },
setCoords: function () {
// 부모 클래스의 setCoords 호출
this.callSuper('setCoords')
// QLine의 경우 추가 처리 - 항상 강제로 재계산
if (this.canvas) {
// 모든 좌표 관련 캐시 초기화
delete this.oCoords
delete this.aCoords
delete this.__corner
// 다시 부모 setCoords 호출
this.callSuper('setCoords')
// 한 번 더 강제로 bounding rect 재계산
this._clearCache && this._clearCache()
}
},
containsPoint: function(point) { containsPoint: function(point) {
// 먼저 좌표 업데이트
this.setCoords()
// 캔버스 줌과 viewport transform 고려한 좌표 변환
let localPoint = point
if (this.canvas) {
const vpt = this.canvas.viewportTransform
if (vpt) {
// viewport transform 역변환
const inverted = fabric.util.invertTransform(vpt)
localPoint = fabric.util.transformPoint(point, inverted)
}
}
// 기본 boundingRect 사용하되 줌을 고려하여 선택 영역 조정
const boundingRect = this.getBoundingRect(true) const boundingRect = this.getBoundingRect(true)
// 선의 방향 판단 // 선의 방향 판단
const dx = Math.abs(this.x2 - this.x1) const dx = Math.abs(this.x2 - this.x1)
const dy = Math.abs(this.y2 - this.y1) const dy = Math.abs(this.y2 - this.y1)
const isVertical = dx < dy && dx < 10 const isVertical = dx < dy && dx < 10 // 세로선 (가로 변화가 작음)
const isDiagonal = dx > 10 && dy > 10 const isDiagonal = dx > 10 && dy > 10 // 대각선 (가로, 세로 모두 변화)
// 줌 레벨에 따른 선택 영역 조정
const zoom = this.canvas ? this.canvas.getZoom() : 1
const baseMultiplier = 1 // 줌이 클수록 선택 영역을 줄임
let reducedWidth, reducedHeight let reducedWidth, reducedHeight
if (isDiagonal) { if (isDiagonal) {
reducedWidth = Math.max(boundingRect.width / 2, 10 * baseMultiplier) // 대각선의 경우: 1/2 크기
reducedHeight = Math.max(boundingRect.height / 2, 10 * baseMultiplier) reducedWidth = boundingRect.width / 2
reducedHeight = boundingRect.height / 2
} else if (isVertical) { } else if (isVertical) {
reducedWidth = Math.max(boundingRect.width * 2, 20 * baseMultiplier) // 세로선의 경우: 가로 선택범위 2배
reducedHeight = boundingRect.height reducedWidth = boundingRect.width * 2
reducedHeight = boundingRect.height / 3
} else { } else {
reducedWidth = boundingRect.width // 가로선의 경우: 세로 선택범위 2배
reducedHeight = Math.max(boundingRect.height * 2, 20 * baseMultiplier) reducedWidth = boundingRect.width / 3
reducedHeight = boundingRect.height * 2
} }
// 축소된 영역의 중심점 계산 // 축소된 영역의 중심점 계산
@ -254,6 +219,9 @@ export const QLine = fabric.util.createClass(fabric.Line, {
const bottom = centerY + reducedHeight / 2 const bottom = centerY + reducedHeight / 2
// 점이 축소된 영역 내에 있는지 확인 // 점이 축소된 영역 내에 있는지 확인
return localPoint.x >= left && localPoint.x <= right && localPoint.y >= top && localPoint.y <= bottom return point.x >= left &&
point.x <= right &&
point.y >= top &&
point.y <= bottom
}, },
}) })

View File

@ -689,46 +689,13 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
return intersects % 2 === 1 return intersects % 2 === 1
}, },
setCoords: function () {
// 부모 클래스의 setCoords 호출
this.callSuper('setCoords')
// QPolygon의 경우 추가 처리 - 항상 강제로 재계산
if (this.canvas) {
// 모든 좌표 관련 캐시 초기화
delete this.oCoords
delete this.aCoords
delete this.__corner
// 다시 부모 setCoords 호출
this.callSuper('setCoords')
// 한 번 더 강제로 bounding rect 재계산
this._clearCache && this._clearCache()
}
},
containsPoint: function (point) { containsPoint: function (point) {
// 먼저 좌표 업데이트
this.setCoords()
// 캔버스 줌과 viewport transform 고려한 좌표 변환
let localPoint = point
if (this.canvas) {
const vpt = this.canvas.viewportTransform
if (vpt) {
// viewport transform 역변환
const inverted = fabric.util.invertTransform(vpt)
localPoint = fabric.util.transformPoint(point, inverted)
}
}
if (this.name === POLYGON_TYPE.ROOF && this.isFixed) { if (this.name === POLYGON_TYPE.ROOF && this.isFixed) {
const isInside = this.inPolygon(localPoint) const isInside = this.inPolygon(point)
this.set('selectable', isInside) this.set('selectable', isInside)
return isInside return isInside
} else { } else {
return this.callSuper('containsPoint', localPoint) return this.callSuper('containsPoint', point)
} }
}, },

View File

@ -16,6 +16,7 @@ import { useTempGrid } from '@/hooks/useTempGrid'
import { gridColorState } from '@/store/gridAtom' import { gridColorState } from '@/store/gridAtom'
import { gridDisplaySelector } from '@/store/settingAtom' import { gridDisplaySelector } from '@/store/settingAtom'
import { MENU, POLYGON_TYPE } from '@/common/common' import { MENU, POLYGON_TYPE } from '@/common/common'
import useMenu from '@/hooks/common/useMenu'
export function useEvent() { export function useEvent() {
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
@ -104,10 +105,6 @@ export function useEvent() {
canvas.setViewportTransform(canvas.viewportTransform) canvas.setViewportTransform(canvas.viewportTransform)
canvas.requestRenderAll() canvas.requestRenderAll()
canvas.getObjects().forEach((obj) => {
obj.setCoords()
})
// 이벤트의 기본 동작 방지 (스크롤 방지) // 이벤트의 기본 동작 방지 (스크롤 방지)
opt.e.preventDefault() opt.e.preventDefault()
opt.e.stopPropagation() opt.e.stopPropagation()