qcast-front/src/hooks/common/useCommonUtils.js

915 lines
28 KiB
JavaScript

import { useEffect } from 'react'
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
import { wordDisplaySelector } from '@/store/settingAtom'
import { useEvent } from '@/hooks/useEvent'
import { checkLineOrientation, getDistance } from '@/util/canvas-util'
import { commonUtilsState, dimensionLineSettingsState } from '@/store/commonUtilsAtom'
import { fontSelector } from '@/store/fontAtom'
import { canvasState, currentMenuState } from '@/store/canvasAtom'
import { v4 as uuidv4 } from 'uuid'
import { usePopup } from '@/hooks/usePopup'
import Distance from '@/components/floor-plan/modal/distance/Distance'
import { usePolygon } from '@/hooks/usePolygon'
import { useObjectBatch } from '@/hooks/object/useObjectBatch'
import { BATCH_TYPE } from '@/common/common'
export function useCommonUtils() {
const canvas = useRecoilValue(canvasState)
const wordDisplay = useRecoilValue(wordDisplaySelector)
const { addCanvasMouseEventListener, addDocumentEventListener, initEvent, removeMouseEvent } = useEvent()
const dimensionSettings = useRecoilValue(dimensionLineSettingsState)
const dimensionLineTextFont = useRecoilValue(fontSelector('dimensionLineText'))
const lengthTextFont = useRecoilValue(fontSelector('lengthText'))
const commonTextFont = useRecoilValue(fontSelector('commonText'))
const [commonUtils, setCommonUtilsState] = useRecoilState(commonUtilsState)
const { addPopup, closeAll, targetClose } = usePopup()
const { drawDirectionArrow, addLengthText } = usePolygon()
const { applyDormers } = useObjectBatch({})
useEffect(() => {
commonTextMode()
if (commonUtils.dimension) {
commonDimensionMode()
return
}
if (commonUtils.distance) {
commonDistanceMode()
return
}
}, [commonUtils, dimensionSettings, commonTextFont, dimensionLineTextFont])
const commonTextMode = () => {
let textbox
if (commonUtils.text) {
targetClose('other')
setTimeout(() => {
commonTextKeyEvent()
addCanvasMouseEventListener('mouse:down', (event) => {
const pointer = canvas?.getPointer(event.e)
textbox = new fabric.Textbox('', {
left: pointer.x,
top: pointer.y,
width: 200,
editable: true,
name: 'commonText',
visible: wordDisplay,
fill: commonTextFont.fontColor.value,
fontFamily: commonTextFont.fontFamily.value,
fontSize: commonTextFont.fontSize.value,
fontStyle: commonTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal',
fontWeight: commonTextFont.fontWeight.value.toLowerCase().includes('bold') ? 'bold' : 'normal',
selectable: true,
lockMovementX: true,
lockMovementY: true,
originX: 'center',
originY: 'center',
})
canvas?.add(textbox)
canvas.setActiveObject(textbox)
textbox.enterEditing()
textbox.selectAll()
})
}, 100)
} else {
removeMouseEvent('mouse:down')
const activeObject = canvas?.getActiveObject()
const commonTexts = canvas?.getObjects().filter((obj) => obj.name === 'commonText')
if (commonTexts) {
commonTexts.forEach((text) => {
if (text.text === '') {
canvas?.remove(text)
}
})
}
/*if (activeObject && activeObject.name === 'commonText') {
if (activeObject && activeObject.isEditing) {
if (activeObject.text === '') {
canvas?.remove(activeObject)
} else {
activeObject.exitEditing()
}
//정책 협의
const texts = canvas.getObjects().filter((obj) => obj.name === 'commonText')
texts.forEach((text) => {
text.set({ editable: false })
})
canvas.renderAll()
}
}*/
initEvent()
}
}
const createDimensionArrow = (x, y, angle, id) => {
return new fabric.Triangle({
left: x,
top: y,
originX: 'center',
originY: 'center',
angle: angle,
width: 15,
height: 15,
fill: dimensionSettings.color,
selectable: true,
name: 'arrow',
id: id,
})
}
const createDimensionExtendLine = (line, lineDirection, extendLength) => {
let extendLine = []
const extendLineLength = extendLength ? extendLength : 0
if (lineDirection === 'horizontal') {
if (extendLineLength >= 0) {
extendLine = [
[line.x1, line.y1 - 20 - extendLineLength, line.x1, line.y1 + 20],
[line.x2, line.y2 - 20 - extendLineLength, line.x2, line.y2 + 20],
]
} else {
extendLine = [
[line.x1, line.y1 + 20 - extendLineLength, line.x1, line.y1 - 20],
[line.x2, line.y2 + 20 - extendLineLength, line.x2, line.y2 - 20],
]
}
} else {
if (extendLineLength >= 0) {
extendLine = [
[line.x1 - 20 - extendLineLength, line.y1, line.x1 + 20, line.y1],
[line.x2 - 20 - extendLineLength, line.y2, line.x2 + 20, line.y2],
]
} else {
extendLine = [
[line.x1 - 20 - extendLineLength, line.y1, line.x1 - 20, line.y1],
[line.x2 - 20 - extendLineLength, line.y2, line.x2 - 20, line.y2],
]
}
}
return extendLine
}
const calcDimensionPosition = (lineDirection, p1CenterX, p1CenterY, p2CenterX, p2CenterY) => {
// 첫 번째 포인트에 화살표 추가 좌측 -> 우측으로 그릴때
let paddingX = lineDirection === 'horizontal' ? p1CenterX + 7.5 : p1CenterX + 0.5
let paddingX2 = lineDirection === 'horizontal' ? p2CenterX - 7.5 : p2CenterX + 0.5
let paddingY = lineDirection === 'horizontal' ? p1CenterY + 0.5 : p1CenterY + 8
let paddingY2 = lineDirection === 'horizontal' ? p2CenterY + 0.5 : p2CenterY - 8
let angle1 = lineDirection === 'horizontal' ? -90 : 0
let angle2 = lineDirection === 'horizontal' ? 90 : 180
// 우측 -> 좌측으로 그릴땐 반대
if (paddingX > paddingX2 || paddingY > paddingY2) {
paddingX = lineDirection === 'horizontal' ? p1CenterX - 7.5 : p1CenterX + 0.5
paddingX2 = lineDirection === 'horizontal' ? p2CenterX + 7.5 : p2CenterX + 0.5
paddingY = lineDirection === 'horizontal' ? p1CenterY + 0.5 : p1CenterY - 7.5
paddingY2 = lineDirection === 'horizontal' ? p2CenterY + 0.5 : p2CenterY + 7.5
angle1 = lineDirection === 'horizontal' ? 90 : 180
angle2 = lineDirection === 'horizontal' ? 270 : 0
}
return {
paddingX,
paddingX2,
paddingY,
paddingY2,
angle1,
angle2,
}
}
const commonDimensionMode = () => {
if (commonUtils.dimension) {
const uuid = uuidv4()
let points = []
let distanceText = null
let minX, minY, maxX, maxY
// 화살표를 생성하는 함수
const circleOptions = {
radius: 5,
strokeWidth: 2,
stroke: 'red',
fill: 'white',
selectable: true,
}
const lineOptions = {
stroke: dimensionSettings.color,
strokeWidth: dimensionSettings.pixel,
selectable: true,
originX: 'center',
originY: 'center',
}
// 캔버스에 클릭 이벤트 추가
addCanvasMouseEventListener('mouse:down', (e) => {
let groupObjects = []
const pointer = canvas.getPointer(e.e)
let point
if (points.length === 0) {
// 첫 번째 포인트는 그대로 클릭한 위치에 추가
point = new fabric.Circle({
left: pointer.x - 5, // 반지름 반영
top: pointer.y - 5, // 반지름 반영
...circleOptions,
})
points.push(point)
canvas.add(point)
} else if (points.length === 1) {
// 두 번째 포인트는 첫 번째 포인트를 기준으로 수평 또는 수직으로만 배치
const p1 = points[0]
const deltaX = Math.abs(pointer.x - (p1.left + p1.radius))
const deltaY = Math.abs(pointer.y - (p1.top + p1.radius))
if (deltaX > deltaY) {
// 수평선 상에만 배치 (y 좌표 고정)
point = new fabric.Circle({
left: pointer.x - 5, // 반지름 반영
top: p1.top, // y 좌표 고정
...circleOptions,
})
} else {
// 수직선 상에만 배치 (x 좌표 고정)
point = new fabric.Circle({
left: p1.left, // x 좌표 고정
top: pointer.y - 5, // 반지름 반영
...circleOptions,
})
}
points.push(point)
canvas.add(point)
// 두 포인트의 중심 좌표 계산
const p2 = points[1]
const p1CenterX = p1.left + p1.radius
const p1CenterY = p1.top + p1.radius
const p2CenterX = p2.left + p2.radius
const p2CenterY = p2.top + p2.radius
points.forEach((point) => {
canvas?.remove(point)
})
// 두 포인트 간에 직선을 그림 (중심을 기준으로)
const line = new fabric.Line([p1CenterX, p1CenterY, p2CenterX, p2CenterY], {
...lineOptions,
name: 'centerLine',
id: uuid,
})
// canvas.add(line)
groupObjects.push(line)
const distance = getDistance(p1CenterX, p1CenterY, p2CenterX, p2CenterY)
const lineDirection = checkLineOrientation(line)
const extendListArray = createDimensionExtendLine(line, lineDirection)
extendListArray.forEach((line) => {
const extendLine = new fabric.Line(line, {
...lineOptions,
name: 'extendLine',
id: uuid,
})
groupObjects.push(extendLine)
})
const dimensionPosition = calcDimensionPosition(lineDirection, p1CenterX, p1CenterY, p2CenterX, p2CenterY)
const arrow1 = createDimensionArrow(dimensionPosition.paddingX, dimensionPosition.paddingY, dimensionPosition.angle1, uuid) // 반대 방향 화살표
const arrow2 = createDimensionArrow(dimensionPosition.paddingX2, dimensionPosition.paddingY2, dimensionPosition.angle2, uuid) // 정방향 화살표
groupObjects.push(arrow1, arrow2)
distanceText = new fabric.Text(`${distance * 10} `, {
left: (p1CenterX + p2CenterX) / 2 + (lineDirection === 'horizontal' ? 0 : -15),
top: (p1CenterY + p2CenterY) / 2 + (lineDirection === 'horizontal' ? +15 : 0),
fill: dimensionLineTextFont.fontColor.value,
fontSize: dimensionLineTextFont.fontSize.value,
fontFamily: dimensionLineTextFont.fontFamily.value,
fontStyle: dimensionLineTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal',
fontWeight: dimensionLineTextFont.fontWeight.value.toLowerCase().includes('bold') ? 'bold' : 'normal',
selectable: true,
textAlign: 'center',
originX: 'center',
originY: 'center',
angle: lineDirection === 'horizontal' ? 0 : 270,
name: 'dimensionLineText',
id: uuid,
// lockMovementX: false,
// lockMovementY: false,
})
// canvas.add(distanceText)
groupObjects.push(distanceText)
const group = new fabric.Group(groupObjects, {
name: 'dimensionGroup',
selectable: true,
originX: 'center',
originY: 'center',
lineDirection: lineDirection,
groupId: uuid,
length: distance * 10,
slopeAble: false,
angle1: null,
angle2: null,
})
canvas.add(group)
// groupObjects.push(distanceText)
canvas.renderAll()
// 거리 계산 후, 다음 측정을 위해 초기화
points = []
if (setCommonUtilsState)
setCommonUtilsState({
...commonUtilsState,
dimension: false,
})
initEvent()
}
// 캔버스 다시 그리기
canvas.renderAll()
})
}
}
const commonDistanceMode = () => {
if (commonUtils.distance) {
let points = []
let distanceText = null
let drawPoints = []
const crossOptions = {
stroke: 'black',
strokeWidth: 1,
originX: 'center',
originY: 'center',
name: 'distance',
}
const lineOptions = {
stroke: 'black',
strokeWidth: 1,
selectable: false,
strokeDashArray: [10, 5],
name: 'distance',
}
const textOptions = {
fill: 'black',
fontSize: 16,
selectable: true,
textAlign: 'center',
originX: 'center',
originY: 'center',
name: 'distance',
}
// 캔버스에 클릭 이벤트 추가
addCanvasMouseEventListener('mouse:down', function (e) {
const pointer = canvas.getPointer(e.e)
let point
let cross = {}
if (points.length === 0) {
point = new fabric.Line([pointer.x - 10, pointer.y, pointer.x + 10, pointer.y], crossOptions)
canvas.add(point)
cross['x'] = parseInt(point.left.toFixed(0))
drawPoints.push(point)
// 세로 선 생성 (십자 모양의 다른 축)
point = new fabric.Line([pointer.x, pointer.y - 10, pointer.x, pointer.y + 10], crossOptions)
cross['y'] = parseInt(point.top.toFixed(0))
drawPoints.push(point)
canvas.add(point)
points.push(cross)
} else if (points.length === 1) {
// 두 번째 포인트는 첫 번째 포인트를 기준으로 수평 또는 수직으로만 배치
const p1 = points[0]
point = new fabric.Line([pointer.x - 10, pointer.y, pointer.x + 10, pointer.y], crossOptions)
canvas.add(point)
cross['x'] = parseInt(point.left.toFixed(0))
drawPoints.push(point)
// 세로 선 생성 (십자 모양의 다른 축)
point = new fabric.Line([pointer.x, pointer.y - 10, pointer.x, pointer.y + 10], crossOptions)
canvas.add(point)
cross['y'] = parseInt(point.top.toFixed(0))
drawPoints.push(point)
points.push(cross)
let isParallel = false
if (points[0].x === points[1].x || points[0].y === points[1].y) {
isParallel = true
}
// 두 포인트의 중심 좌표 계산
const p2 = points[1]
const p1CenterX = p1.x
const p1CenterY = p1.y
const p2CenterX = p2.x
const p2CenterY = p2.y
// 두 포인트 간에 직선을 그림 (중심을 기준으로)
const line = new fabric.Line([p1CenterX, p1CenterY, p2CenterX, p2CenterY], lineOptions)
canvas.add(line)
const distance1 = getDistance(p1CenterX, p1CenterY, p2CenterX, p2CenterY)
// 거리 텍스트가 이미 있으면 업데이트하고, 없으면 새로 생성
distanceText = new fabric.Text(`${distance1 * 10}`, {
left: (p1CenterX + p2CenterX) / 2,
top: (p1CenterY + p2CenterY) / 2,
...textOptions,
})
canvas.add(distanceText)
let distance2 = 0
let distance3 = 0
if (!isParallel) {
const p3 = new fabric.Point(p2CenterX, p1CenterY)
const line2 = new fabric.Line([p2CenterX, p2CenterY, p3.x, p3.y], lineOptions)
const line3 = new fabric.Line([p3.x, p3.y, p1CenterX, p1CenterY], lineOptions)
canvas.add(line2)
canvas.add(line3)
distance2 = getDistance(p2CenterX, p2CenterY, p3.x, p3.y)
distance3 = getDistance(p3.x, p3.y, p1CenterX, p1CenterY)
distanceText = new fabric.Text(`${distance2 * 10}`, {
left: (p2CenterX + p3.x) / 2,
top: (p2CenterY + p3.y) / 2,
...textOptions,
})
canvas.add(distanceText)
distanceText = new fabric.Text(`${distance3 * 10}`, {
left: (p3.x + p1CenterX) / 2,
top: (p3.y + p1CenterY) / 2,
...textOptions,
})
canvas.add(distanceText)
}
const id = uuidv4()
addPopup(
id,
1,
<Distance
id={id}
distance={{
horizon: distance3 * 10,
vertical: distance2 * 10,
diagonal: distance1 * 10,
}}
deleteDistance={closeDistancePopup}
/>,
)
if (setCommonUtilsState)
setCommonUtilsState({
...commonUtils,
distance: false,
})
// 거리 계산 후, 다음 측정을 위해 초기화
points = []
}
// 캔버스 다시 그리기
canvas.renderAll()
})
}
}
const commonTextKeyEvent = () => {
//텍스트 모드일때 엔터 이벤트
addDocumentEventListener('keydown', document, (e) => {
if (e.key === 'Enter') {
const activeObject = canvas.getActiveObject()
if (activeObject && activeObject.name === 'commonText') {
if (activeObject && activeObject.isEditing) {
if (activeObject.text === '') {
canvas?.remove(activeObject)
} else {
activeObject.exitEditing()
}
//정책 협의
const texts = canvas.getObjects().filter((obj) => obj.name === 'commonText')
texts.forEach((text) => {
text.set({ editable: false })
})
canvas.renderAll()
if (setCommonUtilsState) setCommonUtilsState({ ...commonUtils, text: false })
}
}
initEvent()
}
})
}
const commonFunctions = (mode) => {
let tempStates = { ...commonUtils }
if (tempStates[mode]) {
tempStates[mode] = false
} else {
Object.keys(tempStates).forEach((key) => {
tempStates[key] = false
})
if (mode !== undefined) {
tempStates[mode] = true
}
}
if (setCommonUtilsState) setCommonUtilsState(tempStates)
}
const commonDeleteText = (object) => {
if (object) {
canvas?.remove(object)
if (object.id) {
const group = canvas.getObjects().filter((obj) => obj.id === object.id)
group.forEach((obj) => canvas?.remove(obj))
}
if (object.type === 'group') {
object._objects.forEach((obj) => {
if (obj.hasOwnProperty('texts')) {
obj.texts.forEach((text) => {
canvas?.remove(text)
})
}
})
} else {
if (object.hasOwnProperty('texts')) {
object.texts.forEach((text) => {
canvas?.remove(text)
})
}
}
}
}
const commonMoveObject = (obj) => {
if (obj) {
obj.set({
lockMovementX: false,
lockMovementY: false,
})
const originLeft = obj.left
const originTop = obj.top
addCanvasMouseEventListener('mouse:up', (e) => {
obj.set({
lockMovementX: true,
lockMovementY: true,
})
initEvent()
obj.setCoords()
updateGroupObjectCoords(obj, originLeft, originTop)
canvas?.renderAll()
})
}
}
const commonCopyObject = (obj) => {
if (obj) {
//도머는 복사하기 보다 새로 호출해서 만드는 방법으로 함
if (obj.name == BATCH_TYPE.TRIANGLE_DORMER || obj.name == BATCH_TYPE.PENTAGON_DORMER) {
//그룹 객체 0번에 도머 속성을 넣어둠
const dormerAttributes = obj._objects[0].dormerAttributes
const dormerName = obj._objects[0].name
const dormerParams = {
height: dormerAttributes.height,
width: dormerAttributes.width,
pitch: dormerAttributes.pitch,
offsetRef: dormerAttributes.offsetRef,
offsetWidthRef: dormerAttributes.offsetWidthRef,
directionRef: dormerAttributes.directionRef,
}
const buttonAct = dormerName == BATCH_TYPE.TRIANGLE_DORMER ? 3 : 4
applyDormers(dormerParams, buttonAct)
} else {
let clonedObj = null
obj.clone((cloned) => {
clonedObj = cloned
clonedObj.fontSize = lengthTextFont.fontSize.value
})
addCanvasMouseEventListener('mouse:move', (e) => {
const pointer = canvas?.getPointer(e.e)
if (!clonedObj) return
canvas
.getObjects()
.filter((obj) => obj.name === 'clonedObj')
.forEach((obj) => canvas?.remove(obj))
clonedObj.set({
left: pointer.x,
top: pointer.y,
name: 'clonedObj',
})
canvas.add(clonedObj)
})
addCanvasMouseEventListener('mouse:down', (e) => {
clonedObj.set({
lockMovementX: true,
lockMovementY: true,
name: obj.name,
editable: false,
id: uuidv4(), //복사된 객체라 새로 따준다
})
//객체가 그룹일 경우에는 그룹 아이디를 따로 넣어준다
if (clonedObj.type === 'group') clonedObj.set({ groupId: uuidv4() })
//배치면일 경우
if (obj.name === 'roof') {
clonedObj.setCoords()
clonedObj.fire('modified')
clonedObj.fire('polygonMoved')
clonedObj.set({ direction: obj.direction, directionText: obj.directionText, roofMaterial: obj.roofMaterial })
obj.lines.forEach((line, index) => {
clonedObj.lines[index].set({ attributes: line.attributes })
})
canvas.renderAll()
addLengthText(clonedObj) //수치 추가
drawDirectionArrow(clonedObj) //방향 화살표 추가
}
initEvent()
})
}
}
}
const editText = () => {
const obj = canvas?.getActiveObject()
obj.set({ editable: true })
obj.enterEditing()
commonTextKeyEvent()
}
const deleteObject = () => {
const selectedObj = canvas?.getActiveObjects()
if (selectedObj) {
selectedObj.forEach((obj) => {
commonDeleteText(obj)
})
}
selectedObj.forEach((obj) => {
if (obj.type === 'group') {
obj._objects.forEach((lines) => {
if (lines.hasOwnProperty('arrow')) {
canvas
.getObjects()
.filter((obj1) => obj1.name === 'arrow' && lines.id === obj1.parentId)
.forEach((arrow) => {
canvas?.remove(arrow)
})
}
})
}
})
}
const moveObject = () => {
const obj = canvas?.getActiveObject()
commonMoveObject(obj)
}
const copyObject = () => {
const obj = canvas?.getActiveObject()
commonCopyObject(obj)
}
const closeDistancePopup = () => {
const obj = canvas?.getObjects().filter((obj) => obj.name === 'distance')
if (obj) canvas.remove(...obj)
initEvent()
}
//선택된 그룹객체 restore 하고 item으로 다시 그리고 그 그린 객체 가지고 수정해서 재그룹화 시킨다
const changeDimensionExtendLine = () => {
const group = canvas?.getActiveObject()
const restoreGroup = group._restoreObjectsState()
canvas?.remove(group)
canvas?.renderAll()
restoreGroup._objects.forEach((obj) => {
canvas?.add(obj)
})
const id = group.groupId
const originLineDirection = group.lineDirection
const textObj = canvas?.getObjects().filter((obj) => obj.name === 'dimensionLineText' && obj.id === id)[0]
const centerLine = canvas?.getObjects().filter((obj) => obj.name === 'centerLine' && obj.id === id)[0]
const extendLine = canvas?.getObjects().filter((obj) => obj.name === 'extendLine' && obj.id === id)
const arrows = canvas?.getObjects().filter((obj) => obj.name === 'arrow' && obj.id === id)
const originX = centerLine.x1
const originY = centerLine.y1
let reGroupObj = []
addCanvasMouseEventListener('mouse:down', (e) => {
const pointer = canvas?.getPointer(e.e)
if (originLineDirection === 'horizontal') {
centerLine.set({
x1: centerLine.x1,
y1: pointer.y,
x2: centerLine.x2,
y2: pointer.y,
})
const differenceY = centerLine.y1 - originY
extendLine.forEach((obj) => {
obj.set({
x1: obj.x1,
y1: originY,
x2: obj.x2,
y2: differenceY > 0 ? pointer.y + 20 : pointer.y - 20,
})
})
arrows.forEach((arrow) => {
arrow.set({
top: pointer.y,
})
})
textObj.set({
top: pointer.y + 15,
})
textObj.setCoords()
} else {
centerLine.set({
x1: pointer.x,
y1: centerLine.y1,
x2: pointer.x,
y2: centerLine.y2,
})
const differenceX = centerLine.x1 - originX
extendLine.forEach((obj) => {
obj.set({
x1: originX,
y1: obj.y1,
x2: differenceX > 0 ? pointer.x + 20 : pointer.x - 20,
y2: obj.y2,
})
})
arrows.forEach((arrow) => {
arrow.set({
left: pointer.x,
})
})
textObj.set({
left: pointer.x - 15,
})
textObj.setCoords()
}
reGroupObj.push(centerLine, ...extendLine, ...arrows, textObj)
canvas?.remove(centerLine, ...extendLine, ...arrows, textObj)
const reGroup = new fabric.Group(reGroupObj, {
name: 'dimensionGroup',
selectable: true,
lineDirection: originLineDirection,
groupId: id,
})
reGroupObj = []
canvas.add(reGroup)
initEvent()
})
}
// 그룹 이동 시 라인 및 각 객체의 좌표를 절대 좌표로 업데이트하는 함수
function updateGroupObjectCoords(targetObj, originLeft, originTop) {
const diffrenceLeft = targetObj.left - originLeft
const diffrenceTop = targetObj.top - originTop
if (targetObj.type === 'group') {
targetObj.getObjects().forEach((obj) => {
// 그룹 내 객체의 절대 좌표를 계산
const originObjLeft = obj.left
const originObjTop = obj.top
if (obj.type === 'line') {
// Line 객체의 경우, x1, y1, x2, y2 절대 좌표 계산
obj.set({
x1: obj.x1 + diffrenceLeft,
y1: obj.y1 + diffrenceTop,
x2: obj.x2 + diffrenceLeft,
y2: obj.y2 + diffrenceTop,
})
obj.set({
left: originObjLeft,
top: originObjTop,
})
obj.fire('modified')
} else {
// 다른 객체의 경우 left, top 절대 좌표 설정
obj.set({
left: obj.left,
top: obj.top,
})
obj.fire('modified')
}
obj.setCoords() // 좌표 반영
})
} else {
if (targetObj.type === 'line') {
const originObjLeft = obj.left
const originObjTop = obj.top
if (obj.type === 'line') {
// Line 객체의 경우, x1, y1, x2, y2 절대 좌표 계산
obj.set({
x1: obj.x1 + diffrenceLeft,
y1: obj.y1 + diffrenceTop,
x2: obj.x2 + diffrenceLeft,
y2: obj.y2 + diffrenceTop,
})
obj.set({
left: originObjLeft,
top: originObjTop,
})
obj.fire('modified')
} else {
targetObj.set({
...targetObj,
left: targetObj.left,
top: targetObj.top,
})
obj.fire('modified')
}
targetObj.setCoords()
}
canvas?.renderAll()
}
}
const deleteOuterLineObject = () => {
const selectedOuterLine = canvas.getActiveObject()
if (selectedOuterLine && selectedOuterLine.name === 'outerLine') {
canvas.remove(selectedOuterLine)
canvas.renderAll()
}
}
return {
commonFunctions,
dimensionSettings,
commonMoveObject,
commonDeleteText,
deleteObject,
moveObject,
copyObject,
editText,
changeDimensionExtendLine,
deleteOuterLineObject,
}
}