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: [], initialize: function (points, options, canvas) { this.callSuper('initialize', points, { ...options, selectable: options.selectable ?? true }) if (options.id) { this.id = options.id } else { this.id = uuidv4() } this.line = this // 소수점 전부 제거 points.forEach((point) => { point = Math.round(point) }) this.idx = options.idx ?? 0 this.setLength() this.direction = options.direction ?? getDirectionByPoint({ x: this.x1, y: this.y1 }, { x: this.x2, y: this.y2 }) this.startPoint = { x: this.x1, y: this.y1 } this.endPoint = { x: this.x2, y: this.y2 } if (canvas) { this.canvas = canvas } }, toObject: function (propertiesToInclude) { return fabric.util.object.extend(this.callSuper('toObject', propertiesToInclude), { type: this.type, text: this.text, }) }, init: function () { 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 thisText = this.canvas.getObjects().find((obj) => obj.name === 'lengthText' && obj.parentId === this.id) if (thisText) { this.canvas.remove(thisText) } this.text = null }) }, 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 const dx = x2 - x1 const dy = y2 - y1 this.length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(1)) * 10 }, addLengthText() { const thisText = this.canvas.getObjects().find((obj) => obj.name === 'lengthText' && obj.parentId === this.id) 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.length.toFixed(0).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.length.toFixed(0).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 }, setViewLengthText(bool) { const thisText = this.canvas.getObjects().find((obj) => obj.name === 'lengthText' && obj.parentId === this.id) if (thisText) { thisText.set({ visible: bool }) } return this }, })