157 lines
4.7 KiB
JavaScript
157 lines
4.7 KiB
JavaScript
/**
|
|
* Collection of function to use on canvas
|
|
*/
|
|
// define a function that can locate the controls
|
|
export function polygonPositionHandler(dim, finalMatrix, fabricObject) {
|
|
// @ts-ignore
|
|
let x = fabricObject.points[this.pointIndex].x - fabricObject.pathOffset.x
|
|
// @ts-ignore
|
|
let y = fabricObject.points[this.pointIndex].y - fabricObject.pathOffset.y
|
|
return fabric.util.transformPoint(
|
|
{ x, y },
|
|
fabric.util.multiplyTransformMatrices(
|
|
fabricObject.canvas.viewportTransform,
|
|
fabricObject.calcTransformMatrix(),
|
|
),
|
|
)
|
|
}
|
|
|
|
function getObjectSizeWithStroke(object) {
|
|
let stroke = new fabric.Point(
|
|
object.strokeUniform ? 1 / object.scaleX : 1,
|
|
object.strokeUniform ? 1 / object.scaleY : 1,
|
|
).multiply(object.strokeWidth)
|
|
return new fabric.Point(object.width + stroke.x, object.height + stroke.y)
|
|
}
|
|
|
|
// define a function that will define what the control does
|
|
export function actionHandler(eventData, transform, x, y) {
|
|
let polygon = transform.target,
|
|
currentControl = polygon.controls[polygon.__corner],
|
|
mouseLocalPosition = polygon.toLocalPoint(
|
|
new fabric.Point(x, y),
|
|
'center',
|
|
'center',
|
|
),
|
|
polygonBaseSize = getObjectSizeWithStroke(polygon),
|
|
size = polygon._getTransformedDimensions(0, 0)
|
|
polygon.points[currentControl.pointIndex] = {
|
|
x:
|
|
(mouseLocalPosition.x * polygonBaseSize.x) / size.x +
|
|
polygon.pathOffset.x,
|
|
y:
|
|
(mouseLocalPosition.y * polygonBaseSize.y) / size.y +
|
|
polygon.pathOffset.y,
|
|
}
|
|
return true
|
|
}
|
|
|
|
// define a function that can keep the polygon in the same position when we change its width/height/top/left
|
|
export function anchorWrapper(anchorIndex, fn) {
|
|
return function (eventData, transform, x, y) {
|
|
let fabricObject = transform.target
|
|
let originX =
|
|
fabricObject?.points[anchorIndex].x - fabricObject.pathOffset.x
|
|
let originY = fabricObject.points[anchorIndex].y - fabricObject.pathOffset.y
|
|
let absolutePoint = fabric.util.transformPoint(
|
|
{
|
|
x: originX,
|
|
y: originY,
|
|
},
|
|
fabricObject.calcTransformMatrix(),
|
|
)
|
|
let actionPerformed = fn(eventData, transform, x, y)
|
|
let newDim = fabricObject._setPositionDimensions({})
|
|
let polygonBaseSize = getObjectSizeWithStroke(fabricObject)
|
|
let newX =
|
|
(fabricObject.points[anchorIndex].x - fabricObject.pathOffset.x) /
|
|
polygonBaseSize.x
|
|
let newY =
|
|
(fabricObject.points[anchorIndex].y - fabricObject.pathOffset.y) /
|
|
polygonBaseSize.y
|
|
fabricObject.setPositionByOrigin(absolutePoint, newX + 0.5, newY + 0.5)
|
|
return actionPerformed
|
|
}
|
|
}
|
|
|
|
export const getDistance = (x1, y1, x2, y2) => {
|
|
return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2))
|
|
}
|
|
|
|
// polygon의 각 변에 해당 점과 점 사이의 거리를 나타내는 IText를 추가하는 함수
|
|
export function addDistanceTextToPolygon(polygon) {
|
|
const points = polygon.get('points')
|
|
const texts = []
|
|
|
|
for (let i = 0; i < points.length; i++) {
|
|
const start = points[i]
|
|
const end = points[(i + 1) % points.length] // 다음 점 (마지막 점의 경우 첫번째 점으로)
|
|
const distance = Math.sqrt(
|
|
Math.pow(end.x - start.x, 2) + Math.pow(end.y - start.y, 2),
|
|
) // 두 점 사이의 거리 계산
|
|
|
|
const text = new fabric.Textbox(distance.toFixed(2), {
|
|
// 소수 둘째자리까지 표시
|
|
left: (start.x + end.x) / 2, // 텍스트의 위치는 두 점의 중간
|
|
top: (start.y + end.y) / 2,
|
|
fontSize: 20,
|
|
})
|
|
|
|
texts.push(text)
|
|
}
|
|
|
|
return new fabric.Group([polygon, ...texts], {
|
|
// polygon과 텍스트들을 그룹화
|
|
selectable: true,
|
|
})
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param {number} value
|
|
* @param {boolean} useDefault
|
|
* @param {string} delimeter
|
|
* @returns
|
|
* ex) 1,100 mm
|
|
*/
|
|
export const formattedWithComma = (value, unit = 'mm') => {
|
|
let formatterdData = value.toLocaleString('ko-KR')
|
|
if (unit === 'cm') {
|
|
formatterdData = value.toLocaleString('ko-KR') / 10
|
|
} else if (unit === 'm') {
|
|
formatterdData = value.toLocaleString('ko-KR') / 1000
|
|
}
|
|
|
|
return `${formatterdData} ${unit}`
|
|
}
|
|
|
|
export const distanceBetweenPoints = (point1, point2) => {
|
|
const dx = point2.x - point1.x
|
|
const dy = point2.y - point1.y
|
|
return Math.sqrt(dx * dx + dy * dy)
|
|
}
|
|
|
|
/**
|
|
* line의 시작점을 찾는 함수
|
|
* @param lines
|
|
* @returns {number}
|
|
*/
|
|
export const getStartIndex = (lines) => {
|
|
let smallestIndex = 0
|
|
let smallestX1 = lines[0].x1
|
|
let smallestY1 = lines[0].y1
|
|
|
|
for (let i = 1; i < arr.length; i++) {
|
|
if (
|
|
lines[i].x1 < smallestX1 ||
|
|
(lines[i].x1 === smallestX1 && lines[i].y1 < smallestY1)
|
|
) {
|
|
smallestIndex = i
|
|
smallestX1 = lines[i].x1
|
|
smallestY1 = lines[i].y1
|
|
}
|
|
}
|
|
|
|
return smallestIndex
|
|
}
|