Merge branch 'feature/add-text'

This commit is contained in:
sangwook.yoo 2024-06-19 14:56:35 +09:00
commit ae181f1d69
5 changed files with 1595 additions and 285 deletions

1375
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -73,3 +73,7 @@ export function anchorWrapper(anchorIndex, fn) {
return actionPerformed return actionPerformed
} }
} }
export const getDistance = (x1, y1, x2, y2) => {
return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2))
}

View File

@ -1,3 +1,4 @@
import { getDistance } from '@/app/util/canvas-util'
import { useCanvas } from '@/hooks/useCanvas' import { useCanvas } from '@/hooks/useCanvas'
import { fabric } from 'fabric' import { fabric } from 'fabric'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
@ -16,7 +17,7 @@ export default function Roof() {
handleRotate, handleRotate,
attachCustomControlOnPolygon, attachCustomControlOnPolygon,
saveImage, saveImage,
handleFlip handleFlip,
} = useCanvas('canvas') } = useCanvas('canvas')
const addRect = () => { const addRect = () => {
@ -35,17 +36,31 @@ export default function Roof() {
} }
const addHorizontalLine = () => { const addHorizontalLine = () => {
const { x1, y1, x2, y2 } = { x1: 20, y1: 100, x2: 220, y2: 100 }
/** /**
* 시작X,시작Y,도착X,도착Y 좌표 * 시작X,시작Y,도착X,도착Y 좌표
*/ */
const horizontalLine = new fabric.Line([20, 20, 100, 20], { const horizontalLine = new fabric.Line([x1, y1, x2, y2], {
name: uuidv4(), name: uuidv4(),
stroke: 'red', stroke: 'red',
strokeWidth: 3, strokeWidth: 3,
selectable: true, selectable: true,
}) })
addShape(horizontalLine) const text = new fabric.Text(getDistance(x1, y1, x2, y2).toString(), {
fontSize: 20,
left: (x2 - x1) / 2,
top: y1 - 20,
})
const group = new fabric.Group([horizontalLine, text], {
left: 20,
top: 20,
})
// addShape(horizontalLine)
addShape(group)
console.log(JSON.stringify(canvas))
} }
const addVerticalLine = () => { const addVerticalLine = () => {
@ -191,7 +206,6 @@ export default function Roof() {
> >
도형반전 도형반전
</button> </button>
</div> </div>
<div <div

View File

@ -12,7 +12,6 @@ const CANVAS = {
} }
export function useCanvas(id) { export function useCanvas(id) {
const [canvas, setCanvas] = useState() const [canvas, setCanvas] = useState()
const [isLocked, setIsLocked] = useState(false) const [isLocked, setIsLocked] = useState(false)
const [history, setHistory] = useState([]) const [history, setHistory] = useState([])
@ -26,7 +25,7 @@ export function useCanvas(id) {
const c = new fabric.Canvas(id, { const c = new fabric.Canvas(id, {
height: CANVAS.HEIGHT, height: CANVAS.HEIGHT,
width: CANVAS.WIDTH, width: CANVAS.WIDTH,
backgroundColor: 'white' backgroundColor: 'white',
}) })
// settings for all canvas in the app // settings for all canvas in the app
@ -58,9 +57,9 @@ export function useCanvas(id) {
document.addEventListener('keydown', handleKeyDown) document.addEventListener('keydown', handleKeyDown)
}) })
canvas?.on('mouse:move', drawMouseLines); canvas?.on('mouse:move', drawMouseLines)
canvas?.on('mouse:down', handleMouseDown); canvas?.on('mouse:down', handleMouseDown)
canvas?.on('mouse:out', removeMouseLines); canvas?.on('mouse:out', removeMouseLines)
} }
const removeEventOnCanvas = () => { const removeEventOnCanvas = () => {
@ -68,8 +67,8 @@ export function useCanvas(id) {
canvas?.off('object:modified') canvas?.off('object:modified')
canvas?.off('object:removed') canvas?.off('object:removed')
canvas?.off('object:added') canvas?.off('object:added')
canvas?.off('mouse:move', drawMouseLines); canvas?.off('mouse:move', drawMouseLines)
canvas?.off('mouse:down', handleMouseDown); canvas?.off('mouse:down', handleMouseDown)
} }
/** /**
@ -77,11 +76,13 @@ export function useCanvas(id) {
*/ */
const removeMouseLines = () => { const removeMouseLines = () => {
if (canvas?._objects.length > 0) { if (canvas?._objects.length > 0) {
const mouseLines = canvas?._objects.filter((obj) => obj.name === 'mouseLine'); const mouseLines = canvas?._objects.filter(
mouseLines.forEach(item => canvas?.remove(item)); (obj) => obj.name === 'mouseLine',
)
mouseLines.forEach((item) => canvas?.remove(item))
} }
canvas?.renderAll(); canvas?.renderAll()
}; }
/** /**
* 눈금 그리기 * 눈금 그리기
@ -120,49 +121,55 @@ export function useCanvas(id) {
const drawMouseLines = (e) => { const drawMouseLines = (e) => {
// 현재 마우스 포인터의 위치를 가져옵니다. // 현재 마우스 포인터의 위치를 가져옵니다.
const pointer = canvas?.getPointer(e.e); const pointer = canvas?.getPointer(e.e)
// 기존에 그려진 가이드라인을 제거합니다. // 기존에 그려진 가이드라인을 제거합니다.
removeMouseLines(); removeMouseLines()
if(canvas?.getActiveObject()) { if (canvas?.getActiveObject()) {
return return
} }
// 가로선을 그립니다. // 가로선을 그립니다.
const horizontalLine = new fabric.Line([0, pointer.y, CANVAS.WIDTH, pointer.y], { const horizontalLine = new fabric.Line(
stroke: 'black', [0, pointer.y, CANVAS.WIDTH, pointer.y],
strokeWidth: 1, {
selectable: false, stroke: 'black',
name: 'mouseLine', strokeWidth: 1,
strokeDashArray: [5, 5] selectable: false,
}); name: 'mouseLine',
strokeDashArray: [5, 5],
},
)
// 세로선을 그립니다. // 세로선을 그립니다.
const verticalLine = new fabric.Line([pointer.x, 0, pointer.x, CANVAS.HEIGHT], { const verticalLine = new fabric.Line(
stroke: 'black', [pointer.x, 0, pointer.x, CANVAS.HEIGHT],
strokeWidth: 1, {
selectable: false, stroke: 'black',
name: 'mouseLine', strokeWidth: 1,
strokeDashArray: [5, 5] selectable: false,
}); name: 'mouseLine',
strokeDashArray: [5, 5],
},
)
// 선들을 캔버스에 추가합니다. // 선들을 캔버스에 추가합니다.
canvas?.add(horizontalLine, verticalLine); canvas?.add(horizontalLine, verticalLine)
// 캔버스를 다시 그립니다. // 캔버스를 다시 그립니다.
canvas?.renderAll(); canvas?.renderAll()
}; }
const handleMouseDown = (e) => { const handleMouseDown = (e) => {
// 현재 마우스 포인터의 위치를 가져옵니다. // 현재 마우스 포인터의 위치를 가져옵니다.
if(canvas?.getActiveObject()) { if (canvas?.getActiveObject()) {
return; return
} }
const pointer = canvas?.getPointer(e.e); const pointer = canvas?.getPointer(e.e)
// 클릭한 위치를 배열에 추가합니다. // 클릭한 위치를 배열에 추가합니다.
points.current.push(pointer); points.current.push(pointer)
// 두 점을 모두 찍었을 때 사각형을 그립니다. // 두 점을 모두 찍었을 때 사각형을 그립니다.
if (points.current.length === 2) { if (points.current.length === 2) {
@ -174,15 +181,15 @@ export function useCanvas(id) {
fill: 'transparent', fill: 'transparent',
stroke: 'black', stroke: 'black',
strokeWidth: 1, strokeWidth: 1,
}); })
// 사각형을 캔버스에 추가합니다. // 사각형을 캔버스에 추가합니다.
canvas?.add(rect); canvas?.add(rect)
// 배열을 초기화합니다. // 배열을 초기화합니다.
points.current = []; points.current = []
} }
}; }
/** /**
* 눈금 모양에 맞게 움직이도록 한다. * 눈금 모양에 맞게 움직이도록 한다.
@ -456,36 +463,35 @@ export function useCanvas(id) {
const dataURL = canvas?.toDataURL('png') const dataURL = canvas?.toDataURL('png')
// 이미지 다운로드 링크 생성 // 이미지 다운로드 링크 생성
const link = document.createElement('a'); const link = document.createElement('a')
link.download = `${title}.png`; link.download = `${title}.png`
link.href = dataURL; link.href = dataURL
// 링크 클릭하여 이미지 다운로드 // 링크 클릭하여 이미지 다운로드
link.click(); link.click()
} }
const handleFlip = () => { const handleFlip = () => {
const target = canvas?.getActiveObject(); const target = canvas?.getActiveObject()
if (!target) { if (!target) {
return; return
} }
// 현재 scaleX 및 scaleY 값을 가져옵니다. // 현재 scaleX 및 scaleY 값을 가져옵니다.
const scaleX = target.scaleX; const scaleX = target.scaleX
// const scaleY = target.scaleY; // const scaleY = target.scaleY;
// 도형을 반전시킵니다. // 도형을 반전시킵니다.
target.set({ target.set({
scaleX: scaleX * -1, scaleX: scaleX * -1,
// scaleY: scaleY * -1 // scaleY: scaleY * -1
}); })
// 캔버스를 다시 그립니다. // 캔버스를 다시 그립니다.
canvas?.renderAll(); canvas?.renderAll()
} }
return { return {
canvas, canvas,
addShape, addShape,
@ -499,6 +505,6 @@ export function useCanvas(id) {
handleRotate, handleRotate,
attachCustomControlOnPolygon, attachCustomControlOnPolygon,
saveImage, saveImage,
handleFlip handleFlip,
} }
} }

373
yarn.lock

File diff suppressed because it is too large Load Diff