You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

497 lines
15 KiB
TypeScript

/**
* @
* 1. 使
*/
// https://t7.baidu.com/it/u=2757924858,1404466263&fm=193
import video_type_1 from "@/assets/modelSetting/video_type_1.png";
import video_type_2 from "@/assets/modelSetting/video_type_2.png";
import video_type_3 from "@/assets/modelSetting/video_type_3.png";
import device_video_bg from "@/assets/modelSetting/device_video_bg.png";
import device_video_bg_gray from "@/assets/modelSetting/device_video_bg_gray.png";
import notInVisableIcon from "@/assets/modelSetting/notInVisableIcon.png";
import { workspaceIDConf } from "@/config/attribute/viewType";
import { v4 as uuid } from "uuid";
const deviceInfoKey = "deviceInfo";
// TODO 设计实现点位绑定设备实体的位置偏移问题
/**
* @
* 1. (0,0)
*/
export const useDeviceObject = () => {
// 拖拽新增获取设备对象在画布上的坐标
function getDragDeviceObjectOrdinate(event, viewObj, deviceObj) {
// 移动到画布上的设备对象的相对坐标,使用相对图片的坐标系,而不是画布的坐标系
const currWorkSpaceData = document
.getElementById(workspaceIDConf)
.getBoundingClientRect();
const cvsObjects = viewObj.getObjects()[0]; // 获取画布对象
const imgObjects = viewObj.getObjects()[1]; // 获取图片对象
const { left, top, width, height } = currWorkSpaceData;
// .getSelectionElement()
// .getBoundingClientRect();
// 该设备基于当前画布的坐标信息
const currPointView = {
x: event.clientX - left,
y: event.clientY - top
};
// const pointerVpt = viewObj.restorePointerVpt(currPointView);
const x_ordinate =
currPointView.x - width / 2 - (deviceObj.width * deviceObj.scaleX) / 2;
const y_ordinate =
height / 2 - currPointView.y + (deviceObj.height * deviceObj.scaleY) / 2;
console.log(
"currWorkSpace:",
currWorkSpaceData,
"cvsObjects:",
cvsObjects,
"event:",
event,
"getDragDeviceObjectOrdinate",
"imgObjects:",
imgObjects.getCenterPoint(),
x_ordinate,
y_ordinate
);
return {
x_ordinate,
y_ordinate
};
}
// 在画布上移动后设备对象坐标
function fetchMoveDeviceObjectOrdinate(viewObj, activeObject) {
const cvsObjects = viewObj.getObjects()[0]; // 获取画布对象
const x_ordinate = activeObject.get("left") - cvsObjects.width / 2;
const y_ordinate = cvsObjects.height / 2 - activeObject.get("top");
return {
x_ordinate,
y_ordinate
};
}
// 使用相对坐标换实际位置的方法
function fetchOrdinateByView(viewObj, deviceItem) {
const cvsObjects = viewObj.getObjects()[0]; // 获取画布对象
const { x_ordinate, y_ordinate } = deviceItem;
const left = cvsObjects.width / 2 + parseFloat(x_ordinate);
const top = cvsObjects.height / 2 - parseFloat(y_ordinate);
console.log(cvsObjects, "fetchOrdinateByView", left, top);
return {
left,
top
};
}
// 可操作区域的各点位相对坐标【限定可操作区域边界】
function fetchViewsBoundaries(viewObj, activeObj) {
// 图片原点为中心图标
const cvsObjects = viewObj.getObjects()[0]; // 获取画布对象
const imgObjects = viewObj.getObjects()[1]; // 获取图片对象
const y_mistake = -8 * activeObj?.scaleY; // 上下边界误差
const currIconWidth = activeObj?.width * activeObj?.scaleX;
const currIconHeight = activeObj?.height * activeObj?.scaleY;
const startLeft =
(cvsObjects.width * cvsObjects.scaleX -
imgObjects.width * imgObjects.scaleX) /
2 -
currIconWidth / 2;
const startTop =
(cvsObjects.height * cvsObjects.scaleY -
imgObjects.height * imgObjects.scaleY) /
2 -
currIconHeight -
y_mistake;
const endLeft = startLeft + imgObjects.width * imgObjects.scaleX;
const endTop = startTop + imgObjects.height * imgObjects.scaleY;
const currImgWidth = imgObjects.width * imgObjects.scaleX;
const currImgHeight = imgObjects.height * imgObjects.scaleY;
return {
x_min: -currImgWidth / 2 - currIconWidth / 2,
y_min: -currImgHeight / 2 - currIconHeight,
x_max: currImgWidth / 2 + currIconWidth / 2,
y_max: currImgHeight / 2,
startLeft,
startTop,
endLeft,
endTop
};
}
// 操作区判断设备是否在可视区域内
function isInViewBoundaries(viewObj, deviceObj): boolean {
const { x_min, x_max, y_min, y_max } = fetchViewsBoundaries(
viewObj,
deviceObj
);
const { x_ordinate, y_ordinate } = deviceObj;
// 限制对象在画布内移动
if (x_ordinate < x_min) {
return false;
}
if (y_ordinate < y_min) {
return false;
}
if (x_ordinate > x_max) {
return false;
}
if (y_ordinate > y_max) {
return false;
}
return true;
}
// 预览判断当前的图片图层内
function isInCurrViewBoundaries(viewObj, deviceObj): boolean {
const objLeft = deviceObj.left;
const objTop = deviceObj.top;
const canvasObject = viewObj;
const { backgroundImage } = canvasObject; // backgroundImage 背景图片
const currIconWidth = deviceObj?.width * deviceObj?.scaleX;
const currIconHeight = deviceObj?.height * deviceObj?.scaleY;
const y_mistake = -8 * deviceObj?.scaleY; // 上下边界误差
const x_mistake = 1; // 左右边界误差
const startLeft =
(canvasObject.width - backgroundImage.width * backgroundImage.scaleX) /
2 -
currIconWidth / 2;
const startTop =
(canvasObject.height - backgroundImage.height * backgroundImage.scaleY) /
2 -
currIconHeight -
y_mistake;
const endLeft = startLeft + backgroundImage.width * backgroundImage.scaleX;
const endTop = startTop + backgroundImage.height * backgroundImage.scaleY;
console.log(
backgroundImage.getBoundingClientRect(),
canvasObject.width,
canvasObject.scaleX,
backgroundImage.width,
backgroundImage.scaleX,
currIconWidth,
"isInCurrViewBoundaries",
backgroundImage.scaleX,
deviceObj,
"startLeft",
startLeft,
"startTop",
startTop,
"endLeft",
endLeft,
"endTop",
endTop
);
if (
objLeft < startLeft - x_mistake ||
objTop < startTop ||
objLeft > endLeft + x_mistake ||
objTop > endTop
) {
return true;
}
return false;
}
// function isInView() {
// // TODO 用三角函数判断
// return;
// }
// 设备对象是否移动
function isMoveDevice(activeObject, viewObj) {
const x_ordinate_history = activeObject.get(deviceInfoKey)?.x_ordinate;
const y_ordinate_history = activeObject.get(deviceInfoKey)?.y_ordinate;
const { x_ordinate, y_ordinate } = fetchMoveDeviceObjectOrdinate(
viewObj,
activeObject
);
// 误差设置为 0.1
const errorValue = [1, 1];
let x_move = true;
let y_move = true;
const x_move_value = Math.abs(
Number(x_ordinate_history) - Number(x_ordinate)
);
const y_move_value = Math.abs(
Number(y_ordinate_history) - Number(y_ordinate)
);
// 重新绑定车间的设备没有坐标信息,暂时不判断设备是否移动【默认没有移动】
// if (Number.isNaN(x_move_value) || Number.isNaN(y_move_value)) {
// return false;
// }
if (x_move_value < errorValue[0]) {
x_move = false;
}
if (y_move_value < errorValue[1]) {
y_move = false;
}
console.log(
"isMoveDevice:" + (x_move || y_move),
"x_move_value" + x_move_value,
"y_move_value" + y_move_value
);
return x_move || y_move;
}
// 初始化设备对象
const initDeviceGroupObjects: Record<string, any> = (
record,
restDeviceItem = {}
) => {
console.log(record, "initDeviceGroupObjects");
// const { value } = record;
let iconObjectSrc = video_type_1;
switch (record?.icon) {
case "3":
iconObjectSrc = video_type_3;
break;
case "2":
iconObjectSrc = video_type_2;
break;
case "1":
default:
iconObjectSrc = video_type_1;
break;
}
let bgDeviceImage;
const fontStyle = { fill: "#333333" };
// 不在可视区域内的设备
if (record?.notInVisable) {
bgDeviceImage = device_video_bg_gray;
fontStyle.fill = "gray";
} else {
bgDeviceImage = device_video_bg;
}
return {
name: "device",
id: uuid(),
deviceInfo: record, // 设备信息
left: record?.left ? Number(record?.left) : 0,
top: record?.top ? Number(record?.top) : 0,
selectable: true,
hasControls: true,
lockUniScaling: true, // 当设置为trueObject将无法被锁定比例进行缩放。默认值为false。
lockScalingX: true, // 当设置为trueObject水平方向将无法被缩放。默认值为false。
lockScalingY: true, // 当设置为trueObject垂直方向将无法被缩放。默认值为false。
lockRotation: true, // 当设置为trueObject的旋转将被锁定。默认值为false。
type: "group",
version: "5.3.0",
originX: "left",
originY: "top",
width: 132,
height: 62,
fill: "rgb(0,0,0)",
stroke: null,
strokeWidth: 0,
strokeDashArray: null,
strokeLineCap: "butt",
strokeDashOffset: 0,
strokeLineJoin: "miter",
strokeUniform: false,
strokeMiterLimit: 4,
scaleX: 1,
scaleY: 1,
angle: 0,
flipX: false,
flipY: false,
opacity: 1,
shadow: null,
visible: true,
backgroundColor: "",
fillRule: "nonzero",
paintFirst: "fill",
globalCompositeOperation: "source-over",
skewX: 0,
skewY: 0,
objects: [
{
type: "image",
version: "5.3.0",
originX: "left",
originY: "top",
left: -66,
top: -33,
width: 264,
height: 132,
fill: "rgb(0,0,0)",
stroke: null,
strokeWidth: 0,
strokeDashArray: null,
strokeLineCap: "butt",
strokeDashOffset: 0,
strokeLineJoin: "miter",
strokeUniform: false,
strokeMiterLimit: 4,
scaleX: 0.5,
scaleY: 0.5,
angle: 0,
flipX: false,
flipY: false,
opacity: 1,
shadow: null,
visible: true,
backgroundColor: "",
fillRule: "nonzero",
paintFirst: "fill",
globalCompositeOperation: "source-over",
skewX: 0,
skewY: 0,
cropX: 0,
cropY: 0,
selectable: false,
hasControls: false,
src: bgDeviceImage,
crossOrigin: null,
filters: []
},
{
type: "image",
version: "5.3.0",
originX: "left",
originY: "top",
left: -50.6281,
top: -22.9893,
width: 48,
height: 48,
fill: "rgb(0,0,0)",
stroke: null,
strokeWidth: 0,
strokeDashArray: null,
strokeLineCap: "butt",
strokeDashOffset: 0,
strokeLineJoin: "miter",
strokeUniform: false,
strokeMiterLimit: 4,
scaleX: 0.6174,
scaleY: 0.6174,
angle: 0,
flipX: false,
flipY: false,
opacity: 1,
shadow: null,
visible: true,
backgroundColor: "",
fillRule: "nonzero",
paintFirst: "fill",
globalCompositeOperation: "source-over",
skewX: 0,
skewY: 0,
cropX: 0,
cropY: 0,
selectable: false,
hasControls: false,
src: iconObjectSrc,
crossOrigin: null,
filters: []
},
{
type: "textbox",
version: "5.3.0",
originX: "left",
originY: "top",
left: -14.3377,
top: -15.4904,
width: 320,
height: 90.4,
fill: fontStyle.fill,
stroke: null,
strokeWidth: 1,
strokeDashArray: null,
strokeLineCap: "butt",
strokeDashOffset: 0,
strokeLineJoin: "miter",
strokeUniform: false,
strokeMiterLimit: 4,
scaleX: 0.1681,
scaleY: 0.1681,
angle: 0,
flipX: false,
flipY: false,
opacity: 1,
shadow: "",
visible: true,
backgroundColor: "",
fillRule: "nonzero",
paintFirst: "fill",
globalCompositeOperation: "source-over",
skewX: 0,
skewY: 0,
fontFamily: "arial",
fontWeight: "normal",
fontSize: 80,
text: record?.name,
underline: false,
overline: false,
linethrough: false,
textAlign: "left",
fontStyle: "normal",
lineHeight: 1.16,
textBackgroundColor: "",
charSpacing: 0,
styles: [],
direction: "ltr",
path: null,
pathStartOffset: 0,
pathSide: "left",
pathAlign: "baseline",
selectable: false,
hasControls: false
},
{
type: "image",
version: "5.3.0",
originX: "left",
originY: "top",
left: -47.6281,
top: -19.9893,
width: 40,
height: 40,
fill: "rgb(0,0,0)",
stroke: null,
strokeWidth: 0,
strokeDashArray: null,
strokeLineCap: "butt",
strokeDashOffset: 0,
strokeLineJoin: "miter",
strokeUniform: false,
strokeMiterLimit: 4,
scaleX: 0.6174,
scaleY: 0.6174,
angle: 0,
flipX: false,
flipY: false,
opacity: 1,
shadow: null,
visible: false,
backgroundColor: "",
fillRule: "nonzero",
paintFirst: "fill",
globalCompositeOperation: "source-over",
skewX: 0,
skewY: 0,
cropX: 0,
cropY: 0,
selectable: false,
hasControls: false,
src: notInVisableIcon,
crossOrigin: null,
filters: []
}
],
...restDeviceItem
};
};
return {
initDeviceGroupObjects,
isInViewBoundaries,
getDragDeviceObjectOrdinate,
isMoveDevice,
fetchViewsBoundaries,
fetchOrdinateByView,
fetchMoveDeviceObjectOrdinate,
isInCurrViewBoundaries
};
};