외벽선 그리기 완료 후 offset 추가

This commit is contained in:
hyojun.choi 2024-10-02 15:41:22 +09:00
parent 7b6f5709d4
commit 0eaf973517
20 changed files with 204 additions and 89 deletions

View File

@ -6,6 +6,7 @@ import { guideLineState, horiGuideLinesState, vertGuideLinesState } from '@/stor
import { fabric } from 'fabric' import { fabric } from 'fabric'
import { ColorPicker, useColor } from 'react-color-palette' import { ColorPicker, useColor } from 'react-color-palette'
import 'react-color-palette/css' import 'react-color-palette/css'
import { gridColorState } from '@/store/gridAtom'
export default function GridSettingsModal(props) { export default function GridSettingsModal(props) {
const { canvasProps } = props const { canvasProps } = props
@ -23,7 +24,7 @@ export default function GridSettingsModal(props) {
const gridSettingArray = [] const gridSettingArray = []
const [guideColor, setGuideColor] = useColor('rgb(200, 15, 15)') const gridColor = useRecoilValue(gridColorState)
const [colorPickerShow, setColorPickerShow] = useState(false) const [colorPickerShow, setColorPickerShow] = useState(false)
const boxStyle = { const boxStyle = {
@ -67,7 +68,7 @@ export default function GridSettingsModal(props) {
const horizontalLine = new fabric.Line( const horizontalLine = new fabric.Line(
[0, i * moduleVertLength - moduleVertLength / 2, canvasProps.width, i * moduleVertLength - moduleVertLength / 2], [0, i * moduleVertLength - moduleVertLength / 2, canvasProps.width, i * moduleVertLength - moduleVertLength / 2],
{ {
stroke: guideColor.hex, stroke: gridColor,
strokeWidth: 1, strokeWidth: 1,
selectable: true, selectable: true,
lockMovementX: true, lockMovementX: true,
@ -89,7 +90,7 @@ export default function GridSettingsModal(props) {
const verticalLine = new fabric.Line( const verticalLine = new fabric.Line(
[i * moduleHoriLength - moduleHoriLength / 2, 0, i * moduleHoriLength - moduleHoriLength / 2, canvasProps.height], [i * moduleHoriLength - moduleHoriLength / 2, 0, i * moduleHoriLength - moduleHoriLength / 2, canvasProps.height],
{ {
stroke: guideColor.hex, stroke: gridColor,
strokeWidth: 1, strokeWidth: 1,
selectable: true, selectable: true,
lockMovementX: true, lockMovementX: true,

View File

@ -13,7 +13,7 @@ export const QLine = fabric.util.createClass(fabric.Line, {
area: 0, area: 0,
children: [], children: [],
initialize: function (points, options, canvas) { initialize: function (points, options, canvas) {
this.callSuper('initialize', points, { ...options, selectable: options.selectable ?? false }) this.callSuper('initialize', points, { ...options, selectable: options.selectable ?? true })
if (options.id) { if (options.id) {
this.id = options.id this.id = options.id
} else { } else {
@ -75,7 +75,7 @@ export const QLine = fabric.util.createClass(fabric.Line, {
const y2 = this.top + this.height * scaleY const y2 = this.top + this.height * scaleY
const dx = x2 - x1 const dx = x2 - x1
const dy = y2 - y1 const dy = y2 - y1
this.length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(0)) this.length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(1)) * 10
}, },
addLengthText() { addLengthText() {

View File

@ -27,6 +27,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
point.x = Math.round(point.x) point.x = Math.round(point.x)
point.y = Math.round(point.y) point.y = Math.round(point.y)
}) })
options.selectable = options.selectable ?? true
options.sort = options.sort ?? true options.sort = options.sort ?? true
options.parentId = options.parentId ?? null options.parentId = options.parentId ?? null
@ -51,6 +52,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
} }
this.callSuper('initialize', points, options) this.callSuper('initialize', points, options)
if (options.id) { if (options.id) {
this.id = options.id this.id = options.id
} else { } else {
@ -164,6 +166,9 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
stroke: this.stroke, stroke: this.stroke,
strokeWidth: this.strokeWidth, strokeWidth: this.strokeWidth,
fontSize: this.fontSize, fontSize: this.fontSize,
attributes: {
offset: 0,
},
direction: getDirectionByPoint(point, nextPoint), direction: getDirectionByPoint(point, nextPoint),
idx: i, idx: i,
}) })
@ -193,14 +198,14 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
const end = points[(i + 1) % points.length] const end = points[(i + 1) % points.length]
const dx = end.x - start.x const dx = end.x - start.x
const dy = end.y - start.y const dy = end.y - start.y
const length = Math.sqrt(dx * dx + dy * dy) const length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(1)) * 10
const midPoint = new fabric.Point((start.x + end.x) / 2, (start.y + end.y) / 2) const midPoint = new fabric.Point((start.x + end.x) / 2, (start.y + end.y) / 2)
const degree = (Math.atan2(dy, dx) * 180) / Math.PI const degree = (Math.atan2(dy, dx) * 180) / Math.PI
// Create new text object if it doesn't exist // Create new text object if it doesn't exist
const text = new fabric.IText(length.toFixed(0), { const text = new fabric.Text(length.toFixed(0), {
left: midPoint.x, left: midPoint.x,
top: midPoint.y, top: midPoint.y,
fontSize: this.fontSize, fontSize: this.fontSize,

View File

@ -149,7 +149,7 @@ export default function CanvasMenu(props) {
</div> </div>
} }
<div className="btn-from"> <div className="btn-from">
<button className="btn01"></button> <button className="btn01" onClick={() => {}}></button>
<button className="btn02 active"></button> <button className="btn02 active"></button>
<button className="btn03 "></button> <button className="btn03 "></button>
</div> </div>

View File

@ -1,12 +1,13 @@
import WithDraggable from '@/components/common/draggable/WithDraggable' import WithDraggable from '@/components/common/draggable/WithDraggable'
import QSelectBox from '@/components/common/select/QSelectBox' import QSelectBox from '@/components/common/select/QSelectBox'
import { useState } from 'react' import { useEffect, useState } from 'react'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import { canvasState, dotLineGridSettingState, dotLineIntervalSelector } from '@/store/canvasAtom' import { canvasState, dotLineGridSettingState, dotLineIntervalSelector } from '@/store/canvasAtom'
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil' import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'
import { onlyNumberInputChange } from '@/util/input-utils' import { onlyNumberInputChange } from '@/util/input-utils'
import { fabric } from 'fabric' import { fabric } from 'fabric'
import { gridColorState } from '@/store/gridAtom' import { gridColorState } from '@/store/gridAtom'
import { settingModalGridOptionsState } from '@/store/settingAtom'
const TYPE = { const TYPE = {
DOT: 'DOT', DOT: 'DOT',
@ -17,6 +18,7 @@ export default function DotLineGrid(props) {
// const [modalOption, setModalOption] = useRecoilState(modalState); //modal state // const [modalOption, setModalOption] = useRecoilState(modalState); //modal state
const [close, setClose] = useState(false) const [close, setClose] = useState(false)
const { setShowDotLineGridModal } = props const { setShowDotLineGridModal } = props
const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState)
const gridColor = useRecoilValue(gridColorState) const gridColor = useRecoilValue(gridColorState)
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
@ -25,6 +27,17 @@ export default function DotLineGrid(props) {
const interval = useRecoilValue(dotLineIntervalSelector) const interval = useRecoilValue(dotLineIntervalSelector)
const { getMessage } = useMessage() const { getMessage } = useMessage()
useEffect(() => {
return () => {
setSettingModalGridOptions((prev) => {
const newSettingOptions = [...prev]
newSettingOptions[1].selected = false
return [...newSettingOptions]
})
}
}, [])
const SelectOption = [ const SelectOption = [
{ id: 1, name: getMessage('modal.canvas.setting.grid.dot.line.setting.line.origin'), value: 1 }, { id: 1, name: getMessage('modal.canvas.setting.grid.dot.line.setting.line.origin'), value: 1 },
{ id: 2, name: '1/2', value: 1 / 2 }, { id: 2, name: '1/2', value: 1 / 2 },
@ -144,7 +157,7 @@ export default function DotLineGrid(props) {
const verticalLine = new fabric.Line( const verticalLine = new fabric.Line(
[i * horizontalInterval - horizontalInterval / 2, 0, i * horizontalInterval - horizontalInterval / 2, canvas.height], [i * horizontalInterval - horizontalInterval / 2, 0, i * horizontalInterval - horizontalInterval / 2, canvas.height],
{ {
stroke: 'black', stroke: gridColor,
strokeWidth: 1, strokeWidth: 1,
selectable: true, selectable: true,
lockMovementX: true, lockMovementX: true,

View File

@ -1,14 +1,26 @@
import WithDraggable from '@/components/common/draggable/WithDraggable' import WithDraggable from '@/components/common/draggable/WithDraggable'
import ColorPicker from '@/components/common/color-picker/ColorPicker' import ColorPicker from '@/components/common/color-picker/ColorPicker'
import { useRecoilState } from 'recoil' import { useRecoilState, useSetRecoilState } from 'recoil'
import { gridColorState } from '@/store/gridAtom' import { gridColorState } from '@/store/gridAtom'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import { useEffect } from 'react'
import { settingModalGridOptionsState } from '@/store/settingAtom'
export default function GridColorSetting(props) { export default function GridColorSetting(props) {
const { setShowColorPickerModal } = props const { setShowColorPickerModal } = props
const [color, setColor] = useRecoilState(gridColorState) const [color, setColor] = useRecoilState(gridColorState)
const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState)
const { getMessage } = useMessage() const { getMessage } = useMessage()
useEffect(() => {
return () => {
setSettingModalGridOptions((prev) => {
const newSettingOptions = [...prev]
newSettingOptions[3].selected = false
return [...newSettingOptions]
})
}
}, [])
return ( return (
<WithDraggable isShow={true} pos={{ x: 1300, y: -660 }}> <WithDraggable isShow={true} pos={{ x: 1300, y: -660 }}>
<div className={`modal-pop-wrap ssm mount`}> <div className={`modal-pop-wrap ssm mount`}>

View File

@ -2,6 +2,7 @@
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import { onlyNumberInputChange } from '@/util/input-utils' import { onlyNumberInputChange } from '@/util/input-utils'
import GridMove from '@/components/floor-plan/modal/grid/GridMove'
export default function OuterLineWall({ props }) { export default function OuterLineWall({ props }) {
const { getMessage } = useMessage() const { getMessage } = useMessage()

View File

@ -9,7 +9,7 @@ export default function PropertiesSetting(props) {
const { handleSetEaves, handleSetGable, handleRollback, handleFix, closeModal } = usePropertiesSetting() const { handleSetEaves, handleSetGable, handleRollback, handleFix, closeModal } = usePropertiesSetting()
return ( return (
<WithDraggable isShow={true}> <WithDraggable isShow={true} pos={{ x: 50, y: -950 }}>
<div className={`modal-pop-wrap ssm`}> <div className={`modal-pop-wrap ssm`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">{getMessage('modal.canvas.setting.wallline.properties.setting')}</h1> <h1 className="title">{getMessage('modal.canvas.setting.wallline.properties.setting')}</h1>

View File

@ -18,7 +18,6 @@ export default function GridOption(props) {
const [color, setColor] = useColor(gridColor) const [color, setColor] = useColor(gridColor)
useEffect(() => { useEffect(() => {
console.log(color)
setGridColor(color.hex) setGridColor(color.hex)
}, [color]) }, [color])

View File

@ -6,11 +6,18 @@ import WithDraggable from '@/components/common/draggable/WithDraggable'
import SecondOption from '@/components/floor-plan/modal/setting01/SecondOption' import SecondOption from '@/components/floor-plan/modal/setting01/SecondOption'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import GridOption from '@/components/floor-plan/modal/setting01/GridOption' import GridOption from '@/components/floor-plan/modal/setting01/GridOption'
import { canGridOptionSeletor } from '@/store/canvasAtom'
import { useRecoilValue } from 'recoil'
export default function SettingModal01(props) { export default function SettingModal01(props) {
const { setShowCanvasSettingModal, setShowDotLineGridModal, setShowColorPickerModal } = props const { setShowCanvasSettingModal, setShowDotLineGridModal, setShowColorPickerModal } = props
const [buttonAct, setButtonAct] = useState(1) const [buttonAct, setButtonAct] = useState(1)
const { getMessage } = useMessage() const { getMessage } = useMessage()
const canGridOptionSeletorValue = useRecoilValue(canGridOptionSeletor)
const handleBtnClick = (num) => {
setButtonAct(num)
}
return ( return (
<WithDraggable isShow={true} pos={{ x: 1300, y: -950 }}> <WithDraggable isShow={true} pos={{ x: 1300, y: -950 }}>
@ -23,16 +30,18 @@ export default function SettingModal01(props) {
</div> </div>
<div className="modal-body"> <div className="modal-body">
<div className="modal-btn-wrap"> <div className="modal-btn-wrap">
<button className={`btn-frame modal ${buttonAct === 1 ? 'act' : ''}`} onClick={() => setButtonAct(1)}> <button className={`btn-frame modal ${buttonAct === 1 ? 'act' : ''}`} onClick={() => handleBtnClick(1)}>
{getMessage('modal.canvas.setting.display')} {getMessage('modal.canvas.setting.display')}
</button> </button>
<button className={`btn-frame modal ${buttonAct === 2 ? 'act' : ''}`} onClick={() => setButtonAct(2)}> <button className={`btn-frame modal ${buttonAct === 2 ? 'act' : ''}`} onClick={() => handleBtnClick(2)}>
{getMessage('modal.canvas.setting.font.plan')} {getMessage('modal.canvas.setting.font.plan')}
</button> </button>
<button className={`btn-frame modal ${buttonAct === 3 ? 'act' : ''}`} onClick={() => setButtonAct(3)}> {canGridOptionSeletorValue && (
{getMessage('modal.canvas.setting.grid')} <button className={`btn-frame modal ${buttonAct === 3 ? 'act' : ''}`} onClick={() => handleBtnClick(3)}>
</button> {getMessage('modal.canvas.setting.grid')}
</button>
)}
</div> </div>
{buttonAct === 1 && <FirstOption />} {buttonAct === 1 && <FirstOption />}
{buttonAct === 2 && <SecondOption />} {buttonAct === 2 && <SecondOption />}

View File

@ -1,6 +1,6 @@
import { useEffect, useRef } from 'react' import { useEffect, useRef } from 'react'
import { distanceBetweenPoints, getDegreeByChon } from '@/util/canvas-util' import { distanceBetweenPoints, getDegreeByChon } from '@/util/canvas-util'
import { useRecoilState, useRecoilValue } from 'recoil' import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
import { import {
adsorptionPointAddModeState, adsorptionPointAddModeState,
adsorptionPointModeState, adsorptionPointModeState,
@ -20,6 +20,7 @@ import {
outerLineArrow1State, outerLineArrow1State,
outerLineArrow2State, outerLineArrow2State,
outerLineDiagonalState, outerLineDiagonalState,
outerLineFixState,
outerLineLength1State, outerLineLength1State,
outerLineLength2State, outerLineLength2State,
outerLinePointsState, outerLinePointsState,
@ -59,6 +60,8 @@ export function useOuterLineWall() {
const arrow1Ref = useRef(arrow1) const arrow1Ref = useRef(arrow1)
const arrow2Ref = useRef(arrow2) const arrow2Ref = useRef(arrow2)
const setOuterLineFix = useSetRecoilState(outerLineFixState)
const outerLineDiagonalLengthRef = useRef(null) const outerLineDiagonalLengthRef = useRef(null)
const isFix = useRef(false) const isFix = useRef(false)
@ -69,6 +72,15 @@ export function useOuterLineWall() {
if (adsorptionPointAddMode || tempGridMode) { if (adsorptionPointAddMode || tempGridMode) {
return return
} }
if (points.length === 0) {
// 만약 포인트가 없다면 모든 라인과 텍스트를 삭제 후 outerLines에서 point를 뽑아 points에 넣어준다.
const lengthTxts = canvas?.getObjects().filter((obj) => obj.name === 'lengthTxt')
lengthTxts.forEach((txt) => {
canvas?.remove(txt)
})
}
addCanvasMouseEventListener('mouse:down', mouseDown) addCanvasMouseEventListener('mouse:down', mouseDown)
clear() clear()
}, [verticalHorizontalMode, points, adsorptionPointAddMode, adsorptionPointMode, adsorptionRange, interval, tempGridMode]) }, [verticalHorizontalMode, points, adsorptionPointAddMode, adsorptionPointMode, adsorptionRange, interval, tempGridMode])
@ -153,6 +165,7 @@ export function useOuterLineWall() {
canvas?.remove(canvas?.getObjects().find((obj) => obj.name === 'startPoint')) canvas?.remove(canvas?.getObjects().find((obj) => obj.name === 'startPoint'))
if (points.length === 0) { if (points.length === 0) {
setOuterLineFix(true)
removeAllDocumentEventListeners() removeAllDocumentEventListeners()
return return
} }
@ -172,6 +185,7 @@ export function useOuterLineWall() {
canvas?.add(point) canvas?.add(point)
} else { } else {
setOuterLineFix(false)
points.forEach((point, idx) => { points.forEach((point, idx) => {
if (idx === 0) { if (idx === 0) {
return return
@ -183,10 +197,10 @@ export function useOuterLineWall() {
const firstPoint = points[0] const firstPoint = points[0]
if (isFix.current) { if (isFix.current) {
canvas?.renderAll()
closeModalFn.current(false)
removeAllMouseEventListeners() removeAllMouseEventListeners()
removeAllDocumentEventListeners() removeAllDocumentEventListeners()
canvas?.renderAll()
closeModalFn.current(false)
} }
if (points.length < 3) { if (points.length < 3) {

View File

@ -1,91 +1,116 @@
import { useEffect, useRef } from 'react' import { useEffect, useRef } from 'react'
import { LINE_TYPE } from '@/common/common' import { LINE_TYPE } from '@/common/common'
import { useRecoilValue } from 'recoil' import { useRecoilValue } from 'recoil'
import { canvasState } from '@/store/canvasAtom' import { canvasState, currentObjectState } from '@/store/canvasAtom'
import { useMode } from '@/hooks/useMode'
import { usePolygon } from '@/hooks/usePolygon'
import { useLine } from '@/hooks/useLine'
export function usePropertiesSetting() { export function usePropertiesSetting() {
const currentLine = useRef(null)
const currentIdx = useRef(-1)
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
const currentObject = useRecoilValue(currentObjectState)
const { drawRoofPolygon } = useMode()
const { addPolygonByLines } = usePolygon()
const { removeLine } = useLine()
useEffect(() => { useEffect(() => {
selectNextLine() if (!currentObject) {
}, []) return
}
if (currentObject.name !== 'outerLine') {
return
}
const type = currentObject.attributes?.type
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
lines.forEach((line) => {
const lineType = line.attributes?.type
if (!lineType) {
line.set({
stroke: '#000000',
strokeWidth: 4,
})
}
})
if (!type) {
currentObject.set({
stroke: '#EA10AC',
strokeWidth: 4,
})
}
}, [currentObject])
const history = useRef([])
const handleSetEaves = () => { const handleSetEaves = () => {
currentLine.current.set({ const selectedLine = canvas?.getActiveObject()
if (!selectedLine) {
return
}
selectedLine.set({
stroke: '#45CD7D', stroke: '#45CD7D',
strokeWidth: 4, strokeWidth: 4,
attributes: { attributes: {
offset: 500, offset: 50,
type: LINE_TYPE.WALLLINE.EAVES, type: LINE_TYPE.WALLLINE.EAVES,
pitch: 4, pitch: 4,
}, },
}) })
history.current.push(selectedLine)
nextLineFocus(selectedLine)
canvas.renderAll() canvas.renderAll()
selectNextLine()
} }
const handleSetGable = () => { const handleSetGable = () => {
currentLine.current.set({ const selectedLine = canvas?.getActiveObject()
if (!selectedLine) {
return
}
selectedLine.set({
stroke: '#3FBAE6', stroke: '#3FBAE6',
strokeWidth: 4, strokeWidth: 4,
attributes: { attributes: {
offset: 300, offset: 30,
type: LINE_TYPE.WALLLINE.GABLE, type: LINE_TYPE.WALLLINE.GABLE,
}, },
}) })
canvas.renderAll() history.current.push(selectedLine)
selectNextLine() nextLineFocus(selectedLine)
}
const selectNextLine = () => {
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
currentIdx.current++
if (currentIdx.current >= lines.length) {
currentIdx.current = lines.length
currentLine.current = lines[currentIdx.current - 1]
return
}
currentLine.current = lines[currentIdx.current]
currentLine.current.set({
stroke: '#EA10AC',
strokeWidth: 4,
})
canvas.renderAll() canvas.renderAll()
} }
const selectPrevLine = () => { const nextLineFocus = (selectedLine) => {
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
const index = lines.findIndex((line) => line === selectedLine)
currentIdx.current-- const nextLine = lines[index + 1] || lines[0]
if (!nextLine.attributes?.type) {
if (currentIdx.current <= -1) { canvas.setActiveObject(nextLine)
currentIdx.current = -1
selectNextLine()
return
} else { } else {
lines.forEach((line, index) => { //activeObject 해제
if (index >= currentIdx.current) { canvas.discardActiveObject()
delete line.attributes
line.set({
stroke: '#000000',
strokeWidth: 4,
})
}
currentIdx.current--
canvas.renderAll()
selectNextLine()
})
} }
} }
const handleRollback = () => { const handleRollback = () => {
selectPrevLine() if (history.current.length === 0) {
return
}
const lastLine = history.current.pop()
lastLine.set({
stroke: '#000000',
strokeWidth: 4,
})
canvas.setActiveObject(lastLine)
canvas.renderAll()
} }
const handleFix = () => { const handleFix = () => {
@ -100,8 +125,15 @@ export function usePropertiesSetting() {
stroke: '#000000', stroke: '#000000',
strokeWidth: 4, strokeWidth: 4,
}) })
removeLine(line)
}) })
const wall = addPolygonByLines(lines, { name: 'WallLine', fill: 'transparent', stroke: 'black' })
wall.lines = [...lines]
drawRoofPolygon(wall)
canvas.renderAll() canvas.renderAll()
} }
@ -121,7 +153,6 @@ export function usePropertiesSetting() {
}) })
canvas.renderAll() canvas.renderAll()
fn(false) fn(false)
} }

View File

@ -1,6 +1,6 @@
import { useEffect, useRef } from 'react' import { useEffect, useRef } from 'react'
import { useRecoilState, useRecoilValue } from 'recoil' import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
import { canvasState, canvasZoomState, currentMenuState } from '@/store/canvasAtom' import { canvasState, canvasZoomState, currentMenuState, textModeState } from '@/store/canvasAtom'
import { fabric } from 'fabric' import { fabric } from 'fabric'
import { calculateDistance, distanceBetweenPoints, findClosestPoint } from '@/util/canvas-util' import { calculateDistance, distanceBetweenPoints, findClosestPoint } from '@/util/canvas-util'
import { useAdsorptionPoint } from '@/hooks/useAdsorptionPoint' import { useAdsorptionPoint } from '@/hooks/useAdsorptionPoint'
@ -12,12 +12,14 @@ export function useEvent() {
const currentMenu = useRecoilValue(currentMenuState) const currentMenu = useRecoilValue(currentMenuState)
const documentEventListeners = useRef([]) const documentEventListeners = useRef([])
const mouseEventListeners = useRef([]) const mouseEventListeners = useRef([])
const [canvasZoom, setCanvasZoom] = useRecoilState(canvasZoomState) const setCanvasZoom = useSetRecoilState(canvasZoomState)
const { adsorptionPointAddMode, adsorptionPointMode, adsorptionRange, getAdsorptionPoints, adsorptionPointAddModeStateEvent } = useAdsorptionPoint() const { adsorptionPointAddMode, adsorptionPointMode, adsorptionRange, getAdsorptionPoints, adsorptionPointAddModeStateEvent } = useAdsorptionPoint()
const { dotLineGridSetting, interval, getClosestLineGrid } = useDotLineGrid() const { dotLineGridSetting, interval, getClosestLineGrid } = useDotLineGrid()
const { tempGridModeStateLeftClickEvent, tempGridMode, tempGridRightClickEvent } = useTempGrid() const { tempGridModeStateLeftClickEvent, tempGridMode, tempGridRightClickEvent } = useTempGrid()
const textMode = useRecoilValue(textModeState)
useEffect(() => { useEffect(() => {
if (!canvas) { if (!canvas) {
return return
@ -38,6 +40,7 @@ export function useEvent() {
addCanvasMouseEventListener('mouse:move', defaultMouseMoveEvent) addCanvasMouseEventListener('mouse:move', defaultMouseMoveEvent)
addCanvasMouseEventListener('mouse:out', defaultMouseOutEvent) addCanvasMouseEventListener('mouse:out', defaultMouseOutEvent)
addDocumentEventListener('keydown', document, defaultKeyboardEvent) addDocumentEventListener('keydown', document, defaultKeyboardEvent)
addDocumentEventListener('contextmenu', document, defaultContextMenuEvent)
if (adsorptionPointAddMode) { if (adsorptionPointAddMode) {
addCanvasMouseEventListener('mouse:down', adsorptionPointAddModeStateEvent) addCanvasMouseEventListener('mouse:down', adsorptionPointAddModeStateEvent)
} }

View File

@ -1,5 +1,6 @@
import { useRecoilValue } from 'recoil' import { useRecoilValue } from 'recoil'
import { canvasState, fontFamilyState, fontSizeState } from '@/store/canvasAtom' import { canvasState, fontFamilyState, fontSizeState } from '@/store/canvasAtom'
import { QLine } from '@/components/fabric/QLine'
export const useLine = () => { export const useLine = () => {
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
@ -7,13 +8,13 @@ export const useLine = () => {
const fontFamily = useRecoilValue(fontFamilyState) const fontFamily = useRecoilValue(fontFamilyState)
const addLine = (points = [], options) => { const addLine = (points = [], options) => {
const line = new fabric.Line(points, { const line = new QLine(points, {
...options, ...options,
selectable: options.selectable ?? false, fontSize: fontSize,
fontFamily: fontFamily,
}) })
canvas?.add(line) canvas?.add(line)
addLineText(line)
return line return line
} }

View File

@ -1678,7 +1678,7 @@ export function useMode() {
const drawRoofPolygon = (wall) => { const drawRoofPolygon = (wall) => {
// TODO [ljyoung] : offset 입력 처리 후 제거 해야함. // TODO [ljyoung] : offset 입력 처리 후 제거 해야함.
wall.lines.forEach((line, index) => { /*wall.lines.forEach((line, index) => {
if (index === wall.lines.length - 1 || index === 3) { if (index === wall.lines.length - 1 || index === 3) {
line.attributes = { line.attributes = {
type: 'gable', type: 'gable',
@ -1690,7 +1690,7 @@ export function useMode() {
offset: 50, offset: 50,
} }
} }
}) })*/
const polygon = createRoofPolygon(wall.points) const polygon = createRoofPolygon(wall.points)
const originPolygon = new QPolygon(wall.points, { fontSize: 0 }) const originPolygon = new QPolygon(wall.points, { fontSize: 0 })

View File

@ -2,6 +2,7 @@ import { canvasState, fontFamilyState, fontSizeState } from '@/store/canvasAtom'
import { useRecoilValue } from 'recoil' import { useRecoilValue } from 'recoil'
import { fabric } from 'fabric' import { fabric } from 'fabric'
import { getDirectionByPoint } from '@/util/canvas-util' import { getDirectionByPoint } from '@/util/canvas-util'
import { QPolygon } from '@/components/fabric/QPolygon'
export const usePolygon = () => { export const usePolygon = () => {
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
@ -9,19 +10,22 @@ export const usePolygon = () => {
const fontFamily = useRecoilValue(fontFamilyState) const fontFamily = useRecoilValue(fontFamilyState)
const addPolygon = (points, options) => { const addPolygon = (points, options) => {
const polygon = new fabric.Polygon(points, { const polygon = new QPolygon(points, {
...options, ...options,
selectable: options.selectable ?? false, fontSize: fontSize,
fontFamily: fontFamily,
selectable: true,
}) })
canvas?.add(polygon) canvas?.add(polygon)
addLengthText(polygon)
return polygon
} }
const addPolygonByLines = (lines, options) => { const addPolygonByLines = (lines, options) => {
const points = createPolygonPointsFromOuterLines(lines) const points = createPolygonPointsFromOuterLines(lines)
addPolygon(points, { return addPolygon(points, {
...options, ...options,
}) })
} }
@ -39,10 +43,11 @@ export const usePolygon = () => {
const degree = (Math.atan2(dy, dx) * 180) / Math.PI const degree = (Math.atan2(dy, dx) * 180) / Math.PI
// Create new text object if it doesn't exist // Create new text object if it doesn't exist
const text = new fabric.IText(length.toString(), { const text = new fabric.Text(length.toString(), {
left: midPoint.x, left: midPoint.x,
top: midPoint.y, top: midPoint.y,
fontSize: fontSize, fontSize: fontSize,
fontFamily: fontFamily,
parentId: polygon.id, parentId: polygon.id,
minX: Math.min(start.x, end.x), minX: Math.min(start.x, end.x),
maxX: Math.max(start.x, end.x), maxX: Math.max(start.x, end.x),

View File

@ -1,5 +1,6 @@
import { atom, selector } from 'recoil' import { atom, selector } from 'recoil'
import { MENU } from '@/common/common' import { MENU } from '@/common/common'
import { outerLineFixState, outerLinePointsState } from '@/store/outerLineAtom'
export const canvasState = atom({ export const canvasState = atom({
key: 'canvasState', key: 'canvasState',
@ -267,3 +268,18 @@ export const tempGridModeState = atom({
key: 'tempGridModeState', key: 'tempGridModeState',
default: false, default: false,
}) })
export const textModeState = atom({
key: 'textModeState',
default: false,
})
export const canGridOptionSeletor = selector({
key: 'canGridOptionSeletor',
get: ({ get }) => {
const points = get(outerLinePointsState)
const currentMenu = get(currentMenuState)
const outerLineFix = get(outerLineFixState)
return points.length === 0 || outerLineFix
},
})

View File

@ -2,5 +2,5 @@ import { atom } from 'recoil'
export const gridColorState = atom({ export const gridColorState = atom({
key: 'gridColorState', key: 'gridColorState',
default: '#000000', default: '#FF0000',
}) })

View File

@ -63,3 +63,8 @@ export const outerLinePointsState = atom({
key: 'outerLinePointsState', key: 'outerLinePointsState',
default: [], default: [],
}) })
export const outerLineFixState = atom({
key: 'outerLineFixState',
default: false,
})

View File

@ -1,4 +1,4 @@
import { atom } from 'recoil' import { atom, selector } from 'recoil'
export const settingModalFirstOptionsState = atom({ export const settingModalFirstOptionsState = atom({
key: 'settingModalFirstOptions', key: 'settingModalFirstOptions',