A,B 템플릿 방위 대충 작업 업로드
This commit is contained in:
parent
3c3bdca6b6
commit
dcff818c56
@ -5,7 +5,7 @@ import { Button } from '@nextui-org/react'
|
|||||||
|
|
||||||
import RangeSlider from './ui/RangeSlider'
|
import RangeSlider from './ui/RangeSlider'
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||||
import { canvasSizeState, fontSizeState, roofMaterialState, sortedPolygonArray, templateTypeState } from '@/store/canvasAtom'
|
import { canvasSizeState, fontSizeState, roofMaterialState, sortedPolygonArray, templateTypeState, compassState } from '@/store/canvasAtom'
|
||||||
import { QLine } from '@/components/fabric/QLine'
|
import { QLine } from '@/components/fabric/QLine'
|
||||||
import { getCanvasState, insertCanvasState } from '@/lib/canvas'
|
import { getCanvasState, insertCanvasState } from '@/lib/canvas'
|
||||||
import { calculateIntersection } from '@/util/canvas-util'
|
import { calculateIntersection } from '@/util/canvas-util'
|
||||||
@ -35,6 +35,8 @@ export default function Roof2() {
|
|||||||
|
|
||||||
const [templateType, setTemplateType] = useRecoilState(templateTypeState)
|
const [templateType, setTemplateType] = useRecoilState(templateTypeState)
|
||||||
|
|
||||||
|
const [compass, setCompass] = useRecoilState(compassState)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
mode,
|
mode,
|
||||||
setMode,
|
setMode,
|
||||||
@ -492,6 +494,10 @@ export default function Roof2() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setCompassState = (degree) => {
|
||||||
|
setCompass(degree)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{canvas && (
|
{canvas && (
|
||||||
@ -521,6 +527,18 @@ export default function Roof2() {
|
|||||||
<Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`} onClick={() => drawRoofPatterns(2)}>
|
<Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`} onClick={() => drawRoofPatterns(2)}>
|
||||||
지붕패턴2
|
지붕패턴2
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`} onClick={() => setCompassState(90)}>
|
||||||
|
방위표◀
|
||||||
|
</Button>
|
||||||
|
<Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`} onClick={() => setCompassState(270)}>
|
||||||
|
방위표▶
|
||||||
|
</Button>
|
||||||
|
<Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`} onClick={() => setCompassState(180)}>
|
||||||
|
방위표▲
|
||||||
|
</Button>
|
||||||
|
<Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`} onClick={() => setCompassState(0)}>
|
||||||
|
방위표▼
|
||||||
|
</Button>
|
||||||
<Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`} onClick={() => setMode(Mode.ROOF_TRESTLE)}>
|
<Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`} onClick={() => setMode(Mode.ROOF_TRESTLE)}>
|
||||||
지붕가대생성
|
지붕가대생성
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { useEffect, useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import { findTopTwoIndexesByDistance, getCenterPoint, getDirection, getStartIndex, rearrangeArray } from '@/util/canvas-util'
|
import { findTopTwoIndexesByDistance, getCenterPoint, getDirection, getStartIndex, rearrangeArray } from '@/util/canvas-util'
|
||||||
import { useRecoilState } from 'recoil'
|
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
canvasSizeState,
|
canvasSizeState,
|
||||||
@ -12,6 +12,7 @@ import {
|
|||||||
sortedPolygonArray,
|
sortedPolygonArray,
|
||||||
templateTypeState,
|
templateTypeState,
|
||||||
wallState,
|
wallState,
|
||||||
|
compassState,
|
||||||
} from '@/store/canvasAtom'
|
} from '@/store/canvasAtom'
|
||||||
import { QLine } from '@/components/fabric/QLine'
|
import { QLine } from '@/components/fabric/QLine'
|
||||||
import { fabric } from 'fabric'
|
import { fabric } from 'fabric'
|
||||||
@ -60,6 +61,7 @@ export function useMode() {
|
|||||||
const [drewRoofCells, setDrewRoofCells] = useRecoilState(drewRoofCellsState)
|
const [drewRoofCells, setDrewRoofCells] = useRecoilState(drewRoofCellsState)
|
||||||
const [roofStyle, setRoofStyle] = useState(1) //기본 지붕 패턴
|
const [roofStyle, setRoofStyle] = useState(1) //기본 지붕 패턴
|
||||||
const [templateCenterLine, setTemplateCenterLine] = useState([])
|
const [templateCenterLine, setTemplateCenterLine] = useState([])
|
||||||
|
const compass = useRecoilValue(compassState)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// 이벤트 리스너 추가
|
// 이벤트 리스너 추가
|
||||||
@ -717,6 +719,8 @@ export function useMode() {
|
|||||||
points.current = []
|
points.current = []
|
||||||
historyPoints.current = []
|
historyPoints.current = []
|
||||||
historyLines.current = []
|
historyLines.current = []
|
||||||
|
|
||||||
|
setSelectedCellRoofArray([]) //셀 그린거 삭제
|
||||||
}
|
}
|
||||||
|
|
||||||
const zoomIn = () => {
|
const zoomIn = () => {
|
||||||
@ -2545,7 +2549,7 @@ export function useMode() {
|
|||||||
|
|
||||||
const line = new QLine([start.x, start.y, end.x, end.y], {
|
const line = new QLine([start.x, start.y, end.x, end.y], {
|
||||||
stroke: 'blue',
|
stroke: 'blue',
|
||||||
strokeWidth: 1,
|
strokeWidth: 2,
|
||||||
property: 'normal',
|
property: 'normal',
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
idx: i,
|
idx: i,
|
||||||
@ -2620,6 +2624,7 @@ export function useMode() {
|
|||||||
|
|
||||||
vertCenterLine = reSortQlineArray(vertCenterLine)
|
vertCenterLine = reSortQlineArray(vertCenterLine)
|
||||||
lines = reSortQlineArray(lines)
|
lines = reSortQlineArray(lines)
|
||||||
|
setTemplateCenterLine(vertCenterLine)
|
||||||
|
|
||||||
//해당라인에서 만나는점을 계산
|
//해당라인에서 만나는점을 계산
|
||||||
vertCenterLine.forEach((vertLine) => {
|
vertCenterLine.forEach((vertLine) => {
|
||||||
@ -2777,7 +2782,6 @@ export function useMode() {
|
|||||||
} else {
|
} else {
|
||||||
// 오목한 부분이 세로선일때 아래ㄷ, 위ㄷ
|
// 오목한 부분이 세로선일때 아래ㄷ, 위ㄷ
|
||||||
//라인들을 좌측에서 -> 우측으로 그리는거처럼 데이터 보정
|
//라인들을 좌측에서 -> 우측으로 그리는거처럼 데이터 보정
|
||||||
|
|
||||||
lines.forEach((line, index) => {
|
lines.forEach((line, index) => {
|
||||||
if (!(index % 2 === 0)) {
|
if (!(index % 2 === 0)) {
|
||||||
line.line.set('stroke', 'skyblue')
|
line.line.set('stroke', 'skyblue')
|
||||||
@ -2824,6 +2828,7 @@ export function useMode() {
|
|||||||
|
|
||||||
vertCenterLine = reSortQlineArray(vertCenterLine)
|
vertCenterLine = reSortQlineArray(vertCenterLine)
|
||||||
lines = reSortQlineArray(lines)
|
lines = reSortQlineArray(lines)
|
||||||
|
setTemplateCenterLine(vertCenterLine)
|
||||||
|
|
||||||
//해당라인에서 만나는점을 계산
|
//해당라인에서 만나는점을 계산
|
||||||
vertCenterLine.forEach((vertLine) => {
|
vertCenterLine.forEach((vertLine) => {
|
||||||
@ -2989,6 +2994,8 @@ export function useMode() {
|
|||||||
} else if (polygon.lines.length === 6) {
|
} else if (polygon.lines.length === 6) {
|
||||||
console.log('6각형')
|
console.log('6각형')
|
||||||
handleTemplateB(params)
|
handleTemplateB(params)
|
||||||
|
} else if (polygon.lines.length === 8) {
|
||||||
|
handleOuterLineTemplateB8Points(polygon)
|
||||||
}
|
}
|
||||||
|
|
||||||
setTemplateType(3)
|
setTemplateType(3)
|
||||||
@ -3434,6 +3441,578 @@ export function useMode() {
|
|||||||
canvas?.renderAll()
|
canvas?.renderAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleOuterLineTemplateB8Points = (polygon, offsetInputX = 20, offsetInputY = 50) => {
|
||||||
|
let offsetPoints = []
|
||||||
|
|
||||||
|
const originalMax = 71
|
||||||
|
const transformedMax = 100
|
||||||
|
|
||||||
|
let lines = [] //내각라인
|
||||||
|
let outLines = [] //아웃라인
|
||||||
|
let halfLength = 0 //선길이
|
||||||
|
let offsetX
|
||||||
|
let offsetY
|
||||||
|
|
||||||
|
const dashedCenterLineOpt = {
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 1,
|
||||||
|
property: 'centerLine',
|
||||||
|
strokeDashArray: [8, 4],
|
||||||
|
fontSize: 14,
|
||||||
|
}
|
||||||
|
|
||||||
|
const centerLineOpt = {
|
||||||
|
stroke: 'blue',
|
||||||
|
strokeWidth: 2,
|
||||||
|
property: 'bigHoriCenter',
|
||||||
|
fontSize: 14,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 폴리곤의 각 변을 선으로 생성
|
||||||
|
for (let i = 0; i < polygon.points.length; i++) {
|
||||||
|
const start = polygon.points[i]
|
||||||
|
const end = polygon.points[(i + 1) % polygon.points.length] // 다음 점, 마지막 점의 경우 첫 점으로
|
||||||
|
|
||||||
|
const line = new QLine([start.x, start.y, end.x, end.y], {
|
||||||
|
stroke: '#A0D468',
|
||||||
|
strokeWidth: 2,
|
||||||
|
property: 'normal',
|
||||||
|
fontSize: 14,
|
||||||
|
})
|
||||||
|
|
||||||
|
// 선을 배열에 추가
|
||||||
|
lines.push(line)
|
||||||
|
canvas.add(line)
|
||||||
|
}
|
||||||
|
|
||||||
|
offsetInputY = offsetInputY !== 0 ? offsetInputY : offsetInputX
|
||||||
|
|
||||||
|
const sortedIndex = getStartIndex(polygon.lines)
|
||||||
|
let tmpArraySorted = rearrangeArray(polygon.lines, sortedIndex)
|
||||||
|
setSortedArray(tmpArraySorted) //recoil에 넣음
|
||||||
|
|
||||||
|
const points = tmpArraySorted.map((line) => ({
|
||||||
|
x: line.x1,
|
||||||
|
y: line.y1,
|
||||||
|
}))
|
||||||
|
|
||||||
|
//좌표 재정렬
|
||||||
|
function reSortQlineArray(array) {
|
||||||
|
let tmpArray = []
|
||||||
|
let minX, minY, maxX, maxY
|
||||||
|
let tmp
|
||||||
|
array.forEach((arr, index) => {
|
||||||
|
tmp = arr
|
||||||
|
if (arr.x2 < arr.x1 || arr.y2 < arr.y1) {
|
||||||
|
minX = arr.x2
|
||||||
|
minY = arr.y2
|
||||||
|
maxX = arr.x1
|
||||||
|
maxY = arr.y1
|
||||||
|
tmp['x1'] = minX
|
||||||
|
tmp['y1'] = minY
|
||||||
|
tmp['x2'] = maxX
|
||||||
|
tmp['y2'] = maxY
|
||||||
|
tmp.line['x1'] = minX
|
||||||
|
tmp.line['y1'] = minY
|
||||||
|
tmp.line['x2'] = maxX
|
||||||
|
tmp.line['y2'] = maxY
|
||||||
|
}
|
||||||
|
tmpArray.push(tmp)
|
||||||
|
})
|
||||||
|
|
||||||
|
return tmpArray
|
||||||
|
}
|
||||||
|
|
||||||
|
// 오목한 부분 인덱스 찾기
|
||||||
|
const concaveIndicesObj = findConcavePointIndices(points) //오목한 부분을 제외한 인덱스
|
||||||
|
let concavePointIndices = concaveIndicesObj.concavePointIndices
|
||||||
|
|
||||||
|
const concaveLine = {
|
||||||
|
index: concavePointIndices[0],
|
||||||
|
line: lines[concavePointIndices[0]],
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < points.length; i++) {
|
||||||
|
let prev = points[(i - 1 + points.length) % points.length]
|
||||||
|
let current = points[i]
|
||||||
|
let next = points[(i + 1) % points.length]
|
||||||
|
|
||||||
|
// 두 벡터 계산 (prev -> current, current -> next)
|
||||||
|
let vector1 = { x: current.x - prev.x, y: current.y - prev.y }
|
||||||
|
let vector2 = { x: next.x - current.x, y: next.y - current.y }
|
||||||
|
|
||||||
|
// 벡터의 길이 계산
|
||||||
|
let length1 = Math.sqrt(vector1.x * vector1.x + vector1.y * vector1.y)
|
||||||
|
let length2 = Math.sqrt(vector2.x * vector2.x + vector2.y * vector2.y)
|
||||||
|
|
||||||
|
// 벡터를 단위 벡터로 정규화
|
||||||
|
let unitVector1 = { x: vector1.x / length1, y: vector1.y / length1 }
|
||||||
|
let unitVector2 = { x: vector2.x / length2, y: vector2.y / length2 }
|
||||||
|
|
||||||
|
// 법선 벡터 계산 (왼쪽 방향)
|
||||||
|
let normal1 = { x: -unitVector1.y, y: unitVector1.x }
|
||||||
|
let normal2 = { x: -unitVector2.y, y: unitVector2.x }
|
||||||
|
|
||||||
|
// 법선 벡터 평균 계산
|
||||||
|
let averageNormal = {
|
||||||
|
x: (normal1.x + normal2.x) / 2,
|
||||||
|
y: (normal1.y + normal2.y) / 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 평균 법선 벡터를 단위 벡터로 정규화
|
||||||
|
let lengthNormal = Math.sqrt(averageNormal.x * averageNormal.x + averageNormal.y * averageNormal.y)
|
||||||
|
let unitNormal = {
|
||||||
|
x: averageNormal.x / lengthNormal,
|
||||||
|
y: averageNormal.y / lengthNormal,
|
||||||
|
}
|
||||||
|
|
||||||
|
offsetX = (offsetInputX / transformedMax) * originalMax * 2
|
||||||
|
offsetY = (offsetInputY / transformedMax) * originalMax * 2
|
||||||
|
|
||||||
|
// 오프셋 적용
|
||||||
|
let offsetPoint = {
|
||||||
|
x1: current.x + unitNormal.x * offsetX,
|
||||||
|
y1: current.y + unitNormal.y * offsetY,
|
||||||
|
}
|
||||||
|
|
||||||
|
offsetPoints.push(offsetPoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
const outlinePolygon = makePolygon(offsetPoints, false)
|
||||||
|
outlinePolygon.setViewLengthText(false)
|
||||||
|
|
||||||
|
// 아웃라인 폴리곤의 각 변을 선으로 생성
|
||||||
|
for (let i = 0; i < outlinePolygon.points.length; i++) {
|
||||||
|
const start = outlinePolygon.points[i]
|
||||||
|
const end = outlinePolygon.points[(i + 1) % outlinePolygon.points.length] // 다음 점, 마지막 점의 경우 첫 점으로
|
||||||
|
|
||||||
|
const line = new QLine([start.x, start.y, end.x, end.y], {
|
||||||
|
stroke: 'blue',
|
||||||
|
strokeWidth: 2,
|
||||||
|
property: 'normal',
|
||||||
|
fontSize: 14,
|
||||||
|
idx: i,
|
||||||
|
})
|
||||||
|
|
||||||
|
// 선을 배열에 추가
|
||||||
|
outLines.push(line)
|
||||||
|
canvas.add(line)
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas?.remove(outlinePolygon) //임시 폴리곤을 삭제
|
||||||
|
|
||||||
|
let parallelLinesIdx = concavePointIndices[0] + 4 //들어간선에 무조건 평행하는 선 찾기
|
||||||
|
if (parallelLinesIdx >= outLines.length) {
|
||||||
|
parallelLinesIdx = parallelLinesIdx - outLines.length
|
||||||
|
}
|
||||||
|
|
||||||
|
let vertCenterLine = []
|
||||||
|
let halfHoriCenterLinePoint = [] //카라바선의 2분할의 1번 배열
|
||||||
|
let horiCenterLine = []
|
||||||
|
let shorVertCenterLine = []
|
||||||
|
|
||||||
|
let edgeIndexArray = []
|
||||||
|
|
||||||
|
if (concavePointIndices[0] % 2 === 0) {
|
||||||
|
//concave가 짝수면 좌우로 그려진 ㄷ자
|
||||||
|
//케라바 색을 바꾼다
|
||||||
|
lines.forEach((line, index) => {
|
||||||
|
if (index % 2 === 0) {
|
||||||
|
line.line.set('stroke', 'skyblue')
|
||||||
|
if (concavePointIndices[0] !== index) {
|
||||||
|
edgeIndexArray.push(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
outLines = reSortQlineArray(outLines)
|
||||||
|
edgeIndexArray.forEach((idx, index) => {
|
||||||
|
//가로라인이 케라바 라인임
|
||||||
|
if (concavePointIndices[0] !== idx) {
|
||||||
|
//오목이가 아니면 반으로 갈라서 계산
|
||||||
|
|
||||||
|
//카라바 선의 2분할 치수를 그림
|
||||||
|
let halfLength = outLines[idx].length / 2
|
||||||
|
let centerLine1 = new QLine([outLines[idx].x1, outLines[idx].y1, outLines[idx].x1, outLines[idx].y1 + halfLength], centerLineOpt)
|
||||||
|
canvas.add(centerLine1)
|
||||||
|
|
||||||
|
let centerLine2 = new QLine([outLines[idx].x1, centerLine1.y2, outLines[idx].x2, centerLine1.y2 + halfLength], centerLineOpt)
|
||||||
|
canvas.add(centerLine2)
|
||||||
|
canvas.remove(outLines[idx]) //기존 라인 삭제
|
||||||
|
|
||||||
|
halfHoriCenterLinePoint.push({
|
||||||
|
index: idx,
|
||||||
|
x1: centerLine1.x1,
|
||||||
|
y1: centerLine1.y1,
|
||||||
|
x2: centerLine1.x2,
|
||||||
|
y2: centerLine1.y2,
|
||||||
|
}) //각 카라바 라인의 1번이 마지막점을 잡아서 센터선으로 설정
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// //각 센터 라인을 그림
|
||||||
|
halfHoriCenterLinePoint.forEach((centerPoint) => {
|
||||||
|
let tmpX2 = parallelLinesIdx !== centerPoint.index ? concaveLine.line.x2 : outLines[concavePointIndices[0]].x1 //평행선에서 내려오는 선은 아웃라인에 닿아야한다
|
||||||
|
|
||||||
|
let line = new QLine([centerPoint.x2, centerPoint.y2, tmpX2, centerPoint.y2], centerLineOpt)
|
||||||
|
canvas.add(line)
|
||||||
|
|
||||||
|
line['arrayIndex'] = centerPoint.index //커스텀으로 기존 index를 넣어줌
|
||||||
|
vertCenterLine.push(line)
|
||||||
|
})
|
||||||
|
|
||||||
|
vertCenterLine = reSortQlineArray(vertCenterLine)
|
||||||
|
lines = reSortQlineArray(lines)
|
||||||
|
setTemplateCenterLine(vertCenterLine)
|
||||||
|
|
||||||
|
//해당라인에서 만나는점을 계산
|
||||||
|
vertCenterLine.forEach((vertLine) => {
|
||||||
|
if (parallelLinesIdx !== vertLine.arrayIndex) {
|
||||||
|
//평행선을 제외한 애들만 네모를 연결
|
||||||
|
let nearLine
|
||||||
|
let nearOutline
|
||||||
|
if (vertLine.arrayIndex > concaveLine.index) {
|
||||||
|
//센터에 인덱스가 오목점 보다 크면 다음 작으면 앞에꺼
|
||||||
|
nearLine = lines[concaveLine.index + 1]
|
||||||
|
nearOutline = outLines[concaveLine.index + 1]
|
||||||
|
} else {
|
||||||
|
nearLine = lines[concaveLine.index - 1]
|
||||||
|
nearOutline = outLines[concaveLine.index - 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
let nearLineY = nearLine.y1
|
||||||
|
if (parallelLinesIdx < concaveLine.index) {
|
||||||
|
//오목점 위치가 평행선보다 크면 위쪽으로 오목
|
||||||
|
nearLineY = nearLine.y2
|
||||||
|
}
|
||||||
|
|
||||||
|
//기존에 있는 라인에서 연장해서 새로 그림
|
||||||
|
let centerExtendHoriLine = new QLine([vertLine.x1, nearOutline.line.y1, vertLine.x2, nearOutline.line.y2], centerLineOpt)
|
||||||
|
canvas.add(centerExtendHoriLine)
|
||||||
|
canvas.remove(nearOutline)
|
||||||
|
outLines.splice(nearOutline.idx, 1, centerExtendHoriLine) //아웃라인에 데이터를 다시 넣는다
|
||||||
|
|
||||||
|
//가로형에선 기본으로 ㄷ자 형태로 한다
|
||||||
|
let centerExtendLine = new QLine([vertLine.line.x1, vertLine.line.y1, centerExtendHoriLine.x1, centerExtendHoriLine.y1], centerLineOpt)
|
||||||
|
|
||||||
|
//오목이가 배열에 반보다 작으면 역 ㄷ자 여서 변경
|
||||||
|
if (concavePointIndices[0] < outLines.length / 2) {
|
||||||
|
centerExtendLine = new QLine([vertLine.line.x2, vertLine.line.y2, centerExtendHoriLine.x2, centerExtendHoriLine.y2], centerLineOpt)
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.add(centerExtendLine) //새로그리고
|
||||||
|
|
||||||
|
let betweenCenterLine = (vertLine.line.x1 + vertLine.line.x2) / 2
|
||||||
|
let centerDashLine = new QLine([betweenCenterLine, centerExtendLine.y1, betweenCenterLine, centerExtendLine.y2], dashedCenterLineOpt)
|
||||||
|
|
||||||
|
canvas.add(centerDashLine)
|
||||||
|
horiCenterLine.push(centerDashLine)
|
||||||
|
shorVertCenterLine.push(vertLine) //마지막에 가운데 선을 긋기 위해 담음
|
||||||
|
} else {
|
||||||
|
let longDashLine = halfHoriCenterLinePoint.find((obj) => obj.index === parallelLinesIdx) //평행선
|
||||||
|
|
||||||
|
let dashCenterExtendLineLength = longDashLine.y2 - longDashLine.y1 //y반개 길이
|
||||||
|
let betweenCenterLine = (vertLine.line.x1 + vertLine.line.x2) / 2 //y의 길이
|
||||||
|
let totalLength = ((longDashLine.y2 - longDashLine.y1) * 2) / dashCenterExtendLineLength //2개로 나눔
|
||||||
|
|
||||||
|
//반 쪼개서 그린다
|
||||||
|
for (let i = 0; i < totalLength; i++) {
|
||||||
|
//2번에 나눠서
|
||||||
|
let startY = i === 0 ? longDashLine.y1 : longDashLine.y1 + dashCenterExtendLineLength //시작 하는 y의 좌표
|
||||||
|
//x값은 고정이임 //TODO: 지붕 각도 계산법에 의해 재계산해야함
|
||||||
|
let centerDashLine = new QLine([betweenCenterLine, startY, betweenCenterLine, startY + dashCenterExtendLineLength], dashedCenterLineOpt)
|
||||||
|
canvas.add(centerDashLine)
|
||||||
|
horiCenterLine.push(centerDashLine)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//마지막에 오목한 외곽선을 연장한다
|
||||||
|
const tmpLastOutLine = outLines[concavePointIndices[0]]
|
||||||
|
const lastOutLine = new QLine([tmpLastOutLine.x1, shorVertCenterLine[0].y1, tmpLastOutLine.x1, shorVertCenterLine[1].y1], centerLineOpt)
|
||||||
|
canvas.add(lastOutLine)
|
||||||
|
canvas.remove(tmpLastOutLine)
|
||||||
|
|
||||||
|
//폴리곤 패턴을 그리기 위해 작성
|
||||||
|
let tmpVertCenterLine = outLines.filter((x, index) => index % 2 !== 0) //세로만 찾음
|
||||||
|
tmpVertCenterLine = tmpVertCenterLine.concat(vertCenterLine)
|
||||||
|
tmpVertCenterLine.sort((a, b) => a.y1 - b.y1)
|
||||||
|
tmpVertCenterLine.push(lastOutLine)
|
||||||
|
|
||||||
|
let roofPatternPolygonArray = []
|
||||||
|
let tmpArray = []
|
||||||
|
let tmpBigArray = []
|
||||||
|
|
||||||
|
const lastCenterLine = tmpVertCenterLine[tmpVertCenterLine.length - 1] //마지막 센터라인을 정의
|
||||||
|
|
||||||
|
for (let i = 0; i < tmpVertCenterLine.length - 1; i++) {
|
||||||
|
//-1인건 마지막은 오목한 선이라 돌 필요 없음
|
||||||
|
//라인 하나에 두점씩 나온다
|
||||||
|
let firstPointObj = {}
|
||||||
|
let secondPointObj = {}
|
||||||
|
|
||||||
|
let x1 = tmpVertCenterLine[i].x1
|
||||||
|
let y1 = tmpVertCenterLine[i].y1
|
||||||
|
let x2 = tmpVertCenterLine[i].x2
|
||||||
|
let y2 = tmpVertCenterLine[i].y2
|
||||||
|
|
||||||
|
if (i === 2 || i === 4) {
|
||||||
|
//작은 네모들
|
||||||
|
tmpArray = []
|
||||||
|
const prevLine = tmpVertCenterLine[i - 1] //뒤에서 앞라인을 찾는다
|
||||||
|
const nextLine = tmpVertCenterLine[i + 1]
|
||||||
|
|
||||||
|
//내 앞뒤 라인
|
||||||
|
const tmpX1 = i === 2 ? prevLine.x1 : nextLine.x1
|
||||||
|
const tmpY1 = i === 2 ? prevLine.y1 : nextLine.y1
|
||||||
|
const tmpX2 = i === 2 ? prevLine.x2 : nextLine.x2
|
||||||
|
const tmpY2 = i === 2 ? prevLine.y2 : nextLine.y2
|
||||||
|
|
||||||
|
firstPointObj = { x: tmpX1, y: tmpY1 }
|
||||||
|
secondPointObj = { x: tmpX2, y: tmpY2 }
|
||||||
|
tmpArray.push(firstPointObj)
|
||||||
|
tmpArray.push(secondPointObj)
|
||||||
|
|
||||||
|
//현재 내 선
|
||||||
|
firstPointObj = { x: x1, y: y1 }
|
||||||
|
secondPointObj = { x: x2, y: y2 }
|
||||||
|
tmpArray.push(firstPointObj)
|
||||||
|
tmpArray.push(secondPointObj)
|
||||||
|
roofPatternPolygonArray.push(tmpArray)
|
||||||
|
} else {
|
||||||
|
//큰 육각
|
||||||
|
if (i === 1 || i === 5) {
|
||||||
|
// 큰 폴리곤은 가운데 선으로 되야됨
|
||||||
|
if (outLines.length / 2 > concavePointIndices[0]) {
|
||||||
|
x2 = i === 1 ? lastCenterLine.x1 : lastCenterLine.x2
|
||||||
|
y2 = i === 1 ? lastCenterLine.y1 : lastCenterLine.y2
|
||||||
|
} else {
|
||||||
|
//오목이가 배열 전체보다 크면 오른쪽 오목이
|
||||||
|
x1 = i === 1 ? lastCenterLine.x1 : lastCenterLine.x2
|
||||||
|
y1 = i === 1 ? lastCenterLine.y2 : lastCenterLine.y1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i === 5) {
|
||||||
|
//5번일때는 앞에 3번에 선이 필요하다
|
||||||
|
let prevX1 = tmpVertCenterLine[i - 2].x1
|
||||||
|
let prevY1 = tmpVertCenterLine[i - 2].y1
|
||||||
|
let prevX2 = tmpVertCenterLine[i - 2].x2
|
||||||
|
let prevY2 = tmpVertCenterLine[i - 2].y2
|
||||||
|
firstPointObj = { x: prevX1, y: prevY1 }
|
||||||
|
secondPointObj = { x: prevX2, y: prevY2 }
|
||||||
|
tmpBigArray.push(firstPointObj)
|
||||||
|
tmpBigArray.push(secondPointObj)
|
||||||
|
}
|
||||||
|
|
||||||
|
firstPointObj = { x: x1, y: y1 }
|
||||||
|
secondPointObj = { x: x2, y: y2 }
|
||||||
|
tmpBigArray.push(firstPointObj)
|
||||||
|
tmpBigArray.push(secondPointObj)
|
||||||
|
|
||||||
|
if (i === 3 || i === 6) {
|
||||||
|
roofPatternPolygonArray.push(tmpBigArray)
|
||||||
|
tmpBigArray = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setRoofPolygonPattern({ roofPatternPolygonArray, lines })
|
||||||
|
} else {
|
||||||
|
// 오목한 부분이 세로선일때 아래ㄷ, 위ㄷ
|
||||||
|
//라인들을 좌측에서 -> 우측으로 그리는거처럼 데이터 보정
|
||||||
|
lines.forEach((line, index) => {
|
||||||
|
if (!(index % 2 === 0)) {
|
||||||
|
line.line.set('stroke', 'skyblue')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
outLines = reSortQlineArray(outLines)
|
||||||
|
outLines.forEach((outline, index) => {
|
||||||
|
if (!(index % 2 === 0)) {
|
||||||
|
//세로라인이 케라바 라인임
|
||||||
|
|
||||||
|
if (concavePointIndices[0] !== index) {
|
||||||
|
//오목이가 아니면 반으로 갈라서 계산
|
||||||
|
|
||||||
|
//카라바 선의 2분할 치수를 그림
|
||||||
|
let halfLength = outline.length / 2
|
||||||
|
let centerLine1 = new QLine([outline.x1, outline.y1, outline.x1 + halfLength, outline.y1], centerLineOpt)
|
||||||
|
canvas.add(centerLine1)
|
||||||
|
|
||||||
|
let centerLine2 = new QLine([centerLine1.x2, outline.y1, centerLine1.x2 + halfLength, outline.y1], centerLineOpt)
|
||||||
|
canvas.add(centerLine2)
|
||||||
|
canvas.remove(outline) //기존 라인 삭제
|
||||||
|
|
||||||
|
halfHoriCenterLinePoint.push({
|
||||||
|
index: index,
|
||||||
|
x1: centerLine1.x1,
|
||||||
|
y1: centerLine1.y1,
|
||||||
|
x2: centerLine1.x2,
|
||||||
|
y2: centerLine1.y2,
|
||||||
|
}) //각 카라바 라인의 1번이 마지막점을 잡아서 센터선으로 설정
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//각 센터 라인을 그림
|
||||||
|
halfHoriCenterLinePoint.forEach((centerPoint) => {
|
||||||
|
let tmpY2 = parallelLinesIdx !== centerPoint.index ? concaveLine.line.y1 : outLines[concavePointIndices[0]].y2 //평행선에서 내려오는 선은 아웃라인에 닿아야한다
|
||||||
|
|
||||||
|
let line = new QLine([centerPoint.x2, centerPoint.y1, centerPoint.x2, tmpY2], centerLineOpt)
|
||||||
|
canvas.add(line)
|
||||||
|
|
||||||
|
line['arrayIndex'] = centerPoint.index //커스텀으로 기존 index를 넣어줌
|
||||||
|
vertCenterLine.push(line)
|
||||||
|
})
|
||||||
|
|
||||||
|
vertCenterLine = reSortQlineArray(vertCenterLine)
|
||||||
|
lines = reSortQlineArray(lines)
|
||||||
|
setTemplateCenterLine(vertCenterLine)
|
||||||
|
|
||||||
|
//해당라인에서 만나는점을 계산
|
||||||
|
vertCenterLine.forEach((vertLine) => {
|
||||||
|
if (parallelLinesIdx !== vertLine.arrayIndex) {
|
||||||
|
//평행선을 제외한 애들만 네모를 연결
|
||||||
|
let nearLine
|
||||||
|
let nearOutline
|
||||||
|
if (vertLine.arrayIndex > concaveLine.index) {
|
||||||
|
//센터에 인덱스가 오목점 보다 크면 다음 작으면 앞에꺼
|
||||||
|
nearLine = lines[concaveLine.index + 1]
|
||||||
|
nearOutline = outLines[concaveLine.index + 1]
|
||||||
|
} else {
|
||||||
|
nearLine = lines[concaveLine.index - 1]
|
||||||
|
nearOutline = outLines[concaveLine.index - 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
let nearLineY = nearLine.y1
|
||||||
|
if (parallelLinesIdx < concaveLine.index) {
|
||||||
|
//오목점 위치가 평행선보다 크면 위쪽으로 오목
|
||||||
|
nearLineY = nearLine.y2
|
||||||
|
}
|
||||||
|
|
||||||
|
let centerExtendLine = new QLine([vertLine.line.x1, nearLineY, nearOutline.x1, nearLineY], centerLineOpt)
|
||||||
|
canvas.add(centerExtendLine) //새로그리고
|
||||||
|
|
||||||
|
//기존에 있는 라인에서 연장해서 새로 그림
|
||||||
|
let centerExtendHoriLine = new QLine([nearOutline.line.x1, vertLine.y1, nearOutline.line.x2, vertLine.line.y2], centerLineOpt)
|
||||||
|
canvas.add(centerExtendHoriLine)
|
||||||
|
canvas.remove(nearOutline)
|
||||||
|
outLines.splice(nearOutline.idx, 1, centerExtendHoriLine) //아웃라인에 데이터를 다시 넣는다
|
||||||
|
|
||||||
|
let betweenCenterLine = (vertLine.line.y1 + vertLine.line.y2) / 2
|
||||||
|
let centerDashLine = new QLine([vertLine.line.x1, betweenCenterLine, nearOutline.x1, betweenCenterLine], dashedCenterLineOpt)
|
||||||
|
|
||||||
|
canvas.add(centerDashLine)
|
||||||
|
horiCenterLine.push(centerDashLine)
|
||||||
|
shorVertCenterLine.push(vertLine) //마지막에 가운데 선을 긋기 위해 담음
|
||||||
|
} else {
|
||||||
|
let longDashLine = halfHoriCenterLinePoint.find((obj) => obj.index === parallelLinesIdx)
|
||||||
|
|
||||||
|
let dashCenterExtendLineLength = longDashLine.x2 - longDashLine.x1
|
||||||
|
let betweenCenterLine = (vertLine.line.y1 + vertLine.line.y2) / 2
|
||||||
|
let totalLength = ((longDashLine.x2 - longDashLine.x1) * 2) / dashCenterExtendLineLength
|
||||||
|
|
||||||
|
//반 쪼개서 그린다
|
||||||
|
for (let i = 0; i < totalLength; i++) {
|
||||||
|
let startX = i === 0 ? longDashLine.x1 : longDashLine.x1 + dashCenterExtendLineLength
|
||||||
|
let centerDashLine = new QLine([startX, betweenCenterLine, startX + dashCenterExtendLineLength, betweenCenterLine], dashedCenterLineOpt)
|
||||||
|
canvas.add(centerDashLine)
|
||||||
|
horiCenterLine.push(centerDashLine)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//마지막에 오목한 외곽선을 연장한다
|
||||||
|
const tmpLastOutLine = outLines[concavePointIndices[0]]
|
||||||
|
const lastOutLine = new QLine([shorVertCenterLine[0].x1, tmpLastOutLine.y1, shorVertCenterLine[1].x1, tmpLastOutLine.y2], centerLineOpt)
|
||||||
|
canvas.add(lastOutLine)
|
||||||
|
canvas.remove(tmpLastOutLine)
|
||||||
|
|
||||||
|
let tmpVertCenterLine = outLines.filter((x, index) => index % 2 === 0) //세로만 찾음
|
||||||
|
tmpVertCenterLine = tmpVertCenterLine.concat(vertCenterLine)
|
||||||
|
tmpVertCenterLine.sort((a, b) => a.x1 - b.x1)
|
||||||
|
tmpVertCenterLine.push(lastOutLine)
|
||||||
|
|
||||||
|
let roofPatternPolygonArray = []
|
||||||
|
let tmpArray = []
|
||||||
|
let tmpBigArray = []
|
||||||
|
|
||||||
|
const lastCenterLine = tmpVertCenterLine[tmpVertCenterLine.length - 1] //마지막 센터라인을 정의
|
||||||
|
|
||||||
|
for (let i = 0; i < tmpVertCenterLine.length - 1; i++) {
|
||||||
|
//-1인건 마지막은 오목한 선이라 돌 필요 없음
|
||||||
|
//라인 하나에 두점씩 나온다
|
||||||
|
let firstPointObj = {}
|
||||||
|
let secondPointObj = {}
|
||||||
|
|
||||||
|
let x1 = tmpVertCenterLine[i].x1
|
||||||
|
let y1 = tmpVertCenterLine[i].y1
|
||||||
|
let x2 = tmpVertCenterLine[i].x2
|
||||||
|
let y2 = tmpVertCenterLine[i].y2
|
||||||
|
|
||||||
|
if (i === 2 || i === 4) {
|
||||||
|
tmpArray = []
|
||||||
|
const prevLine = tmpVertCenterLine[i - 1] //뒤에서 앞라인을 찾는다
|
||||||
|
const nextLine = tmpVertCenterLine[i + 1]
|
||||||
|
|
||||||
|
//내 앞뒤 라인
|
||||||
|
const tmpX1 = i === 2 ? prevLine.x1 : nextLine.x1
|
||||||
|
const tmpY1 = i === 2 ? prevLine.y1 : nextLine.y1
|
||||||
|
const tmpX2 = i === 2 ? prevLine.x2 : nextLine.x2
|
||||||
|
const tmpY2 = i === 2 ? prevLine.y2 : nextLine.y2
|
||||||
|
|
||||||
|
firstPointObj = { x: tmpX1, y: tmpY1 }
|
||||||
|
secondPointObj = { x: tmpX2, y: tmpY2 }
|
||||||
|
tmpArray.push(firstPointObj)
|
||||||
|
tmpArray.push(secondPointObj)
|
||||||
|
|
||||||
|
//현재 내 선
|
||||||
|
firstPointObj = { x: x1, y: y1 }
|
||||||
|
secondPointObj = { x: x2, y: y2 }
|
||||||
|
tmpArray.push(firstPointObj)
|
||||||
|
tmpArray.push(secondPointObj)
|
||||||
|
roofPatternPolygonArray.push(tmpArray)
|
||||||
|
} else {
|
||||||
|
if (i === 1 || i === 5) {
|
||||||
|
// 큰 폴리곤은 가운데 선으로 되야됨
|
||||||
|
if (outLines.length / 2 < concavePointIndices[0]) {
|
||||||
|
//오목이가 배열 전체보다 크면 위쪽 방향
|
||||||
|
x2 = i === 1 ? lastCenterLine.x2 : lastCenterLine.x1
|
||||||
|
y2 = i === 1 ? lastCenterLine.y2 : lastCenterLine.y1
|
||||||
|
} else {
|
||||||
|
x1 = i === 1 ? lastCenterLine.x1 : lastCenterLine.x2
|
||||||
|
y1 = i === 1 ? lastCenterLine.y1 : lastCenterLine.y2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i === 5) {
|
||||||
|
//5번일때는 앞에 3번에 선이 필요하다
|
||||||
|
let prevX1 = tmpVertCenterLine[i - 2].x1
|
||||||
|
let prevY1 = tmpVertCenterLine[i - 2].y1
|
||||||
|
let prevX2 = tmpVertCenterLine[i - 2].x2
|
||||||
|
let prevY2 = tmpVertCenterLine[i - 2].y2
|
||||||
|
firstPointObj = { x: prevX1, y: prevY1 }
|
||||||
|
secondPointObj = { x: prevX2, y: prevY2 }
|
||||||
|
tmpBigArray.push(firstPointObj)
|
||||||
|
tmpBigArray.push(secondPointObj)
|
||||||
|
}
|
||||||
|
|
||||||
|
firstPointObj = { x: x1, y: y1 }
|
||||||
|
secondPointObj = { x: x2, y: y2 }
|
||||||
|
tmpBigArray.push(firstPointObj)
|
||||||
|
tmpBigArray.push(secondPointObj)
|
||||||
|
|
||||||
|
if (i === 3 || i === 6) {
|
||||||
|
roofPatternPolygonArray.push(tmpBigArray)
|
||||||
|
tmpBigArray = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setRoofPolygonPattern({ roofPatternPolygonArray, lines })
|
||||||
|
}
|
||||||
|
canvas?.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 세로 방샹 라인의 좌표 순서를 위에서 아래로 변경
|
* 세로 방샹 라인의 좌표 순서를 위에서 아래로 변경
|
||||||
* @param {array} arr
|
* @param {array} arr
|
||||||
@ -3620,59 +4199,25 @@ export function useMode() {
|
|||||||
* 가대 생성 로직
|
* 가대 생성 로직
|
||||||
*/
|
*/
|
||||||
const makeRoofTrestle = () => {
|
const makeRoofTrestle = () => {
|
||||||
|
if (compass === undefined) {
|
||||||
|
alert('방위를 먼저 선택 해주세요.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (Object.keys(roofPolygonPattern).length === 0 && roofPolygonPattern.constructor === Object) {
|
if (Object.keys(roofPolygonPattern).length === 0 && roofPolygonPattern.constructor === Object) {
|
||||||
alert('객체가 비어있습니다.')
|
alert('객체가 비어있습니다.')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const polygons = roofPolygonArray //리코일에 있는 패턴그린 폴리곤가져옴
|
const polygons = roofPolygonArray //리코일에 있는 패턴그린 폴리곤가져옴
|
||||||
let selectedAreaArray = []
|
|
||||||
|
|
||||||
const defualtStrokeStyle = {
|
|
||||||
stroke: 'red',
|
|
||||||
strokeDashArray: [9, 5],
|
|
||||||
strokeWidth: 0.3,
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectedStrokeStyle = {
|
|
||||||
stroke: 'red',
|
|
||||||
strokeWidth: 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 지붕가대 생성 후 가대 선택 이벤트를 추가하는 로직
|
* 지붕가대 생성 후 가대 선택 이벤트를 추가하는 로직
|
||||||
* @param polygon
|
* @param polygon
|
||||||
*/
|
*/
|
||||||
function toggleSelection(polygon) {
|
|
||||||
if (polygon.strokeWidth === defualtStrokeStyle.strokeWidth) {
|
|
||||||
//기본 선택이랑 스트로크 굵기가 같으면 선택 안됨으로 봄
|
|
||||||
polygon.set({
|
|
||||||
stroke: selectedStrokeStyle.stroke,
|
|
||||||
strokeWidth: selectedStrokeStyle.strokeWidth,
|
|
||||||
strokeDashArray: [0],
|
|
||||||
})
|
|
||||||
canvas.discardActiveObject() // 객체의 활성 상태 해제
|
|
||||||
selectedAreaArray.push(polygon)
|
|
||||||
} else {
|
|
||||||
//선택후 재선택하면 선택안됨으로 변경
|
|
||||||
polygon.set({
|
|
||||||
stroke: defualtStrokeStyle.stroke,
|
|
||||||
strokeWidth: defualtStrokeStyle.strokeWidth,
|
|
||||||
strokeDashArray: defualtStrokeStyle.strokeDashArray,
|
|
||||||
})
|
|
||||||
canvas.discardActiveObject() // 객체의 활성 상태 해제
|
|
||||||
|
|
||||||
//폴리곤에 커스텀 인덱스를 가지고 해당 배열 인덱스를 찾아 삭제함
|
|
||||||
const removeIndex = polygon.idx
|
|
||||||
const removeArrayIndex = selectedAreaArray.findIndex((x) => x.idx === removeIndex)
|
|
||||||
selectedAreaArray.splice(removeArrayIndex, 1)
|
|
||||||
}
|
|
||||||
canvas?.renderAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
const pattern = getRoofPattern(roofStyle, 'cell') //셀모드 배경색을 칠한다
|
const pattern = getRoofPattern(roofStyle, 'cell') //셀모드 배경색을 칠한다
|
||||||
|
|
||||||
polygons.sort((a, b) => a.lines.length > b.lines.length) //무조건 잴 긴거 정렬
|
polygons.sort((a, b) => b.points.length - a.points.length) //무조건 잴 긴거 정렬
|
||||||
|
|
||||||
// 외각선을 안쪽으로 그려 가대선을 그린다.
|
// 외각선을 안쪽으로 그려 가대선을 그린다.
|
||||||
polygons.forEach((polygon, index) => {
|
polygons.forEach((polygon, index) => {
|
||||||
@ -3680,6 +4225,8 @@ export function useMode() {
|
|||||||
let referenceDirection = 'none' //상단 기준 값
|
let referenceDirection = 'none' //상단 기준 값
|
||||||
let parallelPoint = -1
|
let parallelPoint = -1
|
||||||
trestlePolygon.setViewLengthText(false) //얘는 set으로 안먹는다...
|
trestlePolygon.setViewLengthText(false) //얘는 set으로 안먹는다...
|
||||||
|
trestlePolygon.bringForward()
|
||||||
|
|
||||||
trestlePolygon.set({
|
trestlePolygon.set({
|
||||||
stroke: 'red',
|
stroke: 'red',
|
||||||
strokeDashArray: [9, 5],
|
strokeDashArray: [9, 5],
|
||||||
@ -3689,12 +4236,12 @@ export function useMode() {
|
|||||||
lockRotation: true,
|
lockRotation: true,
|
||||||
lockScalingX: true,
|
lockScalingX: true,
|
||||||
lockScalingY: true,
|
lockScalingY: true,
|
||||||
bringToFront: true,
|
|
||||||
idx: polygon.customIndex, //가대 폴리곤의 임시 인덱스를 넣어줌
|
idx: polygon.customIndex, //가대 폴리곤의 임시 인덱스를 넣어줌
|
||||||
name: 'trestlePolygon',
|
name: 'trestlePolygon',
|
||||||
})
|
})
|
||||||
|
|
||||||
if (polygon.points.length > 4) {
|
if (polygon.points.length > 4) {
|
||||||
|
//6, 8각
|
||||||
//4각 이상일때만 한다
|
//4각 이상일때만 한다
|
||||||
const concave = findConcavePointIndices(polygon.points) //오목한 부분기준으로 시작점을 찾으려 계산
|
const concave = findConcavePointIndices(polygon.points) //오목한 부분기준으로 시작점을 찾으려 계산
|
||||||
parallelPoint = parseInt(concave.concavePointIndices[0] + 3) % polygon.points.length //시작점을 찾기 위해 적용
|
parallelPoint = parseInt(concave.concavePointIndices[0] + 3) % polygon.points.length //시작점을 찾기 위해 적용
|
||||||
@ -3757,11 +4304,107 @@ export function useMode() {
|
|||||||
toggleSelection(trestlePolygon)
|
toggleSelection(trestlePolygon)
|
||||||
})
|
})
|
||||||
polygon.set({ fill: pattern })
|
polygon.set({ fill: pattern })
|
||||||
|
trestlePolygon.bringForward()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
canvas?.renderAll()
|
||||||
|
setMode(Mode.DEFAULT) //default 모드로 변경
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 가대 영역 선택 시 이벤트
|
||||||
|
* @param {} polygon
|
||||||
|
*/
|
||||||
|
const toggleSelection = (polygon) => {
|
||||||
|
const selectedAreaArray = selectedCellRoofArray
|
||||||
|
|
||||||
|
const defualtStrokeStyle = {
|
||||||
|
stroke: 'red',
|
||||||
|
strokeDashArray: [9, 5],
|
||||||
|
strokeWidth: 0.3,
|
||||||
|
}
|
||||||
|
|
||||||
|
const wallDirection = polygon.wallDirection
|
||||||
|
|
||||||
|
// //A템플릿 타입
|
||||||
|
// if (templateType === 2) {
|
||||||
|
// if (compass === 90) {
|
||||||
|
// if (wallDirection === 'right') {
|
||||||
|
// alert('선택할 수 없는 방향입니다.')
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// } else if (compass === 270) {
|
||||||
|
// if (wallDirection === 'left') {
|
||||||
|
// alert('선택할 수 없는 방향입니다.')
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } else if (templateType === 3) {
|
||||||
|
// if (compass === 0) {
|
||||||
|
// if (wallDirection === 'top') {
|
||||||
|
// alert('선택할 수 없는 방향입니다.')
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// } else if (compass === 180) {
|
||||||
|
// if (wallDirection === 'bottom') {
|
||||||
|
// alert('선택할 수 없는 방향입니다.')
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
const invalidDirections = {
|
||||||
|
2: {
|
||||||
|
90: 'right',
|
||||||
|
270: 'left',
|
||||||
|
},
|
||||||
|
3: {
|
||||||
|
0: 'top',
|
||||||
|
180: 'bottom',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if (invalidDirections[templateType] && invalidDirections[templateType][compass] === wallDirection) {
|
||||||
|
alert('선택할 수 없는 방향입니다.')
|
||||||
|
canvas.discardActiveObject() // 객체의 활성 상태 해제
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedStrokeStyle = {
|
||||||
|
stroke: 'red',
|
||||||
|
strokeWidth: 3,
|
||||||
|
}
|
||||||
|
if (polygon.strokeWidth === defualtStrokeStyle.strokeWidth) {
|
||||||
|
//기본 선택이랑 스트로크 굵기가 같으면 선택 안됨으로 봄
|
||||||
|
polygon.set({
|
||||||
|
stroke: selectedStrokeStyle.stroke,
|
||||||
|
strokeWidth: selectedStrokeStyle.strokeWidth,
|
||||||
|
strokeDashArray: [0],
|
||||||
|
})
|
||||||
|
canvas.discardActiveObject() // 객체의 활성 상태 해제
|
||||||
|
|
||||||
|
//중복으로 들어가는걸 방지하기 위한 코드
|
||||||
|
const isExist = selectedAreaArray.some((x) => x.idx === polygon.idx)
|
||||||
|
if (!isExist) {
|
||||||
|
selectedAreaArray.push(polygon)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//선택후 재선택하면 선택안됨으로 변경
|
||||||
|
polygon.set({
|
||||||
|
stroke: defualtStrokeStyle.stroke,
|
||||||
|
strokeWidth: defualtStrokeStyle.strokeWidth,
|
||||||
|
strokeDashArray: defualtStrokeStyle.strokeDashArray,
|
||||||
|
})
|
||||||
|
canvas.discardActiveObject() // 객체의 활성 상태 해제
|
||||||
|
|
||||||
|
//폴리곤에 커스텀 인덱스를 가지고 해당 배열 인덱스를 찾아 삭제함
|
||||||
|
const removeIndex = polygon.idx
|
||||||
|
const removeArrayIndex = selectedAreaArray.findIndex((x) => x.idx === removeIndex)
|
||||||
|
selectedAreaArray.splice(removeArrayIndex, 1)
|
||||||
|
}
|
||||||
|
|
||||||
setSelectedCellRoofArray(selectedAreaArray)
|
setSelectedCellRoofArray(selectedAreaArray)
|
||||||
canvas?.renderAll()
|
canvas?.renderAll()
|
||||||
setMode(Mode.DEFAULT) //default 모드로 변경
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3769,8 +4412,9 @@ export function useMode() {
|
|||||||
*/
|
*/
|
||||||
const makeRoofFillCells = () => {
|
const makeRoofFillCells = () => {
|
||||||
const drawCellsArray = []
|
const drawCellsArray = []
|
||||||
|
const selectedCellRoofs = [...selectedCellRoofArray]
|
||||||
|
|
||||||
if (selectedCellRoofArray.length === 0) {
|
if (selectedCellRoofs.length === 0) {
|
||||||
//배열에 선택된 가대 셀이 없으면 리턴
|
//배열에 선택된 가대 셀이 없으면 리턴
|
||||||
alert('선택된 영역이 없습니다.')
|
alert('선택된 영역이 없습니다.')
|
||||||
setMode(Mode.DEFAULT) //default 모드로 변경
|
setMode(Mode.DEFAULT) //default 모드로 변경
|
||||||
@ -3797,9 +4441,7 @@ export function useMode() {
|
|||||||
;[cellSize.width, cellSize.height] = [cellSize.height, cellSize.width]
|
;[cellSize.width, cellSize.height] = [cellSize.height, cellSize.width]
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedCellRoofArray.forEach((polygon, index) => {
|
selectedCellRoofs.forEach((polygon, index) => {
|
||||||
//오목한 부분의 반대 꼭지점 //없는 애들도 있어서 -1
|
|
||||||
|
|
||||||
const drawCells = polygon.fillCellABType({
|
const drawCells = polygon.fillCellABType({
|
||||||
width: cellSize.width,
|
width: cellSize.width,
|
||||||
height: cellSize.height,
|
height: cellSize.height,
|
||||||
@ -3809,6 +4451,8 @@ export function useMode() {
|
|||||||
startIndex: polygon.startIndex,
|
startIndex: polygon.startIndex,
|
||||||
})
|
})
|
||||||
drawCellsArray.push({ roofIndex: polygon.customIndex, drawCells: drawCells })
|
drawCellsArray.push({ roofIndex: polygon.customIndex, drawCells: drawCells })
|
||||||
|
|
||||||
|
// toggleSelection(polygon) //선택 후 셀그리면 지우려고 했는데 방위 땜에 삭제
|
||||||
})
|
})
|
||||||
|
|
||||||
setDrewRoofCells(drawCellsArray)
|
setDrewRoofCells(drawCellsArray)
|
||||||
|
|||||||
@ -67,3 +67,9 @@ export const roofMaterialState = atom({
|
|||||||
default: { width: 20, height: 10, rafter: 0, roofStyle: 2 },
|
default: { width: 20, height: 10, rafter: 0, roofStyle: 2 },
|
||||||
dangerouslyAllowMutability: true,
|
dangerouslyAllowMutability: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const compassState = atom({
|
||||||
|
key: 'compass',
|
||||||
|
default: undefined,
|
||||||
|
dangerouslyAllowMutability: true,
|
||||||
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user