@@ -29,7 +38,7 @@ export default function PentagonDormer() {
@@ -40,18 +49,18 @@ export default function PentagonDormer() {
-
{getMessage('modal.object.setting.offset.depth')}
+
{getMessage('modal.object.setting.offset.width')}
@@ -62,7 +71,7 @@ export default function PentagonDormer() {
@@ -80,13 +89,15 @@ export default function PentagonDormer() {
{getMessage('commons.east')}
{getMessage('commons.south')}
{getMessage('commons.west')}
-
-
-
-
+
+
+
+
>
)
-}
+})
+
+export default PentagonDormer
diff --git a/src/components/floor-plan/modal/object/type/TriangleDormer.jsx b/src/components/floor-plan/modal/object/type/TriangleDormer.jsx
index 9ab7712d..f2a8a1f0 100644
--- a/src/components/floor-plan/modal/object/type/TriangleDormer.jsx
+++ b/src/components/floor-plan/modal/object/type/TriangleDormer.jsx
@@ -5,7 +5,6 @@ import { forwardRef, useState } from 'react'
const TriangleDormer = forwardRef((props, refs) => {
const { getMessage } = useMessage()
const [direction, setDirection] = useState('down')
-
refs.directionRef.current = direction
const getDirection = (e) => {
diff --git a/src/hooks/object/useObjectBatch.js b/src/hooks/object/useObjectBatch.js
index 7229f470..9ad8af5d 100644
--- a/src/hooks/object/useObjectBatch.js
+++ b/src/hooks/object/useObjectBatch.js
@@ -4,14 +4,7 @@ import { useRecoilState, useRecoilValue } from 'recoil'
import { canvasState } from '@/store/canvasAtom'
import { INPUT_TYPE, BATCH_TYPE } from '@/common/common'
import { useEvent } from '@/hooks/useEvent'
-import {
- polygonToTurfPolygon,
- rectToPolygon,
- triangleToPolygon,
- pointsToTurfPolygon,
- splitDormerTriangle,
- setSurfaceShapePattern,
-} from '@/util/canvas-util'
+import { polygonToTurfPolygon, rectToPolygon, triangleToPolygon, pointsToTurfPolygon, setSurfaceShapePattern } from '@/util/canvas-util'
import { useSwal } from '@/hooks/useSwal'
import * as turf from '@turf/turf'
import { QPolygon } from '@/components/fabric/QPolygon'
@@ -211,11 +204,13 @@ export function useObjectBatch() {
const dormerName = buttonAct === 3 ? BATCH_TYPE.TRIANGLE_DORMER : BATCH_TYPE.PENTAGON_DORMER
const dormerTempName = buttonAct === 3 ? BATCH_TYPE.TRIANGLE_DORMER_TEMP : BATCH_TYPE.PENTAGON_DORMER_TEMP
const height = dormerPlacement.heightRef.current.value / 10
+ const width = dormerPlacement.widthRef.current.value / 10
const pitch = dormerPlacement.pitchRef.current.value
- const directionRef = dormerPlacement.directionRef.current
const offsetRef = dormerPlacement.offsetRef.current.value === '' ? 0 : parseInt(dormerPlacement.offsetRef.current.value) / 10
+ const offsetWidthRef = dormerPlacement.offsetWidthRef.current.value === '' ? 0 : parseInt(dormerPlacement.offsetWidthRef.current.value) / 10
+ const directionRef = dormerPlacement.directionRef.current
- let dormer, dormerOffset, isDown, selectedSurface
+ let dormer, dormerOffset, isDown, selectedSurface, pentagonPoints, pentagonOffsetPoints
console.log('dormerPlacement', dormerPlacement)
@@ -229,8 +224,6 @@ export function useObjectBatch() {
const bottomLength = height / (pitch * 0.25)
const bottomOffsetLength = (height + offsetRef) / (pitch * 0.25)
- console.log(bottomOffsetLength)
-
addCanvasMouseEventListener('mouse:move', (e) => {
isDown = true
if (!isDown) return
@@ -305,16 +298,16 @@ export function useObjectBatch() {
addCanvasMouseEventListener('mouse:up', (e) => {
if (dormer) {
- // const trianglePolygon = pointsToTurfPolygon(triangleToPolygon(dormer))
- // const selectedSurfacePolygon = polygonToTurfPolygon(selectedSurface)
+ const trianglePolygon = pointsToTurfPolygon(triangleToPolygon(dormer))
+ const selectedSurfacePolygon = polygonToTurfPolygon(selectedSurface)
- // //지붕 밖으로 그렸을때
- // if (!turf.booleanWithin(trianglePolygon, selectedSurfacePolygon)) {
- // swalFire({ text: '개구를 배치할 수 없습니다.', icon: 'error' })
- // //일단 지워
- // deleteTempObjects()
- // return
- // }
+ //지붕 밖으로 그렸을때
+ if (!turf.booleanWithin(trianglePolygon, selectedSurfacePolygon)) {
+ swalFire({ text: '개구를 배치할 수 없습니다.', icon: 'error' })
+ //일단 지워
+ deleteTempObjects()
+ return
+ }
//각도 추가
let originAngle = 0 //기본 남쪽
@@ -387,6 +380,183 @@ export function useObjectBatch() {
drawDirectionArrow(leftTriangle)
drawDirectionArrow(rightTriangle)
+ isDown = false
+ initEvent()
+ }
+ })
+ } else if (buttonAct === 4) {
+ const heightLength = height - (width / 2) * (pitch * 0.25)
+ //(동의길이 깊이)+출폭(깊이)-[(입력한 폭값)/2+출폭(폭)]*(0.25*입력한 寸)
+ const heightOffsetLength = height + offsetRef - (width / 2 + offsetWidthRef) * (pitch * 0.25)
+
+ addCanvasMouseEventListener('mouse:move', (e) => {
+ isDown = true
+ if (!isDown) return
+
+ canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === dormerTempName)) //움직일때 일단 지워가면서 움직임
+ const pointer = canvas.getPointer(e.e)
+
+ surfaceShapePolygons.forEach((surface) => {
+ if (surface.inPolygon({ x: pointer.x, y: pointer.y })) {
+ selectedSurface = surface
+ }
+ })
+
+ let angle = 0
+ if (directionRef === 'left') {
+ //서
+ angle = 90
+ } else if (directionRef === 'right') {
+ //동
+ angle = 270
+ } else if (directionRef === 'up') {
+ //북
+ angle = 180
+ }
+
+ pentagonPoints = [
+ { x: pointer.x, y: pointer.y },
+ { x: pointer.x - width / 2, y: pointer.y + (height - heightLength) },
+ { x: pointer.x - width / 2, y: pointer.y + height },
+ { x: pointer.x + width / 2, y: pointer.y + height },
+ { x: pointer.x + width / 2, y: pointer.y + (height - heightLength) },
+ ]
+
+ pentagonOffsetPoints = [
+ { x: pointer.x, y: pointer.y },
+ { x: pointer.x - width / 2 - offsetWidthRef, y: pointer.y + height + offsetRef - heightOffsetLength },
+ { x: pointer.x - width / 2 - offsetWidthRef, y: pointer.y + height + offsetRef },
+ { x: pointer.x + width / 2 + offsetWidthRef, y: pointer.y + height + offsetRef },
+ { x: pointer.x + width / 2 + offsetWidthRef, y: pointer.y + height + offsetRef - heightOffsetLength },
+ ]
+
+ dormer = new QPolygon(pentagonPoints, {
+ fill: 'white',
+ stroke: 'red',
+ strokeDashArray: [5, 5],
+ strokeWidth: 1,
+ selectable: true,
+ lockMovementX: true,
+ lockMovementY: true,
+ lockRotation: true,
+ lockScalingX: true,
+ lockScalingY: true,
+ name: dormerTempName,
+ originX: 'center',
+ originY: 'top',
+ angle: angle,
+ })
+ canvas?.add(dormer)
+
+ if (offsetRef > 0 || offsetWidthRef > 0) {
+ dormerOffset = new QPolygon(pentagonOffsetPoints, {
+ fill: 'gray',
+ stroke: 'red',
+ strokeDashArray: [5, 5],
+ strokeWidth: 1,
+ selectable: true,
+ lockMovementX: true,
+ lockMovementY: true,
+ lockRotation: true,
+ lockScalingX: true,
+ lockScalingY: true,
+ name: dormerTempName,
+ originX: 'center',
+ originY: 'top',
+ angle: angle,
+ })
+ canvas?.add(dormerOffset)
+ }
+ })
+
+ addCanvasMouseEventListener('mouse:up', (e) => {
+ if (dormer) {
+ // const trianglePolygon = pointsToTurfPolygon(triangleToPolygon(dormer))
+ // const selectedSurfacePolygon = polygonToTurfPolygon(selectedSurface)
+
+ // //지붕 밖으로 그렸을때
+ // if (!turf.booleanWithin(trianglePolygon, selectedSurfacePolygon)) {
+ // swalFire({ text: '개구를 배치할 수 없습니다.', icon: 'error' })
+ // //일단 지워
+ // deleteTempObjects()
+ // return
+ // }
+
+ //각도 추가
+ let originAngle = 0 //기본 남쪽
+ let direction = 'south'
+
+ if (directionRef === 'left') {
+ //서
+ originAngle = 90
+ direction = 'west'
+ } else if (directionRef === 'right') {
+ //동
+ originAngle = 270
+ direction = 'east'
+ } else if (directionRef === 'up') {
+ //북
+ originAngle = 180
+ direction = 'north'
+ }
+
+ const offsetMode = offsetRef > 0 || offsetWidthRef > 0 ? 'offset' : 'normal'
+ let splitedPentagon =
+ offsetRef > 0 || offsetWidthRef > 0
+ ? splitDormerPentagon(dormerOffset, directionRef, offsetMode)
+ : splitDormerPentagon(dormer, directionRef, offsetMode)
+ canvas?.remove(offsetRef > 0 || offsetWidthRef > 0 ? dormerOffset : dormer)
+
+ if (offsetRef > 0)
+ dormer.set({
+ name: dormerName,
+ stroke: 'black',
+ strokeWidth: 1,
+ strokeDashArray: [0],
+ }) //오프셋이 있을땐 같이 도머로 만든다
+
+ const leftPentagon = new QPolygon(splitedPentagon[0], {
+ fill: 'transparent',
+ stroke: 'red',
+ strokeWidth: 1,
+ selectable: true,
+ lockMovementX: true, // X 축 이동 잠금
+ lockMovementY: true, // Y 축 이동 잠금
+ lockRotation: true, // 회전 잠금
+ viewLengthText: true,
+ fontSize: 14,
+ direction: direction,
+ originX: 'center',
+ originY: 'center',
+ name: dormerName,
+ })
+
+ const rightPentagon = new QPolygon(splitedPentagon[1], {
+ fill: 'transparent',
+ stroke: 'red',
+ strokeWidth: 1,
+ selectable: true,
+ lockMovementX: true, // X 축 이동 잠금
+ lockMovementY: true, // Y 축 이동 잠금
+ lockRotation: true, // 회전 잠금
+ viewLengthText: true,
+ fontSize: 14,
+ direction: direction,
+ originX: 'center',
+ originY: 'center',
+ name: dormerName,
+ })
+
+ canvas?.add(leftPentagon)
+ canvas?.add(rightPentagon)
+
+ //패턴
+ setSurfaceShapePattern(leftPentagon)
+ setSurfaceShapePattern(rightPentagon)
+ //방향
+ drawDirectionArrow(leftPentagon)
+ drawDirectionArrow(rightPentagon)
+
isDown = false
initEvent()
}
@@ -408,8 +578,140 @@ export function useObjectBatch() {
initEvent() //이벤트 초기화
}
+ const splitDormerTriangle = (triangle, direction) => {
+ const halfWidth = triangle.width / 2
+
+ let leftPoints = []
+ let rightPoints = []
+
+ if (direction === 'down') {
+ leftPoints = [
+ { x: triangle.left, y: triangle.top },
+ { x: triangle.left - halfWidth, y: triangle.top + triangle.height },
+ { x: triangle.left, y: triangle.top + triangle.height },
+ ]
+
+ rightPoints = [
+ { x: triangle.left, y: triangle.top },
+ { x: triangle.left, y: triangle.top + triangle.height },
+ { x: triangle.left + halfWidth, y: triangle.top + triangle.height },
+ ]
+ } else if (direction === 'up') {
+ leftPoints = [
+ { x: triangle.left, y: triangle.top },
+ { x: triangle.left - halfWidth, y: triangle.top - triangle.height },
+ { x: triangle.left, y: triangle.top - triangle.height },
+ ]
+
+ rightPoints = [
+ { x: triangle.left, y: triangle.top },
+ { x: triangle.left, y: triangle.top - triangle.height },
+ { x: triangle.left + halfWidth, y: triangle.top - triangle.height },
+ ]
+ } else if (direction === 'left') {
+ leftPoints = [
+ { x: triangle.left, y: triangle.top },
+ { x: triangle.left - triangle.height, y: triangle.top - halfWidth },
+ { x: triangle.left - triangle.height, y: triangle.top },
+ ]
+
+ rightPoints = [
+ { x: triangle.left, y: triangle.top },
+ { x: triangle.left - triangle.height, y: triangle.top },
+ { x: triangle.left - triangle.height, y: triangle.top + halfWidth },
+ ]
+ } else if (direction === 'right') {
+ leftPoints = [
+ { x: triangle.left, y: triangle.top },
+ { x: triangle.left + triangle.height, y: triangle.top },
+ { x: triangle.left + triangle.height, y: triangle.top + triangle.height },
+ ]
+
+ rightPoints = [
+ { x: triangle.left, y: triangle.top },
+ { x: triangle.left + triangle.height, y: triangle.top },
+ { x: triangle.left + triangle.height, y: triangle.top - triangle.height },
+ ]
+ }
+
+ return [leftPoints, rightPoints]
+ }
+
+ const splitDormerPentagon = (pentagon, direction, offsetMode) => {
+ const points = pentagon.points
+
+ console.log(pentagon.points)
+
+ let leftPoints = []
+ let rightPoints = []
+
+ if (direction === 'down') {
+ leftPoints = [
+ { x: points[0].x, y: points[0].y },
+ { x: points[1].x, y: points[1].y },
+ { x: points[2].x, y: points[2].y },
+ { x: points[0].x, y: points[3].y },
+ ]
+
+ rightPoints = [
+ { x: points[0].x, y: points[0].y },
+ { x: points[0].x, y: points[2].y },
+ { x: points[3].x, y: points[3].y },
+ { x: points[4].x, y: points[4].y },
+ ]
+ } else if (direction === 'up') {
+ leftPoints = [
+ { x: points[0].x, y: points[0].y },
+ { x: points[1].x, y: points[0].y - (points[1].y - points[0].y) },
+ { x: points[2].x, y: points[0].y - (points[2].y - points[0].y) },
+ { x: points[0].x, y: points[0].y - (points[2].y - points[0].y) },
+ ]
+
+ rightPoints = [
+ { x: points[0].x, y: points[0].y },
+ { x: points[3].x, y: points[0].y - (points[1].y - points[0].y) },
+ { x: points[3].x, y: points[0].y - (points[2].y - points[0].y) },
+ { x: points[0].x, y: points[0].y - (points[2].y - points[0].y) },
+ ]
+ } else if (direction === 'left') {
+ leftPoints = [
+ { x: points[0].x, y: points[0].y },
+ { x: points[0].x - (points[1].y - points[0].y), y: points[0].y - (points[0].x - points[1].x) },
+ { x: points[0].x - (points[1].y - points[0].y) - (points[2].y - points[1].y), y: points[0].y - (points[0].x - points[1].x) },
+ { x: points[0].x - (points[1].y - points[0].y) - (points[2].y - points[1].y), y: points[0].y },
+ ]
+
+ rightPoints = [
+ { x: points[0].x, y: points[0].y },
+ { x: points[0].x - (points[1].y - points[0].y), y: points[0].y + (points[0].x - points[1].x) },
+ { x: points[0].x - (points[1].y - points[0].y) - (points[2].y - points[1].y), y: points[0].y + (points[0].x - points[1].x) },
+ { x: points[0].x - (points[1].y - points[0].y) - (points[2].y - points[1].y), y: points[0].y },
+ ]
+ } else if (direction === 'right') {
+ leftPoints = [
+ { x: points[0].x, y: points[0].y },
+ { x: points[0].x + (points[1].y - points[0].y), y: points[0].y + (points[0].x - points[1].x) },
+ { x: points[0].x + (points[1].y - points[0].y) + (points[2].y - points[1].y), y: points[0].y + (points[0].x - points[1].x) },
+ { x: points[0].x + (points[1].y - points[0].y) + (points[2].y - points[1].y), y: points[0].y },
+ ]
+
+ rightPoints = [
+ { x: points[0].x, y: points[0].y },
+ { x: points[0].x + (points[1].y - points[0].y), y: points[0].y - (points[0].x - points[1].x) },
+ { x: points[0].x + (points[1].y - points[0].y) + (points[2].y - points[1].y), y: points[0].y - (points[0].x - points[1].x) },
+ { x: points[0].x + (points[1].y - points[0].y) + (points[2].y - points[1].y), y: points[0].y },
+ ]
+ }
+
+ console.log(leftPoints, rightPoints)
+
+ return [leftPoints, rightPoints]
+ }
+
return {
applyOpeningAndShadow,
applyDormers,
+ splitDormerTriangle,
+ splitDormerPentagon,
}
}
diff --git a/src/util/canvas-util.js b/src/util/canvas-util.js
index 17c30f07..20b6ec66 100644
--- a/src/util/canvas-util.js
+++ b/src/util/canvas-util.js
@@ -744,67 +744,6 @@ export const polygonToTurfPolygon = (polygon) => {
)
}
-export const splitDormerTriangle = (triangle, direction) => {
- const halfWidth = triangle.width / 2
-
- let leftPoints = []
- let rightPoints = []
- let leftPointOffset = []
- let rightPointOffset = []
-
- if (direction === 'down') {
- leftPoints = [
- { x: triangle.left, y: triangle.top },
- { x: triangle.left - halfWidth, y: triangle.top + triangle.height },
- { x: triangle.left, y: triangle.top + triangle.height },
- ]
-
- rightPoints = [
- { x: triangle.left, y: triangle.top },
- { x: triangle.left, y: triangle.top + triangle.height },
- { x: triangle.left + halfWidth, y: triangle.top + triangle.height },
- ]
- } else if (direction === 'up') {
- leftPoints = [
- { x: triangle.left, y: triangle.top },
- { x: triangle.left - halfWidth, y: triangle.top - triangle.height },
- { x: triangle.left, y: triangle.top - triangle.height },
- ]
-
- rightPoints = [
- { x: triangle.left, y: triangle.top },
- { x: triangle.left, y: triangle.top - triangle.height },
- { x: triangle.left + halfWidth, y: triangle.top - triangle.height },
- ]
- } else if (direction === 'left') {
- leftPoints = [
- { x: triangle.left, y: triangle.top },
- { x: triangle.left - triangle.height, y: triangle.top - halfWidth },
- { x: triangle.left - triangle.height, y: triangle.top },
- ]
-
- rightPoints = [
- { x: triangle.left, y: triangle.top },
- { x: triangle.left - triangle.height, y: triangle.top },
- { x: triangle.left - triangle.height, y: triangle.top + halfWidth },
- ]
- } else if (direction === 'right') {
- leftPoints = [
- { x: triangle.left, y: triangle.top },
- { x: triangle.left + triangle.height, y: triangle.top },
- { x: triangle.left + triangle.height, y: triangle.top + triangle.height },
- ]
-
- rightPoints = [
- { x: triangle.left, y: triangle.top },
- { x: triangle.left + triangle.height, y: triangle.top },
- { x: triangle.left + triangle.height, y: triangle.top - triangle.height },
- ]
- }
-
- return [leftPoints, rightPoints]
-}
-
export const triangleToPolygon = (triangle) => {
const points = []
const halfWidth = triangle.width / 2
@@ -853,7 +792,7 @@ export function setSurfaceShapePattern(polygon) {
patternSourceCanvas.width = polygon.width * ratio
patternSourceCanvas.height = polygon.height * ratio
const ctx = patternSourceCanvas.getContext('2d')
- const offset = roofStyle === 1 ? 0 : patternSize.width / 2
+ let offset = roofStyle === 1 ? 0 : patternSize.width / 2
const rows = Math.floor(patternSourceCanvas.height / patternSize.height)
const cols = Math.floor(patternSourceCanvas.width / patternSize.width)
@@ -861,23 +800,46 @@ export function setSurfaceShapePattern(polygon) {
ctx.strokeStyle = 'green'
ctx.lineWidth = 0.4
- for (let row = 0; row <= rows; row++) {
- const y = row * patternSize.height
-
- ctx.beginPath()
- ctx.moveTo(0, y) // 선 시작점
- ctx.lineTo(patternSourceCanvas.width, y) // 선 끝점
- ctx.stroke()
-
+ if (polygon.direction === 'east' || polygon.direction === 'west') {
+ offset = roofStyle === 1 ? 0 : patternSize.height / 2
for (let col = 0; col <= cols; col++) {
- const x = col * patternSize.width + (row % 2 === 0 ? 0 : offset)
- const yStart = row * patternSize.height
- const yEnd = yStart + patternSize.height
-
+ const x = col * patternSize.width
+ const yStart = 0
+ const yEnd = patternSourceCanvas.height
ctx.beginPath()
ctx.moveTo(x, yStart) // 선 시작점
ctx.lineTo(x, yEnd) // 선 끝점
ctx.stroke()
+
+ for (let row = 0; row <= rows; row++) {
+ const y = row * patternSize.height + (col % 2 === 0 ? 0 : offset)
+ const xStart = col * patternSize.width
+ const xEnd = xStart + patternSize.width
+ ctx.beginPath()
+ ctx.moveTo(xStart, y) // 선 시작점
+ ctx.lineTo(xEnd, y) // 선 끝점
+ ctx.stroke()
+ }
+ }
+ } else {
+ for (let row = 0; row <= rows; row++) {
+ const y = row * patternSize.height
+
+ ctx.beginPath()
+ ctx.moveTo(0, y) // 선 시작점
+ ctx.lineTo(patternSourceCanvas.width, y) // 선 끝점
+ ctx.stroke()
+
+ for (let col = 0; col <= cols; col++) {
+ const x = col * patternSize.width + (row % 2 === 0 ? 0 : offset)
+ const yStart = row * patternSize.height
+ const yEnd = yStart + patternSize.height
+
+ ctx.beginPath()
+ ctx.moveTo(x, yStart) // 선 시작점
+ ctx.lineTo(x, yEnd) // 선 끝점
+ ctx.stroke()
+ }
}
}