import { fabric } from 'fabric' import { v4 as uuidv4 } from 'uuid' import { getDirectionByPoint } from '@/util/canvas-util' export const QLine = fabric.util.createClass(fabric.Line, { type: 'QLine', text: null, id: null, line: null, length: 0, direction: null, idx: 0, area: 0, children: [], padding: 5, textVisible: true, initialize: function (points, options, length = 0) { // 소수점 전부 제거 points = points.map((point) => Number(point?.toFixed(1))) this.callSuper('initialize', points, { ...options, selectable: options.selectable ?? true }) if (options.id) { this.id = options.id } else { this.id = uuidv4() } this.line = this this.idx = options.idx ?? 0 this.direction = options.direction ?? getDirectionByPoint({ x: this.x1, y: this.y1 }, { x: this.x2, y: this.y2 }) this.textMode = options.textMode ?? 'plane' // plane:복시도, actual:실측, none:표시안함 this.textVisible = options.textVisible ?? true if (length !== 0) { this.length = length } else { this.setLength() } this.startPoint = { x: this.x1, y: this.y1 } this.endPoint = { x: this.x2, y: this.y2 } }, init: function () { if (!this.textVisible) { return } this.addLengthText() this.on('moving', () => { this.addLengthText() }) this.on('modified', (e) => { this.startPoint = { x: this.x1, y: this.y1 } this.endPoint = { x: this.x2, y: this.y2 } this.addLengthText() }) this.on('removed', () => { const children = this.canvas.getObjects().filter((obj) => obj.parentId === this.id) children.forEach((child) => { this.canvas.remove(child) }) }) }, setLength() { if (this.attributes?.actualSize !== undefined && this.attributes?.planeSize !== undefined) { if (this.textMode === 'plane') { this.length = this.attributes.planeSize / 10 } else if (this.textMode === 'actual') { this.length = this.attributes.actualSize / 10 } } else { 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(1)) } }, addLengthText() { const thisText = this.canvas.getObjects().find((obj) => obj.name === 'lengthText' && obj.parentId === this.id) if (this.textMode === 'none') { if (thisText) { this.canvas.remove(thisText) } } else { this.setLength() 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 if (thisText) { thisText.set({ text: this.getLength().toString(), left: (x1 + x2) / 2, top: (y1 + y2) / 2 }) this.text = thisText return } let left, top if (this.direction === 'left' || this.direction === 'right') { left = (x1 + x2) / 2 top = (y1 + y2) / 2 + 10 } else if (this.direction === 'top' || this.direction === 'bottom') { left = (x1 + x2) / 2 + 10 top = (y1 + y2) / 2 } const minX = this.left const maxX = this.left + this.width const minY = this.top const maxY = this.top + this.length const degree = (Math.atan2(y2 - y1, x2 - x1) * 180) / Math.PI const text = new fabric.Textbox(this.getLength().toString(), { left: left, top: top, fontSize: this.fontSize, minX, maxX, minY, maxY, parentDirection: this.direction, parentDegree: degree, parentId: this.id, editable: false, selectable: true, lockRotation: true, lockScalingX: true, lockScalingY: true, parent: this, name: 'lengthText', }) this.text = text this.canvas.add(text) } }, setFontSize(fontSize) { this.fontSize = fontSize this.text.set({ fontSize }) }, _render: function (ctx) { this.callSuper('_render', ctx) this.init() }, _set: function (key, value) { this.callSuper('_set', key, value) }, setCanvas(canvas) { this.canvas = canvas }, getLength() { //10배 곱해진 값 return return Number(this.length.toFixed(1)) * 10 }, setViewLengthText(bool) { const thisText = this.canvas.getObjects().find((obj) => obj.name === 'lengthText' && obj.parentId === this.id) if (thisText) { thisText.set({ visible: bool }) } return this }, setLengthText(text) { const thisText = this.canvas.getObjects().find((obj) => obj.name === 'lengthText' && obj.parentId === this.id) if (thisText) { thisText.set({ text: text.toString() }) this.canvas.renderAll() } return this }, })