qcast-front/src/app/util/canvas-util.js

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
}