From 864e892a7dd8820ace9ff2d76f0c87e0d101af71 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 8 Jul 2024 14:17:26 +0900 Subject: [PATCH] =?UTF-8?q?QLine=20=EA=B7=B8=EB=A3=B9=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Roof2.jsx | 20 +++++- src/components/fabric/QLine.js | 108 +++++++++++++++++---------------- src/hooks/useMode.js | 2 +- 3 files changed, 77 insertions(+), 53 deletions(-) diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx index 77a5fd38..ffd2e005 100644 --- a/src/components/Roof2.jsx +++ b/src/components/Roof2.jsx @@ -2,7 +2,6 @@ import { useCanvas } from '@/hooks/useCanvas' import { useEffect, useState } from 'react' import { Mode, useMode } from '@/hooks/useMode' import QRect from '@/components/fabric/QRect' -import QLine from '@/components/fabric/QLine' import QPolygon from '@/components/fabric/QPolygon' import RangeSlider from './ui/RangeSlider' @@ -12,6 +11,7 @@ import { fontSizeState, sortedPolygonArray, } from '@/store/canvasAtom' +import { QLine } from '@/components/fabric/QLine' export default function Roof2() { const { @@ -165,6 +165,18 @@ export default function Roof2() { } } + const makeQLine = () => { + if (canvas) { + const line = new QLine([50, 50, 200, 50], { + stroke: 'black', + strokeWidth: 2, + fontSize: fontSize, + }) + + canvas?.add(line) + } + } + return ( <> {canvas && ( @@ -303,6 +315,12 @@ export default function Roof2() { > 회전 +
diff --git a/src/components/fabric/QLine.js b/src/components/fabric/QLine.js index a5d63c83..667fe213 100644 --- a/src/components/fabric/QLine.js +++ b/src/components/fabric/QLine.js @@ -1,27 +1,39 @@ import { fabric } from 'fabric' -export default class QLine extends fabric.Line { +export class QLine extends fabric.Group { + line + text + fontSize length - #text - #viewLengthText - #fontSize + x1 + y1 + x2 + y2 + direction type = 'QLine' + constructor(points, option) { + const [x1, y1, x2, y2] = points + if (!option.fontSize) { throw new Error('Font size is required.') } - super(points, option) - this.#fontSize = option.fontSize - this.#init(option) + const line = new fabric.Line(points, { ...option, strokeWidth: 1 }) + super([line], {}) + + this.x1 = x1 + this.y1 = y1 + this.x2 = x2 + this.y2 = y2 + this.line = line + this.fontSize = option.fontSize + this.direction = option.direction + this.#init() this.#addControl() } - #init(option) { - // 선의 길이를 계산하여 length 속성을 초기화합니다. - const dx = this.x2 - this.x1 - const dy = this.y2 - this.y1 - this.length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(0)) - this.#viewLengthText = option.viewLengthText ?? true + #init() { + this.#addLengthText() } #addControl() { @@ -34,52 +46,46 @@ export default class QLine extends fabric.Line { }) this.on('modified', (e) => { - const scaleX = this.scaleX - const scaleY = this.scaleY - - // x1, y1, x2, y2 속성을 새로운 좌표로 설정합니다. - this.x1 = this.left - this.y1 = this.top - this.x2 = this.left + this.width * scaleX - this.y2 = this.top + this.height * scaleY - - const dx = this.x2 - this.x1 - const dy = this.y2 - this.y1 - const length = Math.sqrt(dx * dx + dy * dy) - this.length = Number(length.toFixed(0)) // 선의 길이를 length 속성에 저장합니다. this.#addLengthText() }) - this.on('removed', () => { - this.canvas.remove(this.#text) - this.#text = null + this.on('selected', () => { + Object.keys(this.controls).forEach((controlKey) => { + if (controlKey !== 'ml' && controlKey !== 'mr') { + this.setControlVisible(controlKey, false) + } + }) }) } - setViewLengthText(bool) { - this.#viewLengthText = bool - this.#addLengthText() + #addLengthText() { + if (this.text) { + this.removeWithUpdate(this.text) + this.text = null + } + + const scaleX = this.scaleX + const scaleY = this.scaleY + const x1 = this.left + const y1 = this.top + const x2 = this.left + this.width * scaleX + const y2 = this.top + this.height * scaleY + const dx = x2 - x1 + const dy = y2 - y1 + this.length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(0)) + + const text = new fabric.Textbox(this.length.toString(), { + left: (x1 + x2) / 2, + top: (y1 + y2) / 2, + fontSize: this.fontSize, + }) + this.text = text + this.addWithUpdate(text) } setFontSize(fontSize) { - this.#fontSize = fontSize - this.#addLengthText() - } - - #addLengthText() { - if (this.#text) { - this.canvas.remove(this.#text) - } - - if (this.#viewLengthText) { - const text = new fabric.Text(this.length.toString(), { - left: (this.x1 + this.x2) / 2, - top: (this.y1 + this.y2) / 2, - fontSize: this.#fontSize, - selectable: false, - }) - this.#text = text - this.canvas.add(text) - } + this.fontSize = fontSize + this.text.set({ fontSize }) + this.addWithUpdate() } } diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js index 256b4968..a44b0407 100644 --- a/src/hooks/useMode.js +++ b/src/hooks/useMode.js @@ -1,5 +1,4 @@ import { useEffect, useRef, useState } from 'react' -import QLine from '@/components/fabric/QLine' import QRect from '@/components/fabric/QRect' import QPolygon from '@/components/fabric/QPolygon' import { @@ -9,6 +8,7 @@ import { } from '@/util/canvas-util' import { useRecoilState } from 'recoil' import { fontSizeState, sortedPolygonArray } from '@/store/canvasAtom' +import { QLine } from '@/components/fabric/QLine' export const Mode = { DRAW_LINE: 'drawLine', // 기준선 긋기모드