diff --git a/package.json b/package.json index 6ae1233..0ac7fb3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vue-webtopo-svgeditor", - "version": "0.0.1", + "version": "0.0.2", "files": [ "dist" ], diff --git a/public/InterfaceReturn.json b/public/InterfaceReturn.json index df6bc6d..fd946e6 100644 --- a/public/InterfaceReturn.json +++ b/public/InterfaceReturn.json @@ -898,5 +898,53 @@ }, "create_type": "draggable", "priview_img": "/ReservoirSvg.png" + }, + { + "type": "WaterPipeValveSvg", + "title": "水管阀", + "panel_class": "common", + "template": "", + "props": [ + "prop_data" + ], + "extend_attr": { + "switch": { + "title": "类型", + "val": { + "selectval": "{\"fill\":\"#FF0000\"}", + "ridiogroup": [ + { + "value": "{\"fill\":\"#FF0000\"}", + "label": "关阀" + }, + { + "value": "{\"fill\":\"#00FF00\"}", + "label": "开阀" + } + ] + }, + "type": "radiogroup" + } + }, + "create_type": "draggable", + "priview_img": "/WaterPipeValveSvg.png" + }, + { + "type": "RightAnglePipeSvg", + "title": "直角管道", + "panel_class": "common", + "template": "", + "props": [ + "prop_data" + ], + "extend_attr": { + "color": { + "title": "管道颜色", + "val": "#0a7ae2", + "type": "colorinputbox" + } + }, + "create_type": "draggable", + "priview_img": "/RightAnglePipeSvg.png" } ] \ No newline at end of file diff --git a/public/RightAnglePipeSvg.png b/public/RightAnglePipeSvg.png new file mode 100644 index 0000000..a259104 Binary files /dev/null and b/public/RightAnglePipeSvg.png differ diff --git a/public/WaterPipeValveSvg.png b/public/WaterPipeValveSvg.png new file mode 100644 index 0000000..9d79200 Binary files /dev/null and b/public/WaterPipeValveSvg.png differ diff --git a/src/components/BottomBar.vue b/src/components/BottomBar.vue index daf4487..5fdaae2 100644 --- a/src/components/BottomBar.vue +++ b/src/components/BottomBar.vue @@ -5,9 +5,12 @@
  • 绘制组件需先选中 再将鼠标移至画布中按住左键开始绘制 松开左键结束绘制
  • 在画布上单击左键并按住可以拖动组件改变位置
  • 当组件选中时会有选中效果 此时右侧面板弹出 可使用快捷键和编辑右侧面板属性更改组件
  • +
  • 鼠标右键点击组件可以进行一些快捷操作
  • 键盘↑↓←→可移动选中组件 ctrl+c复制当前选中组件 deleted删除当前选中组件
  • +
  • ctrl+键盘↑↓←→可移动组件图层
  • 点击画布空白处可以取消选中组件 并关闭属性面板
  • 点击《 符号可以显示或隐藏左侧面板
  • +
  • 如果使用我的在线体验地址 请先保存绘制再切换到预览界面
  • 更多使用帮助请参考githubgitee
  • diff --git a/src/components/SvgEditor.vue b/src/components/SvgEditor.vue index cad3149..e93c380 100644 --- a/src/components/SvgEditor.vue +++ b/src/components/SvgEditor.vue @@ -7,8 +7,9 @@ import BottomBar from './BottomBar.vue'; import { NMessageProvider } from "naive-ui"; import { IComponentInfo, ISvgDataLists, ISvgCanvas, ILeftImgLists, IMouseInfo, ISelectSvg } from "../Model"; import SvgDynamic from "./SvgDynamic.vue"; -import "../assets/css/svgAnimation/index.css"; -const emit = defineEmits(['saveSvgInfo']) +import "../assets/css/svgAnimation/index.css"; +import { moveUp, moveDown, moveLeft, moveRight, hotkeyCopy, hotkeyDel, hotkeyPutOnTop, hotkeyPutOnButtom, hotkeyPutOnUp, hotkeyPutOnDown } from "../func/HotkeyFunc"; +const emit = defineEmits(['saveSvgInfo']); const props = defineProps({ //组件的json格式 component_infos: { @@ -22,8 +23,79 @@ const props = defineProps({ } }); const svg_dom_ref = ref(null); +const contextMenuRef = ref(); const svgLists: ISvgDataLists[] = reactive([]); const topbar_dom_ref = ref(null); +//显示右键菜单 +const display_contextmenu = ref(false); +//右键菜单数据 +const contextmenu_data = reactive([{ + name: "复制", + hotkey: "Ctrl+C", + enable: true, + fun: function () { + if (!this.enable) { + return; + } + hotkeyCopy(svgLists, select_svg); + display_contextmenu.value = false; + } +}, { + name: "删除", + hotkey: "Delete", + enable: false, + fun: function () { + if (!this.enable) { + return; + } + hotkeyDel(svgLists, select_svg); + display_contextmenu.value = false; + } +}, { + name: "置于顶层", + hotkey: "Ctrl+→", + enable: true, + fun: function () { + if (!this.enable) { + return; + } + hotkeyPutOnTop(svgLists, select_svg); + display_contextmenu.value = false; + } +}, { + name: "置于底层", + hotkey: "Ctrl+←", + enable: true, + fun: function () { + if (!this.enable) { + return; + } + hotkeyPutOnButtom(svgLists, select_svg); + display_contextmenu.value = false; + } +}, { + name: "置于上一层", + hotkey: "Ctrl+↑", + enable: true, + fun: function () { + if (!this.enable) { + return; + } + hotkeyPutOnUp(svgLists, select_svg); + display_contextmenu.value = false; + } +}, { + name: "置于下一层", + hotkey: "Ctrl+↓", + enable: true, + fun: function () { + if (!this.enable) { + return; + } + hotkeyPutOnDown(svgLists, select_svg); + display_contextmenu.value = false; + } +}]); const set_svg_info: Ref = ref({ id: '', title: '', svgPositionX: 0, svgPositionY: 0 }); @@ -205,6 +277,51 @@ const mouseDownCanvasEvent = (e: MouseEvent) => { mouseInfo.mPositionX = e.clientX; mouseInfo.mPositionY = e.clientY; } +/** + * @description: 鼠标右键 + * @param {*} + * @return {*} + */ +const contextmenuEvent = (e: MouseEvent) => { + e.preventDefault(); + display_contextmenu.value = true; + (contextMenuRef.value as any).style.left = e.pageX + 'px'; + (contextMenuRef.value as any).style.top = e.pageY + 'px'; + contextmenu_data.map(m => m.enable = true); + //判断当前选中组件的index + if (svgLists.length === 1) { + //禁用下移 + contextmenu_data[3].enable = false; + contextmenu_data[5].enable = false; + //禁用上移 + contextmenu_data[2].enable = false; + contextmenu_data[4].enable = false; + } + else if (select_svg.index === 0) { + //禁用下移 + contextmenu_data[3].enable = false; + contextmenu_data[5].enable = false; + + } + else if (select_svg.index === svgLists.length - 1) { + //禁用上移 + contextmenu_data[2].enable = false; + contextmenu_data[4].enable = false; + } + +} + +/** + * @description: 点击页面其他位置隐藏右键菜单 + * @param {*} + * @return {*} + */ +const documentClickEvent = (e: MouseEvent) => { + if (e.button !== 2) { + display_contextmenu.value = false; + + } +} watch(() => [...props.component_infos], (newval, oldval) => { leftimg_lists.value = { commonComponentList: newval.filter(f => f.panel_class == 'common'), @@ -218,36 +335,41 @@ document.onkeydown = function (e) { if (!select_svg.id) { return; } - if (e.key == 'ArrowUp') { - e.preventDefault(); - svgLists[select_svg.index].svgPositionY -= 1; - } else if (e.key == 'ArrowDown') { - e.preventDefault(); - svgLists[select_svg.index].svgPositionY += 1; - } else if (e.key == 'ArrowLeft') { - e.preventDefault(); - svgLists[select_svg.index].svgPositionX -= 1; - } else if (e.key == 'ArrowRight') { - e.preventDefault(); - svgLists[select_svg.index].svgPositionX += 1; + e.preventDefault(); + if (!e.ctrlKey && e.key == 'ArrowUp') { + moveUp(svgLists, select_svg); + } else if (!e.ctrlKey && e.key == 'ArrowDown') { + moveDown(svgLists, select_svg); + } else if (!e.ctrlKey && e.key == 'ArrowLeft') { + moveLeft(svgLists, select_svg); + } else if (!e.ctrlKey && e.key == 'ArrowRight') { + moveRight(svgLists, select_svg); } //ctrl c else if (e.ctrlKey && e.key.toLowerCase() == 'c') { - e.preventDefault(); - svgLists.push({ - ...(JSON.parse(JSON.stringify(svgLists[select_svg.index]))), - id: `${new Date().getTime()}`, - svgPositionX: svgLists[select_svg.index].svgPositionX + 10, - svgPositionY: svgLists[select_svg.index].svgPositionY + 10, - title: svgLists[select_svg.index].title + `-copy` - }) + hotkeyCopy(svgLists, select_svg); } //deleted else if (e.key == 'Delete') { - e.preventDefault(); - svgLists.splice(select_svg.index, 1); + hotkeyDel(svgLists, select_svg); rightnav_open.value = false; } + //上移一层 + else if (e.ctrlKey && e.key == 'ArrowUp') { + hotkeyPutOnUp(svgLists, select_svg); + } + //下移一层 + else if (e.ctrlKey && e.key == 'ArrowDown') { + hotkeyPutOnDown(svgLists, select_svg); + } + //置于底层 + else if (e.ctrlKey && e.key == 'ArrowLeft') { + hotkeyPutOnButtom(svgLists, select_svg); + } + //置于顶层 + else if (e.ctrlKey && e.key == 'ArrowRight') { + hotkeyPutOnTop(svgLists, select_svg); + } } @@ -257,7 +379,7 @@ document.onkeydown = function (e) { -
    +
    + +
      +
    • +

      + {{ item.name }} + {{ item.hotkey }} +

      +
    • +