|
|
@@ -1,273 +1,308 @@
|
|
|
-<template>
|
|
|
- <div class="overflowWrapper" :style="{ width: props.domWidth + 'px', height: domHeight + 'px' }">
|
|
|
- <div
|
|
|
- class="scaleWrapper"
|
|
|
- :style="{
|
|
|
- scale: scale,
|
|
|
- width: props.canvasSize.width + 'px',
|
|
|
- height: props.canvasSize.height + 'px',
|
|
|
- }"
|
|
|
- >
|
|
|
- <v-stage
|
|
|
- :config="configKonva"
|
|
|
- @mouse-down="handleStageMouseDown"
|
|
|
- @mouse-move="handleStageMouseMove"
|
|
|
- ref="stageRef"
|
|
|
- >
|
|
|
- <v-layer>
|
|
|
- <FenceItem
|
|
|
- :fenceGroups="fenceGroups"
|
|
|
- :draggable="!drawingGroupId"
|
|
|
- @select-group="handleSelectGroup"
|
|
|
- :is-edit="isEdit"
|
|
|
- :current-group-id="currentGroupId"
|
|
|
- />
|
|
|
- </v-layer>
|
|
|
- </v-stage>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-<script lang="ts" setup>
|
|
|
- import Konva from 'konva';
|
|
|
- import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
|
|
|
- import FenceItem from './FenceItem.vue';
|
|
|
- import { createCircleConfigItem, createGroupConfig } from './utils';
|
|
|
- import { FenceGroup } from './types';
|
|
|
- import { ElMessage } from 'element-plus';
|
|
|
- import { GROUP_NAME } from './constants';
|
|
|
-
|
|
|
- const props = defineProps<{
|
|
|
- /** 电子围栏的坐标 */
|
|
|
- linePoints: [number, number][][];
|
|
|
- /** 画布的大小 */
|
|
|
- canvasSize: { width: number; height: number };
|
|
|
- /** dom的真实尺寸 */
|
|
|
- domWidth: number;
|
|
|
- }>();
|
|
|
-
|
|
|
- const scale = computed(() => {
|
|
|
- return props.domWidth / props.canvasSize.width;
|
|
|
- });
|
|
|
-
|
|
|
- const stageRef = ref();
|
|
|
- const isEdit = ref(false);
|
|
|
-
|
|
|
- const fenceGroups = ref<FenceGroup[]>([]);
|
|
|
-
|
|
|
- /** 当前正在画的多边形的groupId */
|
|
|
- const drawingGroupId = ref('');
|
|
|
- /** 当前选中的多边形groupId,点击、拖拽、画线都会给它赋值 */
|
|
|
- const currentGroupId = ref('');
|
|
|
-
|
|
|
- watch(
|
|
|
- () => props.linePoints,
|
|
|
- (newLinePoints) => {
|
|
|
- const configs: FenceGroup[] =
|
|
|
- newLinePoints.map((points) => {
|
|
|
- const flattenedPoints = points.reduce((total, next) => {
|
|
|
- return [...total, ...next];
|
|
|
- }, [] as number[]);
|
|
|
- return createGroupConfig(flattenedPoints, scale.value);
|
|
|
- }) || [];
|
|
|
- fenceGroups.value = configs;
|
|
|
- },
|
|
|
- {
|
|
|
- immediate: true,
|
|
|
- },
|
|
|
- );
|
|
|
-
|
|
|
- onMounted(() => {
|
|
|
- /** 取消默认的右键 */
|
|
|
- document.oncontextmenu = function () {
|
|
|
- return false;
|
|
|
- };
|
|
|
- });
|
|
|
-
|
|
|
- onUnmounted(() => {
|
|
|
- /** 取消默认的右键 */
|
|
|
- document.oncontextmenu = function () {
|
|
|
- return true;
|
|
|
- };
|
|
|
- });
|
|
|
-
|
|
|
- const configKonva = computed(() => {
|
|
|
- return props.canvasSize;
|
|
|
- });
|
|
|
-
|
|
|
- const canvasRatio = computed(() => {
|
|
|
- const size = props.canvasSize;
|
|
|
- if (!size) return 1;
|
|
|
- return size.height / size.width;
|
|
|
- });
|
|
|
-
|
|
|
- const domHeight = computed(() => {
|
|
|
- return props.domWidth * canvasRatio.value;
|
|
|
- });
|
|
|
-
|
|
|
- const handleStageMouseDown = (e) => {
|
|
|
- if (!isEdit.value) return;
|
|
|
- /**
|
|
|
- * parent存在,说明点击的不是stage
|
|
|
- * !drawingGroupId,说明当前不处于绘制多边形中
|
|
|
- * 这两种情况,都不能执行stage的点击事件,要执行点击对象的默认事件
|
|
|
- */
|
|
|
- if (e.target.parent && !drawingGroupId.value) return;
|
|
|
- const stage = e.currentTarget as Konva.Stage;
|
|
|
- // 获取当前鼠标相对舞台的位置
|
|
|
- const mousePosition = stage.getPointerPosition();
|
|
|
- if (!mousePosition?.x || !mousePosition?.y) return;
|
|
|
- const point = [mousePosition.x, mousePosition.y] as [number, number];
|
|
|
-
|
|
|
- /** 如果还没开始画线,那么增加第一个点 */
|
|
|
- if (!drawingGroupId.value) {
|
|
|
- const groupConfig = createGroupConfig(point, scale.value);
|
|
|
- drawingGroupId.value = groupConfig.uid;
|
|
|
- currentGroupId.value = groupConfig.uid;
|
|
|
- groupConfig._temp.points = point;
|
|
|
- fenceGroups.value.push(groupConfig);
|
|
|
- } else {
|
|
|
- /** 右键点击,取消最后一个点 */
|
|
|
- if (e.evt.button === 2) {
|
|
|
- /** 否则就追加点 */
|
|
|
- const groupConfig = fenceGroups.value.find((x) => x.uid === drawingGroupId.value);
|
|
|
- if (!groupConfig) {
|
|
|
- console.error('drawingGroupId无效', drawingGroupId.value);
|
|
|
- return;
|
|
|
- }
|
|
|
- if ((groupConfig._temp.points.length || 0) <= 4) {
|
|
|
- ElMessage({
|
|
|
- message: '顶点数必须大于2个!',
|
|
|
- type: 'warning',
|
|
|
- center: true,
|
|
|
- duration: 1000,
|
|
|
- });
|
|
|
- /** 要把当前的group给删除掉 */
|
|
|
- fenceGroups.value = fenceGroups.value.filter((x) => x.uid !== drawingGroupId.value);
|
|
|
- groupConfig.lineConfig.points = [];
|
|
|
- groupConfig.circleConfigs = [];
|
|
|
- currentGroupId.value = '';
|
|
|
- } else {
|
|
|
- groupConfig.lineConfig.points = groupConfig._temp.points;
|
|
|
- }
|
|
|
- drawingGroupId.value = '';
|
|
|
- groupConfig._temp.points = [];
|
|
|
- return;
|
|
|
- }
|
|
|
- /** 否则就追加点 */
|
|
|
- const groupConfig = fenceGroups.value.find((x) => x.uid === drawingGroupId.value);
|
|
|
- if (!groupConfig) {
|
|
|
- console.error('drawingGroupId无效', drawingGroupId.value);
|
|
|
- return;
|
|
|
- }
|
|
|
- const tempPoints = groupConfig._temp?.points || [];
|
|
|
- const finalPoints = [...tempPoints, ...point];
|
|
|
- groupConfig.lineConfig.points = finalPoints;
|
|
|
- groupConfig._temp.points = finalPoints;
|
|
|
- currentGroupId.value = groupConfig.uid;
|
|
|
-
|
|
|
- const circleConfig = createCircleConfigItem(
|
|
|
- point,
|
|
|
- groupConfig.circleConfigs.length,
|
|
|
- scale.value,
|
|
|
- );
|
|
|
- groupConfig.circleConfigs.push(circleConfig);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- const handleStageMouseMove = (e) => {
|
|
|
- if (!isEdit.value) return;
|
|
|
- const stage = e.currentTarget as Konva.Stage;
|
|
|
- /** 获取当前鼠标的坐标 */
|
|
|
- const mousePosition = stage.getPointerPosition();
|
|
|
- if (!mousePosition?.x || !mousePosition?.y) return;
|
|
|
- const newPoint = [mousePosition.x, mousePosition.y];
|
|
|
- if (drawingGroupId.value) {
|
|
|
- const groupConfig: FenceGroup | undefined = fenceGroups.value.find(
|
|
|
- (x) => x.uid === drawingGroupId.value,
|
|
|
- );
|
|
|
- if (!groupConfig) {
|
|
|
- console.error('drawingGroupId无效', drawingGroupId.value);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- /** 如果正在画线,那么替换最后一个点 */
|
|
|
- const initialPoints = groupConfig.lineConfig.points as number[];
|
|
|
- if (groupConfig._temp.points.length > 0) {
|
|
|
- groupConfig.lineConfig.points = [...groupConfig._temp.points, ...newPoint];
|
|
|
- } else {
|
|
|
- groupConfig._temp.points = initialPoints;
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- const handleSelectGroup = (groupId: string) => {
|
|
|
- currentGroupId.value = groupId;
|
|
|
- };
|
|
|
-
|
|
|
- /** 清空所有元素 */
|
|
|
- const clear = () => {
|
|
|
- fenceGroups.value = [];
|
|
|
- };
|
|
|
-
|
|
|
- /** 删除当前选中的group项 */
|
|
|
- const remove = () => {
|
|
|
- fenceGroups.value = fenceGroups.value.filter((x) => x.uid !== currentGroupId.value);
|
|
|
- currentGroupId.value = '';
|
|
|
- };
|
|
|
-
|
|
|
- /** 导出为json格式 */
|
|
|
- const toObject = () => {
|
|
|
- const stage = stageRef.value.getStage();
|
|
|
- const fenceGroups = stage?.find('.' + GROUP_NAME);
|
|
|
- const gropuPoints = fenceGroups
|
|
|
- ?.map((item) => {
|
|
|
- const groupX = item.x();
|
|
|
- const groupY = item.y();
|
|
|
-
|
|
|
- const line = (item as Konva.Group).findOne(
|
|
|
- (x: any) => x.className === 'Line',
|
|
|
- ) as Konva.Line;
|
|
|
- const points = line?.points();
|
|
|
- /** 有些line对象存在,但是没有点坐标,所以要判断过滤一下 */
|
|
|
- if (points && points.length > 0) {
|
|
|
- const newPoints: number[][] = [];
|
|
|
- /** 存到后端的时候,只给点的坐标信息,不会给group的位置信息,所以要将点的坐标加上group的位移,才是之后点的最终坐标 */
|
|
|
- for (let i = 0; i < points.length; i += 2) {
|
|
|
- newPoints.push([Math.floor(points[i] + groupX), Math.floor(points[i + 1] + groupY)]);
|
|
|
- }
|
|
|
- return newPoints;
|
|
|
- }
|
|
|
- return null;
|
|
|
- })
|
|
|
- .filter(Boolean);
|
|
|
- return gropuPoints;
|
|
|
- };
|
|
|
-
|
|
|
- /** 退出编辑模式 */
|
|
|
- const exitEditMode = () => {
|
|
|
- currentGroupId.value = '';
|
|
|
- isEdit.value = false;
|
|
|
- };
|
|
|
- /** 进入编辑模式 */
|
|
|
- const setEditMode = () => {
|
|
|
- isEdit.value = true;
|
|
|
- };
|
|
|
-
|
|
|
- defineExpose({
|
|
|
- clear,
|
|
|
- remove,
|
|
|
- toObject,
|
|
|
- exitEditMode,
|
|
|
- setEditMode,
|
|
|
- });
|
|
|
-</script>
|
|
|
-
|
|
|
-<style scoped>
|
|
|
- .scaleWrapper {
|
|
|
- transform-origin: left top;
|
|
|
- }
|
|
|
- .overflowWrapper {
|
|
|
- overflow: hidden;
|
|
|
- border: 1px solid #efefef;
|
|
|
- }
|
|
|
-</style>
|
|
|
+<template>
|
|
|
+ <div class="overflowWrapper" :style="{ width: props.domWidth + 'px', height: domHeight + 'px' }">
|
|
|
+ <div
|
|
|
+ class="scaleWrapper"
|
|
|
+ :style="{
|
|
|
+ scale: scale,
|
|
|
+ width: props.canvasSize.width + 'px',
|
|
|
+ height: props.canvasSize.height + 'px',
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ <v-stage
|
|
|
+ :config="configKonva"
|
|
|
+ @mouse-down="handleStageMouseDown"
|
|
|
+ @mouse-move="handleStageMouseMove"
|
|
|
+ ref="stageRef"
|
|
|
+ >
|
|
|
+ <v-layer>
|
|
|
+ <FenceItem
|
|
|
+ :fenceGroups="fenceGroups"
|
|
|
+ :draggable="!drawingGroupId"
|
|
|
+ :is-edit="isEdit"
|
|
|
+ :current-group-id="currentGroupId"
|
|
|
+ @select-group="handleSelectGroup"
|
|
|
+ @group-end-move="handleGroupEndMove"
|
|
|
+ />
|
|
|
+ </v-layer>
|
|
|
+ </v-stage>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+<script lang="ts" setup>
|
|
|
+ import Konva from 'konva';
|
|
|
+ import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
|
|
|
+ import FenceItem from './FenceItem.vue';
|
|
|
+ import { createCircleConfigItem, createGroupConfig, polygonPoint1ToPoint2, stageGroupToPoint2 } from './utils';
|
|
|
+ import { FenceGroup, FencePolygonPoints, SingleFence } from './types';
|
|
|
+ import { ElMessage } from 'element-plus';
|
|
|
+ import { GROUP_NAME } from './constants';
|
|
|
+
|
|
|
+ const props = defineProps<{
|
|
|
+ /** 电子围栏的坐标 */
|
|
|
+ linePoints: SingleFence[];
|
|
|
+ /** 画布的大小 */
|
|
|
+ canvasSize: { width: number; height: number };
|
|
|
+ /** dom的真实尺寸 */
|
|
|
+ domWidth: number;
|
|
|
+ /** 当前选中的是哪个分组 */
|
|
|
+ fenceId?: number | null;
|
|
|
+ }>();
|
|
|
+
|
|
|
+ // 保存修改后的电子围栏, fenceId为空表示新建的,否则表示编辑已存在的
|
|
|
+ interface EmitsEvents {
|
|
|
+ (e: 'save', data: { fenceId?: number; polygon: FencePolygonPoints }): unknown;
|
|
|
+ (e: 'select', fenceId: number | null): unknown;
|
|
|
+ }
|
|
|
+ const emits = defineEmits<EmitsEvents>();
|
|
|
+
|
|
|
+ const scale = computed(() => {
|
|
|
+ return props.domWidth / props.canvasSize.width;
|
|
|
+ });
|
|
|
+
|
|
|
+ const stageRef = ref();
|
|
|
+ const isEdit = ref(true);
|
|
|
+
|
|
|
+ const fenceGroups = ref<FenceGroup[]>([]);
|
|
|
+
|
|
|
+ /** 当前正在画的多边形的groupId */
|
|
|
+ const drawingGroupId = ref('');
|
|
|
+ /** 当前选中的多边形groupId,点击、拖拽、画线都会给它赋值 */
|
|
|
+ const currentGroupId = ref('');
|
|
|
+
|
|
|
+ watch(
|
|
|
+ () => props.linePoints,
|
|
|
+ (newLinePoints) => {
|
|
|
+ const configs: FenceGroup[] =
|
|
|
+ newLinePoints.map((points) => {
|
|
|
+ const polygonJSON = points.polygon || [];
|
|
|
+ const flattenedPoints = polygonJSON.reduce((total, next) => {
|
|
|
+ return [...total, ...next];
|
|
|
+ }, [] as number[]);
|
|
|
+ return createGroupConfig({ fenceId: points.id, points: flattenedPoints, scale: scale.value });
|
|
|
+ }) || [];
|
|
|
+ fenceGroups.value = configs;
|
|
|
+
|
|
|
+ const currentGroup = fenceGroups.value.find((x) => x.fenceId === props.fenceId);
|
|
|
+ const groupId = currentGroup?.uid;
|
|
|
+ if (groupId) {
|
|
|
+ currentGroupId.value = groupId;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ immediate: true,
|
|
|
+ },
|
|
|
+ );
|
|
|
+
|
|
|
+ watch(
|
|
|
+ () => props.fenceId,
|
|
|
+ (nextFenceId) => {
|
|
|
+ const currentGroup = fenceGroups.value.find((x) => x.fenceId === nextFenceId);
|
|
|
+ const groupId = currentGroup?.uid;
|
|
|
+ if (groupId) {
|
|
|
+ currentGroupId.value = groupId;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ immediate: true,
|
|
|
+ },
|
|
|
+ );
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ /** 取消默认的右键 */
|
|
|
+ document.oncontextmenu = function () {
|
|
|
+ return false;
|
|
|
+ };
|
|
|
+ });
|
|
|
+
|
|
|
+ onUnmounted(() => {
|
|
|
+ /** 取消默认的右键 */
|
|
|
+ document.oncontextmenu = function () {
|
|
|
+ return true;
|
|
|
+ };
|
|
|
+ });
|
|
|
+
|
|
|
+ const configKonva = computed(() => {
|
|
|
+ return props.canvasSize;
|
|
|
+ });
|
|
|
+
|
|
|
+ const canvasRatio = computed(() => {
|
|
|
+ const size = props.canvasSize;
|
|
|
+ if (!size) return 1;
|
|
|
+ return size.height / size.width;
|
|
|
+ });
|
|
|
+
|
|
|
+ const domHeight = computed(() => {
|
|
|
+ return props.domWidth * canvasRatio.value;
|
|
|
+ });
|
|
|
+
|
|
|
+ const handleStageMouseDown = (e) => {
|
|
|
+ if (!isEdit.value) return;
|
|
|
+ /**
|
|
|
+ * parent存在,说明点击的不是stage
|
|
|
+ * !drawingGroupId,说明当前不处于绘制多边形中
|
|
|
+ * 这两种情况,都不能执行stage的点击事件,要执行点击对象的默认事件
|
|
|
+ */
|
|
|
+ if (e.target.parent && !drawingGroupId.value) return;
|
|
|
+ const stage = e.currentTarget as Konva.Stage;
|
|
|
+ // 获取当前鼠标相对舞台的位置
|
|
|
+ const mousePosition = stage.getPointerPosition();
|
|
|
+ if (!mousePosition?.x || !mousePosition?.y) return;
|
|
|
+ const point = [mousePosition.x, mousePosition.y] as [number, number];
|
|
|
+
|
|
|
+ /** 如果还没开始画线,那么增加第一个点 */
|
|
|
+ if (!drawingGroupId.value) {
|
|
|
+ const groupConfig = createGroupConfig({ points: point, scale: scale.value });
|
|
|
+ drawingGroupId.value = groupConfig.uid;
|
|
|
+ currentGroupId.value = groupConfig.uid;
|
|
|
+ groupConfig._temp.points = point;
|
|
|
+ fenceGroups.value.push(groupConfig);
|
|
|
+ // 创建新点时,要把之前选中的电子围栏取消高亮
|
|
|
+ emits('select', null);
|
|
|
+ } else {
|
|
|
+ /** 右键点击,取消最后一个点 */
|
|
|
+ if (e.evt.button === 2) {
|
|
|
+ /** 否则就追加点 */
|
|
|
+ const groupConfig = fenceGroups.value.find((x) => x.uid === drawingGroupId.value);
|
|
|
+ if (!groupConfig) {
|
|
|
+ console.error('drawingGroupId无效', drawingGroupId.value);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if ((groupConfig._temp.points.length || 0) <= 4) {
|
|
|
+ ElMessage({
|
|
|
+ message: '顶点数必须大于2个!',
|
|
|
+ type: 'warning',
|
|
|
+ center: true,
|
|
|
+ duration: 1000,
|
|
|
+ });
|
|
|
+ /** 要把当前的group给删除掉 */
|
|
|
+ fenceGroups.value = fenceGroups.value.filter((x) => x.uid !== drawingGroupId.value);
|
|
|
+ groupConfig.lineConfig.points = [];
|
|
|
+ groupConfig.circleConfigs = [];
|
|
|
+ currentGroupId.value = '';
|
|
|
+ } else {
|
|
|
+ const points = groupConfig._temp.points;
|
|
|
+ groupConfig.lineConfig.points = points;
|
|
|
+ console.log('完成了一个电子围栏的编辑groupConfig', groupConfig);
|
|
|
+ const points2 = polygonPoint1ToPoint2(points);
|
|
|
+ if (points2) {
|
|
|
+ emits('save', { fenceId: groupConfig.fenceId, polygon: points2 });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ drawingGroupId.value = '';
|
|
|
+ groupConfig._temp.points = [];
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ /** 否则就追加点 */
|
|
|
+ const groupConfig = fenceGroups.value.find((x) => x.uid === drawingGroupId.value);
|
|
|
+ if (!groupConfig) {
|
|
|
+ console.error('drawingGroupId无效', drawingGroupId.value);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const tempPoints = groupConfig._temp?.points || [];
|
|
|
+ const finalPoints = [...tempPoints, ...point];
|
|
|
+ groupConfig.lineConfig.points = finalPoints;
|
|
|
+ groupConfig._temp.points = finalPoints;
|
|
|
+ currentGroupId.value = groupConfig.uid;
|
|
|
+
|
|
|
+ const circleConfig = createCircleConfigItem(point, groupConfig.circleConfigs.length, scale.value);
|
|
|
+ groupConfig.circleConfigs.push(circleConfig);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleStageMouseMove = (e) => {
|
|
|
+ if (!isEdit.value) return;
|
|
|
+ const stage = e.currentTarget as Konva.Stage;
|
|
|
+ /** 获取当前鼠标的坐标 */
|
|
|
+ const mousePosition = stage.getPointerPosition();
|
|
|
+ if (!mousePosition?.x || !mousePosition?.y) return;
|
|
|
+ const newPoint = [mousePosition.x, mousePosition.y];
|
|
|
+ if (drawingGroupId.value) {
|
|
|
+ const groupConfig: FenceGroup | undefined = fenceGroups.value.find((x) => x.uid === drawingGroupId.value);
|
|
|
+ if (!groupConfig) {
|
|
|
+ console.error('drawingGroupId无效', drawingGroupId.value);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 如果正在画线,那么替换最后一个点 */
|
|
|
+ const initialPoints = groupConfig.lineConfig.points as number[];
|
|
|
+ if (groupConfig._temp.points.length > 0) {
|
|
|
+ groupConfig.lineConfig.points = [...groupConfig._temp.points, ...newPoint];
|
|
|
+ } else {
|
|
|
+ groupConfig._temp.points = initialPoints;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleSelectGroup = (groupId: string) => {
|
|
|
+ currentGroupId.value = groupId;
|
|
|
+ const thisFence = fenceGroups.value.find((x) => x.uid === groupId);
|
|
|
+ if (thisFence?.fenceId) {
|
|
|
+ emits('select', thisFence.fenceId);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ /** 清空所有元素 */
|
|
|
+ const clear = () => {
|
|
|
+ fenceGroups.value = [];
|
|
|
+ };
|
|
|
+
|
|
|
+ /** 删除当前选中的group项 */
|
|
|
+ const remove = () => {
|
|
|
+ fenceGroups.value = fenceGroups.value.filter((x) => x.uid !== currentGroupId.value);
|
|
|
+ currentGroupId.value = '';
|
|
|
+ };
|
|
|
+
|
|
|
+ /** 导出为json格式 */
|
|
|
+ const toObject = () => {
|
|
|
+ const stage = stageRef.value.getStage();
|
|
|
+ const fenceGroups = stage?.find('.' + GROUP_NAME);
|
|
|
+ const gropuPoints = fenceGroups
|
|
|
+ ?.map((item) => {
|
|
|
+ return stageGroupToPoint2(item);
|
|
|
+ })
|
|
|
+ .filter(Boolean);
|
|
|
+ return gropuPoints;
|
|
|
+ };
|
|
|
+
|
|
|
+ // 分组移动后保存位置信息
|
|
|
+ const handleGroupEndMove = (groupId: string) => {
|
|
|
+ const stage = stageRef.value.getStage();
|
|
|
+ const stageGroups = stage?.find('.' + GROUP_NAME);
|
|
|
+ const group = stageGroups?.find((item) => {
|
|
|
+ return item.attrs.groupId === groupId;
|
|
|
+ });
|
|
|
+ if (!group) {
|
|
|
+ console.error('未匹配到groupId', groupId);
|
|
|
+ }
|
|
|
+ const points = stageGroupToPoint2(group);
|
|
|
+ emits('save', { fenceId: group.attrs.fenceId, polygon: points! });
|
|
|
+ };
|
|
|
+
|
|
|
+ /** 退出编辑模式 */
|
|
|
+ const exitEditMode = () => {
|
|
|
+ currentGroupId.value = '';
|
|
|
+ isEdit.value = false;
|
|
|
+ };
|
|
|
+ /** 进入编辑模式 */
|
|
|
+ const setEditMode = () => {
|
|
|
+ isEdit.value = true;
|
|
|
+ };
|
|
|
+
|
|
|
+ defineExpose({
|
|
|
+ clear,
|
|
|
+ remove,
|
|
|
+ toObject,
|
|
|
+ exitEditMode,
|
|
|
+ setEditMode,
|
|
|
+ });
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+ .scaleWrapper {
|
|
|
+ transform-origin: left top;
|
|
|
+ }
|
|
|
+ .overflowWrapper {
|
|
|
+ overflow: hidden;
|
|
|
+ border: 1px solid #efefef;
|
|
|
+ }
|
|
|
+</style>
|