지붕타입 지붕재, 지붕 배터리 추가
This commit is contained in:
parent
3a9ef49e4c
commit
8f051d541b
@ -6,7 +6,7 @@ import QRect from '@/components/fabric/QRect'
|
|||||||
|
|
||||||
import RangeSlider from './ui/RangeSlider'
|
import RangeSlider from './ui/RangeSlider'
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||||
import { canvasSizeState, fontSizeState, roofState, sortedPolygonArray } from '@/store/canvasAtom'
|
import { canvasSizeState, fontSizeState, roofMaterialState, roofState, sortedPolygonArray } from '@/store/canvasAtom'
|
||||||
import { QLine } from '@/components/fabric/QLine'
|
import { QLine } from '@/components/fabric/QLine'
|
||||||
import { getCanvasState, insertCanvasState } from '@/lib/canvas'
|
import { getCanvasState, insertCanvasState } from '@/lib/canvas'
|
||||||
import { calculateIntersection } from '@/util/canvas-util'
|
import { calculateIntersection } from '@/util/canvas-util'
|
||||||
@ -31,7 +31,8 @@ export default function Roof2() {
|
|||||||
|
|
||||||
const [showControl, setShowControl] = useState(false)
|
const [showControl, setShowControl] = useState(false)
|
||||||
|
|
||||||
const roof = useRecoilValue(roofState)
|
//지붕재
|
||||||
|
const roofMaterial = useRecoilValue(roofMaterialState)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
mode,
|
mode,
|
||||||
@ -138,12 +139,12 @@ export default function Roof2() {
|
|||||||
{ x: 100, y: 400 },
|
{ x: 100, y: 400 },
|
||||||
]
|
]
|
||||||
const type2 = [
|
const type2 = [
|
||||||
{ x: 100, y: 100 },
|
{ x: 200, y: 100 },
|
||||||
{ x: 100, y: 1000 },
|
{ x: 200, y: 1000 },
|
||||||
{ x: 1000, y: 1000 },
|
{ x: 1100, y: 1000 },
|
||||||
{ x: 1000, y: 600 },
|
{ x: 1100, y: 600 },
|
||||||
{ x: 550, y: 600 },
|
{ x: 650, y: 600 },
|
||||||
{ x: 550, y: 100 },
|
{ x: 650, y: 100 },
|
||||||
]
|
]
|
||||||
|
|
||||||
const type3 = [
|
const type3 = [
|
||||||
@ -263,58 +264,17 @@ export default function Roof2() {
|
|||||||
{ x: 675, y: 275 },
|
{ x: 675, y: 275 },
|
||||||
{ x: 450, y: 850 },
|
{ x: 450, y: 850 },
|
||||||
]
|
]
|
||||||
const polygon = new QPolygon(type4, {
|
const polygon = new QPolygon(type2, {
|
||||||
fill: 'transparent',
|
fill: 'transparent',
|
||||||
stroke: 'black',
|
stroke: 'black',
|
||||||
strokeWidth: 1,
|
strokeWidth: 1,
|
||||||
selectable: false,
|
selectable: false,
|
||||||
fontSize: fontSize,
|
fontSize: fontSize,
|
||||||
name: 'QPolygon1',
|
name: 'wall',
|
||||||
})
|
})
|
||||||
|
|
||||||
canvas?.add(polygon)
|
canvas?.add(polygon)
|
||||||
|
|
||||||
polygon.set('strokeDashArray', [10, 5, 2, 5])
|
|
||||||
polygon.set('stroke', 'blue')
|
|
||||||
polygon.set('strokeWidth', 1)
|
|
||||||
|
|
||||||
// const newPolygon = fabric.util.clone(polygon)
|
|
||||||
|
|
||||||
handleOuterlinesTest2(polygon)
|
handleOuterlinesTest2(polygon)
|
||||||
|
|
||||||
const roofs = canvas?.getObjects().filter((obj) => obj.name === 'roof')
|
|
||||||
|
|
||||||
roofs.forEach((roof) => {
|
|
||||||
let maxLengthLine = roof.lines.reduce((acc, cur) => {
|
|
||||||
return acc.length > cur.length ? acc : cur
|
|
||||||
})
|
|
||||||
|
|
||||||
// 패턴 소스를 위한 임시 캔버스 생성
|
|
||||||
const patternSourceCanvas = document.createElement('canvas')
|
|
||||||
if (maxLengthLine.direction === 'right' || maxLengthLine.direction === 'left') {
|
|
||||||
patternSourceCanvas.width = 20 * window.devicePixelRatio || 1
|
|
||||||
patternSourceCanvas.height = 10 * window.devicePixelRatio || 1
|
|
||||||
} else {
|
|
||||||
patternSourceCanvas.width = 10 * window.devicePixelRatio || 1
|
|
||||||
patternSourceCanvas.height = 20 * window.devicePixelRatio || 1
|
|
||||||
}
|
|
||||||
|
|
||||||
const ctx = patternSourceCanvas.getContext('2d')
|
|
||||||
|
|
||||||
// 벽돌 패턴 그리기
|
|
||||||
ctx.scale(window.devicePixelRatio || 1, window.devicePixelRatio || 1)
|
|
||||||
ctx.strokeStyle = 'green'
|
|
||||||
ctx.lineWidth = 0.4
|
|
||||||
ctx.strokeRect(0, 0, 100, 100)
|
|
||||||
// 패턴 생성
|
|
||||||
const pattern = new fabric.Pattern({
|
|
||||||
source: patternSourceCanvas,
|
|
||||||
repeat: 'repeat',
|
|
||||||
})
|
|
||||||
|
|
||||||
roof.set('fill', pattern)
|
|
||||||
})
|
|
||||||
|
|
||||||
// const lines = togglePolygonLine(polygon)
|
// const lines = togglePolygonLine(polygon)
|
||||||
// togglePolygonLine(lines[0])
|
// togglePolygonLine(lines[0])
|
||||||
}
|
}
|
||||||
@ -404,6 +364,70 @@ export default function Roof2() {
|
|||||||
handleClear()
|
handleClear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const drawRoofMaterial = () => {
|
||||||
|
const { width, height, roofStyle } = roofMaterial
|
||||||
|
|
||||||
|
const wallPolygon = canvas?.getObjects().find((obj) => obj.name === 'wall')
|
||||||
|
|
||||||
|
wallPolygon.set('strokeDashArray', [10, 5, 2, 5])
|
||||||
|
wallPolygon.set('stroke', 'blue')
|
||||||
|
wallPolygon.set('strokeWidth', 1)
|
||||||
|
|
||||||
|
const roofs = canvas?.getObjects().filter((obj) => obj.name === 'roof')
|
||||||
|
|
||||||
|
roofs.forEach((roof) => {
|
||||||
|
let maxLengthLine = roof.lines.reduce((acc, cur) => {
|
||||||
|
return acc.length > cur.length ? acc : cur
|
||||||
|
})
|
||||||
|
|
||||||
|
const roofRatio = window.devicePixelRatio || 1
|
||||||
|
|
||||||
|
// 패턴 소스를 위한 임시 캔버스 생성
|
||||||
|
const patternSourceCanvas = document.createElement('canvas')
|
||||||
|
if (roofStyle === 1) {
|
||||||
|
if (maxLengthLine.direction === 'right' || maxLengthLine.direction === 'left') {
|
||||||
|
patternSourceCanvas.width = width * roofRatio
|
||||||
|
patternSourceCanvas.height = height * roofRatio
|
||||||
|
} else {
|
||||||
|
patternSourceCanvas.width = height * roofRatio
|
||||||
|
patternSourceCanvas.height = width * roofRatio
|
||||||
|
}
|
||||||
|
} else if (roofStyle === 2) {
|
||||||
|
if (maxLengthLine.direction === 'right' || maxLengthLine.direction === 'left') {
|
||||||
|
patternSourceCanvas.width = width * 2
|
||||||
|
patternSourceCanvas.height = height * 2
|
||||||
|
} else {
|
||||||
|
patternSourceCanvas.width = height * 2
|
||||||
|
patternSourceCanvas.height = width * 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ctx = patternSourceCanvas.getContext('2d')
|
||||||
|
|
||||||
|
ctx.scale(roofRatio, roofRatio)
|
||||||
|
ctx.strokeStyle = 'green'
|
||||||
|
ctx.lineWidth = 0.4
|
||||||
|
// 벽돌 패턴 그리기
|
||||||
|
if (roofStyle === 1) {
|
||||||
|
ctx.strokeRect(0, 0, 50, 30)
|
||||||
|
} else if (roofStyle === 2) {
|
||||||
|
// 지그재그
|
||||||
|
ctx.strokeRect(0, 0, 200, 100)
|
||||||
|
ctx.strokeRect(100, 100, 200, 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 패턴 생성
|
||||||
|
const pattern = new fabric.Pattern({
|
||||||
|
source: patternSourceCanvas,
|
||||||
|
repeat: 'repeat',
|
||||||
|
})
|
||||||
|
roof.set('fill', null)
|
||||||
|
|
||||||
|
roof.set('fill', pattern)
|
||||||
|
canvas?.renderAll()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* canvas 내용 불러오기
|
* canvas 내용 불러오기
|
||||||
*/
|
*/
|
||||||
@ -424,6 +448,21 @@ export default function Roof2() {
|
|||||||
makeRoofPatternPolygon(roofStyle)
|
makeRoofPatternPolygon(roofStyle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const createRoofRack = () => {
|
||||||
|
const roofs = canvas?.getObjects().filter((obj) => obj.name === 'roof')
|
||||||
|
roofs.forEach((roof) => {
|
||||||
|
let maxLengthLine = roof.lines.reduce((acc, cur) => {
|
||||||
|
return acc.length > cur.length ? acc : cur
|
||||||
|
})
|
||||||
|
|
||||||
|
if (maxLengthLine.direction === 'right' || maxLengthLine.direction === 'left') {
|
||||||
|
roof.fillCell({ width: 50, height: 100, padding: 0 })
|
||||||
|
} else {
|
||||||
|
roof.fillCell({ width: 100, height: 50, padding: 0 })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{canvas && (
|
{canvas && (
|
||||||
@ -530,6 +569,12 @@ export default function Roof2() {
|
|||||||
<Button className="m-1 p-2" onClick={addCanvas}>
|
<Button className="m-1 p-2" onClick={addCanvas}>
|
||||||
캔버스 추가
|
캔버스 추가
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button className="m-1 p-2" onClick={drawRoofMaterial}>
|
||||||
|
지붕타입 지붕재
|
||||||
|
</Button>
|
||||||
|
<Button className="m-1 p-2" onClick={createRoofRack}>
|
||||||
|
지붕가대
|
||||||
|
</Button>
|
||||||
<Button className="m-1 p-2" color={`${showControl ? 'primary' : 'default'}`} onClick={handleShowController}>
|
<Button className="m-1 p-2" color={`${showControl ? 'primary' : 'default'}`} onClick={handleShowController}>
|
||||||
canvas 컨트롤러 {`${showControl ? '숨기기' : '보이기'}`}
|
canvas 컨트롤러 {`${showControl ? '숨기기' : '보이기'}`}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@ -234,7 +234,6 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
|||||||
{ x: rectLeft, y: rectTop + rectHeight },
|
{ x: rectLeft, y: rectTop + rectHeight },
|
||||||
{ x: rectLeft + rectWidth, y: rectTop + rectHeight },
|
{ x: rectLeft + rectWidth, y: rectTop + rectHeight },
|
||||||
]
|
]
|
||||||
|
|
||||||
const allPointsInside = rectPoints.every((point) => this.inPolygon(point))
|
const allPointsInside = rectPoints.every((point) => this.inPolygon(point))
|
||||||
|
|
||||||
if (allPointsInside) {
|
if (allPointsInside) {
|
||||||
@ -244,6 +243,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
|||||||
width: rectWidth,
|
width: rectWidth,
|
||||||
height: rectHeight,
|
height: rectHeight,
|
||||||
fill: '#BFFD9F',
|
fill: '#BFFD9F',
|
||||||
|
stroke: 'black',
|
||||||
selectable: true, // 선택 가능하게 설정
|
selectable: true, // 선택 가능하게 설정
|
||||||
lockMovementX: true, // X 축 이동 잠금
|
lockMovementX: true, // X 축 이동 잠금
|
||||||
lockMovementY: true, // Y 축 이동 잠금
|
lockMovementY: true, // Y 축 이동 잠금
|
||||||
@ -261,7 +261,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
|||||||
return drawCellsArray
|
return drawCellsArray
|
||||||
},
|
},
|
||||||
inPolygon(point) {
|
inPolygon(point) {
|
||||||
const vertices = this.getCurrentPoints()
|
const vertices = this.points
|
||||||
let intersects = 0
|
let intersects = 0
|
||||||
|
|
||||||
for (let i = 0; i < vertices.length; i++) {
|
for (let i = 0; i < vertices.length; i++) {
|
||||||
|
|||||||
@ -60,3 +60,10 @@ export const drewRoofCellsState = atom({
|
|||||||
default: [],
|
default: [],
|
||||||
dangerouslyAllowMutability: true,
|
dangerouslyAllowMutability: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 지붕재 width, height, rafter(서까래), roofStyle을 갖고있고 roofStyle 1은 정방향, 2는 지그재그
|
||||||
|
export const roofMaterialState = atom({
|
||||||
|
key: 'roofMaterial',
|
||||||
|
default: { width: 20, height: 10, rafter: 0, roofStyle: 2 },
|
||||||
|
dangerouslyAllowMutability: true,
|
||||||
|
})
|
||||||
|
|||||||
@ -499,6 +499,10 @@ export const dividePolygon = (polygon) => {
|
|||||||
const startHip = hips.find((hip) => hip.startPoint.x === startPoint.x && hip.startPoint.y === startPoint.y)
|
const startHip = hips.find((hip) => hip.startPoint.x === startPoint.x && hip.startPoint.y === startPoint.y)
|
||||||
const endHip = hips.find((hip) => hip.startPoint.x === endPoint.x && hip.startPoint.y === endPoint.y)
|
const endHip = hips.find((hip) => hip.startPoint.x === endPoint.x && hip.startPoint.y === endPoint.y)
|
||||||
|
|
||||||
|
if (!startHip || !endHip) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (startHip && endHip && startHip.endPoint.x === endHip.endPoint.x && startHip.endPoint.y === endHip.endPoint.y) {
|
if (startHip && endHip && startHip.endPoint.x === endHip.endPoint.x && startHip.endPoint.y === endHip.endPoint.y) {
|
||||||
polygonPoints.push(startHip.endPoint)
|
polygonPoints.push(startHip.endPoint)
|
||||||
|
|
||||||
@ -506,7 +510,7 @@ export const dividePolygon = (polygon) => {
|
|||||||
fontSize: polygon.fontSize,
|
fontSize: polygon.fontSize,
|
||||||
id: polygon.id,
|
id: polygon.id,
|
||||||
name: 'roof',
|
name: 'roof',
|
||||||
selectable: true,
|
selectable: false,
|
||||||
stroke: 'black',
|
stroke: 'black',
|
||||||
fill: 'transparent',
|
fill: 'transparent',
|
||||||
strokeWidth: 3,
|
strokeWidth: 3,
|
||||||
@ -535,7 +539,7 @@ export const dividePolygon = (polygon) => {
|
|||||||
fontSize: polygon.fontSize,
|
fontSize: polygon.fontSize,
|
||||||
id: polygon.id,
|
id: polygon.id,
|
||||||
name: 'roof',
|
name: 'roof',
|
||||||
selectable: true,
|
selectable: false,
|
||||||
stroke: 'black',
|
stroke: 'black',
|
||||||
fill: 'transparent',
|
fill: 'transparent',
|
||||||
strokeWidth: 3,
|
strokeWidth: 3,
|
||||||
@ -553,7 +557,7 @@ export const dividePolygon = (polygon) => {
|
|||||||
fontSize: polygon.fontSize,
|
fontSize: polygon.fontSize,
|
||||||
id: polygon.id,
|
id: polygon.id,
|
||||||
name: 'roof',
|
name: 'roof',
|
||||||
selectable: true,
|
selectable: false,
|
||||||
stroke: 'black',
|
stroke: 'black',
|
||||||
fill: 'transparent',
|
fill: 'transparent',
|
||||||
strokeWidth: 3,
|
strokeWidth: 3,
|
||||||
@ -628,7 +632,7 @@ export const dividePolygon = (polygon) => {
|
|||||||
fontSize: polygon.fontSize,
|
fontSize: polygon.fontSize,
|
||||||
id: polygon.id,
|
id: polygon.id,
|
||||||
name: 'roof',
|
name: 'roof',
|
||||||
selectable: true,
|
selectable: false,
|
||||||
stroke: 'black',
|
stroke: 'black',
|
||||||
fill: 'transparent',
|
fill: 'transparent',
|
||||||
strokeWidth: 3,
|
strokeWidth: 3,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user