줌 확대, 축소 시 오브젝트 선택 안되는 현상 수정
This commit is contained in:
parent
71d92f12b8
commit
0badbef52c
@ -183,29 +183,64 @@ export const QLine = fabric.util.createClass(fabric.Line, {
|
|||||||
return this
|
return this
|
||||||
},
|
},
|
||||||
|
|
||||||
containsPoint: function(point) {
|
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) {
|
||||||
|
// 먼저 좌표 업데이트
|
||||||
|
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) {
|
||||||
// 대각선의 경우: 1/2 크기
|
reducedWidth = Math.max(boundingRect.width / 2, 10 * baseMultiplier)
|
||||||
reducedWidth = boundingRect.width / 2
|
reducedHeight = Math.max(boundingRect.height / 2, 10 * baseMultiplier)
|
||||||
reducedHeight = boundingRect.height / 2
|
|
||||||
} else if (isVertical) {
|
} else if (isVertical) {
|
||||||
// 세로선의 경우: 가로 선택범위 2배
|
reducedWidth = Math.max(boundingRect.width * 2, 20 * baseMultiplier)
|
||||||
reducedWidth = boundingRect.width * 2
|
reducedHeight = boundingRect.height
|
||||||
reducedHeight = boundingRect.height / 3
|
|
||||||
} else {
|
} else {
|
||||||
// 가로선의 경우: 세로 선택범위 2배
|
reducedWidth = boundingRect.width
|
||||||
reducedWidth = boundingRect.width / 3
|
reducedHeight = Math.max(boundingRect.height * 2, 20 * baseMultiplier)
|
||||||
reducedHeight = boundingRect.height * 2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 축소된 영역의 중심점 계산
|
// 축소된 영역의 중심점 계산
|
||||||
@ -219,9 +254,6 @@ export const QLine = fabric.util.createClass(fabric.Line, {
|
|||||||
const bottom = centerY + reducedHeight / 2
|
const bottom = centerY + reducedHeight / 2
|
||||||
|
|
||||||
// 점이 축소된 영역 내에 있는지 확인
|
// 점이 축소된 영역 내에 있는지 확인
|
||||||
return point.x >= left &&
|
return localPoint.x >= left && localPoint.x <= right && localPoint.y >= top && localPoint.y <= bottom
|
||||||
point.x <= right &&
|
|
||||||
point.y >= top &&
|
|
||||||
point.y <= bottom
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@ -689,13 +689,46 @@ 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(point)
|
const isInside = this.inPolygon(localPoint)
|
||||||
this.set('selectable', isInside)
|
this.set('selectable', isInside)
|
||||||
return isInside
|
return isInside
|
||||||
} else {
|
} else {
|
||||||
return this.callSuper('containsPoint', point)
|
return this.callSuper('containsPoint', localPoint)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,6 @@ 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)
|
||||||
@ -105,6 +104,10 @@ 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()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user