feat: 使用中心点位坐标调整计算位置

develop
donghao 9 months ago
parent 4c626c7136
commit 381c2a2d7f

@ -0,0 +1 @@
export const workspaceIDConf = "workspace";

@ -22,7 +22,8 @@ const emit = defineEmits(["afterDelete", "editDevice"]);
const event = inject("event"); const event = inject("event");
const update = getCurrentInstance(); const update = getCurrentInstance();
const { mixinState, canvasEditor } = useSelect(); const { mixinState, canvasEditor } = useSelect();
const { fetchViewsBoundaries, isMoveDevice } = useDeviceObject(); const { fetchViewsBoundaries, isMoveDevice, fetchMoveDeviceObjectOrdinate } =
useDeviceObject();
/**业务属性 */ /**业务属性 */
const formData = ref({ const formData = ref({
name: "", name: "",
@ -103,7 +104,7 @@ const fontAttr = reactive({
}); });
const constrainObjectWithinCanvas = obj => { const constrainObjectWithinCanvas = obj => {
const { startLeft, startTop, moveLeft, moveTop } = fetchViewsBoundaries( const { startLeft, startTop, endLeft, endTop } = fetchViewsBoundaries(
canvasEditor.canvas, canvasEditor.canvas,
obj obj
); );
@ -114,11 +115,11 @@ const constrainObjectWithinCanvas = obj => {
if (obj.top < startTop) { if (obj.top < startTop) {
obj.top = startTop; obj.top = startTop;
} }
if (obj.left > moveLeft) { if (obj.left > endLeft) {
obj.left = moveLeft; obj.left = endLeft;
} }
if (obj.top > moveTop) { if (obj.top > endTop) {
obj.top = moveTop; obj.top = endTop;
} }
// //
obj.setCoords(); obj.setCoords();
@ -183,15 +184,18 @@ async function deleteDeviceObject(deleteObject) {
} }
function startEditDevice(callback) { function startEditDevice(callback) {
const { startLeft, startTop } = fetchViewsBoundaries(canvasEditor.canvas);
const activeObject = canvasEditor.canvas.getActiveObject(); const activeObject = canvasEditor.canvas.getActiveObject();
const currDeviceInfo = activeObject.get("deviceInfo"); const currDeviceInfo = activeObject.get("deviceInfo");
const { x_ordinate, y_ordinate } = fetchMoveDeviceObjectOrdinate(
canvasEditor.canvas,
activeObject
);
const editParams = { const editParams = {
id: currDeviceInfo.id, id: currDeviceInfo.id,
device_id: currDeviceInfo.device_id, device_id: currDeviceInfo.device_id,
workshop_id: props.pointInfo?.id, workshop_id: props.pointInfo?.id,
x_ordinate: activeObject.get("left") - startLeft, x_ordinate,
y_ordinate: activeObject.get("top") - startTop, y_ordinate,
icon: formData.value?.icon icon: formData.value?.icon
}; };
emit("editDevice", { editParams, callback }); emit("editDevice", { editParams, callback });
@ -211,7 +215,7 @@ const init = () => {
// //
activeObject && activeObject &&
activeObject.get("deviceInfo") && activeObject.get("deviceInfo") &&
isMoveDevice(activeObject, canvasEditor.canvas) && isMoveDevice(canvasEditor.canvas, activeObject) &&
startEditDevice(); startEditDevice();
}); });
canvasEditor.canvas.on("object:modified", getObjectAttr); canvasEditor.canvas.on("object:modified", getObjectAttr);

@ -26,7 +26,7 @@ const {
initDeviceGroupObjects, initDeviceGroupObjects,
isInViewBoundaries, isInViewBoundaries,
getDragDeviceObjectOrdinate, getDragDeviceObjectOrdinate,
fetchViewsBoundaries fetchOrdinateByView
} = useDeviceObject(); } = useDeviceObject();
// const { t } = useI18n(); // const { t } = useI18n();
@ -75,7 +75,6 @@ canvasEditor.getMaterialType("svg").then((list: materialTypeI[]) => {
* 处理添加设备&重复添加设备同点位不同点位 * 处理添加设备&重复添加设备同点位不同点位
*/ */
function deviceSelected(callback, options) { function deviceSelected(callback, options) {
const { startLeft, startTop } = fetchViewsBoundaries(canvasEditor.canvas);
const { targetDeviceItem } = options; const { targetDeviceItem } = options;
console.log(targetDeviceItem, "deviceSelected", props.currDeviceList); console.log(targetDeviceItem, "deviceSelected", props.currDeviceList);
currDetailInfo.value = targetDeviceItem; currDetailInfo.value = targetDeviceItem;
@ -110,9 +109,13 @@ function deviceSelected(callback, options) {
); );
canvasEditor.canvas.getObjects().forEach(v => { canvasEditor.canvas.getObjects().forEach(v => {
if (v?.deviceInfo?.device_id === targetDeviceItem.id) { if (v?.deviceInfo?.device_id === targetDeviceItem.id) {
const { left, top } = fetchOrdinateByView(
canvasEditor.canvas,
targetDeviceItem
);
v.set({ v.set({
left: targetDeviceItem.x_ordinate + startLeft, left,
top: targetDeviceItem.y_ordinate + startTop top
}); });
canvasEditor.canvas.renderAll(); canvasEditor.canvas.renderAll();
} }
@ -159,10 +162,11 @@ const dragItem = (event, deviceItem) => {
); );
// //
if ( if (
!isInViewBoundaries( !isInViewBoundaries(canvasEditor.canvas, {
{ ...item, x_ordinate, y_ordinate }, ...item,
canvasEditor.canvas x_ordinate,
) y_ordinate
})
) { ) {
return; return;
} }
@ -174,12 +178,13 @@ const dragItem = (event, deviceItem) => {
// canvasEditor.dragAddItem(event, item); // canvasEditor.dragAddItem(event, item);
deviceSelected( deviceSelected(
resData => { _ => {
// //
//
// item.set({ // item.set({
// name: resData?.device_name, // name: resData?.device_name,
// deviceInfo: resData // deviceInfo: resData
// }); // // });
// canvasEditor.dragAddItem(event, item); // canvasEditor.dragAddItem(event, item);
}, },
{ {
@ -219,16 +224,13 @@ const dragItem = (event, deviceItem) => {
// //
function renderDeviceToCanvas(record) { function renderDeviceToCanvas(record) {
const { startLeft, startTop } = fetchViewsBoundaries(canvasEditor.canvas);
console.log(startLeft, "renderDeviceToCanvas");
const startArr = record; const startArr = record;
const finalArr = []; const finalArr = [];
startArr.map(deviceItem => { startArr.map(deviceItem => {
const fullDeviceItem = { const fullDeviceItem = {
...defaultPosition, ...defaultPosition,
...deviceItem, ...deviceItem,
left: Number(deviceItem.x_ordinate) + startLeft, ...fetchOrdinateByView(canvasEditor.canvas, deviceItem),
top: Number(deviceItem.y_ordinate) + startTop,
name: deviceItem.device_name name: deviceItem.device_name
}; };
finalArr.push({ finalArr.push({
@ -253,9 +255,6 @@ watch(
allDeviceList.value = toRaw(props.deviceList); allDeviceList.value = toRaw(props.deviceList);
console.log(allDeviceList.value, "allDeviceList", props.deviceList); console.log(allDeviceList.value, "allDeviceList", props.deviceList);
}, },
// {
// immediate: true
// },
{ {
deep: true deep: true
} }

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd * @Author: donghao donghao@supervision.ltd
* @Date: 2024-08-26 11:32:07 * @Date: 2024-08-26 11:32:07
* @LastEditors: donghao donghao@supervision.ltd * @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-08-28 16:16:06 * @LastEditTime: 2024-08-30 10:56:13
* @FilePath: \General-AI-Platform-Web-Client\src\views\deviceSetting\components\previewCurrent.vue * @FilePath: \General-AI-Platform-Web-Client\src\views\deviceSetting\components\previewCurrent.vue
* @Description: 预览组件 * @Description: 预览组件
--> -->
@ -99,7 +99,7 @@ function renderDeviceToCanvas() {
const canvasObject = cvs.value; const canvasObject = cvs.value;
const startArr = props.currDeviceList; const startArr = props.currDeviceList;
const finalArr = []; const finalArr = [];
const { startLeft, startTop } = getBoundaryPoints(); // const { startLeft, startTop } = getBoundaryPoints();
startArr.map(deviceItem => { startArr.map(deviceItem => {
const fullDeviceItem = { const fullDeviceItem = {
@ -108,8 +108,8 @@ function renderDeviceToCanvas() {
shadow: "", shadow: "",
fontFamily: "1-1", fontFamily: "1-1",
...deviceItem, ...deviceItem,
left: Number(deviceItem.x_ordinate) * scale + startLeft, left: Number(deviceItem.x_ordinate) * scale + viewData.value.width / 2,
top: Number(deviceItem.y_ordinate) * scale + startTop, top: viewData.value.height / 2 - Number(deviceItem.y_ordinate) * scale,
name: deviceItem.device_name name: deviceItem.device_name
}; };
finalArr.push({ finalArr.push({

@ -9,76 +9,134 @@ 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 from "@/assets/modelSetting/device_video_bg.png";
import device_video_bg_gray from "@/assets/modelSetting/device_video_bg_gray.png"; import device_video_bg_gray from "@/assets/modelSetting/device_video_bg_gray.png";
import notInVisableIcon from "@/assets/modelSetting/notInVisableIcon.png"; import notInVisableIcon from "@/assets/modelSetting/notInVisableIcon.png";
import { workspaceIDConf } from "@/config/attribute/viewType";
import { v4 as uuid } from "uuid"; import { v4 as uuid } from "uuid";
const deviceInfoKey = "deviceInfo"; const deviceInfoKey = "deviceInfo";
// TODO 设计实现点位绑定设备实体的位置偏移问题
/**
* @
* 1. (0,0)
*/
export const useDeviceObject = () => { export const useDeviceObject = () => {
// 移动到画布上的设备对象的相对坐标,使用相对图片的左边系,而不是画布的坐标系 // 拖拽新增获取设备对象在画布上的坐标
function getDragDeviceObjectOrdinate(event, viewObj, deviceObj) { function getDragDeviceObjectOrdinate(event, viewObj, deviceObj) {
// const cvsObjects = viewObj.getObjects()[0]; // 获取画布对象 // 移动到画布上的设备对象的相对坐标,使用相对图片的坐标系,而不是画布的坐标系
const currWorkSpaceData = document
.getElementById(workspaceIDConf)
.getBoundingClientRect();
const cvsObjects = viewObj.getObjects()[0]; // 获取画布对象
const imgObjects = viewObj.getObjects()[1]; // 获取图片对象 const imgObjects = viewObj.getObjects()[1]; // 获取图片对象
const { left, top } = viewObj.getSelectionElement().getBoundingClientRect(); const { left, top, width, height } = currWorkSpaceData;
const point = { // .getSelectionElement()
x: event.x - left - imgObjects.left, // .getBoundingClientRect();
y: event.y - top - imgObjects.top // 该设备基于当前画布的坐标信息
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
}; };
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");
// 使用相对坐标换实际位置的方法
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 { return {
x_ordinate: x_ordinate, left,
y_ordinate: y_ordinate top
}; };
} }
// 可操作区域的相对坐标 // 获取图片对象尺寸
// 可操作区域的各点位相对坐标【限定可操作区域边界】
function fetchViewsBoundaries(viewObj, activeObj) { function fetchViewsBoundaries(viewObj, activeObj) {
// 图片原点为中心图标
const cvsObjects = viewObj.getObjects()[0]; // 获取画布对象 const cvsObjects = viewObj.getObjects()[0]; // 获取画布对象
const imgObjects = viewObj.getObjects()[1]; // 获取图片对象 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 = const startLeft =
(cvsObjects.width * cvsObjects.scaleX - (cvsObjects.width * cvsObjects.scaleX -
imgObjects.width * imgObjects.scaleX) / imgObjects.width * imgObjects.scaleX) /
2; 2 -
currIconWidth / 2;
const startTop = const startTop =
(cvsObjects.height * cvsObjects.scaleY - (cvsObjects.height * cvsObjects.scaleY -
imgObjects.height * imgObjects.scaleY) / imgObjects.height * imgObjects.scaleY) /
2; 2 -
currIconHeight -
y_mistake;
const endLeft = startLeft + imgObjects.width * imgObjects.scaleX; const endLeft = startLeft + imgObjects.width * imgObjects.scaleX;
const endTop = startTop + imgObjects.height * imgObjects.scaleY; const endTop = startTop + imgObjects.height * imgObjects.scaleY;
const currImgWidth = imgObjects.width * imgObjects.scaleX;
const currImgHeight = imgObjects.height * imgObjects.scaleY;
return { return {
x_max: imgObjects.width * imgObjects.scaleX, x_min: -currImgWidth / 2 - currIconWidth / 2,
y_max: imgObjects.height * imgObjects.scaleY, y_min: -currImgHeight / 2 - currIconHeight,
x_max: currImgWidth / 2 + currIconWidth / 2,
y_max: currImgHeight / 2,
startLeft, startLeft,
startTop, startTop,
endLeft, endLeft,
endTop, endTop
moveLeft: endLeft - activeObj?.width * activeObj?.scaleX,
moveTop: endTop - activeObj?.height * activeObj?.scaleY
}; };
} }
// 判断设备是否在可视区域内 // 判断设备是否在可视区域内
function isInViewBoundaries(deviceObj, viewObj): boolean { function isInViewBoundaries(viewObj, deviceObj): boolean {
const { x_max, y_max } = fetchViewsBoundaries(viewObj, deviceObj); const { x_min, x_max, y_min, y_max } = fetchViewsBoundaries(
viewObj,
deviceObj
);
const { x_ordinate, y_ordinate } = deviceObj; const { x_ordinate, y_ordinate } = deviceObj;
// 获取对象的当前尺寸和位置
const objLeft = x_ordinate;
const objTop = y_ordinate;
// 限制对象在画布内移动 // 限制对象在画布内移动
if (objLeft < 0) { if (x_ordinate < x_min) {
return false; return false;
} }
if (objTop < 0) { if (y_ordinate < y_min) {
return false; return false;
} }
if (objLeft > x_max) { if (x_ordinate > x_max) {
return false; return false;
} }
if (objTop > y_max) { if (y_ordinate > y_max) {
return false; return false;
} }
return true; return true;
@ -86,45 +144,38 @@ export const useDeviceObject = () => {
// 设备对象是否移动 // 设备对象是否移动
function isMoveDevice(activeObject, viewObj) { function isMoveDevice(activeObject, viewObj) {
const { x_ordinate, y_ordinate } = activeObject.get(deviceInfoKey); const x_ordinate_history = activeObject.get(deviceInfoKey)?.x_ordinate;
const { startLeft, startTop } = fetchViewsBoundaries(viewObj); const y_ordinate_history = activeObject.get(deviceInfoKey)?.y_ordinate;
const { x_ordinate, y_ordinate } = fetchMoveDeviceObjectOrdinate(
viewObj,
activeObject
);
// 误差设置为 0.1 // 误差设置为 0.1
const errorValue = [1, 1]; const errorValue = [1, 1];
let x_move = true; let x_move = true;
let y_move = true; let y_move = true;
const x_move_value = Math.abs( const x_move_value = Math.abs(
Number(activeObject.left) - Number(x_ordinate) - Number(startLeft) Number(x_ordinate_history) - Number(x_ordinate)
); );
const y_move_value = Math.abs( const y_move_value = Math.abs(
Number(activeObject.top) - Number(y_ordinate) - Number(startTop) Number(y_ordinate_history) - Number(y_ordinate)
); );
console.log(
"startLeft" + startLeft, // 重新绑定车间的设备没有坐标信息,暂时不判断设备是否移动【默认没有移动】
"startTop" + startTop, // if (Number.isNaN(x_move_value) || Number.isNaN(y_move_value)) {
"isMoveDevice", // return false;
"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]) { if (x_move_value < errorValue[0]) {
x_move = false; x_move = false;
} }
if (y_move_value < errorValue[1]) { if (y_move_value < errorValue[1]) {
y_move = false; 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; return x_move || y_move;
} }
@ -384,7 +435,9 @@ export const useDeviceObject = () => {
isInViewBoundaries, isInViewBoundaries,
getDragDeviceObjectOrdinate, getDragDeviceObjectOrdinate,
isMoveDevice, isMoveDevice,
fetchViewsBoundaries fetchViewsBoundaries,
fetchOrdinateByView,
fetchMoveDeviceObjectOrdinate
// fetchDeviceObjectBySeemKey // fetchDeviceObjectBySeemKey
}; };
}; };

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd * @Author: donghao donghao@supervision.ltd
* @Date: 2024-08-02 10:52:32 * @Date: 2024-08-02 10:52:32
* @LastEditors: donghao donghao@supervision.ltd * @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-08-28 17:36:58 * @LastEditTime: 2024-08-30 11:11:29
* @FilePath: \General-AI-Platform-Web-Client\src\views\deviceSetting\index.vue * @FilePath: \General-AI-Platform-Web-Client\src\views\deviceSetting\index.vue
* @Description: 设备点位管理设置 * @Description: 设备点位管理设置
@ 交互说明 @ 交互说明
@ -116,11 +116,15 @@ const refreshCanvas = (isLoadDevice = true) => {
const canvasWidth = cvs.width; const canvasWidth = cvs.width;
const canvasHeight = cvs.height; const canvasHeight = cvs.height;
// Calculate the center position for the image // Calculate the center position for the image
const left = (canvasWidth - img.width * img.scaleX) / 2; // TODO
const top = (canvasHeight - img.height * img.scaleY) / 2; const startScale = 0.8;
const left = (canvasWidth - img.width * startScale) / 2;
const top = (canvasHeight - img.height * startScale) / 2;
img.set({ img.set({
left, left,
top top,
scaleX: startScale,
scaleY: startScale
}); });
// Re-render the canvas to apply changes // Re-render the canvas to apply changes
canvasEditor.canvas.renderAll(); canvasEditor.canvas.renderAll();

Loading…
Cancel
Save