|
|
@@ -0,0 +1,649 @@
|
|
|
+<template>
|
|
|
+ <div id="editorMap" ref="mapRef"></div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts" setup>
|
|
|
+ import Konva from 'konva';
|
|
|
+ import { ref, onMounted, onUnmounted } from 'vue';
|
|
|
+ import {
|
|
|
+ GROUP_NAME,
|
|
|
+ POLYGON_NAME,
|
|
|
+ Points,
|
|
|
+ ServerLine,
|
|
|
+ ToolObjectItem,
|
|
|
+ toolObject,
|
|
|
+ } from './constants';
|
|
|
+ import { ElMessage } from 'element-plus';
|
|
|
+ import { getDefaultScale } from './utils';
|
|
|
+ import { Group } from 'konva/lib/Group';
|
|
|
+
|
|
|
+ const mapRef = ref<HTMLCanvasElement | null>(null);
|
|
|
+ let currentTool: ToolObjectItem = toolObject[1];
|
|
|
+
|
|
|
+ let stage: Konva.Stage | null = null;
|
|
|
+ let layer: Konva.Layer | null = null;
|
|
|
+ let currentDrawingShape: Konva.Group | null = null; //现在绘画的图形
|
|
|
+ let polygonPoints: number[] = []; //存储绘画多边形各个顶点的数组
|
|
|
+ let stageWidth = 0; //舞台宽
|
|
|
+ let stageHeight = 0; //舞台高
|
|
|
+ let scale = 1; //窗口变化的缩放比例
|
|
|
+ let drawing = false; //一开始不能绘画
|
|
|
+ let currentDel: Konva.Node | null = null; //删除对象
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ initKonvaStage();
|
|
|
+ //禁止浏览器右击菜单
|
|
|
+ document.oncontextmenu = function () {
|
|
|
+ return false;
|
|
|
+ };
|
|
|
+ });
|
|
|
+
|
|
|
+ onUnmounted(() => {
|
|
|
+ stage?.destroy();
|
|
|
+ });
|
|
|
+
|
|
|
+ /**
|
|
|
+ *初始化konva舞台
|
|
|
+ */
|
|
|
+ function initKonvaStage() {
|
|
|
+ //1实例化stage层
|
|
|
+ stageWidth = mapRef.value?.clientWidth || 0;
|
|
|
+ stageHeight = mapRef.value?.clientHeight || 0;
|
|
|
+ console.log('stageWidth', stageWidth);
|
|
|
+ stage = new Konva.Stage({
|
|
|
+ container: 'editorMap',
|
|
|
+ width: stageWidth,
|
|
|
+ height: stageHeight,
|
|
|
+ ignoreStroke: true,
|
|
|
+ background: '#00ff00',
|
|
|
+ });
|
|
|
+ window.stage = stage;
|
|
|
+ setStageCursor('pointer');
|
|
|
+
|
|
|
+ //2实例化layer层
|
|
|
+ layer = new Konva.Layer();
|
|
|
+ //3添加layer层
|
|
|
+ stage?.add(layer);
|
|
|
+
|
|
|
+ //给***舞台***绑定事件
|
|
|
+ stageBindEvent();
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 舞台绑定的事件
|
|
|
+ * @param vc_this
|
|
|
+ */
|
|
|
+ function stageBindEvent() {
|
|
|
+ //鼠标按下
|
|
|
+ stage?.on('mousedown', (e) => {
|
|
|
+ //鼠标左键开始
|
|
|
+ console.log('stage mousedown', e);
|
|
|
+ if (e.evt.button == 0) {
|
|
|
+ if (e.target === stage) {
|
|
|
+ stageMousedown(currentTool!);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //图形起始点只能在图片层上
|
|
|
+ // if (e.target === shape) {
|
|
|
+ // //开始初始绘画
|
|
|
+ // stageMousedown(currentTool!);
|
|
|
+ // return;
|
|
|
+ // }
|
|
|
+ //允许后续点绘画在其他图形上
|
|
|
+ if (drawing) {
|
|
|
+ stageMousedown(currentTool!);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } else if (e.evt.button == 2) {
|
|
|
+ // 如果polygonPoints为空,那么右击是没有反应的。
|
|
|
+ console.log('mousedown 2');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ //鼠标移动
|
|
|
+ stage?.on('mousemove', () => {
|
|
|
+ if (currentTool && drawing) {
|
|
|
+ //绘画中
|
|
|
+ stageMousemove();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ //鼠标放开
|
|
|
+ stage?.on('mouseup', (e: Konva.KonvaEventObject<any>) => {
|
|
|
+ if (e.evt.button == 0) {
|
|
|
+ if (drawing) {
|
|
|
+ stageMouseup(e);
|
|
|
+ }
|
|
|
+ } else if (e.evt.button == 2) {
|
|
|
+ if (polygonPoints.length != 0) {
|
|
|
+ stageMouseup(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // //鼠标滚轮事件取消
|
|
|
+
|
|
|
+ //舞台快捷键
|
|
|
+ var container = stage?.container();
|
|
|
+ if (!container) return;
|
|
|
+ container.tabIndex = 1;
|
|
|
+ container?.focus();
|
|
|
+ container?.addEventListener('keydown', (e) => {
|
|
|
+ //删除的快捷键
|
|
|
+ if (e.keyCode === 46) {
|
|
|
+ removeCurrent();
|
|
|
+ }
|
|
|
+ if (container) {
|
|
|
+ container.style.cursor = 'crosshair';
|
|
|
+ }
|
|
|
+ e.preventDefault();
|
|
|
+ layer?.draw();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ const getPolygonInGroup = (g: Konva.Group | null) => {
|
|
|
+ if (!g) return;
|
|
|
+ return g.findOne(POLYGON_NAME) as Konva.Line;
|
|
|
+ };
|
|
|
+
|
|
|
+ /** 设置当前选中的group */
|
|
|
+ function setCurrentGroup(group: Konva.Group) {
|
|
|
+ currentDrawingShape = group;
|
|
|
+ setGroupActive(group);
|
|
|
+ currentDel = group;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 在舞台上鼠标点下发生的事件
|
|
|
+ * @param currentTool 当前选择的工具
|
|
|
+ * @param e 传入的event对象
|
|
|
+ */
|
|
|
+ function stageMousedown(currentTool: ToolObjectItem) {
|
|
|
+ console.log('stagemousedown');
|
|
|
+
|
|
|
+ //如果数组长度小于2,初始化多边形和顶点,使它们成为一组,否则什么都不做
|
|
|
+ // 小于2说明一个点也没有,一个点的长度是2,所以要先创建group
|
|
|
+ if (polygonPoints.length < 2) {
|
|
|
+ //最好使用konva提供的鼠标xy点坐标
|
|
|
+ var mousePos = stage?.getPointerPosition();
|
|
|
+ if (!mousePos) return;
|
|
|
+ //考虑鼠标缩放
|
|
|
+ var x = (mousePos.x / scale - layer?.getAttr('x')) / getDefaultScale(layer?.scaleX()),
|
|
|
+ y = (mousePos.y / scale - layer?.getAttr('y')) / getDefaultScale(layer?.scaleY());
|
|
|
+ //拖拽组
|
|
|
+ var group = new Konva.Group({
|
|
|
+ name: currentTool.name + 'group',
|
|
|
+ draggable: false,
|
|
|
+ });
|
|
|
+ polygonPoints = [x, y];
|
|
|
+ //添加多边形的点
|
|
|
+ drawCircle(x, y, group, polygonPoints);
|
|
|
+
|
|
|
+ //绘画多边形
|
|
|
+ drawPolygon(currentTool, polygonPoints, group);
|
|
|
+ //添加多边形的边
|
|
|
+ // drawLine(currentTool, polygonPoints, group);
|
|
|
+ layer?.add(group);
|
|
|
+ setCurrentGroup(group);
|
|
|
+ currentDel = group;
|
|
|
+
|
|
|
+ //使所有顶点在顶层显示
|
|
|
+ stage?.find('Circle').forEach((element) => {
|
|
|
+ element.moveToTop();
|
|
|
+ });
|
|
|
+ layer?.draw();
|
|
|
+ } //多边形增加顶点
|
|
|
+ else {
|
|
|
+ //最好使用konva提供的鼠标xy点坐标
|
|
|
+ var mousePos = stage?.getPointerPosition();
|
|
|
+ if (!mousePos) return;
|
|
|
+ //考虑鼠标缩放
|
|
|
+ var x = (mousePos.x / scale - layer?.getAttr('x')) / getDefaultScale(layer?.scaleX()),
|
|
|
+ y = (mousePos.y / scale - layer?.getAttr('y')) / getDefaultScale(layer?.scaleY());
|
|
|
+ //group继续添加多边形的点
|
|
|
+ drawCircle(x, y, currentDrawingShape!, polygonPoints);
|
|
|
+ polygonPoints.push(x);
|
|
|
+ polygonPoints.push(y);
|
|
|
+
|
|
|
+ const polygon = getPolygonInGroup(currentDrawingShape);
|
|
|
+ currentDel = currentDrawingShape;
|
|
|
+ //绘画多边形
|
|
|
+ polygon?.setAttr('points', polygonPoints);
|
|
|
+ //group继续添加多边形的边
|
|
|
+ //使所有顶点在顶层显示
|
|
|
+ stage?.find('Circle').forEach((element) => {
|
|
|
+ element.moveToTop();
|
|
|
+ });
|
|
|
+ layer?.draw();
|
|
|
+ }
|
|
|
+
|
|
|
+ drawing = true;
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 鼠标在舞台上移动事件
|
|
|
+ * @param currentTool 当前选择的工具
|
|
|
+ * @param e 传入的event对象
|
|
|
+ */
|
|
|
+ function stageMousemove() {
|
|
|
+ const container = stage?.container();
|
|
|
+ if (!container) return;
|
|
|
+
|
|
|
+ container.style.cursor = 'crosshair';
|
|
|
+ //多边形初始化后,如果数组长度大于2,鼠标移动时,实时更新下一个点
|
|
|
+ if (polygonPoints.length >= 2) {
|
|
|
+ var mousePos = stage?.getPointerPosition();
|
|
|
+ if (!mousePos) return;
|
|
|
+ var x = (mousePos.x / scale - layer?.getAttr('x')) / getDefaultScale(layer?.scaleX()),
|
|
|
+ y = (mousePos.y / scale - layer?.getAttr('y')) / getDefaultScale(layer?.scaleY());
|
|
|
+ var tempPoints = polygonPoints.concat([]);
|
|
|
+ tempPoints.push(x);
|
|
|
+ tempPoints.push(y);
|
|
|
+
|
|
|
+ const polygon = getPolygonInGroup(currentDrawingShape);
|
|
|
+ //更新多边形
|
|
|
+ polygon?.setAttr('points', tempPoints);
|
|
|
+ //使所有顶点在顶层显示
|
|
|
+ stage?.find('Circle').forEach((element) => {
|
|
|
+ element.moveToTop();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ layer?.draw();
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 鼠标在舞台弹起
|
|
|
+ * @param currentTool 当前选择的工具
|
|
|
+ * @param e 传入的event对象
|
|
|
+ */
|
|
|
+ function stageMouseup(e: Konva.KonvaEventObject<any>) {
|
|
|
+ if (e.evt.button == 2) {
|
|
|
+ if (polygonPoints.length != 0) {
|
|
|
+ //最好使用konva提供的鼠标xy点坐标
|
|
|
+ var mousePos = stage?.getPointerPosition();
|
|
|
+ if (!mousePos) return;
|
|
|
+ //考虑鼠标缩放
|
|
|
+ var x = (mousePos.x / scale - layer?.getAttr('x')) / getDefaultScale(layer?.scaleX()),
|
|
|
+ y = (mousePos.y / scale - layer?.getAttr('y')) / getDefaultScale(layer?.scaleY());
|
|
|
+ //group继续添加多边形的点
|
|
|
+ // 右击和左击都要添加一个点
|
|
|
+ drawCircle(x, y, currentDrawingShape!, polygonPoints);
|
|
|
+ polygonPoints.push(x);
|
|
|
+ polygonPoints.push(y);
|
|
|
+ const polygon = getPolygonInGroup(currentDrawingShape);
|
|
|
+ //绘画多边形
|
|
|
+ polygon?.setAttr('points', polygonPoints);
|
|
|
+
|
|
|
+ //判断是否是只有两个点的多边形,如果起点和终点相同,不允许绘画
|
|
|
+ if (polygon?.points().length == 2 || polygon?.points().length == 4) {
|
|
|
+ drawing = false;
|
|
|
+ currentDrawingShape?.destroy();
|
|
|
+ polygonPoints = [];
|
|
|
+ ElMessage({
|
|
|
+ message: '顶点数必须大于2个!',
|
|
|
+ type: 'warning',
|
|
|
+ center: true,
|
|
|
+ duration: 1000,
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //右键弹起
|
|
|
+ polygonPoints = [];
|
|
|
+ // 停止事件冒泡
|
|
|
+ e.cancelBubble = true;
|
|
|
+ // 停止画多边形
|
|
|
+ drawing = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //使所有顶点在顶层显示
|
|
|
+ stage?.find('Circle').forEach((element) => {
|
|
|
+ element.moveToTop();
|
|
|
+ });
|
|
|
+
|
|
|
+ layer?.draw();
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 多边形圆形
|
|
|
+ * @param //x x坐标
|
|
|
+ * @param //y y坐标
|
|
|
+ */
|
|
|
+ function drawCircle(x: number, y: number, group: Konva.Group, shapePoints: number[]) {
|
|
|
+ const circle = new Konva.Circle({
|
|
|
+ name: currentTool.name + 'circle',
|
|
|
+ x: x,
|
|
|
+ y: y,
|
|
|
+ radius: 5 / scale / getDefaultScale(layer?.scaleX()),
|
|
|
+ visible: true, //是否显示
|
|
|
+ fill: currentTool.anchorColor,
|
|
|
+ stroke: currentTool.anchorColor,
|
|
|
+ draggable: false,
|
|
|
+ strokeWidth: 0.5,
|
|
|
+ strokeScaleEnabled: false,
|
|
|
+ //增加点击区域
|
|
|
+ hitStrokeWidth: 8 / scale / getDefaultScale(layer?.scaleX()),
|
|
|
+ //设置拖动区域,不能超过舞台大小
|
|
|
+ dragBoundFunc: function (pos) {
|
|
|
+ //左上角
|
|
|
+ if (pos.x < 0 && pos.y < 0) {
|
|
|
+ return {
|
|
|
+ x: 0,
|
|
|
+ y: 0,
|
|
|
+ };
|
|
|
+ } //左侧
|
|
|
+ else if (pos.x <= 0 && 0 <= pos.y && pos.y <= (stage?.height() ?? 0)) {
|
|
|
+ return {
|
|
|
+ x: 0,
|
|
|
+ y: pos.y,
|
|
|
+ };
|
|
|
+ }
|
|
|
+ //左下角
|
|
|
+ else if (pos.x < 0 && pos.y > (stage?.height() ?? 0)) {
|
|
|
+ return {
|
|
|
+ x: 0,
|
|
|
+ y: stage?.height(),
|
|
|
+ };
|
|
|
+ } //下侧
|
|
|
+ else if (0 <= pos.x && pos.x <= (stage?.width() ?? 0) && pos.y > (stage?.height() ?? 0)) {
|
|
|
+ return {
|
|
|
+ x: pos.x,
|
|
|
+ y: stage?.height(),
|
|
|
+ };
|
|
|
+ } //右下角
|
|
|
+ else if (pos.x > (stage?.width() ?? 0) && pos.y > (stage?.height() ?? 0)) {
|
|
|
+ return {
|
|
|
+ x: stage?.width(),
|
|
|
+ y: stage?.height(),
|
|
|
+ };
|
|
|
+ }
|
|
|
+ //右侧
|
|
|
+ else if (pos.x > (stage?.width() ?? 0) && 0 <= pos.y && pos.y <= (stage?.height() ?? 0)) {
|
|
|
+ return {
|
|
|
+ x: stage?.width(),
|
|
|
+ y: pos.y,
|
|
|
+ };
|
|
|
+ }
|
|
|
+ //右上角
|
|
|
+ else if (pos.x > (stage?.width() ?? 0) && pos.y < 0) {
|
|
|
+ return {
|
|
|
+ x: stage?.width(),
|
|
|
+ y: 0,
|
|
|
+ };
|
|
|
+ } //上侧
|
|
|
+ else if (0 <= pos.x && pos.x <= (stage?.width() ?? 0) && pos.y < 0) {
|
|
|
+ return {
|
|
|
+ x: pos.x,
|
|
|
+ y: 0,
|
|
|
+ };
|
|
|
+ }
|
|
|
+ },
|
|
|
+ });
|
|
|
+ group.add(circle);
|
|
|
+ let xChange: number, yChange: number;
|
|
|
+ circle.on('mouseover', () => {
|
|
|
+ const c = stage?.container();
|
|
|
+ if (!c) return;
|
|
|
+ c.style.cursor = 'pointer';
|
|
|
+ });
|
|
|
+ circle.on('mousedown', (e) => {
|
|
|
+ console.log('circle,');
|
|
|
+ if (!drawing) {
|
|
|
+ circle.draggable(true);
|
|
|
+ //将现在绘画的对象改为group
|
|
|
+ setCurrentGroup(circle.getParent() as Konva.Group);
|
|
|
+ } else {
|
|
|
+ circle.draggable(false);
|
|
|
+ }
|
|
|
+ e.cancelBubble = true;
|
|
|
+ });
|
|
|
+ circle.on('mouseleave', () => {
|
|
|
+ const c = stage?.container();
|
|
|
+ if (!c) return;
|
|
|
+ c.style.cursor = 'crosshair';
|
|
|
+ });
|
|
|
+ circle.on('dragstart', () => {
|
|
|
+ switch (currentTool?.type) {
|
|
|
+ case 'poly':
|
|
|
+ //查找拖拽了多边形的哪个点
|
|
|
+ for (var i = 0; i < shapePoints.length; i += 2) {
|
|
|
+ if (
|
|
|
+ circle.getAttr('x') == shapePoints[i] &&
|
|
|
+ circle.getAttr('y') == shapePoints[i + 1]
|
|
|
+ ) {
|
|
|
+ xChange = i;
|
|
|
+ yChange = i + 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ circle.on('dragmove', () => {
|
|
|
+ switch (currentTool?.type) {
|
|
|
+ case 'poly':
|
|
|
+ var x = circle.x();
|
|
|
+ var y = circle.y();
|
|
|
+ //更改拖拽点的位置
|
|
|
+ shapePoints[xChange] = x;
|
|
|
+ shapePoints[yChange] = y;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ circle.on('dragend', (e) => {
|
|
|
+ switch (currentTool?.type) {
|
|
|
+ case 'poly':
|
|
|
+ //使所有顶点在顶层显示
|
|
|
+ stage?.find('Circle').forEach((element) => {
|
|
|
+ element.moveToTop();
|
|
|
+ });
|
|
|
+ circle.draggable(false);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ ElMessage({
|
|
|
+ message: '修改成功!',
|
|
|
+ type: 'success',
|
|
|
+ center: true,
|
|
|
+ duration: 1000,
|
|
|
+ });
|
|
|
+ e.cancelBubble = true;
|
|
|
+ });
|
|
|
+ return circle;
|
|
|
+ }
|
|
|
+
|
|
|
+ function setStageCursor(cursor: string) {
|
|
|
+ const c = stage?.container();
|
|
|
+ if (c) {
|
|
|
+ c.style.cursor = cursor;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 设置当前的group为active */
|
|
|
+ function setGroupActive(activeGroup: Group) {
|
|
|
+ const groups = stage?.find(GROUP_NAME) as Konva.Group[];
|
|
|
+ if (!groups) return;
|
|
|
+ /** 将其他组的线条设为非高亮 */
|
|
|
+ groups.forEach((g: Konva.Group) => {
|
|
|
+ if (g === activeGroup) return;
|
|
|
+ g.find(POLYGON_NAME).forEach((line) => {
|
|
|
+ (line as Konva.Line).stroke(currentTool?.color!);
|
|
|
+ });
|
|
|
+
|
|
|
+ g.find('Circle').forEach((circle) => {
|
|
|
+ (circle as Konva.Circle).hide();
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ const thisLine = activeGroup.findOne(POLYGON_NAME) as Konva.Line;
|
|
|
+ if (thisLine) {
|
|
|
+ thisLine.stroke(currentTool.activeColor);
|
|
|
+ }
|
|
|
+ const thisCircles = activeGroup.find('Circle') as Konva.Circle[];
|
|
|
+ if (thisCircles) {
|
|
|
+ thisCircles.forEach((circle) => {
|
|
|
+ (circle as Konva.Circle).show();
|
|
|
+ });
|
|
|
+ }
|
|
|
+ layer?.draw();
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ *多边形
|
|
|
+ @param currentTool
|
|
|
+ * @param points 多边形绘画的各个顶点,类型数组
|
|
|
+ */
|
|
|
+ function drawPolygon(currentTool: ToolObjectItem, points: number[], group: Konva.Group) {
|
|
|
+ let poly = new Konva.Line({
|
|
|
+ name: currentTool.name + 'poly',
|
|
|
+ points: points,
|
|
|
+ /* fill: currentTool.color, */
|
|
|
+ stroke: currentTool.color,
|
|
|
+ strokeWidth: 1,
|
|
|
+ draggable: false,
|
|
|
+ opacity: 0.5,
|
|
|
+ lineCap: 'round',
|
|
|
+ lineJoin: 'round',
|
|
|
+ closed: true,
|
|
|
+ strokeScaleEnabled: false,
|
|
|
+ });
|
|
|
+ group.add(poly);
|
|
|
+ setCurrentGroup(group);
|
|
|
+ const pParent = group;
|
|
|
+ pParent?.on('mouseleave', () => {
|
|
|
+ const c = stage?.container();
|
|
|
+ if (c) {
|
|
|
+ c.style.cursor = 'crosshair';
|
|
|
+ }
|
|
|
+ });
|
|
|
+ pParent?.on('mousedown', (e) => {
|
|
|
+ console.log('group mouse down');
|
|
|
+ if (e.evt.button == 0) {
|
|
|
+ //绘画结束
|
|
|
+ if (!drawing) {
|
|
|
+ setStageCursor('move');
|
|
|
+ //设置现在绘画节点的对象为该多边形和顶点的组
|
|
|
+ // 如果要让顶点和多边形一起拖拽,必须设置,多边形不能被拖拽
|
|
|
+ poly.setAttr('draggable', false);
|
|
|
+ currentDrawingShape?.setAttr('draggable', true);
|
|
|
+ //使所有顶点在顶层显示
|
|
|
+ stage?.find('Circle').forEach((element) => {
|
|
|
+ element.moveToTop();
|
|
|
+ });
|
|
|
+ //添加删除撤销对象
|
|
|
+ currentDel = currentDrawingShape;
|
|
|
+ setCurrentGroup(poly.getParent() as Konva.Group);
|
|
|
+
|
|
|
+ layer?.draw();
|
|
|
+ } else {
|
|
|
+ setStageCursor('crosshair');
|
|
|
+ poly.getParent()?.setAttr('draggable', false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ pParent?.on('dragend', () => {
|
|
|
+ console.log('dragend');
|
|
|
+ /** 这里可以把工具的类型用枚举值定义 */
|
|
|
+
|
|
|
+ //使所有顶点在顶层显示
|
|
|
+ stage?.find('Circle').forEach((element) => {
|
|
|
+ element.moveToTop();
|
|
|
+ });
|
|
|
+ //添加删除撤销对象
|
|
|
+ currentDel = currentDrawingShape;
|
|
|
+ layer?.draw();
|
|
|
+ /* vc_setMaskData(); */
|
|
|
+
|
|
|
+ ElMessage({
|
|
|
+ message: '修改成功!',
|
|
|
+ type: 'success',
|
|
|
+ center: true,
|
|
|
+ duration: 1000,
|
|
|
+ });
|
|
|
+ setStageCursor('crosshair');
|
|
|
+ //设置组不能拖动
|
|
|
+ currentDrawingShape?.setAttr('draggable', false);
|
|
|
+ });
|
|
|
+ return poly;
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 根据json数据创建group */
|
|
|
+ function createGroupByPoints(points: Points) {
|
|
|
+ var group = new Konva.Group({
|
|
|
+ name: currentTool.name + 'group',
|
|
|
+ draggable: false,
|
|
|
+ });
|
|
|
+ //添加多边形的点
|
|
|
+
|
|
|
+ //绘画多边形
|
|
|
+ drawPolygon(currentTool, points, group);
|
|
|
+ for (let i = 0; i < points.length; i += 2) {
|
|
|
+ const x = points[i];
|
|
|
+ const y = points[i + 1];
|
|
|
+ drawCircle(x, y, group, points);
|
|
|
+ }
|
|
|
+ // group.setAttrs({ x: groupData.attrs.x, y: groupData.attrs.y })
|
|
|
+
|
|
|
+ layer?.add(group);
|
|
|
+ layer?.draw();
|
|
|
+ }
|
|
|
+
|
|
|
+ const removeCurrent = () => {
|
|
|
+ if (currentDel) {
|
|
|
+ currentDel.destroy();
|
|
|
+ currentDel = null;
|
|
|
+ currentDrawingShape = null;
|
|
|
+ ElMessage({
|
|
|
+ message: '删除成功!',
|
|
|
+ type: 'success',
|
|
|
+ center: true,
|
|
|
+ duration: 1000,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ layer?.draw();
|
|
|
+ };
|
|
|
+
|
|
|
+ const toObject = () => {
|
|
|
+ const polyGroups = stage?.find('.polygroup');
|
|
|
+ const gropuPoints = polyGroups?.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();
|
|
|
+ const newPoints = [];
|
|
|
+ /** 存到后端的时候,只给点的坐标信息,不会给group的位置信息,所以要将点的坐标加上group的位移,才是之后点的最终坐标 */
|
|
|
+ for (let i = 0; i < points.length; i += 2) {
|
|
|
+ newPoints.push([points[i] + groupX, points[i + 1] + groupY]);
|
|
|
+ }
|
|
|
+ return newPoints;
|
|
|
+ });
|
|
|
+ return gropuPoints;
|
|
|
+ };
|
|
|
+
|
|
|
+ const initStageByJSON = (param: { width: number; height: number }) => {
|
|
|
+ stage?.setAttrs({ width: param.width, height: param.height });
|
|
|
+ };
|
|
|
+
|
|
|
+ const toRawObject = () => {
|
|
|
+ return stage?.toObject();
|
|
|
+ };
|
|
|
+
|
|
|
+ defineExpose({
|
|
|
+ remove: removeCurrent,
|
|
|
+ toObject,
|
|
|
+ toRawObject,
|
|
|
+ createGroupByPoints,
|
|
|
+ initStageByJSON,
|
|
|
+ });
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+ #editorMap {
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ border: 2px solid #0f0;
|
|
|
+ }
|
|
|
+</style>
|