From 4f4762fb01ad473c43598d2bc5d48170eb92621c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=92=AC=E8=BD=AE=E7=8C=AB?= <10928033@qq.com> Date: Tue, 14 Dec 2021 22:10:56 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8F=B3=E9=94=AE=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E5=92=8C=E5=9B=BE=E5=B1=82=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- public/InterfaceReturn.json | 48 ++++++++ public/RightAnglePipeSvg.png | Bin 0 -> 1790 bytes public/WaterPipeValveSvg.png | Bin 0 -> 1891 bytes src/components/BottomBar.vue | 3 + src/components/SvgEditor.vue | 232 +++++++++++++++++++++++++++++++---- src/func/HotkeyFunc.ts | 105 ++++++++++++++++ 7 files changed, 364 insertions(+), 26 deletions(-) create mode 100644 public/RightAnglePipeSvg.png create mode 100644 public/WaterPipeValveSvg.png create mode 100644 src/func/HotkeyFunc.ts 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 0000000000000000000000000000000000000000..a259104aba236e67fff689ee546924675e1f9762 GIT binary patch literal 1790 zcmbVNeNYr-7+*|92xkJC#$hm*g_&$(Z$FL$ZsP*H!#MMRft$D>NB4H$B!$U@sNOw}8*E6+efQ&i zcYp8mJiq5_JF6<5UY(qgj3CHrd%3L|J~!yss+I75#fe;lk0iPLITbC#+|%?u|63@k6Xfgu!-AsRu7ibFEX`GAJHL4zP#u*rcz3>A0_R%>#Q4%rI4 zLV1eQQGz!st7OYfPh`JnA zs8vz`nr|R+jwETcz-*xM^Nc1s7o|y>BuI)dk~n2zOeAA0L}LdAwJE%ZskUv5>4GZ@ z=G8QrA&6iwXb2h&lF~p>X0w?fX@aJ4h``mbsIehjRI?W(*nr9@f~*OWi0Tqqx74Ir zFlgyKg@7CvE2=R!L5C3`RwgI|sZ)vqc`lBVn-qUkInNQm4+22cREVYGSlKISlIoTI zMRff09SWdp9get;C2a`=;wn_FtQpdXIb=z+>I}<(s0OOkq;R0D8Jd}`vymCA0$5E_ zoRZ{U2vpUA$tVq(pzCV|k(Yw%;~e2BSvd6pd4PPMTt9lF2haK^8J3IS+M6 zyx<8h38fgybO#is49{xpJ;6N3cqApjLc&6TZ2*KUHehJnjf_?DOA1sBtuscga5xyd zsA{ap0lUqDLCyw2;2Dq6ln>yE(;kxtrwj8aoMlN8H{}7|1KgA+-(9${-zITQdSn;& z^Z#>yr6Rz}V*U3mN3Sz?UEK;sF$4(E9g|D+iGwy0(o;II+s(|8Ahi+B$M zB5Yg=>`*t8KD>z_37^_+rOr_I#1DhdEMqf=ZcN^OeZ<_8HItZ|(b}`CE~8OQZ|&== z>(1By z&)Gk{(zC*f{HIZ}F<7$mR)qY8`uRxL`Lp9Uu3Vb9c824?i*tvQ$fPYg_aCna=*C_KrU}L+{B`?rquj_71iv*|E2m z*qxPZup2i7cG zJkrA5#XG(Ew!^6}elfkSTKMbpsja_`AbajMUaI_~#6_1Uj;+`KQ1-G4+wl$CTK@(s C32A`< literal 0 HcmV?d00001 diff --git a/public/WaterPipeValveSvg.png b/public/WaterPipeValveSvg.png new file mode 100644 index 0000000000000000000000000000000000000000..9d79200b090956cefedb23b1b360f984eb088cce GIT binary patch literal 1891 zcmbVNeQXnD7%wn!8=DSC*g7|M+(0*2dmr7__H2h;yU{5fbJT1GLb%?&UC*_5x4Y}w z&6$WSh#;T{3CK1Cg5eKfMn(V;$A*cC6GZvc#3=(&APW-^#S!(ru5Cc4M4H^)d++_; z-}5}b=cBJzSItdL&Pvv3G^v$NM-6W^Ff0@b=|cv+Ak|}p*=)ve5+g|+MCjyZUZKM}Ue1d#IDpJZoTzXDkEo2aM+hob z6nZ)uLO_hu@^VxrC>R!|MU2qnYDf_v%fxYFQ1VBNvkV6OAOLtphFBtw6@7vt$Ufm; zsN~NyAA*ctpF?b>DKrp!1m8hof;|e-AP8?XI4U!QmiKm+=V%U*alw}ZD$4ZWpFL`BMa z{=-*Xy=Yr`;;OW%(+kV$+TKs3C-;qRY(SUoE6cyuw>bS4-`kPn)yb!xsh(xiE}3{z`}q_2w4PjXi?wVNtvBTho5ZC?YpdPzs0m) z+HGYIzFeAgeqh2mq4&bv;qHe3-GS)lv7iF zOvyYlJp1N|cwIa2%lVTTrsmuW`!{S}NxWD3+HgxkqlVzmX`jxvwI+3ab@O7*bW7Ha ztW|f)_I>ujF5C9x)5-2F_7Sb+PVKJ!!#}5HuQ}UYXc$_tttx}+_a2_q5j-=PGyRXu zvx^fuy2rH;A0N22X=Y=(4;yifA6lHa>ALqa^FwX%7gslz@B<%de_t^zRh7lD=h<56 zSlPl>{rt}E=DipDXAdGvmsyCCnO$@3_h=Ur^R26U8dGxDoZq>zW@X;erghi#>uNvw za@LkBXIxmqy7j0fYp~0>?cr}9-??3EDHzGW`Do{#+O^B?%0i4Oo|b=X^k@#|w!ZP{ TH_i(6Z?Lkw%CVKst^% literal 0 HcmV?d00001 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 }} +

      +
    • +