增加右键菜单和图层顺序

old-3.0
咬轮猫 4 years ago
parent 61cc1956dc
commit 4f4762fb01

@ -1,6 +1,6 @@
{
"name": "vue-webtopo-svgeditor",
"version": "0.0.1",
"version": "0.0.2",
"files": [
"dist"
],

@ -898,5 +898,53 @@
},
"create_type": "draggable",
"priview_img": "/ReservoirSvg.png"
},
{
"type": "WaterPipeValveSvg",
"title": "水管阀",
"panel_class": "common",
"template": "<ellipse cx=\"0\" cy=\"-12\" :fill=\"JSON.parse(prop_data.extend_attr.switch.val.selectval).fill\" :stroke=\"JSON.parse(prop_data.extend_attr.switch.val.selectval).fill\" rx=\"20\" ry=\"2\"/><rect :fill=\"JSON.parse(prop_data.extend_attr.switch.val.selectval).fill\" :stroke=\"JSON.parse(prop_data.extend_attr.switch.val.selectval).fill\" height=\"9\" width=\"6\" x=\"-2\" y=\"-12\"/><rect :fill=\"JSON.parse(prop_data.extend_attr.switch.val.selectval).fill\" :stroke=\"JSON.parse(prop_data.extend_attr.switch.val.selectval).fill\" height=\"5\" width=\"19\" x=\"-8\" y=\"-6\"/><rect :fill=\"JSON.parse(prop_data.extend_attr.switch.val.selectval).fill\" :stroke=\"JSON.parse(prop_data.extend_attr.switch.val.selectval).fill\" height=\"12\" width=\"39\" x=\"-19\" y=\"-1\"/><rect :fill=\"JSON.parse(prop_data.extend_attr.switch.val.selectval).fill\" :stroke=\"JSON.parse(prop_data.extend_attr.switch.val.selectval).fill\" height=\"20\" width=\"11\" x=\"-30\" y=\"-6\"/><rect :fill=\"JSON.parse(prop_data.extend_attr.switch.val.selectval).fill\" :stroke=\"JSON.parse(prop_data.extend_attr.switch.val.selectval).fill\" height=\"20\" width=\"11\" x=\"20\" y=\"-6\"/>",
"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": "<path :fill=\"prop_data.extend_attr.color.val\" d=\"m-2.84801,-8.56044l7.8889,0l0,0c4.35692,0 7.8889,3.75583 7.8889,8.38889c0,4.63306 -3.53198,8.38889 -7.8889,8.38889l-7.8889,0l0,-16.77778z\"/><rect :fill=\"prop_data.extend_attr.color.val\" x=\"-16.07021\" y=\"-8.56044\" width=\"15.84921\" height=\"16\" /><rect :fill=\"prop_data.extend_attr.color.val\" x=\"-3.07021\" y=\"1.6548\" width=\"16\" height=\"16\"/>",
"props": [
"prop_data"
],
"extend_attr": {
"color": {
"title": "管道颜色",
"val": "#0a7ae2",
"type": "colorinputbox"
}
},
"create_type": "draggable",
"priview_img": "/RightAnglePipeSvg.png"
}
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

@ -5,9 +5,12 @@
<li>绘制组件需先选中 再将鼠标移至画布中按住左键开始绘制 松开左键结束绘制</li>
<li>在画布上单击左键并按住可以拖动组件改变位置</li>
<li>当组件选中时会有选中效果 此时右侧面板弹出 可使用快捷键和编辑右侧面板属性更改组件</li>
<li>鼠标右键点击组件可以进行一些快捷操作</li>
<li>键盘可移动选中组件 ctrl+c复制当前选中组件 deleted删除当前选中组件</li>
<li>ctrl+键盘可移动组件图层</li>
<li>点击画布空白处可以取消选中组件 并关闭属性面板</li>
<li>点击 符号可以显示或隐藏左侧面板</li>
<li>如果使用我的在线体验地址 请先保存绘制再切换到预览界面</li>
<li>更多使用帮助请参考<a href="https://github.com/yaolunmao/vue-webtopo-svgeditor">github</a><a href="https://gitee.com/yaolunmao/vue-webtopo-svgeditor">gitee</a></li>
</ul>
</n-card>

@ -8,7 +8,8 @@ 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 { 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 | HTMLElement>(null);
const contextMenuRef = ref<HTMLElement>();
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<ISvgDataLists> = 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;
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);
}
}
</script>
@ -257,7 +379,7 @@ document.onkeydown = function (e) {
<top-tool-bar @saveSvgInfo="saveSvgInfo" ref="topbar_dom_ref"></top-tool-bar>
</n-message-provider>
</div>
<div class="ancestors">
<div class="ancestors" @mousedown="documentClickEvent">
<div class="navleft">
<n-message-provider>
<left-tool-bar
@ -297,6 +419,7 @@ document.onkeydown = function (e) {
:id="item.id"
:transform="'translate(' + (item.svgPositionX) + ',' + (item.svgPositionY) + ')' + 'rotate(' + item.angle + ')' + 'scale(' + item.size + ')'"
@mousedown="mouseDownEvent(item, index, $event)"
@contextmenu.stop="contextmenuEvent"
>
<svg-dynamic
:component_type="item.type"
@ -314,9 +437,68 @@ document.onkeydown = function (e) {
<div class="navbuttom">
<bottom-bar></bottom-bar>
</div>
<!-- 右键菜单 -->
<ul ref="contextMenuRef" class="contextMenu" v-show="display_contextmenu">
<li v-for="(item,index) in contextmenu_data" :key="index" @click="item.fun()">
<p :class="item.enable ? '' : 'disabled'">
{{ item.name }}
<span class="shortcut">{{ item.hotkey }}</span>
</p>
</li>
</ul>
</template>
<style scoped>
.contextMenu {
position: absolute;
z-index: 99999;
background: #ffffff;
padding: 5px 0;
margin: 0px;
display: block;
border-radius: 5px;
box-shadow: 2px 5px 10px rgba(0, 0, 0, 0.3);
}
.contextMenu li {
list-style: none;
padding: 0px;
margin: 0px;
}
.contextMenu .shortcut {
width: 115px;
text-align: right;
float: right;
}
.contextMenu p {
text-decoration: none;
display: block;
padding: 0px 15px 1px 20px;
margin: 0;
user-select: none;
-webkit-user-select: none;
}
.contextMenu p:hover {
background-color: #0cf;
color: #ffffff;
cursor: default;
}
.contextMenu .disabled {
color: #999;
}
.contextMenu .disabled:hover {
color: #999;
background-color: transparent;
}
.contextMenu li.separator {
border-top: solid 1px #e3e3e3;
padding-top: 5px;
margin-top: 5px;
}
.ancestors {
display: flex;
flex-direction: row;

@ -0,0 +1,105 @@
import { IComponentInfo, ISvgDataLists, ISvgCanvas, ILeftImgLists, IMouseInfo, ISelectSvg } from "../Model";
/**
*
* @param svgLists
* @param select_svg
*/
export function moveUp(svgLists: ISvgDataLists[], select_svg: ISelectSvg) {
svgLists[select_svg.index].svgPositionY -= 1;
}
/**
*
* @param svgLists
* @param select_svg
*/
export function moveDown(svgLists: ISvgDataLists[], select_svg: ISelectSvg) {
svgLists[select_svg.index].svgPositionY += 1;
}
/**
*
* @param svgLists
* @param select_svg
*/
export function moveLeft(svgLists: ISvgDataLists[], select_svg: ISelectSvg) {
svgLists[select_svg.index].svgPositionX -= 1;
}
/**
*
* @param svgLists
* @param select_svg
*/
export function moveRight(svgLists: ISvgDataLists[], select_svg: ISelectSvg) {
svgLists[select_svg.index].svgPositionX += 1;
}
/**
*
* @param svgLists
* @param select_svg
*/
export function hotkeyCopy(svgLists: ISvgDataLists[], select_svg: ISelectSvg) {
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`
})
}
/**
*
* @param svgLists
* @param select_svg
*/
export function hotkeyDel(svgLists: ISvgDataLists[], select_svg: ISelectSvg) {
svgLists.splice(select_svg.index, 1);
}
/**
*
* @param svgLists
* @param select_svg
*/
export function hotkeyPutOnTop(svgLists: ISvgDataLists[], select_svg: ISelectSvg) {
const temp = svgLists[select_svg.index];
svgLists.splice(select_svg.index, 1);
svgLists.push(temp);
select_svg.index = svgLists.length - 1;
}
/**
*
* @param svgLists
* @param select_svg
*/
export function hotkeyPutOnButtom(svgLists: ISvgDataLists[], select_svg: ISelectSvg) {
const temp = svgLists[select_svg.index];
svgLists.splice(select_svg.index, 1);
svgLists.unshift(temp);
select_svg.index = 0;
}
/**
*
* @param svgLists
* @param select_svg
*/
export function hotkeyPutOnUp(svgLists: ISvgDataLists[], select_svg: ISelectSvg) {
if (svgLists.length === 1 || select_svg.index === svgLists.length - 1) {
return;
}
const temp = svgLists[select_svg.index];
svgLists[select_svg.index] = svgLists[select_svg.index + 1];
svgLists[select_svg.index + 1] = temp;
select_svg.index += 1;
}
/**
*
* @param svgLists
* @param select_svg
*/
export function hotkeyPutOnDown(svgLists: ISvgDataLists[], select_svg: ISelectSvg) {
if (svgLists.length === 1 || select_svg.index === 0) {
return;
}
const temp = svgLists[select_svg.index];
svgLists[select_svg.index] = svgLists[select_svg.index - 1];
svgLists[select_svg.index - 1] = temp;
select_svg.index -= 1;
}
Loading…
Cancel
Save