dev #872
@ -9,14 +9,14 @@ import {
|
||||
globalPitchState,
|
||||
} from '@/store/canvasAtom'
|
||||
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 { QPolygon } from '@/components/fabric/QPolygon'
|
||||
import { useSwal } from '@/hooks/useSwal'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { useEvent } from '@/hooks/useEvent'
|
||||
import { usePopup } from '@/hooks/usePopup'
|
||||
import { roofDisplaySelector } from '@/store/settingAtom'
|
||||
import { roofDisplaySelector, basicSettingState } from '@/store/settingAtom'
|
||||
import { usePolygon } from '@/hooks/usePolygon'
|
||||
import { fontSelector } from '@/store/fontAtom'
|
||||
import { slopeSelector } from '@/store/commonAtom'
|
||||
@ -30,10 +30,12 @@ import { useText } from '@/hooks/useText'
|
||||
import SizeSetting from '@/components/floor-plan/modal/object/SizeSetting'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { useState } from 'react'
|
||||
import { fabric } from 'fabric'
|
||||
|
||||
export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
||||
const { getMessage } = useMessage()
|
||||
const { drawDirectionArrow, addPolygon, addLengthText, setPolygonLinesActualSize } = usePolygon()
|
||||
const roofSizeSet = useRecoilValue(basicSettingState).roofSizeSet
|
||||
const lengthTextFont = useRecoilValue(fontSelector('lengthText'))
|
||||
const resetOuterLinePoints = useResetRecoilState(outerLinePointsState)
|
||||
const resetPlacementShapeDrawingPoints = useResetRecoilState(placementShapeDrawingPointsState)
|
||||
@ -92,9 +94,76 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
||||
let obj = null
|
||||
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 })) {
|
||||
canvas?.on('after:render', afterRenderHandler)
|
||||
addCanvasMouseEventListener('mouse:move', (e) => {
|
||||
if (!isDrawing) {
|
||||
return
|
||||
@ -125,7 +194,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
||||
pitch: globalPitch,
|
||||
}
|
||||
|
||||
obj = new QPolygon(points, options)
|
||||
obj = new fabric.Polygon(points, options)
|
||||
|
||||
let imageRotate = 0
|
||||
if (xInversion && !yInversion) {
|
||||
@ -159,12 +228,25 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
||||
obj.setCoords() //좌표 변경 적용
|
||||
|
||||
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()
|
||||
})
|
||||
|
||||
addCanvasMouseEventListener('mouse:down', (e) => {
|
||||
isDrawing = false
|
||||
|
||||
// after:render 핸들러 해제 및 temp 수치 데이터 초기화
|
||||
tempLengthData = null
|
||||
canvas?.off('after:render', afterRenderHandler)
|
||||
|
||||
const { xInversion, yInversion } = surfaceRefs
|
||||
canvas?.remove(obj)
|
||||
|
||||
@ -186,8 +268,12 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
||||
}
|
||||
|
||||
//회전, flip등이 먹은 기준으로 새로생성
|
||||
// const batchSurface = addPolygon(reorderedPoints, {
|
||||
const batchSurface = addPolygon(obj.getCurrentPoints(), {
|
||||
const objMatrix = obj.calcTransformMatrix()
|
||||
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',
|
||||
stroke: 'red',
|
||||
strokeWidth: 3,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user