diff --git a/src/app/api/image-upload/route.js b/src/app/api/image-upload/route.js index 92cf7da4..b96926a0 100644 --- a/src/app/api/image-upload/route.js +++ b/src/app/api/image-upload/route.js @@ -1,27 +1,15 @@ 'use server' -import fs from 'fs/promises' - import { NextResponse } from 'next/server' import { writeImage } from '@/lib/fileAction' export async function POST(req) { - const path = 'public/plan-bg-images' - const formData = await req.formData() const file = formData.get('file') const fileName = formData.get('fileName') const arrayBuffer = await file.arrayBuffer() const buffer = Buffer.from(arrayBuffer) - // const buffer = new Uint8Array(arrayBuffer) await writeImage(fileName, buffer) - // try { - // await fs.readdir(path) - // } catch { - // await fs.mkdir(path) - // } finally { - // await fs.writeFile(`${path}/${fileName}`, buffer) - // } return NextResponse.json({ fileNm: `${fileName}` }) } diff --git a/src/components/floor-plan/modal/ImgLoad.jsx b/src/components/floor-plan/modal/ImgLoad.jsx index d5724972..132780dd 100644 --- a/src/components/floor-plan/modal/ImgLoad.jsx +++ b/src/components/floor-plan/modal/ImgLoad.jsx @@ -8,6 +8,9 @@ import { useRefFiles } from '@/hooks/common/useRefFiles' import { usePlan } from '@/hooks/usePlan' import WithDraggable from '@/components/common/draggable/WithDraggable' +import { useCanvas } from '@/hooks/useCanvas' +import { useRecoilValue } from 'recoil' +import { canvasState } from '@/store/canvasAtom' export default function ImgLoad() { const { @@ -24,13 +27,21 @@ export default function ImgLoad() { handleMapImageDown, handleAddressDelete, } = useRefFiles() - const { currentCanvasPlan } = usePlan() + const { currentCanvasPlan, setCurrentCanvasPlan } = usePlan() const { getMessage } = useMessage() + const canvas = useRecoilValue(canvasState) const { floorPlanState, setFloorPlanState } = useContext(FloorPlanContext) const handleModal = () => { - console.log(floorPlanState) - setFloorPlanState({ ...floorPlanState, refFileModalOpen: false }) + console.log('floorPlanState', floorPlanState) + console.log('currentCanvasPlan', currentCanvasPlan) + console.log('refImage', refImage) + setFloorPlanState({ ...floorPlanState, refFileModalOpen: false, toggleRotate: false }) + setCurrentCanvasPlan({ + ...currentCanvasPlan, + bgImageName: currentCanvasPlan?.bgImageName ?? null, + mapPositionAddress, + }) } useEffect(() => { @@ -39,8 +50,26 @@ export default function ImgLoad() { }, [floorPlanState.refFileModalOpen]) useEffect(() => { - const refFileMethod = currentCanvasPlan?.mapPositionAddress === null ? '1' : '2' + const backGroundImage = canvas?.getObjects().filter((obj) => obj.name === 'backGroundImage') + if (backGroundImage && backGroundImage.length === 1) { + backGroundImage[0].set({ + lockMovementX: !floorPlanState.toggleRotate, + lockMovementY: !floorPlanState.toggleRotate, + lockRotation: !floorPlanState.toggleRotate, + lockScalingX: !floorPlanState.toggleRotate, + lockScalingY: !floorPlanState.toggleRotate, + selectable: floorPlanState.toggleRotate, + }) + } + }, [floorPlanState.toggleRotate]) + + useEffect(() => { + if (!currentCanvasPlan) return + console.log('currentCanvasPlan', currentCanvasPlan) + const refFileMethod = currentCanvasPlan?.mapPositionAddress === null || currentCanvasPlan?.mapPositionAddress?.trim() === '' ? '1' : '2' setRefFileMethod(refFileMethod) + setMapPositionAddress(currentCanvasPlan?.mapPositionAddress ?? '') + console.log(currentCanvasPlan) }, [currentCanvasPlan]) return ( diff --git a/src/hooks/common/useRefFiles.js b/src/hooks/common/useRefFiles.js index 5997b399..ecca2f62 100644 --- a/src/hooks/common/useRefFiles.js +++ b/src/hooks/common/useRefFiles.js @@ -1,11 +1,12 @@ import { useEffect, useRef, useState } from 'react' -import { useRecoilState } from 'recoil' +import { useRecoilState, useRecoilValue } from 'recoil' import { v4 as uuidv4 } from 'uuid' import { useSwal } from '@/hooks/useSwal' import { useAxios } from '../useAxios' -import { currentCanvasPlanState } from '@/store/canvasAtom' +import { canvasState, currentCanvasPlanState } from '@/store/canvasAtom' import { convertDwgToPng, removeImage, writeImageBuffer } from '@/lib/fileAction' +import { useCanvas } from '@/hooks/useCanvas' export function useRefFiles() { const converterUrl = process.env.NEXT_PUBLIC_CONVERTER_API_URL @@ -14,14 +15,10 @@ export function useRefFiles() { const [mapPositionAddress, setMapPositionAddress] = useState('') const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState) const queryRef = useRef(null) + const canvas = useRecoilValue(canvasState) const { swalFire } = useSwal() - const { get, promisePut, promisePost } = useAxios() - // const { currentCanvasPlan, setCurrentCanvasPlan } = usePlan() - - useEffect(() => { - console.log('refImage', refImage) - }, [refImage]) + const { get, promisePut, promiseGet, promisePost } = useAxios() useEffect(() => { if (refFileMethod === '1') { @@ -41,6 +38,8 @@ export function useRefFiles() { if (file && ['image/png', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/gif'].includes(file.type)) { // setRefImage(file) file.name.split('.').pop() === 'dwg' ? handleUploadConvertRefFile(file) : handleUploadImageRefFile(file) + + return } else { swalFire({ text: '이미지가 아닙니다.', @@ -54,6 +53,11 @@ export function useRefFiles() { type: 'confirm', confirmFn: () => { setRefImage(file) + const backGroundImage = canvas.getObjects().filter((obj) => obj.name === 'backGroundImage') + if (backGroundImage.length > 0) { + canvas.remove(backGroundImage) + } + canvas.renderAll() file.name.split('.').pop() === 'dwg' ? handleUploadConvertRefFile(file) : handleUploadImageRefFile(file) }, }) @@ -109,16 +113,20 @@ export function useRefFiles() { return } - const res = await get({ url: `http://localhost:3000/api/html2canvas?q=${queryRef.current.value}&fileNm=${currentCanvasPlan.id}&zoom=20` }) - // console.log('🚀 ~ handleMapImageDown ~ res:', res) - console.log('currentCanvasPlan', currentCanvasPlan) - setCurrentCanvasPlan((prev) => ({ ...prev, bgImageName: currentCanvasPlan.id, mapPositionAddress: queryRef.current.value })) + const res = await promiseGet({ + url: `http://localhost:3000/api/html2canvas?q=${queryRef.current.value}&fileNm=${currentCanvasPlan.id}&zoom=20`, + }).then((req, res) => { + console.log('handleMapImageDown', res) + handleBackImageLoadToCanvas(`plan-images/${currentCanvasPlan.id}.png`) + setCurrentCanvasPlan((prev) => ({ ...prev, bgImageName: currentCanvasPlan.id, mapPositionAddress: queryRef.current.value })) + }) } /** * 이미지 파일 업로드 * @param {*} file */ + const { handleBackImageLoadToCanvas } = useCanvas() const handleUploadImageRefFile = async (file) => { // console.log('🚀 ~ handleUploadImageRefFile ~ file:', file) const formData = new FormData() @@ -130,6 +138,7 @@ export function useRefFiles() { body: formData, }) + handleBackImageLoadToCanvas(`plan-images/${currentCanvasPlan.id}.png`) const result = await response.json() setRefImage(file) // console.log('🚀 ~ handleUploadImageRefFile ~ res:', result) diff --git a/src/hooks/useCanvas.js b/src/hooks/useCanvas.js index 46dbbb35..33e4a8d3 100644 --- a/src/hooks/useCanvas.js +++ b/src/hooks/useCanvas.js @@ -509,16 +509,34 @@ export function useCanvas(id) { const handleBackImageLoadToCanvas = (url) => { console.log('image load url: ', url) + canvas + .getObjects() + .filter((obj) => obj.name === 'backGroundImage') + .forEach((img) => { + canvas.remove(img) + canvas?.renderAll() + }) fabric.Image.fromURL(url, function (img) { + console.log(img) img.set({ left: 0, top: 0, - width: 1500, - height: 1500, - selectable: true, + width: img.width, + height: img.height, + name: 'backGroundImage', + selectable: false, + hasRotatingPoint: false, // 회전 핸들 활성화 + lockMovementX: false, + lockMovementY: false, + lockRotation: false, + lockScalingX: false, + lockScalingY: false, }) - canvas.add(img) - canvas.renderAll() + // image = img + canvas?.add(img) + canvas?.sendToBack(img) + canvas?.renderAll() + console.log(canvas.getObjects().filter((obj) => obj.name === 'backGroundImage')) setBackImg(img) }) } diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index 7e76cac5..7bf43bbd 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -6,7 +6,8 @@ import { useAxios } from '@/hooks/useAxios' import { useMessage } from '@/hooks/useMessage' import { useSwal } from '@/hooks/useSwal' import { SAVE_KEY } from '@/common/common' -import { readImage } from '@/lib/fileAction' +import { readImage, removeImage } from '@/lib/fileAction' +import { useCanvas } from '@/hooks/useCanvas' export function usePlan() { const [planNum, setPlanNum] = useState(0) @@ -14,6 +15,7 @@ export function usePlan() { const [currentCanvasStatus, setCurrentCanvasStatus] = useState(null) const [canvas, setCanvas] = useRecoilState(canvasState) + const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState) const [plans, setPlans] = useRecoilState(plansState) // 전체 plan const [modifiedPlans, setModifiedPlans] = useRecoilState(modifiedPlansState) // 변경된 canvas plan @@ -198,7 +200,7 @@ export function usePlan() { userId: userId, imageName: 'image_name', // api 필수항목이여서 임시로 넣음, 이후 삭제 필요 objectNo: objectNo, - mapPositionAddress: currentCanvasPlan.mapPositionAddress, + mapPositionAddress: currentCanvasPlan?.mapPositionAddress ?? null, canvasStatus: canvasToDbFormat(canvasStatus), } await promisePost({ url: '/api/canvas-management/canvas-statuses', data: planData }) @@ -218,6 +220,7 @@ export function usePlan() { const putCanvasStatus = async (canvasStatus) => { const planData = { id: currentCanvasPlan.id, + bgImageName: currentCanvasPlan?.id ?? null, mapPositionAddress: currentCanvasPlan.mapPositionAddress, canvasStatus: canvasToDbFormat(canvasStatus), } @@ -272,7 +275,7 @@ export function usePlan() { }, [plans]) const setBgImage = () => { - readImage(selectedPlan?.id) + // readImage(selectedPlan?.id) } /** @@ -321,6 +324,7 @@ export function usePlan() { .then((res) => { setPlans((plans) => plans.filter((plan) => plan.id !== id)) setModifiedPlans((modifiedPlans) => modifiedPlans.filter((planId) => planId !== currentCanvasPlan.id)) + removeImage(currentCanvasPlan.id) swalFire({ text: getMessage('plan.message.delete') }) }) .catch((error) => { @@ -358,6 +362,7 @@ export function usePlan() { plans, selectedPlan, currentCanvasPlan, + setCurrentCanvasPlan, modifiedPlans, modifiedPlanFlag, setModifiedPlanFlag, diff --git a/src/lib/fileAction.js b/src/lib/fileAction.js index 6f88758a..fe870374 100644 --- a/src/lib/fileAction.js +++ b/src/lib/fileAction.js @@ -90,4 +90,4 @@ const removeImage = async (fileName) => { } } -export { convertDwgToPng, writeImageBase64, writeImage, readImage, removeImage } +export { convertDwgToPng, writeImageBase64, writeImage, removeImage }