Merge pull request 'dev' (#691) from dev into prd-deploy
Reviewed-on: #691
This commit is contained in:
commit
abc61b2a0c
@ -93,7 +93,7 @@ export const QLine = fabric.util.createClass(fabric.Line, {
|
|||||||
thisText.set({ actualSize: this.attributes.actualSize })
|
thisText.set({ actualSize: this.attributes.actualSize })
|
||||||
}
|
}
|
||||||
if (this.attributes?.planeSize) {
|
if (this.attributes?.planeSize) {
|
||||||
thisText.set({ planeSize: this.attributes.planeSize })
|
thisText.set({ planeSize: this.attributes.planeSize, text: this.attributes.planeSize.toString() })
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.setLength()
|
this.setLength()
|
||||||
@ -119,7 +119,8 @@ export const QLine = fabric.util.createClass(fabric.Line, {
|
|||||||
const maxY = this.top + this.length
|
const maxY = this.top + this.length
|
||||||
const degree = (Math.atan2(y2 - y1, x2 - x1) * 180) / Math.PI
|
const degree = (Math.atan2(y2 - y1, x2 - x1) * 180) / Math.PI
|
||||||
|
|
||||||
const text = new fabric.Textbox(this.getLength().toString(), {
|
const displayValue = this.attributes?.planeSize ?? this.getLength()
|
||||||
|
const text = new fabric.Textbox(displayValue.toString(), {
|
||||||
actualSize: this.attributes?.actualSize,
|
actualSize: this.attributes?.actualSize,
|
||||||
planeSize: this.attributes?.planeSize,
|
planeSize: this.attributes?.planeSize,
|
||||||
left: left,
|
left: left,
|
||||||
|
|||||||
@ -152,16 +152,12 @@ export default function GridOption(props) {
|
|||||||
<div className="modal-check-btn-wrap">
|
<div className="modal-check-btn-wrap">
|
||||||
<h3 className="check-wrap-title light">{getMessage('modal.canvas.setting.grid')}</h3>
|
<h3 className="check-wrap-title light">{getMessage('modal.canvas.setting.grid')}</h3>
|
||||||
<div className="flex-check-box for2">
|
<div className="flex-check-box for2">
|
||||||
{gridOptions?.map((option) =>
|
{gridOptions?.map((option) => (
|
||||||
option.id === 2 ? (
|
<button key={option.id} className={`check-btn ${option.selected ? 'act' : ''}`} onClick={(e) => onClickOption(option)}>
|
||||||
<></>
|
<span className="check-area"></span>
|
||||||
) : (
|
<span className="title-area">{getMessage(option.name)}</span>
|
||||||
<button key={option.id} className={`check-btn ${option.selected ? 'act' : ''}`} onClick={(e) => onClickOption(option)}>
|
</button>
|
||||||
<span className="check-area"></span>
|
))}
|
||||||
<span className="title-area">{getMessage(option.name)}</span>
|
|
||||||
</button>
|
|
||||||
),
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/*<ColorPickerModal {...colorPickerProps} />*/}
|
{/*<ColorPickerModal {...colorPickerProps} />*/}
|
||||||
|
|||||||
@ -39,56 +39,51 @@ export function useGrid() {
|
|||||||
//const verticalInterval = interval.verticalInterval
|
//const verticalInterval = interval.verticalInterval
|
||||||
|
|
||||||
if (patternData.dotGridDisplay) {
|
if (patternData.dotGridDisplay) {
|
||||||
const circle = new fabric.Circle({
|
const canvasWidth = canvas.getWidth()
|
||||||
radius: 2,
|
const canvasHeight = canvas.getHeight()
|
||||||
fill: 'red',
|
const currentZoom = canvas.getZoom()
|
||||||
strokeWidth: 0.7,
|
const viewportTransform = canvas.viewportTransform
|
||||||
originX: 'center',
|
|
||||||
originY: 'center',
|
|
||||||
selectable: false,
|
|
||||||
lockMovementX: true,
|
|
||||||
lockMovementY: true,
|
|
||||||
lockRotation: true,
|
|
||||||
lockScalingX: true,
|
|
||||||
lockScalingY: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
const patternSourceCanvas = new fabric.StaticCanvas(null, {
|
const visibleLeft = -viewportTransform[4] / currentZoom
|
||||||
width: patternData.gridHorizon,
|
const visibleTop = -viewportTransform[5] / currentZoom
|
||||||
height: patternData.gridVertical,
|
const visibleRight = visibleLeft + canvasWidth / currentZoom
|
||||||
})
|
const visibleBottom = visibleTop + canvasHeight / currentZoom
|
||||||
|
|
||||||
patternSourceCanvas.add(circle)
|
const padding = 200
|
||||||
|
// 원점(0,0) 기준 그리드 간격의 배수로 정렬하여 줌 시 위치 고정
|
||||||
|
const gridLeft = Math.floor((visibleLeft - padding) / patternData.gridHorizon) * patternData.gridHorizon
|
||||||
|
const gridTop = Math.floor((visibleTop - padding) / patternData.gridVertical) * patternData.gridVertical
|
||||||
|
const gridRight = visibleRight + padding
|
||||||
|
const gridBottom = visibleBottom + padding
|
||||||
|
|
||||||
circle.set({
|
const horizontalCount = Math.ceil((gridRight - gridLeft) / patternData.gridHorizon) + 1
|
||||||
left: patternSourceCanvas.width / 2,
|
const verticalCount = Math.ceil((gridBottom - gridTop) / patternData.gridVertical) + 1
|
||||||
top: patternSourceCanvas.height / 2,
|
|
||||||
})
|
|
||||||
|
|
||||||
patternSourceCanvas.renderAll()
|
for (let i = 0; i < horizontalCount; i++) {
|
||||||
|
for (let j = 0; j < verticalCount; j++) {
|
||||||
const pattern = new fabric.Pattern({
|
const dot = new fabric.Circle({
|
||||||
source: patternSourceCanvas.getElement(),
|
left: gridLeft + i * patternData.gridHorizon,
|
||||||
repeat: 'repeat',
|
top: gridTop + j * patternData.gridVertical,
|
||||||
})
|
radius: 2,
|
||||||
|
fill: 'red',
|
||||||
const backgroundPolygon = new fabric.Polygon(
|
stroke: null,
|
||||||
[
|
strokeWidth: 0,
|
||||||
{ x: -1500, y: -1500 },
|
originX: 'center',
|
||||||
{ x: 2500, y: -1500 },
|
originY: 'center',
|
||||||
{ x: 2500, y: 2500 },
|
selectable: true,
|
||||||
{ x: -1500, y: 2500 },
|
lockMovementX: true,
|
||||||
],
|
lockMovementY: true,
|
||||||
{
|
lockRotation: true,
|
||||||
fill: pattern,
|
lockScalingX: true,
|
||||||
selectable: false,
|
lockScalingY: true,
|
||||||
name: 'dotGrid',
|
name: 'dotGrid',
|
||||||
visible: isGridDisplay,
|
padding: GRID_PADDING,
|
||||||
},
|
visible: isGridDisplay,
|
||||||
)
|
})
|
||||||
|
canvas.add(dot)
|
||||||
canvas.add(backgroundPolygon)
|
dot.sendToBack()
|
||||||
backgroundPolygon.sendToBack()
|
}
|
||||||
|
}
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,8 +101,9 @@ export function useGrid() {
|
|||||||
|
|
||||||
// 여유 공간 추가
|
// 여유 공간 추가
|
||||||
const padding = 200
|
const padding = 200
|
||||||
const gridLeft = visibleLeft - padding
|
// 원점(0,0) 기준 그리드 간격의 배수로 정렬하여 줌 시 위치 고정
|
||||||
const gridTop = visibleTop - padding
|
const gridLeft = Math.floor((visibleLeft - padding) / patternData.gridHorizon) * patternData.gridHorizon
|
||||||
|
const gridTop = Math.floor((visibleTop - padding) / patternData.gridVertical) * patternData.gridVertical
|
||||||
const gridRight = visibleRight + padding
|
const gridRight = visibleRight + padding
|
||||||
const gridBottom = visibleBottom + padding
|
const gridBottom = visibleBottom + padding
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import { useEvent } from '@/hooks/useEvent'
|
|||||||
import { useMouse } from '@/hooks/useMouse'
|
import { useMouse } from '@/hooks/useMouse'
|
||||||
import { useLine } from '@/hooks/useLine'
|
import { useLine } from '@/hooks/useLine'
|
||||||
import { useEffect, useRef } from 'react'
|
import { useEffect, useRef } from 'react'
|
||||||
import { distanceBetweenPoints } from '@/util/canvas-util'
|
|
||||||
import { fabric } from 'fabric'
|
import { fabric } from 'fabric'
|
||||||
import { calculateAngle } from '@/util/qpolygon-utils'
|
import { calculateAngle } from '@/util/qpolygon-utils'
|
||||||
import {
|
import {
|
||||||
@ -44,7 +43,7 @@ export function usePlacementShapeDrawing(id) {
|
|||||||
// useContext(EventContext)
|
// useContext(EventContext)
|
||||||
const { getIntersectMousePoint } = useMouse()
|
const { getIntersectMousePoint } = useMouse()
|
||||||
const { addLine, removeLine } = useLine()
|
const { addLine, removeLine } = useLine()
|
||||||
const { addPolygonByLines, drawDirectionArrow } = usePolygon()
|
const { addPolygonByLines, drawDirectionArrow, addLengthText } = usePolygon()
|
||||||
const { setSurfaceShapePattern } = useRoofFn()
|
const { setSurfaceShapePattern } = useRoofFn()
|
||||||
const { changeSurfaceLineType } = useSurfaceShapeBatch({})
|
const { changeSurfaceLineType } = useSurfaceShapeBatch({})
|
||||||
const { handleSelectableObjects } = useObject()
|
const { handleSelectableObjects } = useObject()
|
||||||
@ -135,35 +134,17 @@ export function usePlacementShapeDrawing(id) {
|
|||||||
} else {
|
} else {
|
||||||
const lastPoint = points[points.length - 1]
|
const lastPoint = points[points.length - 1]
|
||||||
let newPoint = { x: pointer.x, y: pointer.y }
|
let newPoint = { x: pointer.x, y: pointer.y }
|
||||||
const length = distanceBetweenPoints(lastPoint, newPoint)
|
|
||||||
if (verticalHorizontalMode) {
|
if (verticalHorizontalMode) {
|
||||||
const vector = {
|
const vector = {
|
||||||
x: pointer.x - points[points.length - 1].x,
|
x: pointer.x - lastPoint.x,
|
||||||
y: pointer.y - points[points.length - 1].y,
|
y: pointer.y - lastPoint.y,
|
||||||
}
|
}
|
||||||
const slope = Math.abs(vector.y / vector.x) // 기울기 계산
|
const slope = Math.abs(vector.y / vector.x)
|
||||||
|
|
||||||
let scaledVector
|
|
||||||
if (slope >= 1) {
|
if (slope >= 1) {
|
||||||
// 기울기가 1 이상이면 x축 방향으로 그림
|
newPoint = { x: lastPoint.x, y: pointer.y }
|
||||||
scaledVector = {
|
|
||||||
x: 0,
|
|
||||||
y: vector.y >= 0 ? Number(length) : -Number(length),
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// 기울기가 1 미만이면 y축 방향으로 그림
|
newPoint = { x: pointer.x, y: lastPoint.y }
|
||||||
scaledVector = {
|
|
||||||
x: vector.x >= 0 ? Number(length) : -Number(length),
|
|
||||||
y: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const verticalLength = scaledVector.y
|
|
||||||
const horizontalLength = scaledVector.x
|
|
||||||
|
|
||||||
newPoint = {
|
|
||||||
x: lastPoint.x + horizontalLength,
|
|
||||||
y: lastPoint.y + verticalLength,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setPoints((prev) => [...prev, newPoint])
|
setPoints((prev) => [...prev, newPoint])
|
||||||
@ -244,6 +225,9 @@ export function usePlacementShapeDrawing(id) {
|
|||||||
from: 'surface',
|
from: 'surface',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 기존 도형의 흡착점을 이용해 그린 경우, 기존 도형의 planeSize를 상속
|
||||||
|
inheritPlaneSizeFromExistingShapes(roof)
|
||||||
|
|
||||||
setSurfaceShapePattern(roof, roofDisplay.column)
|
setSurfaceShapePattern(roof, roofDisplay.column)
|
||||||
drawDirectionArrow(roof)
|
drawDirectionArrow(roof)
|
||||||
|
|
||||||
@ -315,8 +299,169 @@ export function usePlacementShapeDrawing(id) {
|
|||||||
}
|
}
|
||||||
}, [points])
|
}, [points])
|
||||||
|
|
||||||
|
// 기존 도형의 변과 일치하는 경우 planeSize를 상속하는 함수
|
||||||
|
const inheritPlaneSizeFromExistingShapes = (newPolygon) => {
|
||||||
|
const tolerance = 2
|
||||||
|
const existingPolygons = canvas.getObjects().filter(
|
||||||
|
(obj) => (obj.name === POLYGON_TYPE.ROOF || obj.name === POLYGON_TYPE.WALL) && obj.id !== newPolygon.id && obj.lines,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (existingPolygons.length === 0) return
|
||||||
|
|
||||||
|
const inheritedSet = new Set()
|
||||||
|
|
||||||
|
// 1단계: 기존 도형의 변과 매칭하여 planeSize 상속
|
||||||
|
newPolygon.lines.forEach((line, lineIdx) => {
|
||||||
|
const x1 = line.x1,
|
||||||
|
y1 = line.y1,
|
||||||
|
x2 = line.x2,
|
||||||
|
y2 = line.y2
|
||||||
|
const isHorizontal = Math.abs(y1 - y2) < tolerance
|
||||||
|
const isVertical = Math.abs(x1 - x2) < tolerance
|
||||||
|
|
||||||
|
for (const polygon of existingPolygons) {
|
||||||
|
for (const edge of polygon.lines) {
|
||||||
|
if (!edge.attributes?.planeSize) continue
|
||||||
|
|
||||||
|
const ex1 = edge.x1,
|
||||||
|
ey1 = edge.y1,
|
||||||
|
ex2 = edge.x2,
|
||||||
|
ey2 = edge.y2
|
||||||
|
|
||||||
|
// 1순위: 양 끝점이 정확히 일치
|
||||||
|
const forwardMatch =
|
||||||
|
Math.abs(x1 - ex1) < tolerance &&
|
||||||
|
Math.abs(y1 - ey1) < tolerance &&
|
||||||
|
Math.abs(x2 - ex2) < tolerance &&
|
||||||
|
Math.abs(y2 - ey2) < tolerance
|
||||||
|
const reverseMatch =
|
||||||
|
Math.abs(x1 - ex2) < tolerance &&
|
||||||
|
Math.abs(y1 - ey2) < tolerance &&
|
||||||
|
Math.abs(x2 - ex1) < tolerance &&
|
||||||
|
Math.abs(y2 - ey1) < tolerance
|
||||||
|
|
||||||
|
if (forwardMatch || reverseMatch) {
|
||||||
|
line.attributes = { ...line.attributes, planeSize: edge.attributes.planeSize }
|
||||||
|
if (edge.attributes.actualSize) {
|
||||||
|
line.attributes.actualSize = edge.attributes.actualSize
|
||||||
|
}
|
||||||
|
inheritedSet.add(lineIdx)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2순위: 같은 방향 + 같은 좌표 차이 (끝점 공유 불필요)
|
||||||
|
if (isHorizontal && Math.abs(ey1 - ey2) < tolerance && Math.abs(Math.abs(x2 - x1) - Math.abs(ex2 - ex1)) < tolerance) {
|
||||||
|
line.attributes = { ...line.attributes, planeSize: edge.attributes.planeSize }
|
||||||
|
if (edge.attributes.actualSize) {
|
||||||
|
line.attributes.actualSize = edge.attributes.actualSize
|
||||||
|
}
|
||||||
|
inheritedSet.add(lineIdx)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (isVertical && Math.abs(ex1 - ex2) < tolerance && Math.abs(Math.abs(y2 - y1) - Math.abs(ey2 - ey1)) < tolerance) {
|
||||||
|
line.attributes = { ...line.attributes, planeSize: edge.attributes.planeSize }
|
||||||
|
if (edge.attributes.actualSize) {
|
||||||
|
line.attributes.actualSize = edge.attributes.actualSize
|
||||||
|
}
|
||||||
|
inheritedSet.add(lineIdx)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 2단계: 상속받은 변과 평행하고 좌표 차이가 같은 변에 planeSize 전파
|
||||||
|
if (inheritedSet.size > 0) {
|
||||||
|
newPolygon.lines.forEach((line, lineIdx) => {
|
||||||
|
if (inheritedSet.has(lineIdx)) return
|
||||||
|
|
||||||
|
const x1 = line.x1,
|
||||||
|
y1 = line.y1,
|
||||||
|
x2 = line.x2,
|
||||||
|
y2 = line.y2
|
||||||
|
const isHorizontal = Math.abs(y1 - y2) < tolerance
|
||||||
|
const isVertical = Math.abs(x1 - x2) < tolerance
|
||||||
|
|
||||||
|
for (const idx of inheritedSet) {
|
||||||
|
const inherited = newPolygon.lines[idx]
|
||||||
|
const ix1 = inherited.x1,
|
||||||
|
iy1 = inherited.y1,
|
||||||
|
ix2 = inherited.x2,
|
||||||
|
iy2 = inherited.y2
|
||||||
|
const iIsHorizontal = Math.abs(iy1 - iy2) < tolerance
|
||||||
|
const iIsVertical = Math.abs(ix1 - ix2) < tolerance
|
||||||
|
|
||||||
|
if (isHorizontal && iIsHorizontal) {
|
||||||
|
if (Math.abs(Math.abs(x2 - x1) - Math.abs(ix2 - ix1)) < tolerance) {
|
||||||
|
line.attributes = { ...line.attributes, planeSize: inherited.attributes.planeSize }
|
||||||
|
if (inherited.attributes.actualSize) {
|
||||||
|
line.attributes.actualSize = inherited.attributes.actualSize
|
||||||
|
}
|
||||||
|
inheritedSet.add(lineIdx)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else if (isVertical && iIsVertical) {
|
||||||
|
if (Math.abs(Math.abs(y2 - y1) - Math.abs(iy2 - iy1)) < tolerance) {
|
||||||
|
line.attributes = { ...line.attributes, planeSize: inherited.attributes.planeSize }
|
||||||
|
if (inherited.attributes.actualSize) {
|
||||||
|
line.attributes.actualSize = inherited.attributes.actualSize
|
||||||
|
}
|
||||||
|
inheritedSet.add(lineIdx)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// planeSize가 상속된 경우 길이 텍스트를 다시 렌더링
|
||||||
|
if (inheritedSet.size > 0) {
|
||||||
|
addLengthText(newPolygon)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 기존 도형에서 매칭되는 변의 planeSize를 찾는 헬퍼 함수
|
||||||
|
const findMatchingEdgePlaneSize = (x1, y1, x2, y2) => {
|
||||||
|
const tolerance = 2
|
||||||
|
const existingPolygons = canvas.getObjects().filter(
|
||||||
|
(obj) => (obj.name === POLYGON_TYPE.ROOF || obj.name === POLYGON_TYPE.WALL) && obj.lines,
|
||||||
|
)
|
||||||
|
|
||||||
|
const isHorizontal = Math.abs(y1 - y2) < tolerance
|
||||||
|
const isVertical = Math.abs(x1 - x2) < tolerance
|
||||||
|
|
||||||
|
for (const polygon of existingPolygons) {
|
||||||
|
for (const edge of polygon.lines) {
|
||||||
|
if (!edge.attributes?.planeSize) continue
|
||||||
|
const ex1 = edge.x1,
|
||||||
|
ey1 = edge.y1,
|
||||||
|
ex2 = edge.x2,
|
||||||
|
ey2 = edge.y2
|
||||||
|
|
||||||
|
// 1순위: 양 끝점 일치 (정방향/역방향)
|
||||||
|
const forwardMatch =
|
||||||
|
Math.abs(x1 - ex1) < tolerance && Math.abs(y1 - ey1) < tolerance && Math.abs(x2 - ex2) < tolerance && Math.abs(y2 - ey2) < tolerance
|
||||||
|
const reverseMatch =
|
||||||
|
Math.abs(x1 - ex2) < tolerance && Math.abs(y1 - ey2) < tolerance && Math.abs(x2 - ex1) < tolerance && Math.abs(y2 - ey1) < tolerance
|
||||||
|
|
||||||
|
if (forwardMatch || reverseMatch) {
|
||||||
|
return edge.attributes.planeSize
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2순위: 같은 방향 + 같은 좌표 차이 (끝점 공유 불필요)
|
||||||
|
if (isHorizontal && Math.abs(ey1 - ey2) < tolerance && Math.abs(Math.abs(x2 - x1) - Math.abs(ex2 - ex1)) < tolerance) {
|
||||||
|
return edge.attributes.planeSize
|
||||||
|
}
|
||||||
|
if (isVertical && Math.abs(ex1 - ex2) < tolerance && Math.abs(Math.abs(y2 - y1) - Math.abs(ey2 - ey1)) < tolerance) {
|
||||||
|
return edge.attributes.planeSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
const drawLine = (point1, point2, idx) => {
|
const drawLine = (point1, point2, idx) => {
|
||||||
addLine([point1.x, point1.y, point2.x, point2.y], {
|
const line = addLine([point1.x, point1.y, point2.x, point2.y], {
|
||||||
stroke: 'black',
|
stroke: 'black',
|
||||||
strokeWidth: 3,
|
strokeWidth: 3,
|
||||||
idx: idx,
|
idx: idx,
|
||||||
@ -327,6 +472,14 @@ export function usePlacementShapeDrawing(id) {
|
|||||||
x2: point2.x,
|
x2: point2.x,
|
||||||
y2: point2.y,
|
y2: point2.y,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 기존 도형의 변과 일치하는 경우 planeSize 상속
|
||||||
|
if (line) {
|
||||||
|
const matchedPlaneSize = findMatchingEdgePlaneSize(point1.x, point1.y, point2.x, point2.y)
|
||||||
|
if (matchedPlaneSize !== null) {
|
||||||
|
line.attributes = { ...line.attributes, planeSize: matchedPlaneSize }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 직각 완료될 경우 확인
|
// 직각 완료될 경우 확인
|
||||||
|
|||||||
@ -218,7 +218,13 @@ export function useEvent() {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const dotGridPoints = canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === 'dotGrid')
|
||||||
|
.map((obj) => ({ x: obj.left, y: obj.top }))
|
||||||
|
|
||||||
let adsorptionPoints = [
|
let adsorptionPoints = [
|
||||||
|
...dotGridPoints,
|
||||||
...getAdsorptionPoints(),
|
...getAdsorptionPoints(),
|
||||||
...roofAdsorptionPoints.current,
|
...roofAdsorptionPoints.current,
|
||||||
...otherAdsorptionPoints,
|
...otherAdsorptionPoints,
|
||||||
@ -242,17 +248,12 @@ export function useEvent() {
|
|||||||
|
|
||||||
adsorptionPoints = removeDuplicatePoints(adsorptionPoints)
|
adsorptionPoints = removeDuplicatePoints(adsorptionPoints)
|
||||||
|
|
||||||
if (dotLineGridSetting.LINE || canvas.getObjects().filter((obj) => ['lineGrid', 'tempGrid'].includes(obj.name)).length > 1) {
|
if (dotLineGridSetting.LINE || canvas.getObjects().filter((obj) => ['lineGrid', 'tempGrid'].includes(obj.name)).length > 0) {
|
||||||
const closestLine = getClosestLineGrid(pointer)
|
const closestLine = getClosestLineGrid(pointer)
|
||||||
|
|
||||||
const horizonLines = canvas.getObjects().filter((obj) => ['lineGrid', 'tempGrid'].includes(obj.name) && obj.direction === 'horizontal')
|
const horizonLines = canvas.getObjects().filter((obj) => ['lineGrid', 'tempGrid'].includes(obj.name) && obj.direction === 'horizontal')
|
||||||
const verticalLines = canvas.getObjects().filter((obj) => ['lineGrid', 'tempGrid'].includes(obj.name) && obj.direction === 'vertical')
|
const verticalLines = canvas.getObjects().filter((obj) => ['lineGrid', 'tempGrid'].includes(obj.name) && obj.direction === 'vertical')
|
||||||
|
|
||||||
if (!horizonLines || !verticalLines) {
|
|
||||||
drawMouseLine(pointer)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let closestHorizontalLine = null
|
let closestHorizontalLine = null
|
||||||
let closestVerticalLine = null
|
let closestVerticalLine = null
|
||||||
|
|
||||||
@ -272,12 +273,8 @@ export function useEvent() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!closestVerticalLine || !closestHorizontalLine) {
|
const closestIntersectionPoint =
|
||||||
drawMouseLine(pointer)
|
closestHorizontalLine && closestVerticalLine ? calculateIntersection(closestHorizontalLine, closestVerticalLine) : null
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const closestIntersectionPoint = calculateIntersection(closestHorizontalLine, closestVerticalLine)
|
|
||||||
|
|
||||||
if (closestLine) {
|
if (closestLine) {
|
||||||
const distanceClosestLine = calculateDistance(pointer, closestLine)
|
const distanceClosestLine = calculateDistance(pointer, closestLine)
|
||||||
@ -295,7 +292,7 @@ export function useEvent() {
|
|||||||
y: closestLine.y1,
|
y: closestLine.y1,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (distanceClosestPoint * 2 < adsorptionRange) {
|
if (closestIntersectionPoint && distanceClosestPoint * 2 < adsorptionRange) {
|
||||||
arrivalPoint = { ...closestIntersectionPoint }
|
arrivalPoint = { ...closestIntersectionPoint }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -430,7 +427,13 @@ export function useEvent() {
|
|||||||
y: Math.round(originPointer.y),
|
y: Math.round(originPointer.y),
|
||||||
}
|
}
|
||||||
|
|
||||||
const tempGrid = new fabric.Line([-1500, pointer.y, 2500, pointer.y], {
|
const currentZoom = canvas.getZoom()
|
||||||
|
const vt = canvas.viewportTransform
|
||||||
|
const visibleLeft = -vt[4] / currentZoom
|
||||||
|
const visibleRight = visibleLeft + canvas.getWidth() / currentZoom
|
||||||
|
const padding = 500
|
||||||
|
|
||||||
|
const tempGrid = new fabric.Line([visibleLeft - padding, pointer.y, visibleRight + padding, pointer.y], {
|
||||||
stroke: gridColor,
|
stroke: gridColor,
|
||||||
strokeWidth: 1,
|
strokeWidth: 1,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
|
|||||||
@ -11,11 +11,28 @@ export function useTempGrid() {
|
|||||||
const isGridDisplay = useRecoilValue(gridDisplaySelector)
|
const isGridDisplay = useRecoilValue(gridDisplaySelector)
|
||||||
const [tempGridMode, setTempGridMode] = useRecoilState(tempGridModeState)
|
const [tempGridMode, setTempGridMode] = useRecoilState(tempGridModeState)
|
||||||
const { getIntersectMousePoint } = useMouse()
|
const { getIntersectMousePoint } = useMouse()
|
||||||
|
const getVisibleBounds = () => {
|
||||||
|
const currentZoom = canvas.getZoom()
|
||||||
|
const vt = canvas.viewportTransform
|
||||||
|
const visibleLeft = -vt[4] / currentZoom
|
||||||
|
const visibleTop = -vt[5] / currentZoom
|
||||||
|
const visibleRight = visibleLeft + canvas.getWidth() / currentZoom
|
||||||
|
const visibleBottom = visibleTop + canvas.getHeight() / currentZoom
|
||||||
|
const padding = 500
|
||||||
|
return {
|
||||||
|
left: visibleLeft - padding,
|
||||||
|
top: visibleTop - padding,
|
||||||
|
right: visibleRight + padding,
|
||||||
|
bottom: visibleBottom + padding,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const tempGridModeStateLeftClickEvent = (e) => {
|
const tempGridModeStateLeftClickEvent = (e) => {
|
||||||
//임의 그리드 모드일 경우
|
//임의 그리드 모드일 경우
|
||||||
let pointer = getIntersectMousePoint(e)
|
let pointer = getIntersectMousePoint(e)
|
||||||
|
const bounds = getVisibleBounds()
|
||||||
|
|
||||||
const tempGrid = new fabric.Line([pointer.x, -1500, pointer.x, 2500], {
|
const tempGrid = new fabric.Line([pointer.x, bounds.top, pointer.x, bounds.bottom], {
|
||||||
stroke: gridColor,
|
stroke: gridColor,
|
||||||
strokeWidth: 1,
|
strokeWidth: 1,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user