2295 lines
77 KiB
JavaScript
2295 lines
77 KiB
JavaScript
import { useEffect, useRef, useState } from 'react'
|
|
import QRect from '@/components/fabric/QRect'
|
|
import QPolygon from '@/components/fabric/QPolygon'
|
|
import { getStartIndex, rearrangeArray, findTopTwoIndexesByDistance, getDirection, getCenterPoint } from '@/util/canvas-util'
|
|
import { useRecoilState, useSetRecoilState } from 'recoil'
|
|
import { fontSizeState, roofState, sortedPolygonArray, wallState } from '@/store/canvasAtom'
|
|
import { QLine } from '@/components/fabric/QLine'
|
|
|
|
export const Mode = {
|
|
DRAW_LINE: 'drawLine', // 기준선 긋기모드
|
|
EDIT: 'edit',
|
|
TEMPLATE: 'template',
|
|
PATTERNA: 'patterna',
|
|
PATTERNB: 'patternb',
|
|
TEXTBOX: 'textbox',
|
|
DRAW_RECT: 'drawRect',
|
|
DEFAULT: 'default',
|
|
}
|
|
|
|
export function useMode() {
|
|
const [mode, setMode] = useState()
|
|
const points = useRef([])
|
|
const historyPoints = useRef([])
|
|
const historyLines = useRef([])
|
|
const [canvas, setCanvas] = useState(null)
|
|
const [zoom, setZoom] = useState(100)
|
|
const [fontSize] = useRecoilState(fontSizeState)
|
|
const [shape, setShape] = useState(0)
|
|
const [sortedArray, setSortedArray] = useRecoilState(sortedPolygonArray)
|
|
const [roof, setRoof] = useRecoilState(roofState)
|
|
const [wall, setWall] = useRecoilState(wallState)
|
|
|
|
const addEvent = (mode) => {
|
|
switch (mode) {
|
|
case 'default':
|
|
canvas?.off('mouse:down')
|
|
break
|
|
case 'drawLine':
|
|
drawLineMode()
|
|
break
|
|
case 'edit':
|
|
editMode()
|
|
break
|
|
case 'template':
|
|
templateMode()
|
|
break
|
|
case 'patterna':
|
|
applyTemplateA()
|
|
break
|
|
case 'patternb':
|
|
applyTemplateB()
|
|
break
|
|
case 'textbox':
|
|
textboxMode()
|
|
break
|
|
case 'drawRect':
|
|
drawRectMode()
|
|
break
|
|
}
|
|
}
|
|
|
|
const changeMode = (canvas, mode) => {
|
|
setMode(mode)
|
|
// mode변경 시 이전 이벤트 제거
|
|
setCanvas(canvas)
|
|
canvas?.off('mouse:down')
|
|
addEvent(mode)
|
|
}
|
|
|
|
const editMode = () => {
|
|
canvas?.on('mouse:down', function (options) {
|
|
const pointer = canvas?.getPointer(options.e)
|
|
const circle = new fabric.Circle({
|
|
radius: 1,
|
|
fill: 'transparent', // 원 안을 비웁니다.
|
|
stroke: 'black', // 원 테두리 색상을 검은색으로 설정합니다.
|
|
left: pointer.x,
|
|
top: pointer.y,
|
|
originX: 'center',
|
|
originY: 'center',
|
|
selectable: false,
|
|
})
|
|
|
|
historyPoints.current.push(circle)
|
|
points.current.push(circle)
|
|
canvas?.add(circle)
|
|
|
|
if (points.current.length === 2) {
|
|
const length = Number(prompt('길이를 입력하세요:'))
|
|
// length 값이 숫자가 아닌 경우
|
|
if (isNaN(length) || length === 0) {
|
|
//마지막 추가 된 points 제거합니다.
|
|
|
|
const lastPoint = historyPoints.current[historyPoints.current.length - 1]
|
|
|
|
canvas?.remove(lastPoint)
|
|
|
|
historyPoints.current.pop()
|
|
points.current.pop()
|
|
return
|
|
}
|
|
|
|
if (length) {
|
|
const vector = {
|
|
x: points.current[1].left - points.current[0].left,
|
|
y: points.current[1].top - points.current[0].top,
|
|
}
|
|
const slope = Math.abs(vector.y / vector.x) // 기울기 계산
|
|
|
|
let scaledVector
|
|
if (slope >= 1) {
|
|
// 기울기가 1 이상이면 x축 방향으로 그림
|
|
scaledVector = {
|
|
x: 0,
|
|
y: vector.y >= 0 ? Number(length) : -Number(length),
|
|
}
|
|
} else {
|
|
// 기울기가 1 미만이면 y축 방향으로 그림
|
|
scaledVector = {
|
|
x: vector.x >= 0 ? Number(length) : -Number(length),
|
|
y: 0,
|
|
}
|
|
}
|
|
|
|
const line = new QLine(
|
|
[points.current[0].left, points.current[0].top, points.current[0].left + scaledVector.x, points.current[0].top + scaledVector.y],
|
|
{
|
|
stroke: 'black',
|
|
strokeWidth: 2,
|
|
selectable: false,
|
|
viewLengthText: true,
|
|
direction: getDirection(points.current[0], points.current[1]),
|
|
fontSize: fontSize,
|
|
},
|
|
)
|
|
|
|
pushHistoryLine(line)
|
|
|
|
// 라인의 끝에 점을 추가합니다.
|
|
const endPointCircle = new fabric.Circle({
|
|
radius: 1,
|
|
fill: 'transparent', // 원 안을 비웁니다.
|
|
stroke: 'black', // 원 테두리 색상을 검은색으로 설정합니다.
|
|
left: points.current[0].left + scaledVector.x,
|
|
top: points.current[0].top + scaledVector.y,
|
|
originX: 'center',
|
|
originY: 'center',
|
|
selectable: false,
|
|
})
|
|
|
|
canvas?.add(endPointCircle)
|
|
|
|
historyPoints.current.push(endPointCircle)
|
|
|
|
points.current.forEach((point) => {
|
|
canvas?.remove(point)
|
|
})
|
|
points.current = [endPointCircle]
|
|
}
|
|
}
|
|
|
|
canvas?.renderAll()
|
|
})
|
|
}
|
|
|
|
const pushHistoryLine = (line) => {
|
|
if (historyLines.current.length > 0 && historyLines.current[historyLines.current.length - 1].direction === line.direction) {
|
|
// 같은 방향의 선이 두 번 연속으로 그려지면 이전 선을 제거하고, 새로운 선과 merge한다.
|
|
|
|
const lastLine = historyLines.current.pop()
|
|
canvas?.remove(lastLine)
|
|
|
|
const mergedLine = new QLine([lastLine.x1, lastLine.y1, line.x2, line.y2], {
|
|
stroke: 'black',
|
|
strokeWidth: 2,
|
|
selectable: false,
|
|
viewLengthText: true,
|
|
direction: lastLine.direction,
|
|
fontSize: fontSize,
|
|
})
|
|
historyLines.current.push(mergedLine)
|
|
canvas?.add(mergedLine)
|
|
} else {
|
|
historyLines.current.push(line)
|
|
canvas?.add(line)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 마우스로 그린 점 기준으로 외벽선을 완성시켜준다.
|
|
* makePolygon 함수에 포함되어있던 내용을 다른 템플릿 적용에서도 사용할수 있도록 함수로 대체
|
|
*/
|
|
const drawWallPolygon = () => {
|
|
const firstPoint = historyPoints.current[0]
|
|
const lastPoint = historyPoints.current[historyPoints.current.length - 1]
|
|
historyPoints.current.forEach((point) => {
|
|
canvas?.remove(point)
|
|
})
|
|
drawLineWithLength(lastPoint, firstPoint)
|
|
points.current = []
|
|
historyPoints.current = []
|
|
|
|
// handleOuterlines()
|
|
const wall = makePolygon()
|
|
setWall(wall)
|
|
|
|
return wall
|
|
}
|
|
|
|
const templateMode = () => {
|
|
changeMode(canvas, Mode.EDIT)
|
|
|
|
if (historyPoints.current.length >= 4) {
|
|
// handleOuterlinesTest() //외곽선 그리기 테스트
|
|
// drawWallPolygon()
|
|
//아래 내용 drawWallPolygon()으로 대체
|
|
const firstPoint = historyPoints.current[0]
|
|
const lastPoint = historyPoints.current[historyPoints.current.length - 1]
|
|
historyPoints.current.forEach((point) => {
|
|
canvas?.remove(point)
|
|
})
|
|
drawLineWithLength(lastPoint, firstPoint)
|
|
points.current = []
|
|
historyPoints.current = []
|
|
|
|
const roof = handleOuterlinesTest()
|
|
const wall = makePolygon()
|
|
|
|
roof.setWall(wall)
|
|
setWall(wall)
|
|
roof.drawHelpLine()
|
|
}
|
|
}
|
|
|
|
const textboxMode = () => {
|
|
canvas?.on('mouse:down', function (options) {
|
|
if (canvas?.getActiveObject()?.type === 'textbox') return
|
|
const pointer = canvas?.getPointer(options.e)
|
|
|
|
const textbox = new fabric.Textbox('텍스트를 입력하세요', {
|
|
left: pointer.x,
|
|
top: pointer.y,
|
|
width: 150, // 텍스트박스의 너비를 설정합니다.
|
|
fontSize: fontSize, // 텍스트의 크기를 설정합니다.
|
|
})
|
|
|
|
canvas?.add(textbox)
|
|
canvas?.setActiveObject(textbox) // 생성된 텍스트박스를 활성 객체로 설정합니다.
|
|
canvas?.renderAll()
|
|
// textbox가 active가 풀린 경우 editing mode로 변경
|
|
textbox?.on('editing:exited', function () {
|
|
changeMode(canvas, Mode.EDIT)
|
|
})
|
|
})
|
|
}
|
|
|
|
const drawLineMode = () => {
|
|
canvas?.on('mouse:down', function (options) {
|
|
const pointer = canvas?.getPointer(options.e)
|
|
|
|
const line = new QLine(
|
|
[pointer.x, 0, pointer.x, canvas.height], // y축에 1자 선을 그립니다.
|
|
{
|
|
stroke: 'black',
|
|
strokeWidth: 2,
|
|
viewLengthText: true,
|
|
selectable: false,
|
|
fontSize: fontSize,
|
|
},
|
|
)
|
|
|
|
canvas?.add(line)
|
|
canvas?.renderAll()
|
|
})
|
|
}
|
|
|
|
const drawRectMode = () => {
|
|
let rect, isDown, origX, origY
|
|
canvas.on('mouse:down', function (o) {
|
|
isDown = true
|
|
const pointer = canvas.getPointer(o.e)
|
|
origX = pointer.x
|
|
origY = pointer.y
|
|
rect = new fabric.Rect({
|
|
left: origX,
|
|
top: origY,
|
|
originX: 'left',
|
|
originY: 'top',
|
|
width: pointer.x - origX,
|
|
height: pointer.y - origY,
|
|
angle: 0,
|
|
fill: 'transparent',
|
|
stroke: 'black',
|
|
transparentCorners: false,
|
|
})
|
|
canvas.add(rect)
|
|
})
|
|
|
|
canvas.on('mouse:move', function (o) {
|
|
if (!isDown) return
|
|
const pointer = canvas.getPointer(o.e)
|
|
if (origX > pointer.x) {
|
|
rect.set({ left: Math.abs(pointer.x) })
|
|
}
|
|
if (origY > pointer.y) {
|
|
rect.set({ top: Math.abs(pointer.y) })
|
|
}
|
|
|
|
rect.set({ width: Math.abs(origX - pointer.x) })
|
|
rect.set({ height: Math.abs(origY - pointer.y) })
|
|
})
|
|
|
|
canvas.on('mouse:up', function (o) {
|
|
const pointer = canvas.getPointer(o.e)
|
|
const qRect = new QRect({
|
|
left: origX,
|
|
top: origY,
|
|
originX: 'left',
|
|
originY: 'top',
|
|
width: pointer.x - origX,
|
|
height: pointer.y - origY,
|
|
angle: 0,
|
|
viewLengthText: true,
|
|
fill: 'transparent',
|
|
stroke: 'black',
|
|
transparentCorners: false,
|
|
fontSize: fontSize,
|
|
})
|
|
canvas.remove(rect)
|
|
canvas.add(qRect)
|
|
isDown = false
|
|
})
|
|
}
|
|
|
|
/**
|
|
* 두 점을 연결하는 선과 길이를 그립니다.
|
|
* a : 시작점, b : 끝점
|
|
*/
|
|
const drawLineWithLength = (a, b) => {
|
|
const line = new QLine([a.left, a.top, b.left, b.top], {
|
|
stroke: 'black',
|
|
strokeWidth: 2,
|
|
selectable: false,
|
|
viewLengthText: true,
|
|
direction: getDirection(a, b),
|
|
fontSize: fontSize,
|
|
})
|
|
pushHistoryLine(line)
|
|
|
|
canvas?.renderAll()
|
|
}
|
|
|
|
const makePolygon = (otherLines) => {
|
|
// 캔버스에서 모든 라인 객체를 찾습니다.
|
|
const lines = otherLines || historyLines.current
|
|
|
|
if (!otherLines) {
|
|
//외각선 기준
|
|
const topIndex = findTopTwoIndexesByDistance(sortedArray) //배열중에 큰 2값을 가져옴 TODO: 나중에는 인자로 받아서 다각으로 수정 해야됨
|
|
|
|
//일단 배열 6개 짜리 기준의 선 번호
|
|
if (topIndex[0] === 4) {
|
|
if (topIndex[1] === 5) {
|
|
//1번
|
|
setShape(1)
|
|
}
|
|
} else if (topIndex[0] === 1) {
|
|
//4번
|
|
if (topIndex[1] === 2) {
|
|
setShape(4)
|
|
}
|
|
} else if (topIndex[0] === 0) {
|
|
if (topIndex[1] === 1) {
|
|
//2번
|
|
setShape(2)
|
|
} else if (topIndex[1] === 5) {
|
|
setShape(3)
|
|
}
|
|
}
|
|
|
|
historyLines.current = []
|
|
}
|
|
|
|
// 각 라인의 시작점과 끝점을 사용하여 다각형의 점 배열을 생성합니다.
|
|
const points = lines.map((line) => ({ x: line.x1, y: line.y1 }))
|
|
|
|
// 모든 라인 객체를 캔버스에서 제거합니다.
|
|
lines.forEach((line) => {
|
|
canvas?.remove(line)
|
|
})
|
|
|
|
// 점 배열을 사용하여 새로운 다각형 객체를 생성합니다.
|
|
const polygon = new QPolygon(
|
|
points,
|
|
{
|
|
stroke: 'black',
|
|
fill: 'transparent',
|
|
viewLengthText: true,
|
|
selectable: true,
|
|
fontSize: fontSize,
|
|
},
|
|
canvas,
|
|
)
|
|
|
|
// 새로운 다각형 객체를 캔버스에 추가합니다.
|
|
canvas.add(polygon)
|
|
|
|
// 캔버스를 다시 그립니다.
|
|
if (!otherLines) {
|
|
// polygon.fillCell()
|
|
canvas.renderAll()
|
|
polygon.setViewLengthText(false)
|
|
setMode(Mode.DEFAULT)
|
|
}
|
|
|
|
return polygon
|
|
}
|
|
|
|
/**
|
|
* 해당 캔버스를 비운다.
|
|
*/
|
|
const handleClear = () => {
|
|
canvas?.clear()
|
|
points.current = []
|
|
historyPoints.current = []
|
|
historyLines.current = []
|
|
}
|
|
|
|
const zoomIn = () => {
|
|
canvas?.setZoom(canvas.getZoom() + 0.1)
|
|
setZoom(Math.round(zoom + 10))
|
|
}
|
|
|
|
const zoomOut = () => {
|
|
canvas?.setZoom(canvas.getZoom() - 0.1)
|
|
setZoom(Math.ceil(zoom - 10))
|
|
}
|
|
|
|
const handleOuterlines = () => {
|
|
const newOuterlines = []
|
|
for (let i = 0; i < historyLines.current.length; i++) {
|
|
const next = historyLines.current[i + 1]
|
|
const prev = historyLines.current[i - 1] ?? historyLines.current[historyLines.current.length - 1]
|
|
if (next) {
|
|
if (next.direction === 'right') {
|
|
// 다름 라인이 오른쪽으로 이동
|
|
if (historyLines.current[i].direction === 'top') {
|
|
if (prev.direction !== 'right') {
|
|
if (historyLines.current.length === 4) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 - 50,
|
|
y1: historyLines.current[i].y1 + 50,
|
|
x2: historyLines.current[i].x2 - 50,
|
|
y2: historyLines.current[i].y2 - 50,
|
|
})
|
|
} else if (historyLines.current.length === 6) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 - 50,
|
|
y1: historyLines.current[i].y1 + 50,
|
|
x2: historyLines.current[i].x2 - 50,
|
|
y2: historyLines.current[i].y2 - 50,
|
|
})
|
|
} else if (historyLines.current.length === 8) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 + 50,
|
|
y1: historyLines.current[i].y1 - 50,
|
|
x2: historyLines.current[i].x2 + 50,
|
|
y2: historyLines.current[i].y2 + 50,
|
|
})
|
|
}
|
|
} else {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 + 50,
|
|
y1: historyLines.current[i].y1 + 50,
|
|
x2: historyLines.current[i].x2 + 50,
|
|
y2: historyLines.current[i].y2 + 50,
|
|
})
|
|
}
|
|
} else {
|
|
// bottom
|
|
if (prev?.direction !== 'right') {
|
|
if (historyLines.current.length === 4) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 - 50,
|
|
y1: historyLines.current[i].y1 - 50,
|
|
x2: historyLines.current[i].x2 - 50,
|
|
y2: historyLines.current[i].y2 + 50,
|
|
})
|
|
} else if (historyLines.current.length === 6) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 - 50,
|
|
y1: historyLines.current[i].y1 - 50,
|
|
x2: historyLines.current[i].x2 - 50,
|
|
y2: historyLines.current[i].y2 + 50,
|
|
})
|
|
} else if (historyLines.current.length === 8) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 + 50,
|
|
y1: historyLines.current[i].y1 + 50,
|
|
x2: historyLines.current[i].x2 + 50,
|
|
y2: historyLines.current[i].y2 - 50,
|
|
})
|
|
}
|
|
} else {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 - 50,
|
|
y1: historyLines.current[i].y1 + 50,
|
|
x2: historyLines.current[i].x2 - 50,
|
|
y2: historyLines.current[i].y2 + 50,
|
|
})
|
|
}
|
|
}
|
|
} else if (next.direction === 'left') {
|
|
if (historyLines.current[i].direction === 'top') {
|
|
if (prev?.direction !== 'left') {
|
|
if (historyLines.current.length === 4) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 + 50,
|
|
y1: historyLines.current[i].y1 + 50,
|
|
x2: historyLines.current[i].x2 + 50,
|
|
y2: historyLines.current[i].y2 - 50,
|
|
})
|
|
} else if (historyLines.current.length === 6) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 + 50,
|
|
y1: historyLines.current[i].y1 + 50,
|
|
x2: historyLines.current[i].x2 + 50,
|
|
y2: historyLines.current[i].y2 - 50,
|
|
})
|
|
} else if (historyLines.current.length === 8) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 - 50,
|
|
y1: historyLines.current[i].y1 - 50,
|
|
x2: historyLines.current[i].x2 - 50,
|
|
y2: historyLines.current[i].y2 + 50,
|
|
})
|
|
}
|
|
} else {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 + 50,
|
|
y1: historyLines.current[i].y1 - 50,
|
|
x2: historyLines.current[i].x2 + 50,
|
|
y2: historyLines.current[i].y2 - 50,
|
|
})
|
|
}
|
|
} else {
|
|
// bottom
|
|
if (prev?.direction !== 'left') {
|
|
if (historyLines.current.length === 4) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 + 50,
|
|
y1: historyLines.current[i].y1 - 50,
|
|
x2: historyLines.current[i].x2 + 50,
|
|
y2: historyLines.current[i].y2 + 50,
|
|
})
|
|
} else if (historyLines.current.length === 6) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 + 50,
|
|
y1: historyLines.current[i].y1 - 50,
|
|
x2: historyLines.current[i].x2 + 50,
|
|
y2: historyLines.current[i].y2 + 50,
|
|
})
|
|
} else if (historyLines.current.length === 8) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 - 50,
|
|
y1: historyLines.current[i].y1 + 50,
|
|
x2: historyLines.current[i].x2 - 50,
|
|
y2: historyLines.current[i].y2 - 50,
|
|
})
|
|
}
|
|
} else {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 - 50,
|
|
y1: historyLines.current[i].y1 - 50,
|
|
x2: historyLines.current[i].x2 - 50,
|
|
y2: historyLines.current[i].y2 - 50,
|
|
})
|
|
}
|
|
}
|
|
} else if (next.direction === 'top') {
|
|
if (historyLines.current[i].direction === 'right') {
|
|
if (prev?.direction !== 'top') {
|
|
if (historyLines.current.length === 4) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 - 50,
|
|
y1: historyLines.current[i].y1 + 50,
|
|
x2: historyLines.current[i].x2 + 50,
|
|
y2: historyLines.current[i].y2 + 50,
|
|
})
|
|
} else if (historyLines.current.length === 6) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 - 50,
|
|
y1: historyLines.current[i].y1 + 50,
|
|
x2: historyLines.current[i].x2 + 50,
|
|
y2: historyLines.current[i].y2 + 50,
|
|
})
|
|
} else if (historyLines.current.length === 8) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 + 50,
|
|
y1: historyLines.current[i].y1 - 50,
|
|
x2: historyLines.current[i].x2 - 50,
|
|
y2: historyLines.current[i].y2 - 50,
|
|
})
|
|
}
|
|
} else {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 + 50,
|
|
y1: historyLines.current[i].y1 + 50,
|
|
x2: historyLines.current[i].x2 + 50,
|
|
y2: historyLines.current[i].y2 + 50,
|
|
})
|
|
}
|
|
} else {
|
|
// left
|
|
if (prev?.direction !== 'top') {
|
|
if (historyLines.current.length === 4) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 + 50,
|
|
y1: historyLines.current[i].y1 + 50,
|
|
x2: historyLines.current[i].x2 - 50,
|
|
y2: historyLines.current[i].y2 + 50,
|
|
})
|
|
} else if (historyLines.current.length === 6) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 + 50,
|
|
y1: historyLines.current[i].y1 + 50,
|
|
x2: historyLines.current[i].x2 - 50,
|
|
y2: historyLines.current[i].y2 + 50,
|
|
})
|
|
} else if (historyLines.current.length === 8) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 - 50,
|
|
y1: historyLines.current[i].y1 - 50,
|
|
x2: historyLines.current[i].x2 + 50,
|
|
y2: historyLines.current[i].y2 - 50,
|
|
})
|
|
}
|
|
} else {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 + 50,
|
|
y1: historyLines.current[i].y1 - 50,
|
|
x2: historyLines.current[i].x2 + 50,
|
|
y2: historyLines.current[i].y2 - 50,
|
|
})
|
|
}
|
|
}
|
|
} else if (next.direction === 'bottom') {
|
|
if (historyLines.current[i].direction === 'right') {
|
|
if (prev?.direction !== 'bottom') {
|
|
if (historyLines.current.length === 4) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 - 50,
|
|
y1: historyLines.current[i].y1 - 50,
|
|
x2: historyLines.current[i].x2 + 50,
|
|
y2: historyLines.current[i].y2 - 50,
|
|
})
|
|
} else if (historyLines.current.length === 6) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 - 50,
|
|
y1: historyLines.current[i].y1 - 50,
|
|
x2: historyLines.current[i].x2 + 50,
|
|
y2: historyLines.current[i].y2 - 50,
|
|
})
|
|
} else if (historyLines.current.length === 8) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 + 50,
|
|
y1: historyLines.current[i].y1 + 50,
|
|
x2: historyLines.current[i].x2 - 50,
|
|
y2: historyLines.current[i].y2 + 50,
|
|
})
|
|
}
|
|
} else {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 - 50,
|
|
y1: historyLines.current[i].y1 + 50,
|
|
x2: historyLines.current[i].x2 - 50,
|
|
y2: historyLines.current[i].y2 + 50,
|
|
})
|
|
}
|
|
} else {
|
|
// left
|
|
if (prev.direction !== 'bottom') {
|
|
if (historyLines.current.length === 4) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 + 50,
|
|
y1: historyLines.current[i].y1 - 50,
|
|
x2: historyLines.current[i].x2 - 50,
|
|
y2: historyLines.current[i].y2 - 50,
|
|
})
|
|
} else if (historyLines.current.length === 6) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 + 50,
|
|
y1: historyLines.current[i].y1 - 50,
|
|
x2: historyLines.current[i].x2 - 50,
|
|
y2: historyLines.current[i].y2 - 50,
|
|
})
|
|
} else if (historyLines.current.length === 8) {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 - 50,
|
|
y1: historyLines.current[i].y1 + 50,
|
|
x2: historyLines.current[i].x2 + 50,
|
|
y2: historyLines.current[i].y2 + 50,
|
|
})
|
|
}
|
|
} else {
|
|
newOuterlines.push({
|
|
x1: historyLines.current[i].x1 - 50,
|
|
y1: historyLines.current[i].y1 - 50,
|
|
x2: historyLines.current[i].x2 + 50,
|
|
y2: historyLines.current[i].y2 - 50,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
const tmp = newOuterlines[newOuterlines.length - 1]
|
|
newOuterlines.push({
|
|
x1: tmp.x2,
|
|
y1: tmp.y2,
|
|
x2: newOuterlines[0].x1,
|
|
y2: newOuterlines[0].y1,
|
|
})
|
|
}
|
|
}
|
|
|
|
makePolygon(newOuterlines)
|
|
}
|
|
|
|
/**
|
|
*벽 지붕 외곽선 생성
|
|
*/
|
|
const handleOuterlinesTest = (polygon, offset = 71) => {
|
|
var offsetPoints = []
|
|
|
|
const sortedIndex = getStartIndex(polygon.lines)
|
|
let tmpArraySorted = rearrangeArray(polygon.lines, sortedIndex)
|
|
|
|
if (tmpArraySorted[0].direction === 'right') {
|
|
//시계방향
|
|
tmpArraySorted = tmpArraySorted.reverse() //그럼 배열을 거꾸로 만들어서 무조건 반시계방향으로 배열 보정
|
|
}
|
|
|
|
setSortedArray(tmpArraySorted) //recoil에 넣음
|
|
|
|
const points = tmpArraySorted.map((line) => ({
|
|
x: line.x1,
|
|
y: line.y1,
|
|
}))
|
|
|
|
for (var i = 0; i < points.length; i++) {
|
|
var prev = points[(i - 1 + points.length) % points.length]
|
|
var current = points[i]
|
|
var next = points[(i + 1) % points.length]
|
|
|
|
// 두 벡터 계산 (prev -> current, current -> next)
|
|
var vector1 = { x: current.x - prev.x, y: current.y - prev.y }
|
|
var vector2 = { x: next.x - current.x, y: next.y - current.y }
|
|
|
|
// 벡터의 길이 계산
|
|
var length1 = Math.sqrt(vector1.x * vector1.x + vector1.y * vector1.y)
|
|
var length2 = Math.sqrt(vector2.x * vector2.x + vector2.y * vector2.y)
|
|
|
|
// 벡터를 단위 벡터로 정규화
|
|
var unitVector1 = { x: vector1.x / length1, y: vector1.y / length1 }
|
|
var unitVector2 = { x: vector2.x / length2, y: vector2.y / length2 }
|
|
|
|
// 법선 벡터 계산 (왼쪽 방향)
|
|
var normal1 = { x: -unitVector1.y, y: unitVector1.x }
|
|
var normal2 = { x: -unitVector2.y, y: unitVector2.x }
|
|
|
|
// 법선 벡터 평균 계산
|
|
var averageNormal = {
|
|
x: (normal1.x + normal2.x) / 2,
|
|
y: (normal1.y + normal2.y) / 2,
|
|
}
|
|
|
|
// 평균 법선 벡터를 단위 벡터로 정규화
|
|
var lengthNormal = Math.sqrt(averageNormal.x * averageNormal.x + averageNormal.y * averageNormal.y)
|
|
var unitNormal = {
|
|
x: averageNormal.x / lengthNormal,
|
|
y: averageNormal.y / lengthNormal,
|
|
}
|
|
|
|
// 오프셋 적용
|
|
var offsetPoint = {
|
|
x1: current.x + unitNormal.x * offset,
|
|
y1: current.y + unitNormal.y * offset,
|
|
}
|
|
|
|
offsetPoints.push(offsetPoint)
|
|
}
|
|
|
|
const roof = makePolygon(offsetPoints)
|
|
setRoof(roof)
|
|
|
|
return roof
|
|
}
|
|
|
|
/**
|
|
*벽 지붕 외곽선 생성 polygon을 입력받아 만들기
|
|
*/
|
|
const handleOuterlinesTest2 = (polygon, offset = 71) => {
|
|
const offsetPoints = []
|
|
const sortedIndex = getStartIndex(polygon.lines)
|
|
let tmpArraySorted = rearrangeArray(polygon.lines, sortedIndex)
|
|
|
|
if (tmpArraySorted[0].direction === 'right') {
|
|
//시계방향
|
|
tmpArraySorted = tmpArraySorted.reverse() //그럼 배열을 거꾸로 만들어서 무조건 반시계방향으로 배열 보정
|
|
}
|
|
|
|
setSortedArray(tmpArraySorted) //recoil에 넣음
|
|
|
|
const points = tmpArraySorted.map((line) => ({
|
|
x: line.x1,
|
|
y: line.y1,
|
|
}))
|
|
|
|
for (let i = 0; i < points.length; i++) {
|
|
const prev = points[(i - 1 + points.length) % points.length]
|
|
const current = points[i]
|
|
const next = points[(i + 1) % points.length]
|
|
|
|
// 두 벡터 계산 (prev -> current, current -> next)
|
|
const vector1 = { x: current.x - prev.x, y: current.y - prev.y }
|
|
const vector2 = { x: next.x - current.x, y: next.y - current.y }
|
|
|
|
// 벡터의 길이 계산
|
|
const length1 = Math.sqrt(vector1.x * vector1.x + vector1.y * vector1.y)
|
|
const length2 = Math.sqrt(vector2.x * vector2.x + vector2.y * vector2.y)
|
|
|
|
// 벡터를 단위 벡터로 정규화
|
|
const unitVector1 = { x: vector1.x / length1, y: vector1.y / length1 }
|
|
const unitVector2 = { x: vector2.x / length2, y: vector2.y / length2 }
|
|
|
|
// 법선 벡터 계산 (왼쪽 방향)
|
|
const normal1 = { x: -unitVector1.y, y: unitVector1.x }
|
|
const normal2 = { x: -unitVector2.y, y: unitVector2.x }
|
|
|
|
// 법선 벡터 평균 계산
|
|
const averageNormal = {
|
|
x: (normal1.x + normal2.x) / 2,
|
|
y: (normal1.y + normal2.y) / 2,
|
|
}
|
|
|
|
// 평균 법선 벡터를 단위 벡터로 정규화
|
|
const lengthNormal = Math.sqrt(averageNormal.x * averageNormal.x + averageNormal.y * averageNormal.y)
|
|
const unitNormal = {
|
|
x: averageNormal.x / lengthNormal,
|
|
y: averageNormal.y / lengthNormal,
|
|
}
|
|
|
|
// 오프셋 적용
|
|
const offsetPoint = {
|
|
x1: current.x + unitNormal.x * offset,
|
|
y1: current.y + unitNormal.y * offset,
|
|
}
|
|
|
|
offsetPoints.push(offsetPoint)
|
|
}
|
|
|
|
const roof = makePolygon(offsetPoints)
|
|
roof.setWall(polygon)
|
|
setRoof(roof)
|
|
roof.drawHelpLine()
|
|
}
|
|
|
|
const togglePolygonLine = (obj) => {
|
|
const rtnLines = []
|
|
if (obj.type === 'QPolygon') {
|
|
const points = obj.getCurrentPoints()
|
|
points.forEach((point, index) => {
|
|
const nextPoint = points[(index + 1) % points.length] // 마지막 점이면 첫 번째 점으로 연결
|
|
const line = new QLine([point.x, point.y, nextPoint.x, nextPoint.y], {
|
|
stroke: 'black',
|
|
strokeWidth: 2,
|
|
selectable: false,
|
|
fontSize: fontSize, // fontSize는 필요에 따라 조정
|
|
parent: obj,
|
|
})
|
|
obj.visible = false
|
|
canvas.add(line)
|
|
rtnLines.push(line)
|
|
})
|
|
|
|
canvas.renderAll()
|
|
}
|
|
if (obj.type === 'QLine') {
|
|
const parent = obj.parent
|
|
canvas
|
|
?.getObjects()
|
|
.filter((obj) => obj.parent === parent)
|
|
.forEach((obj) => {
|
|
rtnLines.push(obj)
|
|
canvas.remove(obj)
|
|
})
|
|
|
|
parent.visible = true
|
|
canvas.renderAll()
|
|
}
|
|
return rtnLines
|
|
}
|
|
|
|
const applyTemplateA = () => {
|
|
changeMode(canvas, Mode.EDIT)
|
|
const polygon = drawWallPolygon()
|
|
handleClear()
|
|
|
|
if (polygon.lines.length === 4) {
|
|
//4각형
|
|
handleOuterLineTemplateA4Points(polygon)
|
|
} else if (polygon.lines.length === 6) {
|
|
//6각형
|
|
handleOuterLineTemplateA6Points(polygon)
|
|
}
|
|
}
|
|
|
|
const handleOuterLineTemplateA4Points = (polygon) => {
|
|
const edge = 20
|
|
const eaves = 50
|
|
|
|
// 폴리곤의 각 변을 선으로 생성
|
|
const createLine = (start, end, stroke, property) =>
|
|
new QLine([start.x, start.y, end.x, end.y], {
|
|
stroke,
|
|
strokeWidth: 5,
|
|
property,
|
|
fontSize: 14,
|
|
})
|
|
|
|
const lines = polygon.points.map((start, i) => {
|
|
const end = polygon.points[(i + 1) % polygon.points.length]
|
|
const line = createLine(start, end, '#A0D468', 'normal')
|
|
canvas.add(line)
|
|
return line
|
|
})
|
|
|
|
const edgeIndexArray = []
|
|
const normalIndexArray = []
|
|
|
|
lines.forEach((line, i) => {
|
|
if (i % 2 === 0) {
|
|
line.set('stroke', 'skyblue')
|
|
line.set('property', 'edge')
|
|
edgeIndexArray.push(i)
|
|
} else {
|
|
normalIndexArray.push(i)
|
|
}
|
|
canvas.add(line)
|
|
})
|
|
|
|
const centerPointX = (lines[1].x1 + lines[1].x2) / 2
|
|
const centerPointY = (lines[0].y1 + lines[0].y2) / 2
|
|
const horiCenterHalfLine = (lines[1].x2 - lines[1].x1) / 2
|
|
|
|
const createCenterLine = (x1, y1, x2, y2, stroke, strokeWidth, property, dashArray = []) =>
|
|
new QLine([x1, y1, x2, y2], {
|
|
stroke,
|
|
strokeWidth,
|
|
property,
|
|
fontSize: 14,
|
|
strokeDashArray: dashArray,
|
|
})
|
|
|
|
const vertCenterLine = createCenterLine(centerPointX, lines[0].y1 - edge, centerPointX, lines[0].y2 + edge, 'blue', 4, 'center')
|
|
canvas.add(vertCenterLine)
|
|
|
|
const horiCenterLineLeft = createCenterLine(
|
|
lines[1].x1 - eaves,
|
|
centerPointY,
|
|
lines[1].x1 + horiCenterHalfLine,
|
|
centerPointY,
|
|
'black',
|
|
2,
|
|
'center',
|
|
[5, 5],
|
|
)
|
|
canvas.add(horiCenterLineLeft)
|
|
|
|
const horiCenterLineRight = createCenterLine(
|
|
horiCenterLineLeft.x2,
|
|
centerPointY,
|
|
horiCenterLineLeft.x2 + horiCenterHalfLine + eaves,
|
|
centerPointY,
|
|
'black',
|
|
2,
|
|
'center',
|
|
[5, 5],
|
|
)
|
|
canvas.add(horiCenterLineRight)
|
|
|
|
const drawArray = lines
|
|
.map((line) => {
|
|
if (line.x1 === line.x2 && line.y1 < line.y2) {
|
|
return [{ x1: line.x1 - eaves, y1: line.y1 - edge, x2: line.x1 - eaves, y2: line.y2 + edge }]
|
|
} else if (line.x1 === line.x2 && line.y1 > line.y2) {
|
|
return [{ x1: line.x1 + eaves, y1: line.y1 + edge, x2: line.x1 + eaves, y2: line.y2 - edge }]
|
|
} else if (line.x1 < line.x2 && line.y1 === line.y2) {
|
|
return [
|
|
{ x1: line.x1 - eaves, y1: line.y1 + edge, x2: line.x1 + horiCenterHalfLine, y2: line.y2 + edge },
|
|
{
|
|
x1: line.x1 + horiCenterHalfLine,
|
|
y1: line.y1 + edge,
|
|
x2: line.x1 + horiCenterHalfLine + horiCenterHalfLine + eaves,
|
|
y2: line.y2 + edge,
|
|
},
|
|
]
|
|
} else if (line.x1 > line.x2 && line.y1 === line.y2) {
|
|
return [
|
|
{ x1: line.x2 - eaves, y1: line.y1 - edge, x2: line.x2 + horiCenterHalfLine, y2: line.y2 - edge },
|
|
{
|
|
x1: line.x2 + horiCenterHalfLine,
|
|
y1: line.y1 - edge,
|
|
x2: line.x2 + horiCenterHalfLine + horiCenterHalfLine + eaves,
|
|
y2: line.y2 - edge,
|
|
},
|
|
]
|
|
}
|
|
return []
|
|
})
|
|
.flat()
|
|
|
|
drawArray.forEach((line) => {
|
|
const outLine = createLine({ x: line.x1, y: line.y1 }, { x: line.x2, y: line.y2 }, 'blue', 'normal')
|
|
canvas.add(outLine)
|
|
})
|
|
}
|
|
|
|
//탬플릿A 적용
|
|
const handleOuterLineTemplateA6Points = (polygon) => {
|
|
let lines = []
|
|
let outLines = []
|
|
|
|
// 폴리곤의 각 변을 선으로 생성
|
|
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: 5,
|
|
property: 'normal',
|
|
fontSize: 14,
|
|
})
|
|
|
|
// 선을 배열에 추가
|
|
lines.push(line)
|
|
canvas.add(line)
|
|
}
|
|
|
|
let highLineLength = 0
|
|
let lowLineLength = 0
|
|
|
|
let prevHighIndex = 0
|
|
let prevHighLength = 0
|
|
|
|
let prevLowIndex = 0
|
|
let prevLowLength = 0
|
|
|
|
let edgeIndexArray = []
|
|
let normalIndexArray = []
|
|
|
|
for (let i = 0; i < lines.length; i++) {
|
|
let line = lines[i]
|
|
|
|
if (!(i % 2) == 0) {
|
|
//홀수일떄
|
|
line.line.set('stroke', 'skyblue')
|
|
line.line.set('property', 'egde')
|
|
let length = Math.abs(line.get('x1') - line.get('x2')) + Math.abs(line.get('y1') - line.get('y2'))
|
|
|
|
if (length > prevHighLength) {
|
|
//잴긴거 찾음
|
|
prevHighIndex = i
|
|
prevHighLength = length
|
|
highLineLength = length
|
|
}
|
|
|
|
if (prevLowLength === 0) {
|
|
//최초에는 없어서 한번 넣음
|
|
prevLowIndex = i
|
|
prevLowLength = length
|
|
}
|
|
|
|
if (length <= prevLowLength) {
|
|
//그뒤부터는 짧은거 대로 넣음
|
|
prevLowIndex = i
|
|
prevLowLength = length
|
|
lowLineLength = length
|
|
}
|
|
|
|
edgeIndexArray.push(i)
|
|
} else {
|
|
normalIndexArray.push(i)
|
|
}
|
|
|
|
// 캔버스에 선 추가
|
|
canvas.add(line)
|
|
}
|
|
|
|
let prevDirecArray //긴선 앞배열
|
|
let nextDirecArray //긴선 뒷배열
|
|
let horizontalDirection //뽈록이 좌우 방향
|
|
|
|
if (prevHighIndex === 1) {
|
|
//카라바 기준 1과 5밖에 없음
|
|
prevDirecArray = lines[prevHighIndex - 1]
|
|
nextDirecArray = lines[prevHighIndex + 1]
|
|
|
|
//밑에쪽이 긴 방향
|
|
horizontalDirection = prevDirecArray.height > nextDirecArray.height ? 'left' : 'right'
|
|
} else {
|
|
prevDirecArray = lines[prevHighIndex - 1]
|
|
nextDirecArray = lines[0]
|
|
|
|
//위에가 긴 방향
|
|
horizontalDirection = prevDirecArray.height > nextDirecArray.height ? 'right' : 'left'
|
|
}
|
|
|
|
const edge = 20 //케라바
|
|
const eaves = 50 //처마
|
|
let firstLine = lines[1]
|
|
let secondLine = lines[3]
|
|
let lastLine = lines[5]
|
|
let vertCenterLine
|
|
let secondVertCenterLine
|
|
|
|
if (prevHighIndex === 1) {
|
|
if (horizontalDirection === 'left') {
|
|
//배열 순서대로 뒤에꺼를 찾아서 계산한다
|
|
const firstSubLine = lines[2]
|
|
const middleSubLine = lines[4]
|
|
|
|
//ㄴ자 일경우
|
|
//긴면 세로선 그리기
|
|
let vertCenterPoint = (firstLine.x1 + firstLine.x2) / 2 //가장 긴선 중앙선 가운데 점
|
|
vertCenterLine = new QLine(
|
|
[
|
|
vertCenterPoint,
|
|
firstSubLine.y1 + edge, //다음 선의 높이만큼 가져와서 edge길이를 합함
|
|
vertCenterPoint,
|
|
firstSubLine.y2 - edge, //다음 선의 높이만큼 가져옴 edge길이를 합함
|
|
],
|
|
{
|
|
stroke: 'blue',
|
|
strokeWidth: 5,
|
|
property: 'bigHoriCenter',
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(vertCenterLine)
|
|
|
|
//긴면 가로선 그리기
|
|
let horiCenterPoint = (firstSubLine.y1 + firstSubLine.y2) / 2
|
|
let horiCenterLine1 = new QLine(
|
|
[firstLine.x1 - eaves, horiCenterPoint, firstLine.x1 - eaves + firstLine.length / 2 + eaves, horiCenterPoint],
|
|
{
|
|
stroke: 'black',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
strokeDashArray: [5, 5],
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(horiCenterLine1)
|
|
|
|
let horiCenterLine2 = new QLine(
|
|
[
|
|
firstLine.x1 - eaves + firstLine.length / 2 + eaves,
|
|
horiCenterPoint,
|
|
firstLine.x1 - eaves + firstLine.length / 2 + eaves + firstLine.length / 2 + eaves,
|
|
horiCenterPoint,
|
|
],
|
|
{
|
|
stroke: 'black',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
strokeDashArray: [5, 5],
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(horiCenterLine2)
|
|
|
|
//작은 지붕쪽 높이 길이를 구하는 로직
|
|
let secondVertCenterPoint = (lastLine.x1 + lastLine.x2) / 2
|
|
secondVertCenterLine = new QLine([secondVertCenterPoint, middleSubLine.y1, secondVertCenterPoint, middleSubLine.y2 - edge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
|
|
canvas.add(secondVertCenterLine)
|
|
|
|
//작은 지붕쪽 너비 길이를 구한는 로직
|
|
let secondHoriCenterLength = (Math.abs(lastLine.get('x1') - lastLine.get('x2')) + Math.abs(lastLine.get('y1') - lastLine.get('y2'))) / 2
|
|
let secondHoriCenterPoint = (secondVertCenterLine.y1 + secondVertCenterLine.y2) / 2
|
|
|
|
let secondHoriCenterLine = new QLine(
|
|
[secondVertCenterLine.x1, secondHoriCenterPoint, secondVertCenterLine.x1 + secondHoriCenterLength + eaves, secondHoriCenterPoint],
|
|
{
|
|
stroke: 'black',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
strokeDashArray: [5, 5],
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(secondHoriCenterLine)
|
|
|
|
//일반라인 외각선 그리기
|
|
normalIndexArray.forEach((index) => {
|
|
const line = lines[index]
|
|
if (index === 0) {
|
|
let drawline = new QLine([line.x1 - eaves, line.y1 - edge, line.x2 - eaves, line.y2 + edge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawline)
|
|
} else {
|
|
let tmpEdge = index === 2 ? edge : 0
|
|
let drawline = new QLine([line.x1 + eaves, line.y1 + tmpEdge, line.x2 + eaves, line.y2 - edge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawline)
|
|
}
|
|
})
|
|
|
|
//케라바 라인 외각선 그리기
|
|
const firstOuterLine = lines[1]
|
|
const middleOuterLine = lines[3]
|
|
const lastOuterLine = lines[5]
|
|
|
|
//첫번째 외곽선 1번
|
|
let halfLength = firstOuterLine.length / 2
|
|
let drawFirstLine1 = new QLine(
|
|
[firstOuterLine.x1 - eaves, firstOuterLine.y1 + edge, firstOuterLine.x1 + halfLength, firstOuterLine.y2 + edge],
|
|
{
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(drawFirstLine1)
|
|
//첫번째 외곽선 2번
|
|
let drawFirstLine2 = new QLine([drawFirstLine1.x2, firstOuterLine.y1 + edge, firstOuterLine.x2 + eaves, firstOuterLine.y2 + edge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawFirstLine2)
|
|
|
|
//중간라인 외각선
|
|
let drawMiddleLine = new QLine([drawFirstLine2.x2, middleOuterLine.y1 - edge, drawFirstLine2.x1, middleOuterLine.y2 - edge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawMiddleLine)
|
|
|
|
//마지막 외각선
|
|
halfLength = lastLine.length / 2
|
|
let drawLastLine1 = new QLine([lastOuterLine.x2 + halfLength, lastOuterLine.y1 - edge, lastOuterLine.x2 - eaves, lastOuterLine.y2 - edge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawLastLine1)
|
|
|
|
let drawLastLine2 = new QLine([drawLastLine1.x1, lastOuterLine.y1 - edge, lastOuterLine.x1 + length + eaves, lastOuterLine.y2 - edge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawLastLine2)
|
|
|
|
let drawLastInLine1 = new QLine(
|
|
[secondVertCenterLine.x1, secondVertCenterLine.y1, secondVertCenterLine.x1 + halfLength + eaves, secondVertCenterLine.y1],
|
|
{
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(drawLastInLine1)
|
|
|
|
let drawLastInLine2 = new QLine([secondVertCenterLine.x1, vertCenterLine.y2, vertCenterLine.x2, vertCenterLine.y2], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawLastInLine2)
|
|
} else {
|
|
//아래쪽 길게 오른쪽 방향
|
|
//배열 순서대로 뒤에꺼를 찾아서 계산한다
|
|
|
|
firstLine = lines[1]
|
|
secondLine = lines[5]
|
|
lastLine = lines[3]
|
|
|
|
const firstSubLine = lines[0]
|
|
const middleSubLine = lines[4]
|
|
|
|
//ㄴ자 일경우
|
|
//긴면 세로선 그리기
|
|
let vertCenterPoint = (firstLine.x1 + firstLine.x2) / 2 //가장 긴선 중앙선 가운데 점
|
|
vertCenterLine = new QLine(
|
|
[
|
|
vertCenterPoint,
|
|
firstSubLine.y1 - edge, //다음 선의 높이만큼 가져와서 edge길이를 합함
|
|
vertCenterPoint,
|
|
firstSubLine.y2 + edge, //다음 선의 높이만큼 가져옴 edge길이를 합함
|
|
],
|
|
{
|
|
stroke: 'blue',
|
|
strokeWidth: 5,
|
|
property: 'bigHoriCenter',
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(vertCenterLine)
|
|
|
|
//긴면 가로선 그리기
|
|
let horiCenterPoint = (firstSubLine.y1 + firstSubLine.y2) / 2
|
|
let horiCenterLine1 = new QLine(
|
|
[firstLine.x1 - eaves, horiCenterPoint, firstLine.x1 - eaves + firstLine.length / 2 + eaves, horiCenterPoint],
|
|
{
|
|
stroke: 'black',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
strokeDashArray: [5, 5],
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(horiCenterLine1)
|
|
|
|
let horiCenterLine2 = new QLine(
|
|
[
|
|
firstLine.x1 - eaves + firstLine.length / 2 + eaves,
|
|
horiCenterPoint,
|
|
firstLine.x1 - eaves + firstLine.length / 2 + eaves + firstLine.length / 2 + eaves,
|
|
horiCenterPoint,
|
|
],
|
|
{
|
|
stroke: 'black',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
strokeDashArray: [5, 5],
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(horiCenterLine2)
|
|
|
|
//작은 지붕쪽 높이 길이를 구하는 로직
|
|
let secondVertCenterPoint = (lastLine.x1 + lastLine.x2) / 2
|
|
secondVertCenterLine = new QLine([secondVertCenterPoint, middleSubLine.y1 - edge, secondVertCenterPoint, middleSubLine.y2], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
|
|
canvas.add(secondVertCenterLine)
|
|
|
|
//작은 지붕쪽 너비 길이를 구한는 로직
|
|
let secondHoriCenterLength = (Math.abs(lastLine.get('x1') - lastLine.get('x2')) + Math.abs(lastLine.get('y1') - lastLine.get('y2'))) / 2
|
|
let secondHoriCenterPoint = (secondVertCenterLine.y1 + secondVertCenterLine.y2) / 2
|
|
|
|
let secondHoriCenterLine = new QLine(
|
|
[secondVertCenterLine.x1 - secondHoriCenterLength - eaves, secondHoriCenterPoint, secondVertCenterLine.x1, secondHoriCenterPoint],
|
|
{
|
|
stroke: 'black',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
strokeDashArray: [5, 5],
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(secondHoriCenterLine)
|
|
|
|
//일반라인 외각선 그리기
|
|
normalIndexArray.forEach((index) => {
|
|
const line = lines[index]
|
|
if (index === 0 || index === 4) {
|
|
let tmpEdge = index === 4 ? 0 : edge
|
|
let drawline = new QLine([line.x1 - eaves, line.y1 - edge, line.x2 - eaves, line.y2 + tmpEdge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawline)
|
|
} else {
|
|
let drawline = new QLine([line.x1 + eaves, line.y1 + edge, line.x2 + eaves, line.y2 - edge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawline)
|
|
}
|
|
})
|
|
|
|
//케라바 라인 외각선 그리기
|
|
const firstOuterLine = lines[1]
|
|
const middleOuterLine = lines[5]
|
|
const lastOuterLine = lines[3]
|
|
|
|
//첫번째 외곽선 1번
|
|
let halfLength = firstOuterLine.length / 2
|
|
let drawFirstLine1 = new QLine(
|
|
[firstOuterLine.x1 - eaves, firstOuterLine.y1 + edge, firstOuterLine.x1 + halfLength, firstOuterLine.y2 + edge],
|
|
{
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(drawFirstLine1)
|
|
|
|
//첫번째 외곽선 2번
|
|
let drawFirstLine2 = new QLine([drawFirstLine1.x2, firstOuterLine.y1 + edge, firstOuterLine.x2 + eaves, firstOuterLine.y2 + edge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawFirstLine2)
|
|
|
|
//중간라인 외각선
|
|
let drawMiddleLine = new QLine([drawFirstLine1.x1, middleOuterLine.y1 - edge, drawFirstLine1.x2, middleOuterLine.y2 - edge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawMiddleLine)
|
|
|
|
//마지막 외각선
|
|
halfLength = lastLine.length / 2
|
|
|
|
console.log(lastOuterLine)
|
|
|
|
let drawLastLine1 = new QLine([lastOuterLine.x2 - eaves, lastOuterLine.y1 - edge, lastOuterLine.x1 - halfLength, lastOuterLine.y2 - edge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawLastLine1)
|
|
|
|
let drawLastLine2 = new QLine([drawLastLine1.x1, lastOuterLine.y1 - edge, lastOuterLine.x1 + length + eaves, lastOuterLine.y2 - edge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawLastLine2)
|
|
|
|
let drawLastInLine1 = new QLine(
|
|
[secondVertCenterLine.x1, secondVertCenterLine.y2, secondVertCenterLine.x1 - halfLength - eaves, secondVertCenterLine.y2],
|
|
{
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(drawLastInLine1)
|
|
|
|
let drawLastInLine2 = new QLine([secondVertCenterLine.x2, vertCenterLine.y1, vertCenterLine.x1, vertCenterLine.y1], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawLastInLine2)
|
|
}
|
|
} else {
|
|
if (horizontalDirection === 'left') {
|
|
//아래쪽 길게 오른쪽 방향
|
|
//배열 순서대로 뒤에꺼를 찾아서 계산한다
|
|
firstLine = lines[5]
|
|
secondLine = lines[3]
|
|
lastLine = lines[1]
|
|
|
|
const firstSubLine = lines[4]
|
|
const middleSubLine = lines[2]
|
|
|
|
//ㄴ자 일경우
|
|
//긴면 세로선 그리기
|
|
let vertCenterPoint = (firstLine.x1 + firstLine.x2) / 2 //가장 긴선 중앙선 가운데 점
|
|
vertCenterLine = new QLine(
|
|
[
|
|
vertCenterPoint,
|
|
firstSubLine.y2 - edge, //다음 선의 높이만큼 가져와서 edge길이를 합함
|
|
vertCenterPoint,
|
|
firstSubLine.y1 + edge, //다음 선의 높이만큼 가져옴 edge길이를 합함
|
|
],
|
|
{
|
|
stroke: 'blue',
|
|
strokeWidth: 5,
|
|
property: 'bigHoriCenter',
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(vertCenterLine)
|
|
|
|
//긴면 가로선 그리기
|
|
let horiCenterPoint = (firstSubLine.y1 + firstSubLine.y2) / 2
|
|
let horiCenterLine1 = new QLine(
|
|
[firstLine.x2 - eaves, horiCenterPoint, firstLine.x2 - eaves + firstLine.length / 2 + eaves, horiCenterPoint],
|
|
{
|
|
stroke: 'black',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
strokeDashArray: [5, 5],
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(horiCenterLine1)
|
|
|
|
let horiCenterLine2 = new QLine(
|
|
[
|
|
firstLine.x2 - eaves + firstLine.length / 2 + eaves,
|
|
horiCenterPoint,
|
|
firstLine.x2 - eaves + firstLine.length / 2 + eaves + firstLine.length / 2 + eaves,
|
|
horiCenterPoint,
|
|
],
|
|
{
|
|
stroke: 'black',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
strokeDashArray: [5, 5],
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(horiCenterLine2)
|
|
|
|
//작은 지붕쪽 높이 길이를 구하는 로직
|
|
let secondVertCenterPoint = (lastLine.x1 + lastLine.x2) / 2
|
|
secondVertCenterLine = new QLine([secondVertCenterPoint, middleSubLine.y1 + edge, secondVertCenterPoint, middleSubLine.y2], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
|
|
canvas.add(secondVertCenterLine)
|
|
|
|
//작은 지붕쪽 너비 길이를 구한는 로직
|
|
let secondHoriCenterLength = (Math.abs(lastLine.get('x1') - lastLine.get('x2')) + Math.abs(lastLine.get('y1') - lastLine.get('y2'))) / 2
|
|
let secondHoriCenterPoint = (secondVertCenterLine.y1 + secondVertCenterLine.y2) / 2
|
|
|
|
let secondHoriCenterLine = new QLine(
|
|
[secondVertCenterLine.x1 + secondHoriCenterLength + eaves, secondHoriCenterPoint, secondVertCenterLine.x1, secondHoriCenterPoint],
|
|
{
|
|
stroke: 'black',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
strokeDashArray: [5, 5],
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(secondHoriCenterLine)
|
|
|
|
//일반라인 외각선 그리기
|
|
normalIndexArray.forEach((index) => {
|
|
const line = lines[index]
|
|
if (index === 0) {
|
|
let drawline = new QLine([line.x1 - eaves, line.y1 - edge, line.x2 - eaves, line.y2 + edge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawline)
|
|
} else {
|
|
let tmpEdge = index === 2 ? 0 : edge
|
|
let drawline = new QLine([line.x1 + eaves, line.y1 + edge, line.x2 + eaves, line.y2 - tmpEdge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawline)
|
|
}
|
|
})
|
|
|
|
//케라바 라인 외각선 그리기
|
|
const firstOuterLine = lines[5]
|
|
const middleOuterLine = lines[3]
|
|
const lastOuterLine = lines[1]
|
|
|
|
//첫번째 외곽선 1번
|
|
let halfLength = firstOuterLine.length / 2
|
|
let drawFirstLine1 = new QLine(
|
|
[firstOuterLine.x2 - eaves, firstOuterLine.y1 - edge, firstOuterLine.x2 + halfLength, firstOuterLine.y2 - edge],
|
|
{
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(drawFirstLine1)
|
|
|
|
//첫번째 외곽선 2번
|
|
let drawFirstLine2 = new QLine([drawFirstLine1.x2, drawFirstLine1.y1, drawFirstLine1.x2 + halfLength + eaves, drawFirstLine1.y2], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawFirstLine2)
|
|
|
|
//중간라인 외각선
|
|
let drawMiddleLine = new QLine([drawFirstLine2.x1, middleOuterLine.y1 + edge, drawFirstLine2.x2, middleOuterLine.y2 + edge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawMiddleLine)
|
|
|
|
//마지막 외각선
|
|
halfLength = lastLine.length / 2
|
|
|
|
console.log(lastOuterLine)
|
|
|
|
let drawLastLine1 = new QLine([lastOuterLine.x1 - eaves, lastOuterLine.y1 + edge, lastOuterLine.x1 + halfLength, lastOuterLine.y2 + edge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawLastLine1)
|
|
|
|
let drawLastLine2 = new QLine([drawLastLine1.x2, drawLastLine1.y1, drawLastLine1.x2 + halfLength + eaves, drawLastLine1.y1], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawLastLine2)
|
|
|
|
let drawLastInLine1 = new QLine(
|
|
[secondVertCenterLine.x1, secondVertCenterLine.y2, secondVertCenterLine.x1 + halfLength + eaves, secondVertCenterLine.y2],
|
|
{
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(drawLastInLine1)
|
|
|
|
let drawLastInLine2 = new QLine([vertCenterLine.x1, vertCenterLine.y2, secondVertCenterLine.x2, vertCenterLine.y2], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawLastInLine2)
|
|
} else {
|
|
//윗쪽 길게 오른쪽 방향
|
|
//배열 순서대로 뒤에꺼를 찾아서 계산한다
|
|
firstLine = lines[5]
|
|
secondLine = lines[1]
|
|
lastLine = lines[3]
|
|
|
|
const firstSubLine = lines[0]
|
|
const middleSubLine = lines[2]
|
|
|
|
//ㄴ자 일경우
|
|
//긴면 세로선 그리기
|
|
let vertCenterPoint = (firstLine.x1 + firstLine.x2) / 2 //가장 긴선 중앙선 가운데 점
|
|
vertCenterLine = new QLine(
|
|
[
|
|
vertCenterPoint,
|
|
firstSubLine.y1 - edge, //다음 선의 높이만큼 가져와서 edge길이를 합함
|
|
vertCenterPoint,
|
|
firstSubLine.y2 + edge, //다음 선의 높이만큼 가져옴 edge길이를 합함
|
|
],
|
|
{
|
|
stroke: 'blue',
|
|
strokeWidth: 5,
|
|
property: 'bigHoriCenter',
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(vertCenterLine)
|
|
|
|
//긴면 가로선 그리기
|
|
let horiCenterPoint = (firstSubLine.y1 + firstSubLine.y2) / 2
|
|
let horiCenterLine1 = new QLine(
|
|
[firstLine.x2 - eaves, horiCenterPoint, firstLine.x2 - eaves + firstLine.length / 2 + eaves, horiCenterPoint],
|
|
{
|
|
stroke: 'black',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
strokeDashArray: [5, 5],
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(horiCenterLine1)
|
|
|
|
let horiCenterLine2 = new QLine(
|
|
[
|
|
firstLine.x2 - eaves + firstLine.length / 2 + eaves,
|
|
horiCenterPoint,
|
|
firstLine.x2 - eaves + firstLine.length / 2 + eaves + firstLine.length / 2 + eaves,
|
|
horiCenterPoint,
|
|
],
|
|
{
|
|
stroke: 'black',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
strokeDashArray: [5, 5],
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(horiCenterLine2)
|
|
|
|
//작은 지붕쪽 높이 길이를 구하는 로직
|
|
let secondVertCenterPoint = (lastLine.x1 + lastLine.x2) / 2
|
|
secondVertCenterLine = new QLine([secondVertCenterPoint, middleSubLine.y1, secondVertCenterPoint, middleSubLine.y2 + edge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
|
|
canvas.add(secondVertCenterLine)
|
|
|
|
//작은 지붕쪽 너비 길이를 구한는 로직
|
|
let secondHoriCenterLength = (Math.abs(lastLine.get('x1') - lastLine.get('x2')) + Math.abs(lastLine.get('y1') - lastLine.get('y2'))) / 2
|
|
let secondHoriCenterPoint = (secondVertCenterLine.y1 + secondVertCenterLine.y2) / 2
|
|
|
|
let secondHoriCenterLine = new QLine(
|
|
[secondVertCenterLine.x1, secondHoriCenterPoint, secondVertCenterLine.x1 - secondHoriCenterLength - eaves, secondHoriCenterPoint],
|
|
{
|
|
stroke: 'black',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
strokeDashArray: [5, 5],
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(secondHoriCenterLine)
|
|
|
|
//일반라인 외각선 그리기
|
|
normalIndexArray.forEach((index) => {
|
|
const line = lines[index]
|
|
if (index === 0 || index === 2) {
|
|
let tmpEdge = index === 2 ? 0 : edge
|
|
let drawline = new QLine([line.x1 - eaves, line.y1 - tmpEdge, line.x2 - eaves, line.y2 + edge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawline)
|
|
} else {
|
|
let drawline = new QLine([line.x1 + eaves, line.y1 + edge, line.x2 + eaves, line.y2 - edge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawline)
|
|
}
|
|
})
|
|
|
|
//케라바 라인 외각선 그리기
|
|
const firstOuterLine = lines[5]
|
|
const middleOuterLine = lines[1]
|
|
const lastOuterLine = lines[3]
|
|
|
|
//첫번째 외곽선 1번
|
|
let halfLength = firstOuterLine.length / 2
|
|
let drawFirstLine1 = new QLine(
|
|
[firstOuterLine.x2 - eaves, firstOuterLine.y1 - edge, firstOuterLine.x2 + halfLength, firstOuterLine.y2 - edge],
|
|
{
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
},
|
|
)
|
|
canvas.add(drawFirstLine1)
|
|
|
|
//첫번째 외곽선 2번
|
|
let drawFirstLine2 = new QLine([drawFirstLine1.x2, drawFirstLine1.y1, drawFirstLine1.x2 + halfLength + eaves, drawFirstLine1.y2], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawFirstLine2)
|
|
|
|
//중간라인 외각선
|
|
let drawMiddleLine = new QLine([drawFirstLine1.x1, middleOuterLine.y1 + edge, drawFirstLine1.x2, middleOuterLine.y2 + edge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawMiddleLine)
|
|
|
|
//마지막 외각선
|
|
halfLength = lastLine.length / 2
|
|
|
|
let drawLastLine1 = new QLine([lastOuterLine.x1 - eaves, lastOuterLine.y1 + edge, lastOuterLine.x1 + halfLength, lastOuterLine.y2 + edge], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawLastLine1)
|
|
|
|
let drawLastLine2 = new QLine([drawLastLine1.x2, drawLastLine1.y1, drawLastLine1.x2 + halfLength + eaves, drawLastLine1.y1], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawLastLine2)
|
|
|
|
let drawLastInLine1 = new QLine([vertCenterLine.x2, vertCenterLine.y2, secondVertCenterLine.x1, vertCenterLine.y2], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawLastInLine1)
|
|
|
|
let drawLastInLine2 = new QLine([secondLine.x2 - eaves, secondLine.y1, drawLastLine1.x2, secondLine.y1], {
|
|
stroke: 'blue',
|
|
strokeWidth: 4,
|
|
property: 'centerLine',
|
|
fontSize: 14,
|
|
})
|
|
canvas.add(drawLastInLine2)
|
|
}
|
|
}
|
|
|
|
canvas.renderAll()
|
|
}
|
|
|
|
/**
|
|
* 템플릿 B 적용
|
|
*/
|
|
const applyTemplateB = () => {
|
|
changeMode(canvas, Mode.EDIT)
|
|
const polygon = drawWallPolygon()
|
|
const params = {
|
|
eaves: 50,
|
|
edge: 20,
|
|
polygon,
|
|
}
|
|
handleInnerLineColor(polygon)
|
|
// handleOuterLineTemplateB(params)
|
|
console.log(polygon.lines.length)
|
|
if (polygon.lines.length === 4) {
|
|
handleTemplateBRect(params)
|
|
} else if (polygon.length === 6) {
|
|
handleTemplateB(params)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 4각형일때 계산 로직
|
|
* @param {obj} params
|
|
*/
|
|
const handleTemplateBRect = (params) => {
|
|
const { eaves, edge, polygon } = params
|
|
const centerLinePoint = {}
|
|
const centerDashLinePoint = {}
|
|
|
|
const qlineOpt = {
|
|
stroke: 'blue',
|
|
strokeWidth: 2,
|
|
selectable: false,
|
|
fontSize: fontSize,
|
|
}
|
|
const qlineOptDash = {
|
|
stroke: 'black',
|
|
strokeWidth: 2,
|
|
strokeDashArray: [5, 5],
|
|
selectable: false,
|
|
fontSize: fontSize,
|
|
}
|
|
const qlineOptDashWithoutLength = {
|
|
...qlineOptDash,
|
|
isActiveLengthText: false,
|
|
}
|
|
|
|
polygon.lines.forEach((line, index) => {
|
|
let outline
|
|
if (index === 0) {
|
|
outline = new QLine([line.x1 - edge, line.y1 - eaves, line.x2 - edge, line.y2 + eaves], qlineOpt)
|
|
const centeredPoint = getCenterPoint(line.y1, line.y2)
|
|
centerLinePoint.x1 = line.x1 - edge
|
|
centerLinePoint.y1 = centeredPoint
|
|
centerLinePoint.y2 = centeredPoint
|
|
centerDashLinePoint.y1 = line.y1 - eaves
|
|
centerDashLinePoint.y2 = line.y2 + eaves
|
|
} else if (index === 1) {
|
|
outline = new QLine([line.x1 - edge, line.y1 + eaves, line.x2 + edge, line.y2 + eaves], qlineOpt)
|
|
const centeredPoint = getCenterPoint(line.x1, line.x2)
|
|
centerLinePoint.x2 = line.x2 + edge
|
|
centerDashLinePoint.x1 = centeredPoint
|
|
centerDashLinePoint.x2 = centeredPoint
|
|
} else if (index === 2) {
|
|
outline = new QLine([line.x1 + edge, line.y1 + eaves, line.x2 + edge, line.y2 - eaves], qlineOpt)
|
|
} else if (index === 3) {
|
|
outline = new QLine([line.x1 + edge, line.y1 - eaves, line.x2 - edge, line.y2 - eaves], qlineOpt)
|
|
}
|
|
canvas.add(outline)
|
|
})
|
|
const centerLine = new QLine([centerLinePoint.x1, centerLinePoint.y1, centerLinePoint.x2, centerLinePoint.y2], qlineOpt)
|
|
canvas.add(centerLine)
|
|
const centerDashLine1 = new QLine(
|
|
[centerDashLinePoint.x1, centerDashLinePoint.y1, centerDashLinePoint.x2, getCenterPoint(centerDashLinePoint.y1, centerDashLinePoint.y2)],
|
|
qlineOptDashWithoutLength,
|
|
)
|
|
canvas.add(centerDashLine1)
|
|
const centerDashLine2 = new QLine(
|
|
[centerDashLinePoint.x1, getCenterPoint(centerDashLinePoint.y1, centerDashLinePoint.y2), centerDashLinePoint.x2, centerDashLinePoint.y2],
|
|
qlineOptDashWithoutLength,
|
|
)
|
|
canvas.add(centerDashLine2)
|
|
|
|
canvas.renderAll()
|
|
}
|
|
|
|
/**
|
|
* 6각형일때 계산 로직
|
|
* @param {obj} params
|
|
*/
|
|
const handleTemplateB = (params) => {
|
|
const { eaves, edge, polygon } = params
|
|
// 가장 긴 라인이 첫번째일때
|
|
let shapeType = 0
|
|
console.log(polygon)
|
|
const odd = polygon.lines.filter((line, index) => index % 2 === 0)
|
|
const even = polygon.lines.filter((line, index) => index % 2 !== 0)
|
|
const rerangeOdd = chgLineDirectionVertical(odd)
|
|
const rerangeEven = chgLineDirectionHorizontal(even)
|
|
// 가장 긴 라인이 첫번째인지 판단
|
|
chkLengthIndex({ arr: odd, type: 'L' }) !== 0 ? (shapeType = 1) : null
|
|
// 가장 짧은 라인의 인덱스 반환
|
|
const shortIndex = chkLengthIndex({ arr: odd, type: 'S' })
|
|
|
|
const centralLinePoint = {
|
|
x1: 0,
|
|
y1: 0,
|
|
x2: 0,
|
|
y2: 0,
|
|
}
|
|
const centralSubLinePoint = {
|
|
x1: 0,
|
|
y1: 0,
|
|
x2: 0,
|
|
y2: 0,
|
|
}
|
|
const centralDashLinePoint = {
|
|
x1: 0,
|
|
y1: 0,
|
|
x2: 0,
|
|
y2: 0,
|
|
}
|
|
const centralSubDashLinePoint = {
|
|
x1: 0,
|
|
y1: 0,
|
|
x2: 0,
|
|
y2: 0,
|
|
}
|
|
const qlineOpt = {
|
|
stroke: 'blue',
|
|
strokeWidth: 2,
|
|
selectable: false,
|
|
fontSize: fontSize,
|
|
}
|
|
const qlineOptDash = {
|
|
stroke: 'black',
|
|
strokeWidth: 2,
|
|
strokeDashArray: [5, 5],
|
|
selectable: false,
|
|
fontSize: fontSize,
|
|
}
|
|
|
|
rerangeOdd.forEach((line, index) => {
|
|
const centeredPoint = getCenterPoint(line.y1, line.y2)
|
|
let points1 = []
|
|
let points2 = []
|
|
if (polygon.shape === 2 || polygon.shape === 3) {
|
|
if (index === 0) {
|
|
points1 = [line.x1 - edge, line.y1 - eaves, line.x1 - edge, centeredPoint]
|
|
points2 = [line.x2 - edge, centeredPoint, line.x2 - edge, line.y2 + eaves]
|
|
centralLinePoint.x1 = line.x1 - edge
|
|
centralLinePoint.y1 = centeredPoint
|
|
centralLinePoint.y2 = centeredPoint
|
|
centralDashLinePoint.y1 = line.y1 - eaves
|
|
centralDashLinePoint.y2 = line.y2 + eaves
|
|
} else if (index === 1) {
|
|
if (polygon.shape === 2) {
|
|
points1 = [line.x1 + edge, line.y1 - eaves, line.x1 + edge, centeredPoint]
|
|
points2 = [line.x1 + edge, centeredPoint, line.x2 + edge, line.y2 + eaves]
|
|
centralSubLinePoint.x2 = line.x1 + edge
|
|
centralSubLinePoint.y2 = centeredPoint
|
|
} else {
|
|
points1 = [line.x1 + edge, getCenterPoint(rerangeOdd[2].y1, rerangeOdd[2].y2), line.x2 + edge, line.y2 + eaves]
|
|
points2 = [line.x1, getCenterPoint(rerangeOdd[2].y1, rerangeOdd[2].y2), line.x1, line.y1 + eaves]
|
|
centralLinePoint.x2 = line.x1 + edge
|
|
centralSubLinePoint.y1 = getCenterPoint(rerangeOdd[2].y1, rerangeOdd[2].y2)
|
|
centralSubLinePoint.y2 = getCenterPoint(rerangeOdd[2].y1, rerangeOdd[2].y2)
|
|
}
|
|
} else if (index === 2) {
|
|
if (polygon.shape === 2) {
|
|
points1 = [line.x1 + edge, line.y1 - eaves, line.x2 + edge, centralSubLinePoint.y2]
|
|
points2 = [line.x2, line.y2 - eaves, line.x2, centralSubLinePoint.y2]
|
|
} else {
|
|
points1 = [line.x1 + edge, line.y1 - eaves, line.x2 + edge, centeredPoint]
|
|
points2 = [line.x2 + edge, centeredPoint, line.x2 + edge, line.y2 + eaves]
|
|
}
|
|
}
|
|
} else {
|
|
if (index === 0) {
|
|
points1 = [line.x1 - edge, line.y1 - eaves, line.x2 - edge, line.y2 + eaves]
|
|
centralSubLinePoint.x1 = line.x1 - edge
|
|
centralSubLinePoint.y1 = getCenterPoint(line.y1, line.y2)
|
|
centralSubLinePoint.y2 = getCenterPoint(line.y1, line.y2)
|
|
} else if (index === 1) {
|
|
if (polygon.shape === 1) {
|
|
points1 = [line.x1 - edge, centralSubLinePoint.y1, line.x2 - edge, line.y2 + eaves]
|
|
points2 = [line.x1, centralSubLinePoint.y1, line.x1, line.y1 + eaves]
|
|
centralLinePoint.x1 = line.x1 - edge
|
|
centralSubLinePoint.x2 = line.x2
|
|
} else {
|
|
points1 = [line.x1 + edge, line.y1 - eaves, line.x2 + edge, centeredPoint]
|
|
points2 = [line.x2 + edge, centeredPoint, line.x2 + edge, line.y2 + eaves]
|
|
centralLinePoint.x2 = line.x1 + edge
|
|
centralLinePoint.y1 = centeredPoint
|
|
centralLinePoint.y2 = centeredPoint
|
|
centralDashLinePoint.y1 = line.y1 - eaves
|
|
centralDashLinePoint.y2 = line.y2 + eaves
|
|
}
|
|
} else {
|
|
if (polygon.shape === 1) {
|
|
points1 = [line.x1 + edge, line.y1 - eaves, line.x1 + edge, centeredPoint]
|
|
points2 = [line.x2 + edge, centeredPoint, line.x2 + edge, line.y2 + eaves]
|
|
centralLinePoint.x2 = line.x1 + edge
|
|
centralLinePoint.y1 = centeredPoint
|
|
centralLinePoint.y2 = centeredPoint
|
|
centralDashLinePoint.y1 = line.y1 - eaves
|
|
centralDashLinePoint.y2 = line.y2 + eaves
|
|
} else {
|
|
points1 = [line.x1 - edge, line.y1 - eaves, line.x2 - edge, centralSubLinePoint.y1]
|
|
points2 = [line.x2, line.y2 - eaves, line.x2, centralSubLinePoint.y2]
|
|
centralLinePoint.x1 = line.x1 - edge
|
|
centralSubLinePoint.x2 = line.x2
|
|
}
|
|
}
|
|
}
|
|
|
|
if (points1.length > 0) {
|
|
const subLine1 = new QLine(points1, qlineOpt)
|
|
canvas.add(subLine1)
|
|
}
|
|
if (points2.length > 0) {
|
|
const subLine2 = new QLine(points2, qlineOpt)
|
|
canvas.add(subLine2)
|
|
}
|
|
})
|
|
|
|
rerangeEven.forEach((line, index) => {
|
|
let points = []
|
|
if (polygon.shape === 2 || polygon.shape === 3) {
|
|
if (index === 0) {
|
|
points = [line.x1 - edge, line.y1 + eaves, line.x2 + edge, line.y2 + eaves]
|
|
if (polygon.shape === 3) {
|
|
centralDashLinePoint.x1 = getCenterPoint(line.x1, line.x2)
|
|
centralDashLinePoint.x2 = getCenterPoint(line.x1, line.x2)
|
|
}
|
|
} else if (index === 2) {
|
|
points = [line.x1 - edge, line.y1 - eaves, line.x2 + edge, line.y2 - eaves]
|
|
if (polygon.shape === 2) {
|
|
centralDashLinePoint.x1 = getCenterPoint(line.x1, line.x2)
|
|
centralDashLinePoint.x2 = getCenterPoint(line.x1, line.x2)
|
|
centralLinePoint.x2 = line.x2 + edge
|
|
}
|
|
} else {
|
|
if (polygon.shape === 2) {
|
|
const subLines = [
|
|
[line.x1, line.y1 - eaves, line.x2 + edge, line.y2 - eaves],
|
|
[line.x1, centralSubLinePoint.y2, centralSubLinePoint.x2, centralSubLinePoint.y2],
|
|
]
|
|
subLines.forEach((sLine, index) => {
|
|
const subLine = new QLine(sLine, qlineOpt)
|
|
canvas.add(subLine)
|
|
})
|
|
centralSubDashLinePoint.x1 = getCenterPoint(line.x1, line.x2 + edge)
|
|
centralSubDashLinePoint.x2 = getCenterPoint(line.x1, line.x2 + edge)
|
|
centralSubDashLinePoint.y1 = line.y1 - eaves
|
|
centralSubDashLinePoint.y2 = centralSubLinePoint.y2
|
|
} else {
|
|
const subLines = [
|
|
[line.x1, line.y1 + eaves, line.x2 + edge, line.y2 + eaves],
|
|
[line.x1, centralSubLinePoint.y1, line.x2 + edge, centralSubLinePoint.y2],
|
|
]
|
|
subLines.forEach((sLine, index) => {
|
|
const subLine = new QLine(sLine, qlineOpt)
|
|
canvas.add(subLine)
|
|
})
|
|
centralSubDashLinePoint.x1 = getCenterPoint(line.x1, line.x2 + edge)
|
|
centralSubDashLinePoint.x2 = getCenterPoint(line.x1, line.x2 + edge)
|
|
centralSubDashLinePoint.y1 = centralSubLinePoint.y1
|
|
centralSubDashLinePoint.y2 = line.y2 + eaves
|
|
}
|
|
}
|
|
} else {
|
|
if (index === 0) {
|
|
if (polygon.shape === 1) {
|
|
const subLines = [
|
|
[centralSubLinePoint.x1, centralSubLinePoint.y1, centralSubLinePoint.x2, centralSubLinePoint.y2],
|
|
[line.x1 - edge, line.y1 + eaves, line.x2, line.y1 + eaves],
|
|
]
|
|
subLines.forEach((sLine, index) => {
|
|
const subLine = new QLine(sLine, qlineOpt)
|
|
canvas.add(subLine)
|
|
})
|
|
centralSubDashLinePoint.x1 = getCenterPoint(line.x1 - edge, line.x2)
|
|
centralSubDashLinePoint.x2 = getCenterPoint(line.x1 - edge, line.x2)
|
|
centralSubDashLinePoint.y1 = centralSubLinePoint.y1
|
|
centralSubDashLinePoint.y2 = line.y2 + eaves
|
|
} else {
|
|
points = [line.x1 - edge, line.y1 + eaves, line.x2 + edge, line.y2 + eaves]
|
|
}
|
|
} else if (index === 1) {
|
|
if (polygon.shape === 1) {
|
|
points = [line.x1 - edge, line.y1 + eaves, line.x2 + edge, line.y2 + eaves]
|
|
centralDashLinePoint.x1 = getCenterPoint(line.x1, line.x2)
|
|
centralDashLinePoint.x2 = getCenterPoint(line.x1, line.x2)
|
|
} else {
|
|
points = [line.x1 - edge, line.y1 - eaves, line.x2 + edge, line.y2 - eaves]
|
|
centralDashLinePoint.x1 = getCenterPoint(line.x1, line.x2)
|
|
centralDashLinePoint.x2 = getCenterPoint(line.x1, line.x2)
|
|
}
|
|
} else {
|
|
if (polygon.shape === 1) {
|
|
points = [line.x1 - edge, line.y1 - eaves, line.x2 + edge, line.y2 - eaves]
|
|
} else {
|
|
const subLines = [
|
|
[centralSubLinePoint.x1, centralSubLinePoint.y1, centralSubLinePoint.x2, centralSubLinePoint.y2],
|
|
[line.x1 - edge, line.y1 - eaves, line.x2, line.y1 - eaves],
|
|
]
|
|
subLines.forEach((sLine, index) => {
|
|
const subLine = new QLine(sLine, qlineOpt)
|
|
canvas.add(subLine)
|
|
})
|
|
centralSubDashLinePoint.x1 = getCenterPoint(line.x1 - edge, line.x2)
|
|
centralSubDashLinePoint.x2 = getCenterPoint(line.x1 - edge, line.x2)
|
|
centralSubDashLinePoint.y1 = line.y1 - eaves
|
|
centralSubDashLinePoint.y2 = centralSubLinePoint.y2
|
|
}
|
|
}
|
|
}
|
|
|
|
if (points.length > 0) {
|
|
const subLine = new QLine(points, qlineOpt)
|
|
canvas.add(subLine)
|
|
}
|
|
})
|
|
|
|
const centralLine = new QLine([centralLinePoint.x1, centralLinePoint.y1, centralLinePoint.x2, centralLinePoint.y2], qlineOpt)
|
|
canvas.add(centralLine)
|
|
const centralDashLine1 = new QLine([centralDashLinePoint.x1, centralDashLinePoint.y1, centralDashLinePoint.x1, centralLinePoint.y2], qlineOptDash)
|
|
canvas.add(centralDashLine1)
|
|
const centralDashLine2 = new QLine([centralDashLine1.x2, centralDashLine1.y2, centralDashLinePoint.x2, centralDashLinePoint.y2], qlineOptDash)
|
|
canvas.add(centralDashLine2)
|
|
const centralSubDashLine = new QLine(
|
|
[centralSubDashLinePoint.x1, centralSubDashLinePoint.y1, centralSubDashLinePoint.x2, centralSubDashLinePoint.y2],
|
|
qlineOptDash,
|
|
)
|
|
canvas.add(centralSubDashLine)
|
|
|
|
canvas.renderAll()
|
|
}
|
|
|
|
/**
|
|
* 세로 방샹 라인의 좌표 순서를 위에서 아래로 변경
|
|
* @param {array} arr
|
|
* @returns
|
|
*/
|
|
const chgLineDirectionVertical = (arr) => {
|
|
const newArr = arr.map((line, index) => {
|
|
if (line.direction !== 'bottom') {
|
|
const newPoint = { x1: line.x2, y1: line.y2, x2: line.x1, y2: line.y1 }
|
|
return newPoint
|
|
} else {
|
|
return line
|
|
}
|
|
})
|
|
return newArr
|
|
}
|
|
|
|
/**
|
|
* 가로 방향 라인의 좌표 순서를 왼쪽에서 오른쪽으로 변경
|
|
* @param {array} arr
|
|
* @returns
|
|
*/
|
|
const chgLineDirectionHorizontal = (arr) => {
|
|
const newArr = arr.map((line, index) => {
|
|
if (line.direction !== 'right') {
|
|
const newPoint = { x1: line.x2, y1: line.y2, x2: line.x1, y2: line.y1 }
|
|
return newPoint
|
|
} else {
|
|
return line
|
|
}
|
|
})
|
|
return newArr
|
|
}
|
|
|
|
/**
|
|
* 라인 배열 중 가장 긴 라인의 인덱스를 반환합니다.
|
|
*/
|
|
const chkLengthIndex = (params) => {
|
|
const { arr, type } = params
|
|
let maxIndex = 0
|
|
for (let i = 1; i < arr.length; i++) {
|
|
if (type === 'L') {
|
|
if (arr[maxIndex].length < arr[i].length) {
|
|
maxIndex = i
|
|
}
|
|
} else {
|
|
if (arr[maxIndex].length > arr[i].length) {
|
|
maxIndex = i
|
|
}
|
|
}
|
|
}
|
|
return maxIndex
|
|
}
|
|
|
|
/**
|
|
* 외벽선 색깔을 변경
|
|
* @param {array} polygon
|
|
*/
|
|
const handleInnerLineColor = (polygon) => {
|
|
polygon.lines.forEach((line, index) => {
|
|
if (index % 2 === 0) {
|
|
line.set('stroke', 'rgb(0, 220, 221)')
|
|
} else {
|
|
line.set('stroke', 'rgb(0, 224, 61)')
|
|
}
|
|
|
|
const overLine = new QLine([line.x1, line.y1, line.x2, line.y2], {
|
|
stroke: line.stroke,
|
|
strokeWidth: 2,
|
|
selectable: false,
|
|
fontSize: fontSize,
|
|
isActiveLengthText: false,
|
|
})
|
|
canvas.add(overLine)
|
|
})
|
|
canvas.renderAll()
|
|
}
|
|
|
|
return {
|
|
mode,
|
|
changeMode,
|
|
setCanvas,
|
|
handleClear,
|
|
zoomIn,
|
|
zoomOut,
|
|
zoom,
|
|
togglePolygonLine,
|
|
handleOuterlinesTest2,
|
|
}
|
|
}
|