QLine 그룹화

This commit is contained in:
hyojun.choi 2024-07-08 14:17:26 +09:00
parent ee88a3e47e
commit 864e892a7d
3 changed files with 77 additions and 53 deletions

View File

@ -2,7 +2,6 @@ import { useCanvas } from '@/hooks/useCanvas'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { Mode, useMode } from '@/hooks/useMode' import { Mode, useMode } from '@/hooks/useMode'
import QRect from '@/components/fabric/QRect' import QRect from '@/components/fabric/QRect'
import QLine from '@/components/fabric/QLine'
import QPolygon from '@/components/fabric/QPolygon' import QPolygon from '@/components/fabric/QPolygon'
import RangeSlider from './ui/RangeSlider' import RangeSlider from './ui/RangeSlider'
@ -12,6 +11,7 @@ import {
fontSizeState, fontSizeState,
sortedPolygonArray, sortedPolygonArray,
} from '@/store/canvasAtom' } from '@/store/canvasAtom'
import { QLine } from '@/components/fabric/QLine'
export default function Roof2() { export default function Roof2() {
const { 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 ( return (
<> <>
{canvas && ( {canvas && (
@ -303,6 +315,12 @@ export default function Roof2() {
> >
회전 회전
</button> </button>
<button
className="w-30 m-2 p-2 rounded bg-gray-500 text-white"
onClick={makeQLine}
>
QLine
</button>
</div> </div>
<div className="flex justify-center flex-col items-center"> <div className="flex justify-center flex-col items-center">
<div className="m-2 p-2 w-80"> <div className="m-2 p-2 w-80">

View File

@ -1,27 +1,39 @@
import { fabric } from 'fabric' import { fabric } from 'fabric'
export default class QLine extends fabric.Line { export class QLine extends fabric.Group {
line
text
fontSize
length length
#text x1
#viewLengthText y1
#fontSize x2
y2
direction
type = 'QLine' type = 'QLine'
constructor(points, option) { constructor(points, option) {
const [x1, y1, x2, y2] = points
if (!option.fontSize) { if (!option.fontSize) {
throw new Error('Font size is required.') throw new Error('Font size is required.')
} }
super(points, option) const line = new fabric.Line(points, { ...option, strokeWidth: 1 })
this.#fontSize = option.fontSize super([line], {})
this.#init(option)
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() this.#addControl()
} }
#init(option) { #init() {
// 선의 길이를 계산하여 length 속성을 초기화합니다. this.#addLengthText()
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
} }
#addControl() { #addControl() {
@ -34,52 +46,46 @@ export default class QLine extends fabric.Line {
}) })
this.on('modified', (e) => { 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.#addLengthText()
}) })
this.on('removed', () => { this.on('selected', () => {
this.canvas.remove(this.#text) Object.keys(this.controls).forEach((controlKey) => {
this.#text = null if (controlKey !== 'ml' && controlKey !== 'mr') {
this.setControlVisible(controlKey, false)
}
})
}) })
} }
setViewLengthText(bool) { #addLengthText() {
this.#viewLengthText = bool if (this.text) {
this.#addLengthText() 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) { setFontSize(fontSize) {
this.#fontSize = fontSize this.fontSize = fontSize
this.#addLengthText() this.text.set({ fontSize })
} this.addWithUpdate()
#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)
}
} }
} }

View File

@ -1,5 +1,4 @@
import { useEffect, useRef, useState } from 'react' import { useEffect, useRef, useState } from 'react'
import QLine from '@/components/fabric/QLine'
import QRect from '@/components/fabric/QRect' import QRect from '@/components/fabric/QRect'
import QPolygon from '@/components/fabric/QPolygon' import QPolygon from '@/components/fabric/QPolygon'
import { import {
@ -9,6 +8,7 @@ import {
} from '@/util/canvas-util' } from '@/util/canvas-util'
import { useRecoilState } from 'recoil' import { useRecoilState } from 'recoil'
import { fontSizeState, sortedPolygonArray } from '@/store/canvasAtom' import { fontSizeState, sortedPolygonArray } from '@/store/canvasAtom'
import { QLine } from '@/components/fabric/QLine'
export const Mode = { export const Mode = {
DRAW_LINE: 'drawLine', // 기준선 긋기모드 DRAW_LINE: 'drawLine', // 기준선 긋기모드