|
|
|
|
/**
|
|
|
|
|
* @交互说明
|
|
|
|
|
* 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 { v4 as uuid } from "uuid";
|
|
|
|
|
|
|
|
|
|
const deviceInfoKey = "deviceInfo";
|
|
|
|
|
|
|
|
|
|
export const useDeviceObject = () => {
|
|
|
|
|
// 移动到画布上的设备对象的相对坐标,使用相对图片的左边系,而不是画布的坐标系
|
|
|
|
|
function getDragDeviceObjectOrdinate(event, viewObj, deviceObj) {
|
|
|
|
|
// const cvsObjects = viewObj.getObjects()[0]; // 获取画布对象
|
|
|
|
|
const imgObjects = viewObj.getObjects()[1]; // 获取图片对象
|
|
|
|
|
const { left, top } = viewObj.getSelectionElement().getBoundingClientRect();
|
|
|
|
|
const point = {
|
|
|
|
|
x: event.x - left - imgObjects.left,
|
|
|
|
|
y: event.y - top - imgObjects.top
|
|
|
|
|
};
|
|
|
|
|
const pointerVpt = viewObj.restorePointerVpt(point);
|
|
|
|
|
const x_ordinate = pointerVpt.x - (deviceObj.width * deviceObj.scaleX) / 2;
|
|
|
|
|
const y_ordinate = pointerVpt.y - (deviceObj.height * deviceObj.scaleY) / 2;
|
|
|
|
|
console.log(x_ordinate, y_ordinate, "getDragDeviceObjectOrdinate");
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
x_ordinate: x_ordinate,
|
|
|
|
|
y_ordinate: y_ordinate
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
// 可操作区域的相对坐标
|
|
|
|
|
function fetchViewsBoundaries(viewObj, activeObj) {
|
|
|
|
|
const cvsObjects = viewObj.getObjects()[0]; // 获取画布对象
|
|
|
|
|
const imgObjects = viewObj.getObjects()[1]; // 获取图片对象
|
|
|
|
|
const startLeft =
|
|
|
|
|
(cvsObjects.width * cvsObjects.scaleX -
|
|
|
|
|
imgObjects.width * imgObjects.scaleX) /
|
|
|
|
|
2;
|
|
|
|
|
const startTop =
|
|
|
|
|
(cvsObjects.height * cvsObjects.scaleY -
|
|
|
|
|
imgObjects.height * imgObjects.scaleY) /
|
|
|
|
|
2;
|
|
|
|
|
const endLeft = startLeft + imgObjects.width * imgObjects.scaleX;
|
|
|
|
|
const endTop = startTop + imgObjects.height * imgObjects.scaleY;
|
|
|
|
|
return {
|
|
|
|
|
x_max: imgObjects.width * imgObjects.scaleX,
|
|
|
|
|
y_max: imgObjects.height * imgObjects.scaleY,
|
|
|
|
|
startLeft,
|
|
|
|
|
startTop,
|
|
|
|
|
endLeft,
|
|
|
|
|
endTop,
|
|
|
|
|
moveLeft: endLeft - activeObj?.width * activeObj?.scaleX,
|
|
|
|
|
moveTop: endTop - activeObj?.height * activeObj?.scaleY
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 判断设备是否在可视区域内
|
|
|
|
|
function isInViewBoundaries(deviceObj, viewObj): boolean {
|
|
|
|
|
const { x_max, y_max } = fetchViewsBoundaries(viewObj, deviceObj);
|
|
|
|
|
const { x_ordinate, y_ordinate } = deviceObj;
|
|
|
|
|
// 获取对象的当前尺寸和位置
|
|
|
|
|
const objLeft = x_ordinate;
|
|
|
|
|
const objTop = y_ordinate;
|
|
|
|
|
|
|
|
|
|
// 限制对象在画布内移动
|
|
|
|
|
if (objLeft < 0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (objTop < 0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (objLeft > x_max) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (objTop > y_max) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设备对象是否移动
|
|
|
|
|
function isMoveDevice(activeObject, viewObj) {
|
|
|
|
|
const { x_ordinate, y_ordinate } = activeObject.get(deviceInfoKey);
|
|
|
|
|
const { startLeft, startTop } = fetchViewsBoundaries(viewObj);
|
|
|
|
|
// 误差设置为 0.1
|
|
|
|
|
const errorValue = [1, 1];
|
|
|
|
|
let x_move = true;
|
|
|
|
|
let y_move = true;
|
|
|
|
|
const x_move_value = Math.abs(
|
|
|
|
|
Number(activeObject.left) - Number(x_ordinate) - Number(startLeft)
|
|
|
|
|
);
|
|
|
|
|
const y_move_value = Math.abs(
|
|
|
|
|
Number(activeObject.top) - Number(y_ordinate) - Number(startTop)
|
|
|
|
|
);
|
|
|
|
|
console.log(
|
|
|
|
|
"startLeft" + startLeft,
|
|
|
|
|
"startTop" + startTop,
|
|
|
|
|
"isMoveDevice",
|
|
|
|
|
"x_move_value" + x_move_value,
|
|
|
|
|
"y_move_value" + y_move_value,
|
|
|
|
|
activeObject.left,
|
|
|
|
|
x_ordinate,
|
|
|
|
|
activeObject.top,
|
|
|
|
|
y_ordinate,
|
|
|
|
|
Math.abs(
|
|
|
|
|
Number(activeObject.top) - Number(y_ordinate) - Number(startTop)
|
|
|
|
|
),
|
|
|
|
|
Math.abs(
|
|
|
|
|
Number(activeObject.left) - Number(x_ordinate) - Number(startLeft)
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
// TODO 重新绑定车间的设备没有坐标信息,暂时不判断设备是否移动【默认没有移动】
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
return x_move || y_move;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// function fetchDeviceObjectBySeemKey(targetDeviceItem, viewObj) {
|
|
|
|
|
// console.log(targetDeviceItem, viewObj, "fetchDeviceObjectBySeemKey");
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// 初始化设备对象
|
|
|
|
|
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 {
|
|
|
|
|
id: uuid(),
|
|
|
|
|
deviceInfo: record, // 设备信息
|
|
|
|
|
left: record?.left ? Number(record?.left) : 0,
|
|
|
|
|
top: record?.top ? Number(record?.top) : 0,
|
|
|
|
|
selectable: true,
|
|
|
|
|
hasControls: true,
|
|
|
|
|
lockUniScaling: true, // 当设置为true,Object将无法被锁定比例进行缩放。默认值为false。
|
|
|
|
|
lockScalingX: true, // 当设置为true,Object水平方向将无法被缩放。默认值为false。
|
|
|
|
|
lockScalingY: true, // 当设置为true,Object垂直方向将无法被缩放。默认值为false。
|
|
|
|
|
lockRotation: true, // 当设置为true,Object的旋转将被锁定。默认值为false。
|
|
|
|
|
type: "group",
|
|
|
|
|
version: "5.3.0",
|
|
|
|
|
originX: "left",
|
|
|
|
|
originY: "top",
|
|
|
|
|
width: 132,
|
|
|
|
|
height: 66,
|
|
|
|
|
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
|
|
|
|
|
// fetchDeviceObjectBySeemKey
|
|
|
|
|
};
|
|
|
|
|
};
|