저장 시 줌 관련 문제 수정

This commit is contained in:
hyojun.choi 2025-12-02 11:05:03 +09:00
parent 1fff48bbfa
commit bf681dccba
6 changed files with 104 additions and 20 deletions

View File

@ -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]

View File

@ -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')

View File

@ -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)
} }
} }

View File

@ -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,
} }
} }

View File

@ -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()
} }

View File

@ -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
} }