도형 외곽선 로직 테스트중

This commit is contained in:
Jaeyoung Lee 2024-08-01 13:24:51 +09:00
parent 8d37aef2e4
commit 0559b2d8e4
2 changed files with 322 additions and 40 deletions

View File

@ -255,8 +255,20 @@ export default function Roof2() {
const diagonalType = [
{ x: 100, y: 100 },
{ x: 100, y: 600 },
{ x: 250, y: 600 },
{ x: 250, y: 450 },
{ x: 400, y: 450 },
{ x: 400, y: 600 },
{ x: 600, y: 600 },
{ x: 400, y: 100 }]
{ x: 400, y: 100 },
]
const triangleType = [
{ x: 100, y: 100 },
{ x: 100, y: 600 },
{ x: 600, y: 600 },
{ x: 300, y: 100 },
]
if (canvas) {
const polygon = new QPolygon(diagonalType, {
@ -325,7 +337,7 @@ export default function Roof2() {
}
const addBackgroundInPolygon = (polygon) => {
fabric.Image.fromURL('assets/img/check2.png', function(img) {
fabric.Image.fromURL('assets/img/check2.png', function (img) {
// .
const pattern = new fabric.Pattern({
source: img.getElement(),
@ -389,8 +401,7 @@ export default function Roof2() {
{canvas && (
<>
<div className=" my-8 w-full text:pretty">
<Button className="m-1 p-2" color={`${mode === Mode.DEFAULT ? 'primary' : 'default'}`}
onClick={fillCellInPolygon}>
<Button className="m-1 p-2" color={`${mode === Mode.DEFAULT ? 'primary' : 'default'}`} onClick={fillCellInPolygon}>
모드 DEFAULT
</Button>
<Button
@ -400,28 +411,22 @@ export default function Roof2() {
>
기준선 긋기 모드
</Button>
<Button className="m-1 p-2" color={`${mode === Mode.EDIT ? 'primary' : 'default'}`}
onClick={() => changeMode(canvas, Mode.EDIT)}>
<Button className="m-1 p-2" color={`${mode === Mode.EDIT ? 'primary' : 'default'}`} onClick={() => changeMode(canvas, Mode.EDIT)}>
에디팅모드
</Button>
<Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`}
onClick={() => changeMode(canvas, Mode.TEMPLATE)}>
<Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`} onClick={() => changeMode(canvas, Mode.TEMPLATE)}>
템플릿(기둥)
</Button>
<Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`}
onClick={() => changeMode(canvas, Mode.PATTERNA)}>
<Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`} onClick={() => changeMode(canvas, Mode.PATTERNA)}>
템플릿(A 패턴)
</Button>
<Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`}
onClick={() => changeMode(canvas, Mode.PATTERNB)}>
<Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`} onClick={() => changeMode(canvas, Mode.PATTERNB)}>
템플릿(B 패턴)
</Button>
<Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`}
onClick={() => drawRoofPatterns(1)}>
<Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`} onClick={() => drawRoofPatterns(1)}>
지붕패턴1
</Button>
<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
</Button>
<Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`} onClick={() => changeMode(canvas, Mode.MODULE)}>

View File

@ -1,22 +1,9 @@
import { useEffect, useRef, useState } from 'react'
import QRect from '@/components/fabric/QRect'
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 {
canvasSizeState,
fontSizeState,
roofPolygonPatternArrayState,
roofState,
sortedPolygonArray,
wallState,
} from '@/store/canvasAtom'
import { canvasSizeState, fontSizeState, roofPolygonPatternArrayState, roofState, sortedPolygonArray, wallState } from '@/store/canvasAtom'
import { QLine } from '@/components/fabric/QLine'
import { fabric } from 'fabric'
import { QPolygon } from '@/components/fabric/QPolygon'
@ -400,7 +387,7 @@ export function useMode() {
}
const editMode = () => {
canvas?.on('mouse:down', function(options) {
canvas?.on('mouse:down', function (options) {
const pointer = canvas?.getPointer(options.e)
const circle = new fabric.Circle({
radius: 5,
@ -528,7 +515,7 @@ export function useMode() {
}
const textboxMode = () => {
canvas?.on('mouse:down', function(options) {
canvas?.on('mouse:down', function (options) {
if (canvas?.getActiveObject()?.type === 'textbox') return
const pointer = canvas?.getPointer(options.e)
@ -543,14 +530,14 @@ export function useMode() {
canvas?.setActiveObject(textbox) // 생성된 텍스트박스를 활성 객체로 설정합니다.
canvas?.renderAll()
// textbox가 active가 풀린 경우 editing mode로 변경
textbox?.on('editing:exited', function() {
textbox?.on('editing:exited', function () {
changeMode(canvas, Mode.EDIT)
})
})
}
const drawLineMode = () => {
canvas?.on('mouse:down', function(options) {
canvas?.on('mouse:down', function (options) {
const pointer = canvas?.getPointer(options.e)
const line = new QLine(
@ -571,7 +558,7 @@ export function useMode() {
const drawRectMode = () => {
let rect, isDown, origX, origY
canvas.on('mouse:down', function(o) {
canvas.on('mouse:down', function (o) {
isDown = true
const pointer = canvas.getPointer(o.e)
origX = pointer.x
@ -591,7 +578,7 @@ export function useMode() {
canvas.add(rect)
})
canvas.on('mouse:move', function(o) {
canvas.on('mouse:move', function (o) {
if (!isDown) return
const pointer = canvas.getPointer(o.e)
if (origX > pointer.x) {
@ -605,7 +592,7 @@ export function useMode() {
rect.set({ height: Math.abs(origY - pointer.y) })
})
canvas.on('mouse:up', function(o) {
canvas.on('mouse:up', function (o) {
const pointer = canvas.getPointer(o.e)
const qRect = new QRect({
left: origX,
@ -1169,9 +1156,299 @@ export function useMode() {
roof.drawHelpLine()
}
const drawRoofPolygon = (wall, offset = 71) => {
const drawRoofPolygon = (wall, offset = 50) => {
console.log(wall)
const offsetPoints = []
let lines = wall.lines,
points = wall.points,
expandedPoints = []
let minX = points[0].x,
minY = points[0].y,
maxX = points[0].x,
maxY = points[0].y
points.forEach((point) => {
if (point.x < minX) minX = point.x
if (point.y < minY) minY = point.y
if (point.x > maxX) maxX = point.x
if (point.y > maxY) maxY = point.y
})
wall.lines.forEach((currentWall, index) => {
let prevWall = wall.lines[index === 0 ? wall.lines.length - 1 : index - 1]
let nextWall = wall.lines[index === wall.lines.length - 1 ? 0 : index + 1]
let isStartPointIn = minX < currentWall.x1 && currentWall.x1 < maxX && minY < currentWall.y1 && currentWall.y1 < maxY
let isEndPointIn = minX < currentWall.x2 && currentWall.x2 < maxX && minY < currentWall.y2 && currentWall.y2 < maxY
if (prevWall.direction !== nextWall.direction) {
console.log('if ::::')
if (currentWall.direction === 'top') {
if (prevWall.direction === 'right') {
//밑변
let a = Math.abs(currentWall.x1 - prevWall.x1)
//빗변
let c = Math.sqrt(Math.abs(currentWall.x1 - currentWall.x2) ** 2 + Math.abs(currentWall.y1 - currentWall.y2) ** 2)
//밑변과 빗변사이의 각도
let alphaDegree = 90 - Math.acos(a / c) * (180 / Math.PI)
console.log(a, c, alphaDegree)
let addLength = Math.abs(offset * Math.tan(alphaDegree * (Math.PI / 180)))
console.log(addLength)
expandedPoints.push({
x1: currentWall.x1 + offset + addLength,
y1: currentWall.y1 + offset,
})
}
if (prevWall.direction === 'left') {
console.log('prevWall degree : ', 225)
expandedPoints.push({
x1: currentWall.x1 - offset,
y1: currentWall.y1 + offset,
})
}
}
if (currentWall.direction === 'bottom') {
if (prevWall.direction === 'right') {
console.log('prevWall degree : ', 45)
expandedPoints.push({
x1: currentWall.x1 + offset,
y1: currentWall.y1 - offset,
})
}
if (prevWall.direction === 'left') {
console.log('prevWall degree : ', 315)
expandedPoints.push({
x1: currentWall.x1 - offset,
y1: currentWall.y1 - offset,
})
}
}
if (currentWall.direction === 'right') {
if (prevWall.direction === 'top') {
if (isStartPointIn) {
console.log('prevWall degree : ', 135)
expandedPoints.push({
x1: currentWall.x1 + offset,
y1: currentWall.y1 + offset,
})
} else {
console.log('prevWall degree : ', 315)
expandedPoints.push({
x1: currentWall.x1 - offset,
y1: currentWall.y1 - offset,
})
}
}
if (prevWall.direction === 'bottom') {
if (isStartPointIn) {
console.log('prevWall degree : ', 45)
expandedPoints.push({
x1: currentWall.x1 + offset,
y1: currentWall.y1 - offset,
})
} else {
console.log('prevWall degree : ', 225)
expandedPoints.push({
x1: currentWall.x1 - offset,
y1: currentWall.y1 + offset,
})
}
}
}
if (currentWall.direction === 'left') {
if (prevWall.direction === 'top') {
if (isStartPointIn) {
console.log('prevWall degree : ', 225)
expandedPoints.push({
x1: currentWall.x1 - offset,
y1: currentWall.y1 + offset,
})
} else {
console.log('prevWall degree : ', 45)
//밑변
let a = Math.abs(currentWall.x1 - prevWall.x1)
//빗변
let c = Math.sqrt(Math.abs(currentWall.x1 - currentWall.x2) ** 2 + Math.abs(currentWall.y1 - currentWall.y2) ** 2)
//밑변과 빗변사이의 각도
let alphaDegree = 90 - Math.acos(a / c) * (180 / Math.PI)
console.log(a, c, alphaDegree)
let addLength = Math.abs(offset * Math.tan(alphaDegree * (Math.PI / 180)))
console.log(addLength)
expandedPoints.push({
x1: currentWall.x1 + offset + addLength,
y1: currentWall.y1 - offset,
})
}
}
if (prevWall.direction === 'bottom') {
if (isStartPointIn) {
console.log('prevWall degree : ', 315)
expandedPoints.push({
x1: currentWall.x1 - offset,
y1: currentWall.y1 - offset,
})
} else {
console.log('prevWall degree : ', 135)
expandedPoints.push({
x1: currentWall.x1 + offset,
y1: currentWall.y1 + offset,
})
}
}
}
} else {
console.log('else :::: ')
if (currentWall.direction === 'top') {
if (prevWall.direction === 'right') {
if (isStartPointIn) {
console.log('prevWall degree : ', 315)
expandedPoints.push({
x1: currentWall.x1 - offset,
y1: currentWall.y1 - offset,
})
} else {
console.log('prevWall degree : ', 135)
expandedPoints.push({
x1: currentWall.x1 + offset,
y1: currentWall.y1 + offset,
})
}
}
if (prevWall.direction === 'left') {
if (isStartPointIn) {
console.log('prevWall degree : ', 45)
expandedPoints.push({
x1: currentWall.x1 + offset,
y1: currentWall.y1 - offset,
})
} else {
console.log('prevWall degree : ', 225)
expandedPoints.push({
x1: currentWall.x1 - offset,
y1: currentWall.y1 + offset,
})
}
}
}
if (currentWall.direction === 'bottom') {
if (prevWall.direction === 'right') {
if (isStartPointIn) {
console.log('prevWall degree : ', 225)
expandedPoints.push({
x1: currentWall.x1 - offset,
y1: currentWall.y1 + offset,
})
} else {
console.log('prevWall degree : ', 45)
expandedPoints.push({
x1: currentWall.x1 + offset,
y1: currentWall.y1 - offset,
})
}
}
}
if (currentWall.direction === 'right') {
if (prevWall.direction === 'top') {
if (isStartPointIn) {
console.log('prevWall degree : ', 135)
expandedPoints.push({
x1: currentWall.x1 + offset,
y1: currentWall.y1 + offset,
})
} else {
console.log('prevWall degree : ', 315)
expandedPoints.push({
x1: currentWall.x1 - offset,
y1: currentWall.y1 - offset,
})
}
}
if (prevWall.direction === 'bottom') {
if (isStartPointIn) {
console.log('prevWall degree : ', 225)
expandedPoints.push({
x1: currentWall.x1 - offset,
y1: currentWall.y1 + offset,
})
} else {
console.log('prevWall degree : ', 45)
expandedPoints.push({
x1: currentWall.x1 + offset,
y1: currentWall.y1 - offset,
})
}
}
}
if (currentWall.direction === 'left') {
if (prevWall.direction === 'top') {
if (isStartPointIn) {
console.log('prevWall degree : ', 225)
expandedPoints.push({
x1: currentWall.x1 - offset,
y1: currentWall.y1 + offset,
})
} else {
console.log('prevWall degree : ', 45)
expandedPoints.push({
x1: currentWall.x1 + offset,
y1: currentWall.y1 - offset,
})
}
}
if (prevWall.direction === 'bottom') {
if (isStartPointIn) {
console.log('prevWall degree : ', 135)
expandedPoints.push({
x1: currentWall.x1 + offset,
y1: currentWall.y1 + offset,
})
} else {
console.log('prevWall degree : ', 315)
expandedPoints.push({
x1: currentWall.x1 - offset,
y1: currentWall.y1 - offset,
})
}
}
}
}
})
const roof = makePolygon(expandedPoints)
roof.setWall(wall)
setRoof(roof)
}
const calculateParallelPoint = (x1, y1, x2, y2, distance) => {
// 원래 선의 dx, dy 계산
const dx = x2 - x1
const dy = y2 - y1
// 법선 벡터 정규화
const norm = Math.sqrt(dx * dx + dy * dy)
const unitVectorX = dy / norm
const unitVectorY = -dx / norm
// 원하는 거리만큼 평행 이동
const offsetX = distance * unitVectorX
const offsetY = distance * unitVectorY
// 새로운 평행선의 두 점 계산
const newX1 = x1 + offsetX
const newY1 = y1 + offsetY
const newX2 = x2 + offsetX
const newY2 = y2 + offsetY
return { newPoint1: { x: newX1, y: newY1 }, newPoint2: { x: newX2, y: newY2 } }
}
const togglePolygonLine = (obj) => {