1525 면형상배치 치수 표기 이상
This commit is contained in:
parent
5f4673dd3f
commit
f77794ceed
@ -9,14 +9,14 @@ import {
|
|||||||
globalPitchState,
|
globalPitchState,
|
||||||
} from '@/store/canvasAtom'
|
} from '@/store/canvasAtom'
|
||||||
import { LINE_TYPE, MENU, POLYGON_TYPE } from '@/common/common'
|
import { LINE_TYPE, MENU, POLYGON_TYPE } from '@/common/common'
|
||||||
import { getIntersectionPoint } from '@/util/canvas-util'
|
import { getIntersectionPoint, getDegreeByChon } from '@/util/canvas-util'
|
||||||
import { degreesToRadians } from '@turf/turf'
|
import { degreesToRadians } from '@turf/turf'
|
||||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useEvent } from '@/hooks/useEvent'
|
import { useEvent } from '@/hooks/useEvent'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import { roofDisplaySelector } from '@/store/settingAtom'
|
import { roofDisplaySelector, basicSettingState } from '@/store/settingAtom'
|
||||||
import { usePolygon } from '@/hooks/usePolygon'
|
import { usePolygon } from '@/hooks/usePolygon'
|
||||||
import { fontSelector } from '@/store/fontAtom'
|
import { fontSelector } from '@/store/fontAtom'
|
||||||
import { slopeSelector } from '@/store/commonAtom'
|
import { slopeSelector } from '@/store/commonAtom'
|
||||||
@ -30,10 +30,12 @@ import { useText } from '@/hooks/useText'
|
|||||||
import SizeSetting from '@/components/floor-plan/modal/object/SizeSetting'
|
import SizeSetting from '@/components/floor-plan/modal/object/SizeSetting'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
|
import { fabric } from 'fabric'
|
||||||
|
|
||||||
export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const { drawDirectionArrow, addPolygon, addLengthText, setPolygonLinesActualSize } = usePolygon()
|
const { drawDirectionArrow, addPolygon, addLengthText, setPolygonLinesActualSize } = usePolygon()
|
||||||
|
const roofSizeSet = useRecoilValue(basicSettingState).roofSizeSet
|
||||||
const lengthTextFont = useRecoilValue(fontSelector('lengthText'))
|
const lengthTextFont = useRecoilValue(fontSelector('lengthText'))
|
||||||
const resetOuterLinePoints = useResetRecoilState(outerLinePointsState)
|
const resetOuterLinePoints = useResetRecoilState(outerLinePointsState)
|
||||||
const resetPlacementShapeDrawingPoints = useResetRecoilState(placementShapeDrawingPointsState)
|
const resetPlacementShapeDrawingPoints = useResetRecoilState(placementShapeDrawingPointsState)
|
||||||
@ -92,9 +94,76 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
|||||||
let obj = null
|
let obj = null
|
||||||
let points = []
|
let points = []
|
||||||
|
|
||||||
|
// azimuth로부터 direction 결정
|
||||||
|
let direction = 'south'
|
||||||
|
if (azimuth === 'left') direction = 'west'
|
||||||
|
else if (azimuth === 'right') direction = 'east'
|
||||||
|
else if (azimuth === 'up') direction = 'north'
|
||||||
|
|
||||||
|
// after:render 콜백 - 매 렌더링 후 temp 수치 텍스트를 ctx에 직접 그림
|
||||||
|
let tempLengthData = null // { transformedPoints, direction }
|
||||||
|
const afterRenderHandler = () => {
|
||||||
|
if (!tempLengthData) return
|
||||||
|
const ctx = canvas?.getContext('2d')
|
||||||
|
if (!ctx) return
|
||||||
|
|
||||||
|
const { tPoints, dir } = tempLengthData
|
||||||
|
const vpt = canvas.viewportTransform
|
||||||
|
const zoom = vpt[0]
|
||||||
|
const oX = vpt[4]
|
||||||
|
const oY = vpt[5]
|
||||||
|
|
||||||
|
ctx.save()
|
||||||
|
ctx.font = `bold ${(lengthTextFont.fontSize.value || 14) * zoom}px sans-serif`
|
||||||
|
ctx.fillStyle = 'black'
|
||||||
|
ctx.textAlign = 'center'
|
||||||
|
ctx.textBaseline = 'middle'
|
||||||
|
|
||||||
|
tPoints.forEach((start, i) => {
|
||||||
|
const end = tPoints[(i + 1) % tPoints.length]
|
||||||
|
const dx = end.x - start.x
|
||||||
|
const dy = end.y - start.y
|
||||||
|
const planeSize = Math.round(Math.sqrt(dx * dx + dy * dy) * 10)
|
||||||
|
|
||||||
|
let actualSize = planeSize
|
||||||
|
const lineDir = Math.abs(dx) > Math.abs(dy) ? (dx > 0 ? 'right' : 'left') : (dy > 0 ? 'bottom' : 'top')
|
||||||
|
if (+roofSizeSet === 1 && globalPitch > 0) {
|
||||||
|
const pitchDeg = getDegreeByChon(globalPitch)
|
||||||
|
const isV = Math.abs(start.x - end.x) < 1
|
||||||
|
const isH = Math.abs(start.y - end.y) < 1
|
||||||
|
const isD = !isH && !isV
|
||||||
|
if (dir === 'south' || dir === 'north') {
|
||||||
|
if (isV) actualSize = Math.round(planeSize / Math.cos(pitchDeg * Math.PI / 180))
|
||||||
|
else if (isD) {
|
||||||
|
const h = Math.abs(dy) * 10 * Math.tan(pitchDeg * Math.PI / 180)
|
||||||
|
actualSize = Math.round(Math.sqrt(h * h + planeSize * planeSize))
|
||||||
|
}
|
||||||
|
} else if (dir === 'west' || dir === 'east') {
|
||||||
|
if (isH) actualSize = Math.round(planeSize / Math.cos(pitchDeg * Math.PI / 180))
|
||||||
|
else if (isD) {
|
||||||
|
const h = Math.abs(dx) * 10 * Math.tan(pitchDeg * Math.PI / 180)
|
||||||
|
actualSize = Math.round(Math.sqrt(h * h + planeSize * planeSize))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const displayValue = (+roofSizeSet === 1 ? actualSize : planeSize).toString()
|
||||||
|
let tx = (start.x + end.x) / 2
|
||||||
|
let ty = (start.y + end.y) / 2
|
||||||
|
if (lineDir === 'right') ty += 15
|
||||||
|
else if (lineDir === 'left') ty -= 15
|
||||||
|
else if (lineDir === 'top') tx += 15
|
||||||
|
else tx -= 25
|
||||||
|
|
||||||
|
ctx.fillText(displayValue, tx * zoom + oX, ty * zoom + oY)
|
||||||
|
})
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
|
||||||
//일단 팝업을 가린다
|
//일단 팝업을 가린다
|
||||||
|
|
||||||
if (checkSurfaceShape(surfaceId, { length1, length2, length3, length4, length5 })) {
|
if (checkSurfaceShape(surfaceId, { length1, length2, length3, length4, length5 })) {
|
||||||
|
canvas?.on('after:render', afterRenderHandler)
|
||||||
addCanvasMouseEventListener('mouse:move', (e) => {
|
addCanvasMouseEventListener('mouse:move', (e) => {
|
||||||
if (!isDrawing) {
|
if (!isDrawing) {
|
||||||
return
|
return
|
||||||
@ -125,7 +194,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
|||||||
pitch: globalPitch,
|
pitch: globalPitch,
|
||||||
}
|
}
|
||||||
|
|
||||||
obj = new QPolygon(points, options)
|
obj = new fabric.Polygon(points, options)
|
||||||
|
|
||||||
let imageRotate = 0
|
let imageRotate = 0
|
||||||
if (xInversion && !yInversion) {
|
if (xInversion && !yInversion) {
|
||||||
@ -159,12 +228,25 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
|||||||
obj.setCoords() //좌표 변경 적용
|
obj.setCoords() //좌표 변경 적용
|
||||||
|
|
||||||
canvas?.add(obj)
|
canvas?.add(obj)
|
||||||
|
|
||||||
|
// 회전/반전이 적용된 실제 좌표를 계산하여 after:render에서 그릴 데이터 설정
|
||||||
|
const matrix = obj.calcTransformMatrix()
|
||||||
|
const tPoints = obj.get('points').map((p) => {
|
||||||
|
const pt = new fabric.Point(p.x - obj.pathOffset.x, p.y - obj.pathOffset.y)
|
||||||
|
return fabric.util.transformPoint(pt, matrix)
|
||||||
|
})
|
||||||
|
tempLengthData = { tPoints, dir: direction }
|
||||||
|
|
||||||
canvas?.renderAll()
|
canvas?.renderAll()
|
||||||
})
|
})
|
||||||
|
|
||||||
addCanvasMouseEventListener('mouse:down', (e) => {
|
addCanvasMouseEventListener('mouse:down', (e) => {
|
||||||
isDrawing = false
|
isDrawing = false
|
||||||
|
|
||||||
|
// after:render 핸들러 해제 및 temp 수치 데이터 초기화
|
||||||
|
tempLengthData = null
|
||||||
|
canvas?.off('after:render', afterRenderHandler)
|
||||||
|
|
||||||
const { xInversion, yInversion } = surfaceRefs
|
const { xInversion, yInversion } = surfaceRefs
|
||||||
canvas?.remove(obj)
|
canvas?.remove(obj)
|
||||||
|
|
||||||
@ -186,8 +268,12 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//회전, flip등이 먹은 기준으로 새로생성
|
//회전, flip등이 먹은 기준으로 새로생성
|
||||||
// const batchSurface = addPolygon(reorderedPoints, {
|
const objMatrix = obj.calcTransformMatrix()
|
||||||
const batchSurface = addPolygon(obj.getCurrentPoints(), {
|
const finalPoints = obj.get('points').map((p) => {
|
||||||
|
const pt = new fabric.Point(p.x - obj.pathOffset.x, p.y - obj.pathOffset.y)
|
||||||
|
return fabric.util.transformPoint(pt, objMatrix)
|
||||||
|
})
|
||||||
|
const batchSurface = addPolygon(finalPoints, {
|
||||||
fill: 'transparent',
|
fill: 'transparent',
|
||||||
stroke: 'red',
|
stroke: 'red',
|
||||||
strokeWidth: 3,
|
strokeWidth: 3,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user