그리드 설정 후 에디팅 모드 변경 시 가까운 line에 붙도록 추가

This commit is contained in:
hyojun.choi 2024-08-23 16:38:16 +09:00
parent dfeadd5d17
commit 8fe2960f92
3 changed files with 110 additions and 52 deletions

View File

@ -26,12 +26,14 @@ import ThumbnailList from './ui/ThumbnailLIst'
import QContextMenu from './common/context-menu/QContextMenu'
import { modalContent, modalState } from '@/store/modalAtom'
import SettingsModal from './SettingsModal'
import { get } from '@/lib/Axios'
import { useAxios } from '@/hooks/useAxios'
export default function Roof2(props) {
const { name, userId, email, isLoggedIn } = props
const { canvas, handleRedo, handleUndo, setCanvasBackgroundWithDots, saveImage, addCanvas } = useCanvas('canvas')
const { get } = useAxios()
const canvasRef = useRef(null)
//canvas

View File

@ -4,6 +4,8 @@ import {
distanceBetweenPoints,
findTopTwoIndexesByDistance,
getCenterPoint,
getClosestHorizontalLine,
getClosestVerticalLine,
getDirection,
getStartIndex,
rearrangeArray,
@ -42,7 +44,6 @@ export function useMode() {
const [canvas, setCanvas] = useState(null)
const [zoom, setZoom] = useState(100)
const [fontSize] = useRecoilState(fontSizeState)
const [shape, setShape] = useState(0)
const [sortedArray, setSortedArray] = useRecoilState(sortedPolygonArray)
const [roof, setRoof] = useRecoilState(roofState)
const [wall, setWall] = useRecoilState(wallState)
@ -65,7 +66,7 @@ export function useMode() {
const compass = useRecoilValue(compassState)
const [isCellCenter, setIsCellCenter] = useState(false)
const guideLine = useRecoilValue(guideLineState)
const guideLineInfo = useRecoilValue(guideLineState)
useEffect(() => {
// 이벤트 리스너 추가
@ -107,7 +108,27 @@ export function useMode() {
}, [mode, isGuidePointMode])
const drawMouseLines = (e) => {
console.log('guideLine', guideLine)
let isGuideLineMode = false,
isGuideDotMode = false
let guideDotLength, guideLineLength, horizontalLineArray, verticalLineArray
if (isObjectNotEmpty(guideLineInfo)) {
const guideLineState = guideLineInfo.filter((item) => item.guideMode === 'guideLine')
const guideDotState = guideLineInfo.filter((item) => item.guideMode === 'guideDot')
isGuideLineMode = guideLineState.length > 0
isGuideDotMode = guideDotState.length > 0
if (isGuideDotMode) {
guideDotLength = Number(guideDotState[0].moduleLength)
}
if (isGuideLineMode) {
horizontalLineArray = [...guideLineState[0].horizontalLineArray]
verticalLineArray = [...guideLineState[0].verticalLineArray]
guideLineLength = Number(guideLineState[0].moduleLength)
}
}
// 현재 마우스 포인터의 위치를 가져옵니다.
const pointer = canvas?.getPointer(e.e)
@ -115,21 +136,56 @@ export function useMode() {
// 기존에 그려진 가이드라인을 제거합니다.
removeMouseLines()
if (canvas?.getActiveObject()) {
return
}
let newX, newY
if (isGuidePointMode && mode === Mode.EDIT) {
newX = Math.round(pointer.x / 200) * 200
newY = Math.round(pointer.y / 200) * 200
} else {
newX = pointer.x
newY = pointer.y
let newX = pointer.x
let newY = pointer.y
if (isGuideLineMode && isGuideDotMode && mode === Mode.EDIT) {
} else if (isGuideDotMode && mode === Mode.EDIT) {
const x = pointer.x - guideDotLength * Math.floor(pointer.x / guideDotLength)
const y = pointer.y - guideDotLength * Math.floor(pointer.y / guideDotLength)
const xRate = x / guideDotLength
const yRate = y / guideDotLength
const isAttachX = xRate >= 0.4 && xRate <= 0.7
const isAttachY = yRate >= 0.4 && yRate <= 0.7
if (isAttachX && isAttachY) {
newX = Math.floor(pointer.x / guideDotLength) * guideDotLength + guideDotLength / 2
newY = Math.floor(pointer.y / guideDotLength) * guideDotLength + guideDotLength / 2
}
} else if (isGuideLineMode && mode === Mode.EDIT) {
const closestHorizontalLine = getClosestHorizontalLine(pointer, horizontalLineArray)
const closetVerticalLine = getClosestVerticalLine(pointer, verticalLineArray)
const xDiff = Math.abs(pointer.x - closetVerticalLine.x1)
const yDiff = Math.abs(pointer.y - closestHorizontalLine.y1)
const x = pointer.x - guideLineLength * Math.floor(pointer.x / guideLineLength)
const y = pointer.y - guideLineLength * Math.floor(pointer.y / guideLineLength)
const xRate = x / guideLineLength
const yRate = y / guideLineLength
const isAttachX = xRate >= 0.4 && xRate <= 0.7
const isAttachY = yRate >= 0.4 && yRate <= 0.7
if (isAttachX && isAttachY) {
newX = Math.floor(pointer.x / guideLineLength) * guideLineLength + guideLineLength / 2
newY = Math.floor(pointer.y / guideLineLength) * guideLineLength + guideLineLength / 2
} else {
if (Math.min(xDiff, yDiff) <= 20) {
if (xDiff < yDiff) {
newX = closetVerticalLine.x1
newY = pointer.y
} else {
newX = pointer.x
newY = closestHorizontalLine.y1
}
}
}
}
// 가로선을 그립니다.
const horizontalLine = new fabric.Line([0, newY, canvasSize.horizontal, newY], {
stroke: 'black',
stroke: 'red',
strokeWidth: 1,
selectable: false,
name: 'mouseLine',
@ -137,7 +193,7 @@ export function useMode() {
// 세로선을 그립니다.
const verticalLine = new fabric.Line([newX, 0, newX, canvasSize.vertical], {
stroke: 'black',
stroke: 'red',
strokeWidth: 1,
selectable: false,
name: 'mouseLine',
@ -762,10 +818,8 @@ export function useMode() {
points.current = []
historyPoints.current = []
// handleOuterlines()
const wall = makePolygon(null, sort)
wall.set({ name: 'wall' })
console.log('wall', wall)
return wall
}
@ -804,33 +858,7 @@ export function useMode() {
const makePolygon = (otherLines, sort = true) => {
// 캔버스에서 모든 라인 객체를 찾습니다.
const lines = otherLines || historyLines.current
if (!otherLines) {
//외각선 기준
const topIndex = findTopTwoIndexesByDistance(sortedArray) //배열중에 큰 2값을 가져옴 TODO: 나중에는 인자로 받아서 다각으로 수정 해야됨
//일단 배열 6개 짜리 기준의 선 번호
if (topIndex[0] === 4) {
if (topIndex[1] === 5) {
//1번
setShape(1)
}
} else if (topIndex[0] === 1) {
//4번
if (topIndex[1] === 2) {
setShape(4)
}
} else if (topIndex[0] === 0) {
if (topIndex[1] === 1) {
//2번
setShape(2)
} else if (topIndex[1] === 5) {
setShape(3)
}
}
historyLines.current = []
}
historyLines.current = []
// 각 라인의 시작점과 끝점을 사용하여 다각형의 점 배열을 생성합니다.
const points = lines.map((line) => ({ x: line.x1, y: line.y1 }))
@ -858,12 +886,10 @@ export function useMode() {
canvas.add(polygon)
// 캔버스를 다시 그립니다.
if (!otherLines) {
// polygon.fillCell()
canvas?.renderAll()
// polygon.setViewLengthText(false)
setMode(Mode.DEFAULT)
}
// polygon.fillCell()
canvas?.renderAll()
// polygon.setViewLengthText(false)
setMode(Mode.DEFAULT)
return polygon
}

View File

@ -38,7 +38,7 @@ export function actionHandler(eventData, transform, x, y) {
// define a function that can keep the polygon in the same position when we change its width/height/top/left
export function anchorWrapper(anchorIndex, fn) {
return function(eventData, transform, x, y) {
return function (eventData, transform, x, y) {
let fabricObject = transform.target
let originX = fabricObject?.points[anchorIndex].x - fabricObject.pathOffset.x
let originY = fabricObject.points[anchorIndex].y - fabricObject.pathOffset.y
@ -675,3 +675,33 @@ export function findClosestPointWithDifferentXY(targetPoint, points) {
return closestPoint
}
export const getClosestHorizontalLine = (pointer, horizontalLineArray) => {
let closestLine = null
let minDistance = Infinity
horizontalLineArray.forEach((line) => {
const distance = Math.abs(line.y1 - pointer.y) // Assuming horizontal lines have the same y1 and y2
if (distance < minDistance) {
minDistance = distance
closestLine = line
}
})
return closestLine
}
export const getClosestVerticalLine = (pointer, verticalLineArray) => {
let closestLine = null
let minDistance = Infinity
verticalLineArray.forEach((line) => {
const distance = Math.abs(line.x1 - pointer.x) // Assuming horizontal lines have the same y1 and y2
if (distance < minDistance) {
minDistance = distance
closestLine = line
}
})
return closestLine
}