diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx index b2f9a022..0b6e30f7 100644 --- a/src/components/Roof2.jsx +++ b/src/components/Roof2.jsx @@ -144,7 +144,7 @@ export default function Roof2() { { fill: 'transparent', stroke: 'black', - strokeWidth: 2, + strokeWidth: 1, selectable: true, fontSize: fontSize, }, @@ -152,6 +152,10 @@ export default function Roof2() { ) canvas?.add(polygon) + + polygon.drawOuterLine(-50) + + console.log(polygon.outerPolygon) } } @@ -170,7 +174,7 @@ export default function Roof2() { if (canvas) { const line = new QLine([50, 50, 200, 50], { stroke: 'black', - strokeWidth: 2, + strokeWidth: 1, fontSize: fontSize, }) diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js index a13a69d6..cc8bbce8 100644 --- a/src/components/fabric/QPolygon.js +++ b/src/components/fabric/QPolygon.js @@ -9,6 +9,7 @@ export default class QPolygon extends fabric.Group { canvas fontSize qCells = [] + outerPolygon constructor(points, options, canvas) { if (!options.fontSize) { throw new Error('Font size is required.') @@ -247,4 +248,73 @@ export default class QPolygon extends fabric.Group { } }) } + + /** + * 외곽선 그리기 + * @param offset + */ + drawOuterLine(offset = -10) { + const points = this.getCurrentPoints() + const offsetPoints = [] + 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 = { + x: current.x + unitNormal.x * offset, + y: current.y + unitNormal.y * offset, + } + + offsetPoints.push(offsetPoint) + } + + const outPolygon = new QPolygon( + offsetPoints, + { + stroke: 'black', + strokeWidth: 1, + fill: 'transparent', + fontSize: this.fontSize, + }, + this.canvas, + ) + + this.outerPolygon = outPolygon + + this.addWithUpdate(outPolygon) + this.canvas.renderAll() + } } diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js index ebcaa5c5..d2ebd3dd 100644 --- a/src/hooks/useMode.js +++ b/src/hooks/useMode.js @@ -416,6 +416,7 @@ export function useMode() { // 새로운 다각형 객체를 캔버스에 추가합니다. canvas.add(polygon) + // polygon.drawOuterLine(50) // 캔버스를 다시 그립니다. if (!otherLines) {