From 8eca824c8fb9fb354ed85f96a13e994affdc1373 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 13 Apr 2026 10:35:12 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=20=EC=8B=9C=20=ED=99=94=EC=82=B4=ED=91=9C=20=EC=9C=84?= =?UTF-8?q?=EC=B9=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/common/useRoofFn.js | 38 ++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/hooks/common/useRoofFn.js b/src/hooks/common/useRoofFn.js index e7a06d38..4721d581 100644 --- a/src/hooks/common/useRoofFn.js +++ b/src/hooks/common/useRoofFn.js @@ -250,7 +250,7 @@ export function useRoofFn() { const allRoofObject = canvas .getObjects() - .filter((obj) => obj !== roof && (obj.attributes?.roofId === roof.id || obj.parentId === roof.id || obj.parentId === wall.id)) + .filter((obj) => obj !== roof && (obj.attributes?.roofId === roof.id || obj.parentId === roof.id || (wall && obj.parentId === wall.id))) /** 지붕이 움직인 만큼의 delta를 구한다. */ const originalRoofLeft = roof.left @@ -276,15 +276,33 @@ export function useRoofFn() { // Move all related objects by the delta allRoofObject.forEach((obj) => { if (obj.points !== undefined) { - obj.set({ - left: obj.left + deltaX, - top: obj.top + deltaY, - originX: 'center', - originY: 'center', - objectCaching: false, - }) - obj.fire('polygonMoved') - obj.fire('modified') + if (obj.name === 'arrow') { + // arrow 는 originX='left' 기본값이며 polygonMoved 가 left=pathOffset(중심) 으로 + // 리셋하면 origin 불일치로 위치가 밀리므로, 단순 점 이동만 수행. + obj.points = obj.points.map((p) => ({ x: p.x + deltaX, y: p.y + deltaY })) + const dim = obj._calcDimensions({}) + obj.set({ + left: dim.left + dim.width / 2, + top: dim.top + dim.height / 2, + width: dim.width, + height: dim.height, + pathOffset: { x: dim.left + dim.width / 2, y: dim.top + dim.height / 2 }, + originX: 'center', + originY: 'center', + objectCaching: false, + }) + obj.setCoords() + } else { + obj.set({ + left: obj.left + deltaX, + top: obj.top + deltaY, + originX: 'center', + originY: 'center', + objectCaching: false, + }) + obj.fire('polygonMoved') + obj.fire('modified') + } } else { obj.set({ left: obj.left + deltaX, -- 2.47.2 From 9c25d3ed66dfc6fd7c92486d9154725d5eaf8f56 Mon Sep 17 00:00:00 2001 From: ysCha Date: Mon, 13 Apr 2026 11:04:59 +0900 Subject: [PATCH 2/2] =?UTF-8?q?[1960]=EC=B6=9C=EB=A0=A5=EB=90=9C=20[?= =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=8F=84=C2=B7=EA=B3=84=ED=86=B5=EB=8F=84]?= =?UTF-8?q?=EC=97=90=20=EA=B0=80=EB=8C=80=EA=B0=80=20=ED=91=9C=EC=8B=9C?= =?UTF-8?q?=EB=90=98=EB=8A=94=20=EA=B2=BD=EC=9A=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/floorPlan/useImgLoader.js | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/hooks/floorPlan/useImgLoader.js b/src/hooks/floorPlan/useImgLoader.js index dc272441..47eea944 100644 --- a/src/hooks/floorPlan/useImgLoader.js +++ b/src/hooks/floorPlan/useImgLoader.js @@ -84,15 +84,25 @@ export function useImgLoader() { const originalBg = canvas.backgroundColor canvas.backgroundColor = '#ffffff' - // CORS 대응: 이미지 오브젝트에 crossOrigin 설정 - canvas.getObjects('image').forEach((obj) => { - if (obj.getSrc) { - const img = new Image() - img.crossOrigin = 'anonymous' - img.src = obj.getSrc() - obj.setElement(img) - } - }) + // CORS 대응: 이미지 오브젝트에 crossOrigin 설정 (로드 완료 대기) + const imageObjects = canvas.getObjects('image').filter((obj) => obj.getSrc) + await Promise.all( + imageObjects.map( + (obj) => + new Promise((resolve) => { + const img = new Image() + img.crossOrigin = 'anonymous' + img.onload = () => { + obj.setElement(img) + resolve() + } + img.onerror = () => { + resolve() + } + img.src = obj.getSrc() + }), + ), + ) canvas.renderAll() -- 2.47.2