삼각도머
This commit is contained in:
parent
652516146b
commit
8fb523cf3d
@ -5,7 +5,14 @@ import { useRecoilValue } from 'recoil'
|
||||
import { canvasState } from '@/store/canvasAtom'
|
||||
import { BATCH_TYPE, INPUT_TYPE, POLYGON_TYPE } from '@/common/common'
|
||||
import { useEvent } from '@/hooks/useEvent'
|
||||
import { pointsToTurfPolygon, polygonToTurfPolygon, rectToPolygon, triangleToPolygon, getDegreeByChon } from '@/util/canvas-util'
|
||||
import {
|
||||
pointsToTurfPolygon,
|
||||
polygonToTurfPolygon,
|
||||
rectToPolygon,
|
||||
triangleToPolygon,
|
||||
getDegreeByChon,
|
||||
toFixedWithoutRounding,
|
||||
} from '@/util/canvas-util'
|
||||
import { useSwal } from '@/hooks/useSwal'
|
||||
import * as turf from '@turf/turf'
|
||||
import { usePolygon } from '@/hooks/usePolygon'
|
||||
@ -13,6 +20,7 @@ import { QPolygon } from '@/components/fabric/QPolygon'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { fontSelector } from '@/store/fontAtom'
|
||||
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
||||
import { roofDisplaySelector } from '@/store/settingAtom'
|
||||
|
||||
export function useObjectBatch({ isHidden, setIsHidden }) {
|
||||
const { getMessage } = useMessage()
|
||||
@ -23,6 +31,9 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
|
||||
const { drawDirectionArrow } = usePolygon()
|
||||
const { setSurfaceShapePattern } = useRoofFn()
|
||||
const lengthTextFont = useRecoilValue(fontSelector('lengthText'))
|
||||
const roofDisplay = useRecoilValue(roofDisplaySelector)
|
||||
|
||||
const { addPolygon } = usePolygon()
|
||||
|
||||
useEffect(() => {
|
||||
if (canvas) {
|
||||
@ -293,6 +304,15 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
|
||||
if (buttonAct === 3) {
|
||||
let groupDormerPoints = [] //나중에 offset을 위한 포인트 저장용
|
||||
|
||||
let bottomLength = 0,
|
||||
bottomOffsetLength = 0,
|
||||
planeHypotenuse = 0,
|
||||
planeOffsetHypotenuse = 0,
|
||||
actualBottomLength = 0,
|
||||
actualBottomOffsetLength = 0,
|
||||
actualHypotenuse = 0,
|
||||
actualOffsetHypotenuse = 0
|
||||
|
||||
addCanvasMouseEventListener('mouse:move', (e) => {
|
||||
isDown = true
|
||||
if (!isDown) return
|
||||
@ -306,57 +326,51 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
|
||||
}
|
||||
})
|
||||
|
||||
console.log('selectedSurface', selectedSurface)
|
||||
if (selectedSurface) {
|
||||
const roofAngle = selectedSurface.roofMaterial.angle
|
||||
|
||||
const roofAngle = selectedSurface.roofMaterial.angle
|
||||
theta = Math.atan(Math.tan((roofAngle * Math.PI) / 180) / Math.tan((dormerAngle * Math.PI) / 180))
|
||||
|
||||
theta = Math.atan(Math.tan((roofAngle * Math.PI) / 180) / Math.tan((dormerAngle * Math.PI) / 180))
|
||||
//센터 삼각형용
|
||||
bottomLength = Number((Math.tan(theta) * height).toFixed())
|
||||
|
||||
const bottomLength = Number((Math.tan(theta) * height).toFixed())
|
||||
const bottomOffsetLength = Number((Math.tan(theta) * (height + offsetRef)).toFixed())
|
||||
//좌우 삼각형용
|
||||
bottomOffsetLength = Number((Math.tan(theta) * (height + offsetRef)).toFixed())
|
||||
|
||||
let angle = 0
|
||||
if (directionRef === 'left') {
|
||||
//서
|
||||
angle = 90
|
||||
} else if (directionRef === 'right') {
|
||||
//동
|
||||
angle = 270
|
||||
} else if (directionRef === 'up') {
|
||||
//북
|
||||
angle = 180
|
||||
}
|
||||
planeHypotenuse = Math.sqrt(Math.pow(height, 2) + Math.pow(bottomLength, 2))
|
||||
|
||||
dormer = new fabric.Triangle({
|
||||
fill: 'white',
|
||||
stroke: 'red',
|
||||
strokeDashArray: [5, 5],
|
||||
strokeWidth: 1,
|
||||
width: bottomLength * 2,
|
||||
height: height,
|
||||
left: pointer.x,
|
||||
top: pointer.y,
|
||||
selectable: true,
|
||||
lockMovementX: true,
|
||||
lockMovementY: true,
|
||||
lockRotation: true,
|
||||
lockScalingX: true,
|
||||
lockScalingY: true,
|
||||
name: dormerTempName,
|
||||
originX: 'center',
|
||||
originY: 'top',
|
||||
angle: angle,
|
||||
})
|
||||
canvas?.add(dormer)
|
||||
actualBottomLength = Math.sqrt(
|
||||
Math.pow(Math.tan(theta) * height, 2) + Math.pow(Math.tan(theta) * height * Math.tan((dormerAngle * Math.PI) / 180), 2),
|
||||
)
|
||||
actualHypotenuse = Math.sqrt(Math.pow(height, 2) + Math.pow(actualBottomLength, 2))
|
||||
|
||||
if (offsetRef > 0) {
|
||||
dormerOffset = new fabric.Triangle({
|
||||
fill: 'gray',
|
||||
actualBottomOffsetLength = Math.sqrt(
|
||||
Math.pow(Math.tan(theta) * (height + offsetRef), 2) +
|
||||
Math.pow(Math.tan(theta) * (height + offsetRef) * Math.tan((dormerAngle * Math.PI) / 180), 2),
|
||||
)
|
||||
|
||||
planeOffsetHypotenuse = Math.sqrt(Math.pow(height + offsetRef, 2) + Math.pow(bottomOffsetLength, 2))
|
||||
actualOffsetHypotenuse = Math.sqrt(Math.pow(height + offsetRef, 2) + Math.pow(actualBottomOffsetLength, 2))
|
||||
|
||||
let angle = 0
|
||||
if (directionRef === 'left') {
|
||||
//서
|
||||
angle = 90
|
||||
} else if (directionRef === 'right') {
|
||||
//동
|
||||
angle = 270
|
||||
} else if (directionRef === 'up') {
|
||||
//북
|
||||
angle = 180
|
||||
}
|
||||
|
||||
dormer = new fabric.Triangle({
|
||||
fill: 'white',
|
||||
stroke: 'red',
|
||||
strokeDashArray: [5, 5],
|
||||
strokeWidth: 1,
|
||||
width: bottomOffsetLength * 2,
|
||||
height: height + offsetRef,
|
||||
width: bottomLength * 2,
|
||||
height: height,
|
||||
left: pointer.x,
|
||||
top: pointer.y,
|
||||
selectable: true,
|
||||
@ -369,9 +383,33 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
|
||||
originX: 'center',
|
||||
originY: 'top',
|
||||
angle: angle,
|
||||
objectId: id,
|
||||
})
|
||||
canvas?.add(dormerOffset)
|
||||
canvas?.add(dormer)
|
||||
|
||||
if (offsetRef > 0) {
|
||||
dormerOffset = new fabric.Triangle({
|
||||
fill: 'gray',
|
||||
stroke: 'red',
|
||||
strokeDashArray: [5, 5],
|
||||
strokeWidth: 1,
|
||||
width: bottomOffsetLength * 2,
|
||||
height: height + offsetRef,
|
||||
left: pointer.x,
|
||||
top: pointer.y,
|
||||
selectable: true,
|
||||
lockMovementX: true,
|
||||
lockMovementY: true,
|
||||
lockRotation: true,
|
||||
lockScalingX: true,
|
||||
lockScalingY: true,
|
||||
name: dormerTempName,
|
||||
originX: 'center',
|
||||
originY: 'top',
|
||||
angle: angle,
|
||||
objectId: id,
|
||||
})
|
||||
canvas?.add(dormerOffset)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -418,68 +456,120 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
|
||||
strokeDashArray: [0],
|
||||
}) //오프셋이 있을땐 같이 도머로 만든다
|
||||
|
||||
const leftTriangle = new QPolygon(leftPoints, {
|
||||
fill: 'white',
|
||||
stroke: 'black',
|
||||
strokeWidth: 1,
|
||||
selectable: true,
|
||||
lockMovementX: true, // X 축 이동 잠금
|
||||
lockMovementY: true, // Y 축 이동 잠금
|
||||
lockRotation: true, // 회전 잠금
|
||||
viewLengthText: true,
|
||||
// direction: direction,
|
||||
originX: 'center',
|
||||
originY: 'center',
|
||||
name: dormerName,
|
||||
pitch: pitch,
|
||||
fontSize: lengthTextFont.fontSize.value,
|
||||
fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal',
|
||||
fontWeight: lengthTextFont.fontWeight.value,
|
||||
groupPoints: groupPoints,
|
||||
dormerAttributes: {
|
||||
height: height,
|
||||
width: width,
|
||||
const leftTriangle = addPolygon(
|
||||
leftPoints,
|
||||
{
|
||||
fill: 'white',
|
||||
stroke: 'black',
|
||||
strokeWidth: 1,
|
||||
selectable: true,
|
||||
lockMovementX: true, // X 축 이동 잠금
|
||||
lockMovementY: true, // Y 축 이동 잠금
|
||||
lockRotation: true, // 회전 잠금
|
||||
viewLengthText: true,
|
||||
// direction: direction,
|
||||
originX: 'center',
|
||||
originY: 'center',
|
||||
name: dormerName,
|
||||
pitch: pitch,
|
||||
offsetRef: offsetRef,
|
||||
offsetWidthRef: offsetWidthRef,
|
||||
directionRef: directionRef,
|
||||
fontSize: lengthTextFont.fontSize.value,
|
||||
fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal',
|
||||
fontWeight: lengthTextFont.fontWeight.value,
|
||||
groupPoints: groupPoints,
|
||||
dormerAttributes: {
|
||||
height: height,
|
||||
width: width,
|
||||
pitch: pitch,
|
||||
offsetRef: offsetRef,
|
||||
offsetWidthRef: offsetWidthRef,
|
||||
directionRef: directionRef,
|
||||
},
|
||||
lines: [
|
||||
{
|
||||
attributes: {
|
||||
planeSize: toFixedWithoutRounding(planeOffsetHypotenuse, 1) * 10,
|
||||
actualSize: toFixedWithoutRounding(actualOffsetHypotenuse, 1) * 10,
|
||||
},
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
planeSize: toFixedWithoutRounding(bottomOffsetLength, 1) * 10,
|
||||
actualSize: toFixedWithoutRounding(actualBottomOffsetLength, 1) * 10,
|
||||
},
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
planeSize: toFixedWithoutRounding(height + offsetRef, 1) * 10,
|
||||
actualSize: toFixedWithoutRounding(height + offsetRef, 1) * 10,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
false,
|
||||
)
|
||||
|
||||
leftTriangle.texts.forEach((text) => {
|
||||
text.bringToFront()
|
||||
})
|
||||
|
||||
const rightTriangle = new QPolygon(rightPoints, {
|
||||
fill: 'white',
|
||||
stroke: 'black',
|
||||
strokeWidth: 1,
|
||||
selectable: true,
|
||||
lockMovementX: true, // X 축 이동 잠금
|
||||
lockMovementY: true, // Y 축 이동 잠금
|
||||
lockRotation: true, // 회전 잠금
|
||||
viewLengthText: true,
|
||||
// direction: direction,
|
||||
originX: 'center',
|
||||
originY: 'center',
|
||||
name: dormerName,
|
||||
pitch: pitch,
|
||||
fontSize: lengthTextFont.fontSize.value,
|
||||
fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal',
|
||||
fontWeight: lengthTextFont.fontWeight.value,
|
||||
groupPoints: groupPoints,
|
||||
dormerAttributes: {
|
||||
height: height,
|
||||
width: width,
|
||||
const rightTriangle = addPolygon(
|
||||
rightPoints,
|
||||
{
|
||||
fill: 'white',
|
||||
stroke: 'black',
|
||||
strokeWidth: 1,
|
||||
selectable: true,
|
||||
lockMovementX: true, // X 축 이동 잠금
|
||||
lockMovementY: true, // Y 축 이동 잠금
|
||||
lockRotation: true, // 회전 잠금
|
||||
viewLengthText: true,
|
||||
// direction: direction,
|
||||
originX: 'center',
|
||||
originY: 'center',
|
||||
name: dormerName,
|
||||
pitch: pitch,
|
||||
offsetRef: offsetRef,
|
||||
offsetWidthRef: offsetWidthRef,
|
||||
directionRef: directionRef,
|
||||
fontSize: lengthTextFont.fontSize.value,
|
||||
fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal',
|
||||
fontWeight: lengthTextFont.fontWeight.value,
|
||||
groupPoints: groupPoints,
|
||||
dormerAttributes: {
|
||||
height: height,
|
||||
width: width,
|
||||
pitch: pitch,
|
||||
offsetRef: offsetRef,
|
||||
offsetWidthRef: offsetWidthRef,
|
||||
directionRef: directionRef,
|
||||
},
|
||||
lines: [
|
||||
{
|
||||
attributes: {
|
||||
planeSize: toFixedWithoutRounding(height + offsetRef, 1) * 10,
|
||||
actualSize: toFixedWithoutRounding(height + offsetRef, 1) * 10,
|
||||
},
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
planeSize: toFixedWithoutRounding(bottomOffsetLength, 1) * 10,
|
||||
actualSize: toFixedWithoutRounding(actualBottomOffsetLength, 1) * 10,
|
||||
},
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
planeSize: toFixedWithoutRounding(planeOffsetHypotenuse, 1) * 10,
|
||||
actualSize: toFixedWithoutRounding(actualOffsetHypotenuse, 1) * 10,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
false,
|
||||
)
|
||||
|
||||
// canvas?.add(leftTriangle)
|
||||
// canvas?.add(rightTriangle)
|
||||
|
||||
//패턴
|
||||
setSurfaceShapePattern(leftTriangle)
|
||||
setSurfaceShapePattern(rightTriangle)
|
||||
setSurfaceShapePattern(leftTriangle, roofDisplay.column, false, selectedSurface.roofMaterial, true)
|
||||
setSurfaceShapePattern(rightTriangle, roofDisplay.column, false, selectedSurface.roofMaterial, true)
|
||||
//방향
|
||||
|
||||
// drawDirectionArrow(leftTriangle)
|
||||
@ -492,33 +582,57 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
|
||||
if (offsetRef > 0) {
|
||||
canvas?.remove(dormer)
|
||||
|
||||
offsetPolygon = new QPolygon(triangleToPolygon(dormer), {
|
||||
selectable: true,
|
||||
lockMovementX: true, // X 축 이동 잠금
|
||||
lockMovementY: true, // Y 축 이동 잠금
|
||||
lockRotation: true, // 회전 잠금
|
||||
viewLengthText: true,
|
||||
name: 'triangleDormerOffset',
|
||||
id: id,
|
||||
fill: 'rgba(255, 255, 255, 0.6)',
|
||||
stroke: 'black',
|
||||
strokeWidth: 1,
|
||||
originX: 'center',
|
||||
originY: 'top',
|
||||
fontSize: lengthTextFont.fontSize.value,
|
||||
fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal',
|
||||
fontWeight: lengthTextFont.fontWeight.value,
|
||||
angle: originAngle,
|
||||
pitch: pitch,
|
||||
dormerAttributes: {
|
||||
height: height,
|
||||
width: width,
|
||||
offsetPolygon = addPolygon(
|
||||
triangleToPolygon(dormer),
|
||||
{
|
||||
selectable: true,
|
||||
lockMovementX: true, // X 축 이동 잠금
|
||||
lockMovementY: true, // Y 축 이동 잠금
|
||||
lockRotation: true, // 회전 잠금
|
||||
viewLengthText: true,
|
||||
name: 'triangleDormerOffset',
|
||||
id: id,
|
||||
fill: 'rgba(255, 255, 255, 0.6)',
|
||||
stroke: 'black',
|
||||
strokeWidth: 1,
|
||||
originX: 'center',
|
||||
originY: 'top',
|
||||
fontSize: lengthTextFont.fontSize.value,
|
||||
fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal',
|
||||
fontWeight: lengthTextFont.fontWeight.value,
|
||||
angle: originAngle,
|
||||
pitch: pitch,
|
||||
offsetRef: offsetRef,
|
||||
offsetWidthRef: offsetWidthRef,
|
||||
directionRef: directionRef,
|
||||
dormerAttributes: {
|
||||
height: height,
|
||||
width: width,
|
||||
pitch: pitch,
|
||||
offsetRef: offsetRef,
|
||||
offsetWidthRef: offsetWidthRef,
|
||||
directionRef: directionRef,
|
||||
},
|
||||
lines: [
|
||||
{
|
||||
attributes: {
|
||||
planeSize: toFixedWithoutRounding(planeHypotenuse, 1) * 10,
|
||||
actualSize: toFixedWithoutRounding(actualHypotenuse, 1) * 10,
|
||||
},
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
planeSize: toFixedWithoutRounding(bottomLength * 2, 1) * 10,
|
||||
actualSize: toFixedWithoutRounding(bottomLength * 2, 1) * 10,
|
||||
},
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
planeSize: toFixedWithoutRounding(planeHypotenuse, 1) * 10,
|
||||
actualSize: toFixedWithoutRounding(actualHypotenuse, 1) * 10,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
const groupPolygon = offsetPolygon ? [leftTriangle, rightTriangle, offsetPolygon] : [leftTriangle, rightTriangle]
|
||||
@ -534,10 +648,6 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
|
||||
})
|
||||
canvas?.add(objectGroup)
|
||||
|
||||
objectGroup.getObjects().forEach((obj, index) => {
|
||||
console.log(`최초 pathOffset ${index}`, obj.get('pathOffset'))
|
||||
})
|
||||
|
||||
objectGroup._objects.forEach((obj) => {
|
||||
if (obj.hasOwnProperty('texts')) {
|
||||
obj.texts.forEach((text) => {
|
||||
@ -548,7 +658,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
|
||||
|
||||
isDown = false
|
||||
initEvent()
|
||||
dbClickEvent()
|
||||
// dbClickEvent()
|
||||
if (setIsHidden) setIsHidden(false)
|
||||
}
|
||||
})
|
||||
@ -805,7 +915,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
|
||||
isDown = false
|
||||
initEvent()
|
||||
|
||||
dbClickEvent()
|
||||
// dbClickEvent()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
||||
|
||||
export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
||||
const { getMessage } = useMessage()
|
||||
const { drawDirectionArrow } = usePolygon()
|
||||
const { drawDirectionArrow, addPolygon } = usePolygon()
|
||||
const lengthTextFont = useRecoilValue(fontSelector('lengthText'))
|
||||
const resetOuterLinePoints = useResetRecoilState(outerLinePointsState)
|
||||
const resetPlacementShapeDrawingPoints = useResetRecoilState(placementShapeDrawingPointsState)
|
||||
@ -178,7 +178,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
||||
}
|
||||
|
||||
//회전, flip등이 먹은 기준으로 새로생성
|
||||
const batchSurface = new QPolygon(obj.getCurrentPoints(), {
|
||||
const batchSurface = addPolygon(obj.getCurrentPoints(), {
|
||||
fill: 'transparent',
|
||||
stroke: 'red',
|
||||
strokeWidth: 3,
|
||||
|
||||
@ -17,16 +17,16 @@ export const usePolygon = () => {
|
||||
const currentAngleType = useRecoilValue(currentAngleTypeSelector)
|
||||
const pitchText = useRecoilValue(pitchTextSelector)
|
||||
|
||||
const addPolygon = (points, options) => {
|
||||
const addPolygon = (points, options, isAddCanvas = true) => {
|
||||
const polygon = new QPolygon(points, {
|
||||
...options,
|
||||
fontSize: lengthTextFontOptions.fontSize.value,
|
||||
fill: options.fill || 'transparent',
|
||||
stroke: options.stroke || '#000000',
|
||||
selectable: true,
|
||||
// selectable: true,
|
||||
})
|
||||
|
||||
canvas?.add(polygon)
|
||||
if (isAddCanvas) canvas?.add(polygon)
|
||||
addLengthText(polygon)
|
||||
|
||||
return polygon
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user