From 215cdde7cc68b2869a45cbf7b8fc9fd65cb5e851 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 1 Jul 2024 10:41:17 +0900 Subject: [PATCH] =?UTF-8?q?Q=EC=8B=9C=EB=A6=AC=EC=A6=88=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Roof2.jsx | 16 +---- src/components/fabric/QLine.js | 20 +++--- src/components/fabric/QPolygon.js | 103 +++++++++++++++++------------- src/components/fabric/QRect.js | 91 ++++++++++++++++---------- src/hooks/useMode.js | 4 +- 5 files changed, 131 insertions(+), 103 deletions(-) diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx index 19c64337..6cc92fe2 100644 --- a/src/components/Roof2.jsx +++ b/src/components/Roof2.jsx @@ -34,13 +34,9 @@ export default function Roof2() { stroke: 'black', width: 400, height: 100, - viewLengthText: true, // 이 속성이 true로 설정되면, 사각형의 각 선분의 길이를 표시하는 텍스트가 생성됩니다. - selectable: false, }) canvas?.add(rect) - - setTimeout(() => rect.delete(), 500) } } @@ -60,25 +56,19 @@ export default function Roof2() { const polygon = new QPolygon( [ { x: 100, y: 100 }, - { x: 200, y: 200 }, - { x: 200, y: 300 }, - { x: 100, y: 300 }, + { x: 600, y: 200 }, + { x: 700, y: 800 }, + { x: 100, y: 800 }, ], { fill: 'transparent', stroke: 'black', strokeWidth: 2, - - viewLengthText: true, // 이 속성이 true로 설정되면, 다각형의 각 변의 길이를 표시하는 텍스트가 생성됩니다. selectable: true, }, ) canvas?.add(polygon) - - setTimeout(() => { - polygon.fillCell({ width: 10, height: 20 }) - }, 500) } } diff --git a/src/components/fabric/QLine.js b/src/components/fabric/QLine.js index 8beda276..68b3efab 100644 --- a/src/components/fabric/QLine.js +++ b/src/components/fabric/QLine.js @@ -1,8 +1,8 @@ import { fabric } from 'fabric' export default class QLine extends fabric.Line { - length - text + #length + #text constructor(points, option) { super(points, option) @@ -14,7 +14,7 @@ export default class QLine extends fabric.Line { // 선의 길이를 계산하여 length 속성을 초기화합니다. const dx = this.x2 - this.x1 const dy = this.y2 - this.y1 - this.length = Math.sqrt(dx * dx + dy * dy).toFixed(0) + this.#length = Math.sqrt(dx * dx + dy * dy).toFixed(0) this.viewLengthText = option.viewLengthText ?? true } @@ -36,9 +36,13 @@ export default class QLine extends fabric.Line { const dx = this.x2 - this.x1 const dy = this.y2 - this.y1 const length = Math.sqrt(dx * dx + dy * dy) - this.length = length.toFixed(0) // 선의 길이를 length 속성에 저장합니다. + this.#length = length.toFixed(0) // 선의 길이를 length 속성에 저장합니다. this.#addLengthText() }) + + this.on('removed', () => { + this.canvas.remove(this.#text) + }) } setViewLengthText(bool) { @@ -47,18 +51,18 @@ export default class QLine extends fabric.Line { } #addLengthText() { - if (this.text) { - this.canvas.remove(this.text) + if (this.#text) { + this.canvas.remove(this.#text) } if (this.viewLengthText) { - const text = new fabric.Text(this.length, { + const text = new fabric.Text(this.#length, { left: (this.x1 + this.x2) / 2, top: (this.y1 + this.y2) / 2, fontSize: 16, selectable: false, }) - this.text = text + this.#text = text this.canvas.add(text) } } diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js index 812f7ef0..6338253d 100644 --- a/src/components/fabric/QPolygon.js +++ b/src/components/fabric/QPolygon.js @@ -1,65 +1,88 @@ import { fabric } from 'fabric' -import QRect from '@/components/fabric/QRect' import { distanceBetweenPoints } from '@/app/util/canvas-util' export default class QPolygon extends fabric.Polygon { - group - polygon + #viewLengthText + #text = [] constructor(points, option) { super(points, option) - this.polygon = this - this.on('added', () => { - if (this.viewLengthText) { - this.#addLengthText() - } else { - this.#makeGroupItem([this]) + this.#init(points) + this.#addControl() + } + + #init(points) { + this.#viewLengthText = points.viewLengthText ?? true + } + + setViewLengthText(bool) { + this.#viewLengthText = bool + this.#addLengthText() + } + + #addControl() { + this.on('removed', () => { + if (this.#text.length > 0) { + this.#text.forEach((text) => { + this.canvas.remove(text) + }) + this.#text = [] } }) - } - #makeGroupItem(groupItems) { - const group = new fabric.Group(groupItems, { - selectable: this.selectable, - type: 'QRect', - canvas: this.canvas, + this.on('added', () => { + this.#addLengthText() }) - this.group = group - this.canvas.add(group) - this.canvas.renderAll() - this.canvas.remove(this) - } + this.on('modified', (e) => { + this.#addLengthText() + }) - delete() { - this.group.canvas.remove(this.group) + this.on('scaling', (e) => { + this.#addLengthText() + }) + + this.on('removed', (e) => { + this.#text.forEach((text) => { + this.canvas.remove(text) + }) + }) } #addLengthText() { - const groupItems = [this] + if (this.#text.length > 0) { + this.#text.forEach((text) => { + this.canvas.remove(text) + }) + this.#text = [] + } + if (!this.#viewLengthText) { + return + } + + const scaleX = this.scaleX + const scaleY = this.scaleY for (let i = 0; i < this.points.length; i++) { const start = this.points[i] const end = this.points[(i + 1) % this.points.length] - const dx = end.x - start.x - const dy = end.y - start.y + const dx = (end.x - start.x) * scaleX + const dy = (end.y - start.y) * scaleY const length = Math.sqrt(dx * dx + dy * dy) const text = new fabric.Text(length.toFixed(0), { - left: (start.x + end.x) / 2, - top: (start.y + end.y) / 2, + left: ((start.x + end.x) / 2) * scaleX, + top: ((start.y + end.y) / 2) * scaleY, fontSize: 16, selectable: false, }) - - groupItems.push(text) + this.#text.push(text) + this.canvas.add(text) } - - this.#makeGroupItem(groupItems) } #distanceFromEdge(point) { - const vertices = this.getPoints() + const vertices = this.points let minDistance = Infinity for (let i = 0; i < vertices.length; i++) { @@ -92,7 +115,7 @@ export default class QPolygon extends fabric.Polygon { } fillCell(cell = { width: 50, height: 100, padding: 10 }) { - const points = this.getPoints() + const points = this.points let bounds try { @@ -136,24 +159,16 @@ export default class QPolygon extends fabric.Polygon { ) if (isInside) { - this.group.canvas.add(rect) + this.canvas.add(rect) } } } - this.group.canvas.renderAll() - } - - getPoints() { - return this.points - } - - getInfo() { - return this + this.canvas.renderAll() } inPolygon(point) { - const vertices = this.getPoints() + const vertices = this.points let intersects = 0 for (let i = 0; i < vertices.length; i++) { diff --git a/src/components/fabric/QRect.js b/src/components/fabric/QRect.js index c460e70f..a99f5adf 100644 --- a/src/components/fabric/QRect.js +++ b/src/components/fabric/QRect.js @@ -1,49 +1,76 @@ import { fabric } from 'fabric' export default class QRect extends fabric.Rect { - group - constructor(options) { - super(options) + #text = [] + #viewLengthText + constructor(points, option) { + super(points, option) + this.#init(points) + this.#addControl() + } - this.on('added', () => { - if (this.viewLengthText) { - this.#addLengthText() - } else { - this.#makeGroupItem([this]) + #init(points) { + this.#viewLengthText = points.viewLengthText ?? true + } + + setViewLengthText(bool) { + this.#viewLengthText = bool + this.#addLengthText() + } + + #addControl() { + this.on('removed', () => { + if (this.#text.length > 0) { + this.#text.forEach((text) => { + this.canvas.remove(text) + }) + this.#text = [] } }) - } - delete() { - this.group.canvas.remove(this.group) - } - - #makeGroupItem(groupItems) { - const group = new fabric.Group(groupItems, { - selectable: this.selectable, - type: 'QRect', - canvas: this.canvas, + this.on('added', () => { + this.#addLengthText() }) - this.group = group - this.canvas.add(group) - this.canvas.renderAll() - this.canvas.remove(this) - } + this.on('modified', (e) => { + this.#addLengthText() + }) + this.on('scaling', (e) => { + this.#addLengthText() + }) + + this.on('removed', (e) => { + this.#text.forEach((text) => { + this.canvas.remove(text) + }) + }) + } #addLengthText() { + if (this.#text.length > 0) { + this.#text.forEach((text) => { + this.canvas.remove(text) + }) + this.#text = [] + } + + if (!this.#viewLengthText) { + return + } + + const scaleX = this.scaleX + const scaleY = this.scaleY + const lines = [ { start: { x: this.left, y: this.top }, - end: { x: this.left + this.width, y: this.top }, + end: { x: this.left + this.width * scaleX, y: this.top }, }, { - start: { x: this.left, y: this.top + this.height }, + start: { x: this.left, y: this.top + this.height * scaleY }, end: { x: this.left, y: this.top }, }, ] - const groupItems = [this] - lines.forEach((line) => { const dx = line.end.x - line.start.x const dy = line.end.y - line.start.y @@ -55,14 +82,8 @@ export default class QRect extends fabric.Rect { fontSize: 16, selectable: false, }) - - groupItems.push(text) + this.#text.push(text) + this.canvas.add(text) }) - - this.#makeGroupItem(groupItems) - } - - getInfo() { - return this } } diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js index b5a8cd06..1098643f 100644 --- a/src/hooks/useMode.js +++ b/src/hooks/useMode.js @@ -356,9 +356,6 @@ export function useMode() { if (line.type === 'line') { canvas?.remove(line) } - if (line.type === 'QLine') { - line.delete() - } }) // 점 배열을 사용하여 새로운 다각형 객체를 생성합니다. @@ -376,6 +373,7 @@ export function useMode() { if (!otherLines) { polygon.fillCell() canvas.renderAll() + polygon.setViewLengthText(false) } }