저장 시 줌 관련 문제 수정
This commit is contained in:
parent
1fff48bbfa
commit
bf681dccba
@ -219,7 +219,8 @@ export const SAVE_KEY = [
|
|||||||
'originWidth',
|
'originWidth',
|
||||||
'originHeight',
|
'originHeight',
|
||||||
'skeletonLines',
|
'skeletonLines',
|
||||||
'skeleton'
|
'skeleton',
|
||||||
|
'viewportTransform',
|
||||||
]
|
]
|
||||||
|
|
||||||
export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype, fabric.Group.prototype]
|
export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype, fabric.Group.prototype]
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { useContext, useEffect, useRef } from 'react'
|
import { useContext, useEffect, useRef } from 'react'
|
||||||
|
|
||||||
import { useRecoilValue, useResetRecoilState } from 'recoil'
|
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
|
||||||
|
|
||||||
import QContextMenu from '@/components/common/context-menu/QContextMenu'
|
import QContextMenu from '@/components/common/context-menu/QContextMenu'
|
||||||
import PanelBatchStatistics from '@/components/floor-plan/modal/panelBatch/PanelBatchStatistics'
|
import PanelBatchStatistics from '@/components/floor-plan/modal/panelBatch/PanelBatchStatistics'
|
||||||
@ -11,7 +11,7 @@ import { useCanvas } from '@/hooks/useCanvas'
|
|||||||
import { usePlan } from '@/hooks/usePlan'
|
import { usePlan } from '@/hooks/usePlan'
|
||||||
import { useContextMenu } from '@/hooks/useContextMenu'
|
import { useContextMenu } from '@/hooks/useContextMenu'
|
||||||
import { useCanvasConfigInitialize } from '@/hooks/common/useCanvasConfigInitialize'
|
import { useCanvasConfigInitialize } from '@/hooks/common/useCanvasConfigInitialize'
|
||||||
import { currentMenuState } from '@/store/canvasAtom'
|
import { canvasZoomState, currentMenuState } from '@/store/canvasAtom'
|
||||||
import { totalDisplaySelector } from '@/store/settingAtom'
|
import { totalDisplaySelector } from '@/store/settingAtom'
|
||||||
import { POLYGON_TYPE } from '@/common/common'
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
||||||
@ -50,6 +50,7 @@ export default function CanvasFrame() {
|
|||||||
const resetSeriesState = useResetRecoilState(seriesState)
|
const resetSeriesState = useResetRecoilState(seriesState)
|
||||||
const resetModelsState = useResetRecoilState(modelsState)
|
const resetModelsState = useResetRecoilState(modelsState)
|
||||||
const resetCompasDeg = useResetRecoilState(compasDegAtom)
|
const resetCompasDeg = useResetRecoilState(compasDegAtom)
|
||||||
|
const [zoom, setCanvasZoom] = useRecoilState(canvasZoomState)
|
||||||
const resetSelectedModelsState = useResetRecoilState(selectedModelsState)
|
const resetSelectedModelsState = useResetRecoilState(selectedModelsState)
|
||||||
const resetPcsCheckState = useResetRecoilState(pcsCheckState)
|
const resetPcsCheckState = useResetRecoilState(pcsCheckState)
|
||||||
const { handleModuleSelectionTotal } = useCanvasPopupStatusController()
|
const { handleModuleSelectionTotal } = useCanvasPopupStatusController()
|
||||||
@ -67,6 +68,13 @@ export default function CanvasFrame() {
|
|||||||
canvasLoadInit() //config된 상태로 캔버스 객체를 그린다
|
canvasLoadInit() //config된 상태로 캔버스 객체를 그린다
|
||||||
canvas?.renderAll() // 캔버스를 다시 그립니다.
|
canvas?.renderAll() // 캔버스를 다시 그립니다.
|
||||||
|
|
||||||
|
if (canvas.viewportTransform) {
|
||||||
|
if (canvas.viewportTransform[0] !== 1) {
|
||||||
|
setCanvasZoom(Number((canvas.viewportTransform[0] * 100).toFixed(0)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
canvas.originViewPortTransform = canvas.viewportTransform
|
||||||
|
|
||||||
if (canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE).length > 0) {
|
if (canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE).length > 0) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setSelectedMenu('module')
|
setSelectedMenu('module')
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { useContext, useEffect, useState } from 'react'
|
import { useContext, useEffect, useState } from 'react'
|
||||||
|
|
||||||
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
|
import { usePathname, useRouter } from 'next/navigation'
|
||||||
|
|
||||||
import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'
|
import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'
|
||||||
|
|
||||||
@ -25,17 +25,18 @@ import { useCommonUtils } from '@/hooks/common/useCommonUtils'
|
|||||||
import useMenu from '@/hooks/common/useMenu'
|
import useMenu from '@/hooks/common/useMenu'
|
||||||
import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController'
|
import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController'
|
||||||
import { useAxios } from '@/hooks/useAxios'
|
import { useAxios } from '@/hooks/useAxios'
|
||||||
import { canvasSettingState, canvasState, canvasZoomState, currentMenuState, verticalHorizontalModeState, currentCanvasPlanState } from '@/store/canvasAtom'
|
import {
|
||||||
|
canvasSettingState,
|
||||||
|
canvasState,
|
||||||
|
canvasZoomState,
|
||||||
|
currentCanvasPlanState,
|
||||||
|
currentMenuState,
|
||||||
|
verticalHorizontalModeState,
|
||||||
|
} from '@/store/canvasAtom'
|
||||||
import { sessionStore } from '@/store/commonAtom'
|
import { sessionStore } from '@/store/commonAtom'
|
||||||
import { outerLinePointsState } from '@/store/outerLineAtom'
|
import { outerLinePointsState } from '@/store/outerLineAtom'
|
||||||
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
|
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
|
||||||
import {
|
import { addedRoofsState, basicSettingState, selectedRoofMaterialSelector, settingModalFirstOptionsState } from '@/store/settingAtom'
|
||||||
addedRoofsState,
|
|
||||||
basicSettingState,
|
|
||||||
corridorDimensionSelector,
|
|
||||||
selectedRoofMaterialSelector,
|
|
||||||
settingModalFirstOptionsState,
|
|
||||||
} from '@/store/settingAtom'
|
|
||||||
import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom'
|
import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom'
|
||||||
import { commonUtilsState } from '@/store/commonUtilsAtom'
|
import { commonUtilsState } from '@/store/commonUtilsAtom'
|
||||||
import { menusState } from '@/store/menuAtom'
|
import { menusState } from '@/store/menuAtom'
|
||||||
@ -51,6 +52,7 @@ import { QcastContext } from '@/app/QcastProvider'
|
|||||||
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
||||||
import { usePolygon } from '@/hooks/usePolygon'
|
import { usePolygon } from '@/hooks/usePolygon'
|
||||||
import { useTrestle } from '@/hooks/module/useTrestle'
|
import { useTrestle } from '@/hooks/module/useTrestle'
|
||||||
|
|
||||||
export default function CanvasMenu(props) {
|
export default function CanvasMenu(props) {
|
||||||
const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState)
|
const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState)
|
||||||
const { selectedMenu, setSelectedMenu } = props
|
const { selectedMenu, setSelectedMenu } = props
|
||||||
@ -515,7 +517,10 @@ export default function CanvasMenu(props) {
|
|||||||
if (createUser === 'T01' && sessionState.storeId !== 'T01') {
|
if (createUser === 'T01' && sessionState.storeId !== 'T01') {
|
||||||
setAllButtonStyles('none')
|
setAllButtonStyles('none')
|
||||||
} else {
|
} else {
|
||||||
setEstimateContextState({ tempFlg: estimateRecoilState.tempFlg, lockFlg: estimateRecoilState.lockFlg })
|
setEstimateContextState({
|
||||||
|
tempFlg: estimateRecoilState.tempFlg,
|
||||||
|
lockFlg: estimateRecoilState.lockFlg,
|
||||||
|
})
|
||||||
handleButtonStyles(estimateRecoilState.tempFlg, estimateRecoilState.lockFlg, estimateContextState.docNo)
|
handleButtonStyles(estimateRecoilState.tempFlg, estimateRecoilState.lockFlg, estimateContextState.docNo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,8 +31,11 @@ export function useCommonUtils() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
commonTextMode()
|
commonTextMode()
|
||||||
if (commonUtils.dimension) {
|
if (commonUtils.dimension) {
|
||||||
|
generateTempGrid()
|
||||||
commonDimensionMode()
|
commonDimensionMode()
|
||||||
return
|
return
|
||||||
|
} else {
|
||||||
|
removeTempGrid()
|
||||||
}
|
}
|
||||||
if (commonUtils.distance) {
|
if (commonUtils.distance) {
|
||||||
commonDistanceMode()
|
commonDistanceMode()
|
||||||
@ -655,7 +658,7 @@ export function useCommonUtils() {
|
|||||||
if (obj.name === 'roof') {
|
if (obj.name === 'roof') {
|
||||||
clonedObj.setCoords()
|
clonedObj.setCoords()
|
||||||
clonedObj.fire('modified')
|
clonedObj.fire('modified')
|
||||||
clonedObj.fire('polygonMoved')
|
// clonedObj.fire('polygonMoved')
|
||||||
clonedObj.set({
|
clonedObj.set({
|
||||||
direction: obj.direction,
|
direction: obj.direction,
|
||||||
directionText: obj.directionText,
|
directionText: obj.directionText,
|
||||||
@ -905,6 +908,45 @@ export function useCommonUtils() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const generateTempGrid = () => {
|
||||||
|
if (!canvas) return
|
||||||
|
|
||||||
|
const objects = canvas.getObjects().filter((obj) => ['QPolygon'].includes(obj.type))
|
||||||
|
const gridLines = []
|
||||||
|
|
||||||
|
objects.forEach((obj) => {
|
||||||
|
const lines = obj.lines
|
||||||
|
|
||||||
|
lines.forEach((line) => {
|
||||||
|
const gridLine = new fabric.Line([line.x1, line.y1, line.x2, line.y2], {
|
||||||
|
stroke: 'gray',
|
||||||
|
strokeWidth: 1,
|
||||||
|
selectable: false,
|
||||||
|
evented: false,
|
||||||
|
opacity: 0.5,
|
||||||
|
name: 'tempGrid',
|
||||||
|
direction: line.x1 === line.x2 ? 'vertical' : 'horizontal',
|
||||||
|
visible: false,
|
||||||
|
})
|
||||||
|
gridLines.push(gridLine)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
gridLines.forEach((line) => {
|
||||||
|
canvas.add(line)
|
||||||
|
})
|
||||||
|
|
||||||
|
canvas.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
const removeTempGrid = () => {
|
||||||
|
if (!canvas) return
|
||||||
|
|
||||||
|
const tempGrids = canvas.getObjects().filter((obj) => obj.name === 'tempGrid' && !obj.visible)
|
||||||
|
tempGrids.forEach((grid) => canvas.remove(grid))
|
||||||
|
canvas.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
commonFunctions,
|
commonFunctions,
|
||||||
dimensionSettings,
|
dimensionSettings,
|
||||||
@ -916,5 +958,7 @@ export function useCommonUtils() {
|
|||||||
editText,
|
editText,
|
||||||
changeDimensionExtendLine,
|
changeDimensionExtendLine,
|
||||||
deleteOuterLineObject,
|
deleteOuterLineObject,
|
||||||
|
generateTempGrid,
|
||||||
|
removeTempGrid,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -402,7 +402,8 @@ export function useCanvasEvent() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
zoom = canvasZoom - 10
|
zoom = canvasZoom - 10
|
||||||
if (zoom < 10) { //50%->10%
|
if (zoom < 10) {
|
||||||
|
//50%->10%
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -412,8 +413,33 @@ export function useCanvasEvent() {
|
|||||||
|
|
||||||
const handleZoomClear = () => {
|
const handleZoomClear = () => {
|
||||||
setCanvasZoom(100)
|
setCanvasZoom(100)
|
||||||
canvas.set({ zoom: 1 })
|
|
||||||
canvas.viewportTransform = [1, 0, 0, 1, 0, 0]
|
zoomToAllObjects()
|
||||||
|
canvas.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
const zoomToAllObjects = () => {
|
||||||
|
const objects = canvas.getObjects().filter((obj) => obj.visible)
|
||||||
|
if (objects.length === 0) return
|
||||||
|
|
||||||
|
let minX = Infinity,
|
||||||
|
minY = Infinity
|
||||||
|
let maxX = -Infinity,
|
||||||
|
maxY = -Infinity
|
||||||
|
|
||||||
|
objects.forEach((obj) => {
|
||||||
|
const bounds = obj.getBoundingRect()
|
||||||
|
minX = Math.min(minX, bounds.left)
|
||||||
|
minY = Math.min(minY, bounds.top)
|
||||||
|
maxX = Math.max(maxX, bounds.left + bounds.width)
|
||||||
|
maxY = Math.max(maxY, bounds.top + bounds.height)
|
||||||
|
})
|
||||||
|
|
||||||
|
const centerX = (minX + maxX) / 2
|
||||||
|
const centerY = (minY + maxY) / 2
|
||||||
|
const centerPoint = new fabric.Point(centerX, centerY)
|
||||||
|
|
||||||
|
canvas.zoomToPoint(centerPoint, 1)
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -269,7 +269,7 @@ export const getDegreeByChon = (chon) => {
|
|||||||
* @returns {number}
|
* @returns {number}
|
||||||
*/
|
*/
|
||||||
export const getChonByDegree = (degree) => {
|
export const getChonByDegree = (degree) => {
|
||||||
return Number((Math.tan((degree * Math.PI) / 180) * 10).toFixed(1))
|
return Number((Math.tan((degree * Math.PI) / 180) * 10).toFixed(2))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1036,11 +1036,11 @@ export const getDegreeInOrientation = (degree) => {
|
|||||||
{ min: -51, max: -37, value: -45 },
|
{ min: -51, max: -37, value: -45 },
|
||||||
{ min: -36, max: -22, value: -30 },
|
{ min: -36, max: -22, value: -30 },
|
||||||
{ min: -21, max: -7, value: -15 },
|
{ min: -21, max: -7, value: -15 },
|
||||||
{ min: -6, max: 0, value: 0 }
|
{ min: -6, max: 0, value: 0 },
|
||||||
]
|
]
|
||||||
|
|
||||||
// 해당 범위에 맞는 값 찾기
|
// 해당 범위에 맞는 값 찾기
|
||||||
const range = degreeRanges.find(range => degree >= range.min && degree <= range.max)
|
const range = degreeRanges.find((range) => degree >= range.min && degree <= range.max)
|
||||||
return range ? range.value : degree
|
return range ? range.value : degree
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user