159 lines
4.0 KiB
JavaScript

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
},
})