|
|
<!DOCTYPE html>
|
|
|
<html>
|
|
|
|
|
|
<head>
|
|
|
<meta charset="utf8">
|
|
|
<title>Kep Web图形组件</title>
|
|
|
<link rel="shortcut icon" href="#" />
|
|
|
<link rel="stylesheet" href="zTree/css/zTreeStyle/zTreeStyle.css" type="text/css" />
|
|
|
<link rel="stylesheet" href="css/menu.css" type="text/css" />
|
|
|
<style type="text/css">
|
|
|
<!--
|
|
|
html,
|
|
|
body {
|
|
|
color: #000000;
|
|
|
/* background-color: #0072C6; */
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
margin: 0;
|
|
|
}
|
|
|
|
|
|
#app {
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
}
|
|
|
|
|
|
img {
|
|
|
border: none;
|
|
|
}
|
|
|
|
|
|
.button {
|
|
|
padding: 3px 5px 3px 5px;
|
|
|
margin: 2px;
|
|
|
font-size: 15px;
|
|
|
cursor: pointer;
|
|
|
background-color: #4CAF50;
|
|
|
color: white;
|
|
|
border: none;
|
|
|
border-radius: 3px;
|
|
|
margin-top: 5px;
|
|
|
/* transition: all 0.3s ease; */
|
|
|
/* 添加过渡效果 */
|
|
|
}
|
|
|
|
|
|
.button:hover {
|
|
|
box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.24), 0 4px 10px 0 rgba(0, 0, 0, 0.19);
|
|
|
background-color: #3e8e41;
|
|
|
}
|
|
|
|
|
|
.button--pressed {
|
|
|
background-color: #3e8e41;
|
|
|
/* 更深的绿色 */
|
|
|
}
|
|
|
|
|
|
.button-group {
|
|
|
display: flex;
|
|
|
justify-content: center;
|
|
|
/* 水平居中对齐 */
|
|
|
gap: 10px;
|
|
|
}
|
|
|
|
|
|
.overlay-image {
|
|
|
z-index: 9999;
|
|
|
/* 设置较高的z-index值 */
|
|
|
}
|
|
|
|
|
|
ul.ztree {
|
|
|
margin-top: 0px;
|
|
|
border: 0px solid #abcecb;
|
|
|
background: #f0f6e4;
|
|
|
overflow-y: auto;
|
|
|
overflow-x: hidden;
|
|
|
}
|
|
|
|
|
|
.ztree li span.button.switch.level0 {
|
|
|
visibility: hidden;
|
|
|
width: 0px;
|
|
|
}
|
|
|
|
|
|
.ztree li ul.level0 {
|
|
|
padding: 0;
|
|
|
background: none;
|
|
|
}
|
|
|
|
|
|
.layerButton {
|
|
|
margin-top: 1px;
|
|
|
margin-right: 0px;
|
|
|
margin-bottom: 1px;
|
|
|
margin-left: 0px;
|
|
|
|
|
|
background-size: auto;
|
|
|
background-repeat: no-repeat;
|
|
|
background-position: center;
|
|
|
width: 24px;
|
|
|
height: 24px;
|
|
|
border: none;
|
|
|
padding: 0px;
|
|
|
display: inline-flex;
|
|
|
|
|
|
color: black;
|
|
|
background-color: transparent;
|
|
|
border: 0px solid black;
|
|
|
border-radius: 3px;
|
|
|
transition: all 0.3s ease;
|
|
|
cursor: pointer;
|
|
|
|
|
|
flex: 0 0 auto;
|
|
|
}
|
|
|
|
|
|
.layerButton:hover {
|
|
|
color: blue;
|
|
|
border-color: black;
|
|
|
background-color: #c8d7c8;
|
|
|
}
|
|
|
|
|
|
.layerButton:after {
|
|
|
background: #90EE90;
|
|
|
opacity: 0;
|
|
|
transition: all 0.8s
|
|
|
}
|
|
|
|
|
|
.layerButton:active:after {
|
|
|
opacity: 1;
|
|
|
transition: 0s
|
|
|
}
|
|
|
|
|
|
.barSeparator {
|
|
|
width: 1px;
|
|
|
flex: 0 0 auto;
|
|
|
box-sizing: border-box;
|
|
|
border: solid #dee2e6;
|
|
|
border-width: 0 1px 0 0;
|
|
|
margin: 5px 2px;
|
|
|
min-height: 16px;
|
|
|
min-width: 1px;
|
|
|
height: 16px;
|
|
|
}
|
|
|
|
|
|
.loader-content {
|
|
|
position: relative;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
align-items: center;
|
|
|
gap: 10px;
|
|
|
}
|
|
|
|
|
|
.loader-text {
|
|
|
color: #4CAF50;
|
|
|
font-weight: bold;
|
|
|
font-size: 14px;
|
|
|
animation: pulse 1.5s infinite;
|
|
|
}
|
|
|
|
|
|
.loader-dots {
|
|
|
display: flex;
|
|
|
gap: 4px;
|
|
|
}
|
|
|
|
|
|
.dot {
|
|
|
width: 6px;
|
|
|
height: 6px;
|
|
|
background: #76c779;
|
|
|
border-radius: 50%;
|
|
|
animation: bounce 1.4s infinite;
|
|
|
}
|
|
|
|
|
|
.dot:nth-child(2) {
|
|
|
animation-delay: 0.2s;
|
|
|
}
|
|
|
|
|
|
.dot:nth-child(3) {
|
|
|
animation-delay: 0.4s;
|
|
|
}
|
|
|
|
|
|
@keyframes bounce {
|
|
|
|
|
|
0%,
|
|
|
80%,
|
|
|
100% {
|
|
|
transform: translateY(0);
|
|
|
}
|
|
|
|
|
|
40% {
|
|
|
transform: translateY(-6px);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.loader-overlay {
|
|
|
position: fixed;
|
|
|
top: 0;
|
|
|
left: 0;
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
background: rgba(0, 0, 0, 0.5);
|
|
|
z-index: 9999;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
}
|
|
|
|
|
|
.loader-modal {
|
|
|
background: white;
|
|
|
/* 设置背景颜色为白色 */
|
|
|
padding: 30px 400px;
|
|
|
/* 设置内边距:上下30像素,左右400像素 */
|
|
|
border-radius: 10px;
|
|
|
/* 设置圆角为10像素,使边角显得圆滑 */
|
|
|
box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
|
|
|
/* 添加阴影效果:水平偏移0,垂直偏移0,模糊20像素,黑色透明度0.2 */
|
|
|
text-align: center;
|
|
|
/* 文本居中对齐 */
|
|
|
}
|
|
|
|
|
|
.loader-spinner {
|
|
|
width: 30px;
|
|
|
/* 控制旋转图标的宽度为30像素 */
|
|
|
height: 40px;
|
|
|
/* 控制旋转图标的高度为40像素(注意宽高不同会形成椭圆形) */
|
|
|
border: 4px solid #f3f3f3;
|
|
|
/* 设置4像素宽的浅灰色边框作为spinner的基础圆环 */
|
|
|
border-top: 4px solid #4CAF50;
|
|
|
/* 将顶部边框设为绿色,形成旋转时的视觉效果 */
|
|
|
border-radius: 50%;
|
|
|
/* 将元素变成圆形(或椭圆形,因为宽高不同) */
|
|
|
margin: 0 auto 15px;
|
|
|
/* 上边距0,左右自动居中,下边距15像素 */
|
|
|
animation: spin 1s linear infinite;
|
|
|
/* 应用名为spin的动画,持续1秒,线性变化,无限循环 */
|
|
|
}
|
|
|
|
|
|
@keyframes spin {
|
|
|
0% {
|
|
|
transform: rotate(0deg);
|
|
|
}
|
|
|
|
|
|
100% {
|
|
|
transform: rotate(360deg);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/*自定义右键菜单样式*/
|
|
|
.custom-context-menu {
|
|
|
position: absolute;
|
|
|
background: white;
|
|
|
border: 1px solid #ccc;
|
|
|
padding: 5px;
|
|
|
z-index: 1000;
|
|
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
|
|
}
|
|
|
|
|
|
.custom-context-menu div {
|
|
|
cursor: pointer;
|
|
|
padding: 5px;
|
|
|
}
|
|
|
|
|
|
.custom-context-menu div:hover {
|
|
|
background-color: #f0f0f0;
|
|
|
}
|
|
|
|
|
|
/*分隔线样式*/
|
|
|
.divider {
|
|
|
border: none;
|
|
|
height: 1px;
|
|
|
background: #ccc;
|
|
|
margin: 3px 0;
|
|
|
}
|
|
|
-->
|
|
|
</style>
|
|
|
|
|
|
|
|
|
<script src="dist/vue.global.js"></script>
|
|
|
|
|
|
<script src="zTree/js/jquery.min.js"></script>
|
|
|
<script src="zTree/js/jquery.ztree.core-3.5.js"></script>
|
|
|
<script src="zTree/js/jquery.ztree.excheck-3.5.js"></script>
|
|
|
<script src="zTree/js/jquery.ztree.exedit-3.5.js"></script>
|
|
|
|
|
|
</head>
|
|
|
|
|
|
<body>
|
|
|
<div id="app" style="position:relative; overflow:hidden;width: 100%; height: 100%;">
|
|
|
<!-- 新增进度条 -->
|
|
|
<div v-if="isLoading" class="loader-overlay">
|
|
|
<div class="loader-modal">
|
|
|
<div class="loader-content">
|
|
|
<div class="loader-spinner"></div>
|
|
|
<span class="loader-text">加载中</span>
|
|
|
<div class="loader-dots">
|
|
|
<div class="dot"></div>
|
|
|
<div class="dot"></div>
|
|
|
<div class="dot"></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<!-- 进度条 结束-->
|
|
|
<!-- 工具栏 -->
|
|
|
<div v-if="toolbarStyle===0" class="Meta2dMenu flex menu"><a target="_self" class="logo"
|
|
|
href="javascript:;"><img src="img/KEP001.svg" alt="KEP" /> KE Platform</a>
|
|
|
<div class="menus flex">
|
|
|
<div class="flex">
|
|
|
<div class="mr30" v-for="(item, index) in toolMainItems" :key="index">
|
|
|
<div class="ant-dropdown-trigger MenuItem" :style="{cursor: 'pointer', color: item.color }"
|
|
|
@click="toolMainClick(index)" @mouseover="setToolHoverColor(index)"
|
|
|
@mouseout="resetToolColor(index)">
|
|
|
<div class="iconItem">
|
|
|
<div class="icon"><img :src="item.imgSrc" :alt="item.title" class="t-icon"></img></div>
|
|
|
<span>{{item.title}}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div v-if="toolbarStyle===1" id="header"
|
|
|
style="position:relative; left: 0px; top:0px;height: 32px; background-color:#90908a;">
|
|
|
<button class="button" :class="{ 'button--pressed': isBtnPressed }" @click="toolDefault">浏览</button><button
|
|
|
class="button" @click="drawZoomIn">放大{{count}}</button><button class="button"
|
|
|
@click="drawZoomOut">缩小</button><button class="button" @click="toolViewWindow">局部</button><button
|
|
|
class="button" @click="viewAll">全部</button><button class="button" @click="toolViewMove"
|
|
|
:class="{ 'button--pressed': isBtnPressed }">移动</button><button class="button" @click="toolSelect"
|
|
|
:class="{ 'button--pressed': isBtnPressed }">选择</button><button class="button"
|
|
|
@click="drawSave">保存</button><button class="button" @click="switchLayerPanel">图层</button>
|
|
|
</div>
|
|
|
|
|
|
<div
|
|
|
style="overflow:visible;position: relative; height: 100%; width: 100%; margin: 0; display: flex; flex-direction: row;">
|
|
|
<div v-if="layerVisible" id="drawerTree"
|
|
|
:style="{width: layerSize.width+'px', height: layerSize.height+'px'}"
|
|
|
style="float:left; border: #b2b3b2; border-style:solid; border-width:2px; box-sizing: border-box;">
|
|
|
<!-- 图层树工具条 -->
|
|
|
<div
|
|
|
style="border: 1px solid #f8f9fa; border-top: 0; border-left: 0; border-right:0; box-sizing: border-box;vertical-align:middle; display: flex; flex-direction: row;">
|
|
|
<button class="layerButton" style="background-image: url('img/ViewEdit.png');" title="可编辑"
|
|
|
@click="setLayerStatus(1)"></button><button class="layerButton"
|
|
|
style="background-image: url('img/ViewNotEdit.png');" title="只读"
|
|
|
@click="setLayerStatus(2)"></button><button class="layerButton"
|
|
|
style="background-image: url('img/NotViewNotEdit.png');" title="隐藏"
|
|
|
@click="setLayerStatus(3)"></button>
|
|
|
<div class="barSeparator"></div><button class="layerButton"
|
|
|
style="background-image: url('img/Action_Delete.svg');" title="删除"
|
|
|
@click="deleteLayer"></button>
|
|
|
</div>
|
|
|
<!-- 图层树 -->
|
|
|
<ul id="treeDemo" class="ztree"
|
|
|
:style="{width: layerSize.width-6+'px', height: layerSize.height-32+'px' }" style="padding: 0;">
|
|
|
</ul>
|
|
|
</div>
|
|
|
<!-- 绘图区域 -->
|
|
|
<div id="content" @wheel.prevent=""
|
|
|
style="overflow: hidden; position:relative; left: 0px; top:0px;height:100%;width:100%; float:left; padding: 0px; margin: 0px;">
|
|
|
<!-- 水平刻度尺 -->
|
|
|
<canvas id="ruler-horizontal" :width="viewSize.width*2+'px'" :height="rulerHeight*2+'px'"
|
|
|
:style="{width:viewSize.width+'px', height:rulerHeight+'px', left:rulerHeight+'px'}"
|
|
|
style="position:absolute; top:0px; background-color: rgb(245, 245, 245);">
|
|
|
</canvas>
|
|
|
<!-- 水平刻度指示 -->
|
|
|
<div ref="rulerHorizontalIndicator" width="1px"
|
|
|
:style="{height:rulerHeight+'px', left:mouseHorizontal+'px'}"
|
|
|
style="position:absolute; top:0px; width: 1px; background-color: #3e8e41; z-index: 99;box-sizing: border-box;">
|
|
|
</div>
|
|
|
|
|
|
<!-- 垂直刻度尺 -->
|
|
|
<canvas id="ruler-vertical" :width="rulerHeight*2+'px'" :height="viewSize.height*2+'px'"
|
|
|
:style="{height:viewSize.height+'px', width:rulerHeight+'px', top:rulerHeight+'px'}"
|
|
|
style="position:absolute; left: 0px; background-color: rgb(245, 245, 245);">
|
|
|
</canvas>
|
|
|
<!-- 垂直刻度指示 -->
|
|
|
<div width="1px" :style="{width:rulerHeight+'px', top:mouseVertical+'px'}"
|
|
|
style="position:absolute; left:0px; height: 1px; background-color: #3e8e41; z-index: 99;box-sizing: border-box;">
|
|
|
</div>
|
|
|
<div @wheel.prevent=""
|
|
|
style="overflow: hidden; position:relative; padding: 0px; margin: 0px; background-color: #4CAF50;"
|
|
|
:style="{ cursor: GetCursor(), left:rulerHeight+'px', top:rulerHeight+'px', width:viewSize.width+'px', height:viewSize.height+'px' }">
|
|
|
<!--橡皮筋选取框div-->
|
|
|
<div v-if="rubberVisible" ref="rubberbandDiv"
|
|
|
:style="{ position:'absolute', left: rubberbandRectangle.left + 'px', top: rubberbandRectangle.top + 'px', width: rubberbandRectangle.width + 'px', height: rubberbandRectangle.height + 'px' }"
|
|
|
style="pointer-events: none; border: 2px dashed rgb(81, 153, 212); cursor: crosshair;opacity: 0.5; display: inline; z-index: 999">
|
|
|
</div>
|
|
|
<canvas ref="canvas" @mousedown="canvasMouseDown" @mouseup="canvasMouseUp"
|
|
|
@mousemove="canvasMouseMove" @wheel="canvasMouseWheel" :width="viewSize.width +'px'"
|
|
|
:height="viewSize.height +'px'"
|
|
|
:style="{ cursor: GetCursor(), width:viewSize.width+'px', height:viewSize.height+'px' }"
|
|
|
style="position:absolute; margin: 0px;left: 0px; top:0px; padding: 0px; background-color: rgb(255, 255, 255);image-rendering: crisp-edges;"
|
|
|
@contextmenu="handleWellContextMenu">
|
|
|
<div v-show="showContextMenu" class="custom-context-menu" :style="{
|
|
|
top: `${contextMenuY}px`,
|
|
|
left: `${contextMenuX}px`,
|
|
|
}">
|
|
|
<div @click="handleMenuAction('edit')">编辑</div>
|
|
|
<hr class="divider" />
|
|
|
<div @click="handleMenuAction('wellGroupClone')">应用井组参数到其它井组</div>
|
|
|
<div @click="handleMenuAction('wellGroupData')">井组数据</div>
|
|
|
</div>
|
|
|
</canvas>
|
|
|
<img v-if="imgVisible" ref="image"
|
|
|
:style="{ position:'absolute', left: imgPosition.x + 'px', top: imgPosition.y + 'px' }"
|
|
|
style="pointer-events: none;" />
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<script>
|
|
|
const layerStatusIcons = {
|
|
|
1: "img/ViewEdit.png",
|
|
|
2: "img/ViewNotEdit.png",
|
|
|
3: "img/NotViewNotEdit.png"
|
|
|
}
|
|
|
/** 光标svg资源 */
|
|
|
const MouseIcons = {
|
|
|
auto: 'auto',
|
|
|
default: 'default',
|
|
|
crosshair: 'crosshair',
|
|
|
resizee: 'e-resize',
|
|
|
resizen: 'n-resize',
|
|
|
resizene: 'ne-resize',
|
|
|
resizenw: 'nw-resize',
|
|
|
resizes: 's-resize',
|
|
|
resizese: 'resizese',
|
|
|
resizesw: 'sw-resize',
|
|
|
resizew: 'w-resize',
|
|
|
text: 'text',
|
|
|
url: 'url',
|
|
|
wait: 'wait',
|
|
|
pointer: 'pointer',
|
|
|
help: 'help',
|
|
|
move: 'move',
|
|
|
pointerSelect: `url('data:image/svg+xml;utf8,<svg width="24px" height="24px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="m300.62812,496.77405l149.37188,347.20313l-112.5,56.25l-130.66875,-356.56875l-206.83125,187.81875l0,-731.25l562.5,450l-261.87188,46.54687z" /></svg>') 0 0, auto`,
|
|
|
viewPan: `url('data:image/svg+xml;utf8,<svg width="24px" height="24px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path fill="currentColor" d="M802.5 262.3c-11.9 0-23.4 2.1-34 5.9v-57.6c0-56-45.5-101.5-101.5-101.5-16.1 0-31.4 3.8-44.9 10.5-16.8-33-51.1-55.7-90.6-55.7-43.5 0-80.7 27.5-95 66.1-12.4-5.4-26-8.4-40.4-8.4-55.9 0-101.4 45.5-101.4 101.4v199.2c-10-10.9-22.5-19.6-36.6-25.4-25.4-10.3-53.2-10-78.3 0.9-50.6 21.9-74.6 81.1-53.4 132.1L178 653.3c5.9 14.2 12.6 28.3 19.9 41.9l94.3 175.2c29.8 55.4 87.4 89.8 150.3 89.8h231.9c68.4 0 130-40.7 156.9-103.6l42.6-99.6c19.9-46.6 30-96 30-146.7V363.7c0-55.9-45.5-101.4-101.4-101.4z m33.9 348c0 41.5-8.3 82-24.6 120.2l-42.6 99.6c-16.2 38-53.5 62.6-94.8 62.6H442.5c-38 0-72.8-20.8-90.8-54.3l-94.3-175.2c-6.3-11.6-12-23.7-17.1-35.9l-51.6-123.5c-7.1-17 0.9-36.8 17.8-44.1 8.4-3.6 17.7-3.7 26.1-0.3 8.5 3.4 15.1 10 18.5 18.4l46 111.5c6.1 14.9 22 23.4 37.8 20.2 15.8-3.1 27.2-17 27.2-33.1V223c0-18.7 15.2-33.8 34-33.8 18.7 0 33.8 15.2 33.8 33.8v286.7c0 1.2 0.1 2.3 0.2 3.5 1.7 17 16.1 30.3 33.6 30.3s31.9-13.3 33.6-30.3c0.1-1.1 0.2-2.3 0.2-3.5V165.3c0-18.7 15.2-33.9 33.9-33.9s34 15.2 34 34V509.6c0 18.7 15.1 33.8 33.8 33.8 18.7 0 33.8-15.1 33.8-33.8V210.5c0-18.7 15.2-33.9 33.9-33.9s33.9 15.2 33.9 33.9v342.9c0 18.7 15.1 33.8 33.8 33.8 18.7 0 33.8-15.1 33.8-33.8V363.8c0-18.7 15.2-34 34-34 18.7 0 33.9 15.2 33.9 33.8v246.7z"></path></svg>') 0 0, auto`,
|
|
|
test: `url('data:image/svg+xml;utf8,<svg width="24px" height="24px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path fill="currentColor" d="m186.496 544 41.408 41.344a32 32 0 1 1-45.248 45.312l-96-96a32 32 0 0 1 0-45.312l96-96a32 32 0 1 1 45.248 45.312L186.496 480h290.816V186.432l-41.472 41.472a32 32 0 1 1-45.248-45.184l96-96.128a32 32 0 0 1 45.312 0l96 96.064a32 32 0 0 1-45.248 45.184l-41.344-41.28V480H832l-41.344-41.344a32 32 0 0 1 45.248-45.312l96 96a32 32 0 0 1 0 45.312l-96 96a32 32 0 0 1-45.248-45.312L832 544H541.312v293.44l41.344-41.28a32 32 0 1 1 45.248 45.248l-96 96a32 32 0 0 1-45.312 0l-96-96a32 32 0 1 1 45.312-45.248l41.408 41.408V544H186.496z"></path></svg>') 0 0, auto`,
|
|
|
}
|
|
|
const canvasToolType = {
|
|
|
Default: 0,
|
|
|
Select: 1,
|
|
|
Pointer: 2,
|
|
|
ViewPan: 3,
|
|
|
ViewWindow: 4,
|
|
|
Connection: 5,
|
|
|
Convexity: 6,
|
|
|
Model: 7,
|
|
|
Fault: 8,
|
|
|
FaultReverse: 9,
|
|
|
Rectangle: 10,
|
|
|
Ellipse: 11,
|
|
|
Curve: 12, // Line,
|
|
|
Arc: 13,
|
|
|
Chord: 14,
|
|
|
Pie: 15,
|
|
|
Polygon: 16,
|
|
|
Proportion: 17, // 比例尺
|
|
|
Point: 18,
|
|
|
FractionPoint: 19, // 分数点
|
|
|
CrossPoint: 20, // 十字点
|
|
|
Text: 21,
|
|
|
Equilateral: 22, // 等边多边形
|
|
|
RectangularCSGrid: 23, // 直角坐标网
|
|
|
BreakDirect: 24, // 直接打断
|
|
|
Break: 25, // 打断
|
|
|
Delete: 26, // 删除
|
|
|
DeleteIn: 27, // 删除区域内元素
|
|
|
DeleteCondition: 28, // 条件删除
|
|
|
DeleteOut: 29, // 删除区域外元素
|
|
|
ExtendCurve: 30, // 延伸曲线
|
|
|
TrimCurve: 31, // 剪切曲线
|
|
|
CloseCurve: 32, // 闭合曲线
|
|
|
MoveCurveName: 33, // 移动曲线内部名字
|
|
|
LinkCurve: 34, // 连接曲线
|
|
|
MergeCurve: 35, // 连接曲线
|
|
|
ReverseCurve: 36, // 反转曲线
|
|
|
NameToZ: 37, // 曲线名称变为Z值,
|
|
|
ZToName: 38, // Z值变为曲线名称,
|
|
|
FindCurveOfEmptyName: 39, // 发现空名称的曲线
|
|
|
RangeToImage: 40, // 复制选择区域为图像
|
|
|
WindowToImage: 41, // 复制窗口区域为图像
|
|
|
AllToImage: 42, // 复制全图为图像
|
|
|
RangeToImageEx: 43, // 定制复制选择区域为图像
|
|
|
LeftAlignment: 44, // 左对齐
|
|
|
RightAlignment: 45, // 右对齐
|
|
|
TopAlignment: 46, // 顶对齐
|
|
|
BottomAlignment: 47, // 底对齐
|
|
|
HCenterAlignment: 48, // 水平居中
|
|
|
VCenterAlignment: 49, // 垂直居中
|
|
|
DisplayOrderTop: 50, // 最上显示
|
|
|
DisplayOrderBottom: 51, // 最下显示
|
|
|
DisplayOrderFront: 52, // 上移一层
|
|
|
DisplayOrderBack: 53, // 下移一层
|
|
|
HorizontalMirror: 54, // 水平镜像
|
|
|
VerticalMirror: 55, // 垂直镜像
|
|
|
EditCurveNode: 56, // 编辑曲线节点
|
|
|
CurveDensityNode: 57, // 曲线节点加密
|
|
|
CurveRedundancy: 58, // 曲线冗余 去掉曲线上多余的节点
|
|
|
CurveSmooth: 59, // 光滑曲线
|
|
|
CutOutByRect: 60, // 矩形式外切
|
|
|
CutOutByPickup: 61, // 拾取式外切
|
|
|
CutInByRect: 62, // 矩形式内切
|
|
|
CutInByPickup: 63, // 拾取式内切
|
|
|
CalculateVolume: 64, // 计算体积
|
|
|
SetZValueOfSurface: 65, // 设置曲面Z值
|
|
|
EditGridPoint: 66,
|
|
|
PointPropertyClear: 67, // 点属性的批量清理
|
|
|
PointPropertySet: 68, // 点属性的批量设置
|
|
|
CurvePropertyClear: 69, // 线属性的批量清理
|
|
|
CurvePropertySet: 70, // 线属性的批量设置
|
|
|
HighLightTip: 71, // 高亮图元并获得提示信息
|
|
|
ArcToCurve: 72,
|
|
|
CurveZFromSurface: 73, // 由曲面设置曲线节点的Z值
|
|
|
Calibration2: 74, // 两点校正
|
|
|
Calibration4: 75, // 四点校正
|
|
|
ConnectCurveFilling: 76, // 连接曲线形成填充区域
|
|
|
SolidAuto: 77, // 自动填充区域
|
|
|
SolidLink: 78, // 连接填充区域
|
|
|
SaveAsSymbol: 79, // 保存为符号
|
|
|
PositiveNegativeSign: 80, // Z值正负号
|
|
|
CurveNameSetting: 81, // 曲线名称设置
|
|
|
SetContourName: 82, // 设置等值线名称
|
|
|
Finsih: 83, // 完成了一个命令 此值没有对应的类
|
|
|
PolygonToImage: 84, // 复制选择区域内选中多边形区域为图像
|
|
|
WellGroup: 85, // 井组绘制
|
|
|
WellGroupEdit: 86, // 井组编辑
|
|
|
EditWellGroupBranchCurveNode: 87, // 井分支的编辑
|
|
|
CurveBroaden: 88, // 曲线外扩
|
|
|
FaultSymply: 89, // 断层简化
|
|
|
Measure: 90, // 测量
|
|
|
Eraser: 91, // 橡皮擦
|
|
|
SelectWellPole: 92,
|
|
|
NumberOfDrawTools: 93,
|
|
|
}
|
|
|
const VueApp = {
|
|
|
data() {
|
|
|
return {
|
|
|
// 加载状态,滚动条显示状态
|
|
|
isLoading: false, // 新增加载状态
|
|
|
firstConnect: true,
|
|
|
drawerToken: '',
|
|
|
isBtnPressed: false,
|
|
|
websocket: null, // WebSocket对象
|
|
|
reconnectInterval: 3000, // 重连间隔时间(毫秒)
|
|
|
heartbeatInterval: null, // 心跳定时器
|
|
|
count: 0,
|
|
|
canvas: null,
|
|
|
// 选中的井组ID
|
|
|
selectedElementId: "",
|
|
|
selectedElement: {},
|
|
|
// 是否显示右键菜单
|
|
|
showContextMenu: false,
|
|
|
contextMenuX: 0,
|
|
|
contextMenuY: 0,
|
|
|
layerVisible: false,
|
|
|
|
|
|
isDragging: false,
|
|
|
isDragFirst: true,
|
|
|
|
|
|
queryDrawRuler: false,
|
|
|
|
|
|
imageSrc: '',
|
|
|
imgVisible: false,
|
|
|
imgPosition: { x: 0, y: 0 },
|
|
|
mouseStartX: 0,
|
|
|
mouseStartY: 0,
|
|
|
lastX: 0,
|
|
|
lastY: 0,
|
|
|
|
|
|
// isRegionSelecting: false,
|
|
|
|
|
|
mouseHorizontal: 0,
|
|
|
mouseVertical: 0,
|
|
|
|
|
|
viewSize: { width: 0, height: 0 },
|
|
|
rulerHeight: 0,
|
|
|
rulerWidth: 0,
|
|
|
|
|
|
mouseX: 0,
|
|
|
mouseY: 0,
|
|
|
|
|
|
mouseDownX: 0,
|
|
|
mouseDownY: 0,
|
|
|
|
|
|
mouseDown: false,
|
|
|
pressedKeyCode: null,
|
|
|
|
|
|
drawerToolType: canvasToolType.ITEM_DEFAULT, // 当前操作模式
|
|
|
handleIndex: -1,
|
|
|
/** 画布对象 */
|
|
|
canvas: null,
|
|
|
ctx: null,
|
|
|
/** 橡皮筋选框 */
|
|
|
rubberbandDiv: null,
|
|
|
rubberbandRectangle: { left: 10, top: 10, width: 100, height: 100 },
|
|
|
rubberDragging: false,
|
|
|
rubberVisible: false,
|
|
|
|
|
|
/* 选择轮廓图 */
|
|
|
initialRect: { left: 0, top: 0, width: 0, height: 0 },
|
|
|
|
|
|
toolbarStyle: 0,
|
|
|
toolMainItems: [
|
|
|
{
|
|
|
colorOld: '#000000d9',
|
|
|
color: 'rgb(24, 144, 255)',
|
|
|
imgSrc: 'img/mornejiantou.svg',
|
|
|
title: '默认',
|
|
|
checked: false,
|
|
|
}, {
|
|
|
colorOld: '#000000d9',
|
|
|
color: '#000000d9',
|
|
|
imgSrc: 'img/fangda.svg',
|
|
|
title: '放大',
|
|
|
checked: false,
|
|
|
}, {
|
|
|
colorOld: '#000000d9',
|
|
|
color: '#000000d9',
|
|
|
imgSrc: 'img/suoxiao.svg',
|
|
|
title: '缩小',
|
|
|
checked: false,
|
|
|
},
|
|
|
{
|
|
|
colorOld: '#000000d9',
|
|
|
color: '#000000d9',
|
|
|
imgSrc: 'img/refresh.svg',
|
|
|
title: '刷新',
|
|
|
checked: false,
|
|
|
}, {
|
|
|
colorOld: '#000000d9',
|
|
|
color: '#000000d9',
|
|
|
imgSrc: 'img/center.svg',
|
|
|
title: '居中',
|
|
|
checked: false,
|
|
|
},
|
|
|
{
|
|
|
colorOld: '#000000d9',
|
|
|
color: '#000000d9',
|
|
|
imgSrc: 'img/fangdaWindow.svg',
|
|
|
title: '局部',
|
|
|
checked: false,
|
|
|
}, {
|
|
|
colorOld: '#000000d9',
|
|
|
color: '#000000d9',
|
|
|
imgSrc: 'img/quantu.svg',
|
|
|
title: '全部',
|
|
|
checked: false,
|
|
|
}, {
|
|
|
colorOld: '#000000d9',
|
|
|
color: '#000000d9',
|
|
|
imgSrc: 'img/yidong.svg',
|
|
|
title: '移动',
|
|
|
checked: false,
|
|
|
}, {
|
|
|
colorOld: '#000000d9',
|
|
|
color: '#000000d9',
|
|
|
imgSrc: 'img/xuanzejiantou.svg',
|
|
|
title: '选择',
|
|
|
checked: false,
|
|
|
}, {
|
|
|
colorOld: '#000000d9',
|
|
|
color: '#000000d9',
|
|
|
imgSrc: 'img/baocun.svg',
|
|
|
title: '保存',
|
|
|
checked: false,
|
|
|
}, {
|
|
|
colorOld: '#000000d9',
|
|
|
color: '#000000d9',
|
|
|
imgSrc: 'img/tucengshuxingtu.svg',
|
|
|
title: '图层',
|
|
|
checked: false,
|
|
|
}
|
|
|
],
|
|
|
rulerHeight: 20,
|
|
|
layerSize: { width: 180, height: 600 },
|
|
|
viewSize: { width: 1024, height: 768 },
|
|
|
windowMouseDown: false,
|
|
|
// 选择框的句柄
|
|
|
SelectHandle: {
|
|
|
TopLeft: 0,
|
|
|
Top: 1,
|
|
|
TopRight: 2,
|
|
|
Right: 3,
|
|
|
BottomRight: 4,
|
|
|
Bottom: 5,
|
|
|
BottomLeft: 6,
|
|
|
Left: 7,
|
|
|
Center: 8,
|
|
|
Body: 9,
|
|
|
Nothing: -1
|
|
|
},
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
/* 联动选中父子节点
|
|
|
initZTree() {
|
|
|
const setting = {
|
|
|
check: {
|
|
|
enable: true,
|
|
|
chkboxType: { "Y": "ps", "N": "ps" } // 父子联动选择
|
|
|
},
|
|
|
callback: {
|
|
|
onCheck: this.onZTreeCheck,
|
|
|
beforeCheck: function(treeId, treeNode) {
|
|
|
// 阻止图层根节点被选中
|
|
|
if(treeNode.id === "Layer:"){
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
},
|
|
|
data: {
|
|
|
key: {
|
|
|
// 设置图层根节点不可选
|
|
|
chkDisabled: function(node) {
|
|
|
return node.id === "Layer:";
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
$.fn.zTree.init($("#treeDemo"), setting, zNodes);
|
|
|
},
|
|
|
|
|
|
onZTreeCheck(event, treeId, treeNode) {
|
|
|
const zTree = $.fn.zTree.getZTreeObj("treeDemo");
|
|
|
// 选中父节点时自动选中所有子节点
|
|
|
if (treeNode.checked) {
|
|
|
const children = treeNode.children;
|
|
|
if (children && children.length > 0) {
|
|
|
zTree.checkNode(children[0], true, true);
|
|
|
}
|
|
|
}
|
|
|
// 选中子节点时自动选中父节点
|
|
|
else {
|
|
|
const parentNode = treeNode.getParentNode();
|
|
|
if (parentNode) {
|
|
|
zTree.checkNode(parentNode, false, true);
|
|
|
}
|
|
|
}
|
|
|
},*/
|
|
|
handleWellContextMenu(event) {
|
|
|
// 阻止默认的右键菜单
|
|
|
event.preventDefault();
|
|
|
|
|
|
if (this.selectedElementId === "") {
|
|
|
console.warn('没有选中任何井组');
|
|
|
return;
|
|
|
}
|
|
|
// 设置右键菜单的位置
|
|
|
this.contextMenuX = event.layerX;
|
|
|
this.contextMenuY = event.layerY;
|
|
|
this.showContextMenu = true;
|
|
|
|
|
|
// 阻止事件冒泡,避免触发 mouseup 事件
|
|
|
event.stopPropagation();
|
|
|
},
|
|
|
// 处理右键菜单的操作
|
|
|
handleMenuAction(action) {
|
|
|
this.showContextMenu = false; // 隐藏右键菜单
|
|
|
switch (action) {
|
|
|
// 应用井组参数
|
|
|
case 'wellGroupClone':
|
|
|
if (window.parent && window.parent.postMessage) {
|
|
|
window.parent.postMessage({ action: 'wellGroupClone', data: this.selectedElementId }, '*');
|
|
|
}
|
|
|
break;
|
|
|
case 'wellGroupData':
|
|
|
if (window.parent && window.parent.postMessage) {
|
|
|
window.parent.postMessage({ action: 'wellGroupData' }, '*');
|
|
|
}
|
|
|
break;
|
|
|
// 取消操作
|
|
|
case 'cancel':
|
|
|
showContextMenu = false;
|
|
|
break;
|
|
|
// 编辑操作
|
|
|
case 'edit':
|
|
|
if (window.parent && window.parent.postMessage) {
|
|
|
/* console.log('编辑井组:', this.selectedElementId, this.selectedElement); */
|
|
|
window.parent.postMessage({ action: 'editWellGroup', data: this.selectedElement, dataid: this.selectedElementId, parenttoken: this.drawerToken }, '*');
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
console.warn('未知操作:', action);
|
|
|
}
|
|
|
},
|
|
|
toolMainClick(index) {
|
|
|
this.toolMainItems[index].color = 'rgb(255, 0, 0)'; // 修改对应索引的颜色
|
|
|
var strTitle = this.toolMainItems[index].title;
|
|
|
switch (strTitle) {
|
|
|
case '默认':
|
|
|
this.toolDefault();
|
|
|
this.togglePressed(index);
|
|
|
break;
|
|
|
case '放大':
|
|
|
this.drawZoomIn();
|
|
|
break;
|
|
|
case '缩小':
|
|
|
this.drawZoomOut();
|
|
|
break;
|
|
|
case '刷新':
|
|
|
this.drawRefresh();
|
|
|
break;
|
|
|
case '刷新':
|
|
|
this.drawCenter();
|
|
|
break;
|
|
|
case '局部':
|
|
|
this.toolViewWindow();
|
|
|
this.togglePressed(index);
|
|
|
break;
|
|
|
case '全部':
|
|
|
this.viewAll();
|
|
|
break;
|
|
|
case '移动':
|
|
|
this.toolViewMove();
|
|
|
this.togglePressed(index);
|
|
|
break;
|
|
|
case '选择':
|
|
|
this.toolSelect();
|
|
|
this.togglePressed(index);
|
|
|
break;
|
|
|
case '保存':
|
|
|
this.drawSave();
|
|
|
break;
|
|
|
case '图层':
|
|
|
this.switchLayerPanel();
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
},
|
|
|
setToolHoverColor(index) {
|
|
|
this.toolMainItems[index].colorOld = this.toolMainItems[index].color;
|
|
|
this.toolMainItems[index].color = 'rgb(24, 144, 255)'; // 修改对应索引的颜色
|
|
|
},
|
|
|
resetToolColor(index) {
|
|
|
if (this.toolMainItems[index].checked === false) {
|
|
|
this.toolMainItems[index].color = this.toolMainItems[index].colorOld;
|
|
|
}
|
|
|
},
|
|
|
togglePressed(index) {
|
|
|
this.isBtnPressed = !this.isBtnPressed;
|
|
|
|
|
|
this.toolMainItems[index].checked = true;
|
|
|
for (var i = 0; i < this.toolMainItems.length; i++) {
|
|
|
if (i !== index) {
|
|
|
this.toolMainItems[i].checked = false;
|
|
|
this.toolMainItems[i].color = '#000000d9';
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
setupWebSocket() {
|
|
|
//this.websocket = new WebSocket("ws://kep.kepoil.com:8000/event", "json"); // 创建WebSocket连接(外网)
|
|
|
// this.websocket = new WebSocket("ws://192.168.31.45:8000/event", "json"); // 创建WebSocket连接
|
|
|
//this.websocket = new WebSocket("ws://192.168.31.113:8080/event", "json"); // 创建WebSocket连接
|
|
|
this.websocket = new WebSocket("ws://localhost:8080/event", "json"); // 创建WebSocket连接
|
|
|
this.websocket.onopen = this.onWebSocketOpen; // WebSocket连接打开时的处理函数
|
|
|
this.websocket.onmessage = this.onWebSocketMessage; // 收到WebSocket消息时的处理函数
|
|
|
this.websocket.onclose = this.onWebSocketClose; // WebSocket连接关闭时的处理函数
|
|
|
},
|
|
|
closeWebSocket() {
|
|
|
if (this.websocket) {
|
|
|
this.websocket.close(); // 关闭WebSocket连接
|
|
|
}
|
|
|
},
|
|
|
onWebSocketOpen() {
|
|
|
console.log("链接成功");
|
|
|
// this.openFile();
|
|
|
|
|
|
// this.sendMessage('ping', null);
|
|
|
//this.startHeartbeat(100);
|
|
|
// 测试
|
|
|
// this.openFile("测试1-.dfd");
|
|
|
/* // 通知父页面 WebSocket 已经打开
|
|
|
const message = { action: 'webSocketOpened' };
|
|
|
if (window.parent && window.parent.postMessage) {
|
|
|
window.parent.postMessage(message, '*');
|
|
|
} */
|
|
|
},
|
|
|
onWebSocketMessage(event) {
|
|
|
try {
|
|
|
const json = JSON.parse(event.data);
|
|
|
// console.info(json);
|
|
|
const evtType = json.type;
|
|
|
console.log(evtType)
|
|
|
// 根据消息的内容执行不同的操作
|
|
|
if (evtType === 'Pong') {
|
|
|
if (this.firstConnect == true) {
|
|
|
//this.stopHeartbeat();
|
|
|
//this.startHeartbeat(10000);
|
|
|
// 通知父页面 WebSocket 已经打开
|
|
|
const message = { action: 'webSocketOpened' };
|
|
|
if (window.parent && window.parent.postMessage) {
|
|
|
window.parent.postMessage(message, '*');
|
|
|
}
|
|
|
this.firstConnect = false;
|
|
|
}
|
|
|
}
|
|
|
else if (evtType === 'NewToken') {
|
|
|
this.isLoading = true;// 开始加载
|
|
|
this.drawerToken = json.drawerToken;
|
|
|
// 通知父页面 图件 已经打开
|
|
|
const message = { action: 'fileOpend', token: this.drawerToken, file: json.userID };
|
|
|
console.info(message);
|
|
|
if (window.parent && window.parent.postMessage) {
|
|
|
window.parent.postMessage(message, '*');
|
|
|
}
|
|
|
console.log("NewToken: " + this.drawerToken);
|
|
|
}
|
|
|
else if (evtType === 'OpenError') {
|
|
|
this.drawerToken = "";
|
|
|
this.ctx.fillStyle = '#FFFFFF'; // 设置背景色
|
|
|
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
|
|
|
alert("打开文件失败:" + json.userID);
|
|
|
|
|
|
// 通知父页面 图件 已经打开
|
|
|
const message = { action: 'OpenError', token: '', file: json.userID };
|
|
|
if (window.parent && window.parent.postMessage) {
|
|
|
window.parent.postMessage(message, '*');
|
|
|
}
|
|
|
}
|
|
|
else if (evtType === 'Redraw') {
|
|
|
this.imageSrc = json.data + '?_=' + Math.random();
|
|
|
this.drawerToken = json.drawerToken;
|
|
|
|
|
|
this.redrawCanvas(this.imageSrc);
|
|
|
}
|
|
|
else if (evtType === "SelectHandle") {
|
|
|
if (json.data !== -2) {
|
|
|
this.handleIndex = json.data;
|
|
|
// console.log(json.data);
|
|
|
}
|
|
|
}
|
|
|
else if (evtType === "DragElement") { // 显示拖拽轮廓图片
|
|
|
let imgContent = json.data;
|
|
|
if (!(imgContent && imgContent.Data)) {
|
|
|
return;
|
|
|
}
|
|
|
this.imgVisible = true;
|
|
|
this.imgPosition = { x: imgContent.ImgLeft, y: imgContent.ImgTop };
|
|
|
this.initialRect = { left: imgContent.ImgLeft, top: imgContent.ImgTop, width: imgContent.ImgWidth, height: imgContent.ImgHeight };
|
|
|
this.$nextTick(() => {
|
|
|
let imgTmp = this.$refs.image;
|
|
|
imgTmp.src = imgContent.Data;
|
|
|
});
|
|
|
// this.redrawCanvas(this.imageSrc);
|
|
|
}
|
|
|
else if (evtType === "ElementProperty") {
|
|
|
let imgContent = json.data;
|
|
|
this.selectedElementId = imgContent.ElementID;
|
|
|
this.selectedElement = imgContent.ElementData;
|
|
|
if (window.parent && window.parent.postMessage) {
|
|
|
window.parent.postMessage({ action: 'data-change', data: imgContent.ElementData, Id: imgContent.ElementID }, '*');
|
|
|
}
|
|
|
}
|
|
|
else if (evtType === "ReloadLayer") { // 隐藏拖拽轮廓图片
|
|
|
console.log("ReloadLayer:" + json.data);
|
|
|
this.showLayers(json.data);
|
|
|
}
|
|
|
else if (evtType === "MapRangeReal") { // 绘制刻度尺
|
|
|
if (this.queryDrawRuler === true) {
|
|
|
this.drawRuler(json.data);
|
|
|
queryDrawRuler = false;
|
|
|
}
|
|
|
this.isLoading = true;
|
|
|
}
|
|
|
}
|
|
|
finally {
|
|
|
this.isLoading = false; // 结束加载
|
|
|
}
|
|
|
},
|
|
|
onWebSocketClose() {
|
|
|
console.log("WebSocket connection is closed");
|
|
|
this.stopHeartbeat(); // WebSocket连接关闭时,停止心跳检测
|
|
|
setTimeout(this.setupWebSocket, this.reconnectInterval); // 在一定时间后重连WebSocket
|
|
|
},
|
|
|
startHeartbeat(stepTime = 3000) {
|
|
|
this.heartbeatInterval = setInterval(() => {
|
|
|
/* if (this.websocket && this.websocket.readyState === WebSocket.OPEN) {
|
|
|
this.websocket.send("ping"); // 发送心跳消息
|
|
|
} */
|
|
|
this.sendMessage('ping', null);
|
|
|
}, stepTime); // 每10秒发送一次心跳
|
|
|
},
|
|
|
stopHeartbeat() {
|
|
|
if (this.heartbeatInterval) {
|
|
|
clearInterval(this.heartbeatInterval); // 停止心跳检测定时器
|
|
|
}
|
|
|
},
|
|
|
getContaierOverflow() {
|
|
|
if (this.imgVisible) {
|
|
|
return 'hidden';
|
|
|
}
|
|
|
else {
|
|
|
return 'visible';
|
|
|
}
|
|
|
},
|
|
|
|
|
|
initCanvas() {
|
|
|
this.rubberbandDiv = this.$refs.rubberbandDiv;
|
|
|
this.canvas = this.$refs.canvas;
|
|
|
this.ctx = this.canvas.getContext('2d');
|
|
|
const devicePixelRatio = window.devicePixelRatio || 1;
|
|
|
|
|
|
const rect = this.canvas.getBoundingClientRect();
|
|
|
this.canvas.width = rect * devicePixelRatio;
|
|
|
this.canvas.height = rect * devicePixelRatio;
|
|
|
|
|
|
this.ctx.scale(devicePixelRatio, devicePixelRatio);
|
|
|
// 关闭图像平滑处理
|
|
|
this.ctx.imageSmoothingEnabled = false;
|
|
|
|
|
|
this.ctx.fillStyle = '#FFFFFF'; // 设置背景色
|
|
|
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
|
|
|
|
|
|
this.imgPosition = { x: rect.left, y: rect.top };
|
|
|
},
|
|
|
sendMessage(name, json) { // 发送消息到WebSocket服务器
|
|
|
if (this.websocket && this.websocket.readyState === WebSocket.OPEN) {
|
|
|
const message = {
|
|
|
type: name,
|
|
|
drawerToken: this.drawerToken,
|
|
|
data: json,
|
|
|
};
|
|
|
// console.log('sendMessage Open:' + name);
|
|
|
this.websocket.send(JSON.stringify(message));
|
|
|
}
|
|
|
else {
|
|
|
console.log('sendMessage Error:' + name);
|
|
|
}
|
|
|
},
|
|
|
openFile(fileUrl, token) {
|
|
|
if (!fileUrl) {
|
|
|
return;
|
|
|
}
|
|
|
if (this.drawerToken !== null && this.drawerToken.length > 0) {
|
|
|
// alert("OpenFile" + this.drawerToken);
|
|
|
this.closeDrawer(this.drawerToken);
|
|
|
}
|
|
|
// alert("OpenFile" + fileUrl);
|
|
|
console.log('OpenFile:' + fileUrl);
|
|
|
const rect = this.canvas.getBoundingClientRect();
|
|
|
// console.log('rect:' + rect);
|
|
|
// this.sendMessage("OpenFile", { file: fileUrl, width: rect.width*2, height: rect.height*2 });
|
|
|
this.sendMessage("OpenFile", { file: fileUrl, token: token, width: rect.width, height: rect.height });
|
|
|
},
|
|
|
closeDrawer(token) {
|
|
|
if (this.drawerToken !== null && this.drawerToken.length > 0) {
|
|
|
this.sendMessage("CloseDrawer", { token: token });
|
|
|
}
|
|
|
},
|
|
|
redraw() {
|
|
|
const rect = this.canvas.getBoundingClientRect();
|
|
|
//this.sendMessage("Redraw", { width: rect.width*2, height: rect.height*2 });
|
|
|
this.sendMessage("Redraw", { width: rect.width, height: rect.height });
|
|
|
},
|
|
|
drawRuler(range) {
|
|
|
const ctx = this.ctx;
|
|
|
|
|
|
const widthS = this.viewSize.width;
|
|
|
const heightS = this.viewSize.height;
|
|
|
|
|
|
const leftR = range.left;
|
|
|
const rightR = range.right;
|
|
|
const bottomR = range.bottom;
|
|
|
const topR = range.top;
|
|
|
|
|
|
redrawRuler(widthS, heightS, leftR, rightR, bottomR, topR);
|
|
|
},
|
|
|
drawSave() {
|
|
|
this.sendMessage("SaveFile", "");
|
|
|
},
|
|
|
switchLayerPanel() {
|
|
|
this.layerVisible = !this.layerVisible;
|
|
|
if (this.layerVisible) {
|
|
|
this.sendMessage("GetLayers", "");
|
|
|
}
|
|
|
},
|
|
|
showLayers(layerData) {
|
|
|
// console.log(layerData);
|
|
|
// 使用 '\r\n' 作为分隔符拆分字符串
|
|
|
|
|
|
/*const splitLines = layerData.split('\r\n');
|
|
|
let layerNodes = [];
|
|
|
layerNodes[0] = { id: "Layer:", pId: "-1", name: "图层", open: true, halfCheck: false }
|
|
|
splitLines.forEach((line, index) => {
|
|
|
if (line.length == 0) {
|
|
|
return;
|
|
|
}
|
|
|
let layerStatus = line.substring(0, line.indexOf("|"));
|
|
|
let layerData = line.substring(line.indexOf("|") + 1);
|
|
|
let layerArray = layerData.split("\\");
|
|
|
if (layerArray.length == 0) {
|
|
|
return;
|
|
|
}
|
|
|
let currLayer = "Layer:";
|
|
|
|
|
|
for (let i = 0; i < layerArray.length; i++) {
|
|
|
let currName = layerArray[i];
|
|
|
if (currName == "Layer:") {
|
|
|
continue;
|
|
|
}
|
|
|
let layerItem = { id: "", pId: "0", name: "", open: false };
|
|
|
layerItem.pId = currLayer;
|
|
|
currLayer += ("\\" + currName);
|
|
|
layerItem.id = "" + currLayer;
|
|
|
layerItem.name = currName;
|
|
|
layerItem.open = i < layerArray.length - 1;
|
|
|
if (i == layerArray.length - 1) {
|
|
|
layerItem.icon = layerStatusIcons[1];
|
|
|
layerNodes.push(layerItem);
|
|
|
}
|
|
|
else {
|
|
|
const findIndex = layerNodes.findIndex(item => item.id == layerItem.id);
|
|
|
if (findIndex == -1) {
|
|
|
layerItem.icon = layerStatusIcons[1];
|
|
|
layerNodes.push(layerItem);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
//zNodes = [...layerNodes].reverse();
|
|
|
zNodes = layerNodes;*/
|
|
|
// 确保layerData是有效的JSON字符串
|
|
|
if (typeof layerData === 'string') {
|
|
|
layerData = JSON.parse(layerData);
|
|
|
}
|
|
|
|
|
|
// 确保转换后是数组
|
|
|
if (!Array.isArray(layerData)) {
|
|
|
console.error('Invalid layer data format - expected array');
|
|
|
return;
|
|
|
}
|
|
|
// 创建图层根节点
|
|
|
let layerNodes = [{
|
|
|
id: "Layer:",
|
|
|
pId: "-1",
|
|
|
name: "图层",
|
|
|
open: true,
|
|
|
halfCheck: false,
|
|
|
icon: layerStatusIcons[1],
|
|
|
children: []
|
|
|
}];
|
|
|
// 递归处理节点和子节点
|
|
|
const processNode = (node) => {
|
|
|
const treeNode = {
|
|
|
id: node.id,
|
|
|
pId: "Layer:",// node.ParentId.toString(),
|
|
|
name: node.name || "",
|
|
|
open: false,
|
|
|
icon: layerStatusIcons[1],
|
|
|
status: node.status || 0,
|
|
|
fullPath: node.fullPath || "",
|
|
|
children: [],
|
|
|
};
|
|
|
|
|
|
// 如果有子节点,递归处理
|
|
|
if (node.children && node.children.length > 0) {
|
|
|
treeNode.children = node.children.map(child => {
|
|
|
const childNode = processNode(child);
|
|
|
// 确保子节点的pId指向父节点id
|
|
|
childNode.pId = treeNode.id;
|
|
|
return childNode;
|
|
|
});
|
|
|
// 有子节点时默认展开
|
|
|
treeNode.open = true;
|
|
|
}
|
|
|
return treeNode;
|
|
|
};
|
|
|
|
|
|
// let layerNodes = layerData.map(node => processNode(node));
|
|
|
// 处理传入的图层数据并添加到根节点下
|
|
|
if (Array.isArray(layerData)) {
|
|
|
layerNodes[0].children = layerData.map(node => processNode(node));
|
|
|
}
|
|
|
zNodes = layerNodes;
|
|
|
this.$nextTick(() => {
|
|
|
console.log("zNodes: " + zNodes);
|
|
|
reset(zNodes);
|
|
|
// this.initZTree(); 联动选中父子节点
|
|
|
});
|
|
|
},
|
|
|
setLayerStatus(status) { /* 设置选中节点的图层状态 */
|
|
|
var treeObj = $.fn.zTree.getZTreeObj("treeDemo");
|
|
|
var nodes = treeObj.getCheckedNodes(true);
|
|
|
// 移除name为"图层"的根节点
|
|
|
nodes = nodes.filter(node => node.name !== "图层");
|
|
|
var nCount = nodes.length;
|
|
|
if (nCount === 0) {
|
|
|
return;
|
|
|
}
|
|
|
var strStatus = "10";
|
|
|
if (status === 2) {
|
|
|
strStatus = "11";
|
|
|
}
|
|
|
else if (status === 3) {
|
|
|
strStatus = "12";
|
|
|
}
|
|
|
var statusData = "";
|
|
|
for (var i = 0; i < nCount; i++) {
|
|
|
var imgUrl = layerStatusIcons[status];
|
|
|
nodes[i].icon = imgUrl;
|
|
|
treeObj.updateNode(nodes[i]);
|
|
|
|
|
|
statusData += (strStatus + "|Layer:\\" + nodes[i].fullPath + "\r\n");
|
|
|
}
|
|
|
this.sendMessage("SetLayersStatus", { layerData: statusData });
|
|
|
},
|
|
|
deleteLayer() {
|
|
|
var treeObj = $.fn.zTree.getZTreeObj("treeDemo");
|
|
|
var nodes = treeObj.getCheckedNodes(true);
|
|
|
nodes = nodes.filter(node => node.name !== "图层");
|
|
|
var nCount = nodes.length;
|
|
|
if (nCount === 0) {
|
|
|
return;
|
|
|
}
|
|
|
var statusData = "";
|
|
|
for (var i = 0; i < nCount; i++) {
|
|
|
// statusData += (nodes[i].id + ",");
|
|
|
statusData += ("Layer:\\" + nodes[i].fullPath + ",");
|
|
|
treeObj.removeNode(nodes[i]);
|
|
|
}
|
|
|
this.sendMessage("DeleteLayers", { layers: statusData, widthChild: 1 });
|
|
|
},
|
|
|
canvasMouseDown(event) {
|
|
|
this.mouseDown = true;
|
|
|
|
|
|
this.lastX = event.offsetX;
|
|
|
this.lastY = event.offsetY;
|
|
|
this.mouseStartX = event.offsetX;
|
|
|
this.mouseStartY = event.offsetY;
|
|
|
if (this.drawerToolType == canvasToolType.ViewPan) {
|
|
|
this.isDragFirst = true;
|
|
|
this.imgVisible = true;
|
|
|
// 重置拖动图片到起始位置
|
|
|
this.imgPosition = { x: 0, y: 0 };
|
|
|
|
|
|
const rect = this.$refs.canvas.getBoundingClientRect();
|
|
|
this.mouseStartX = event.clientX - rect.left;
|
|
|
this.mouseStartY = event.clientY - rect.top;
|
|
|
// console.log("start: X:" + this.mouseStartX + " Y:" + this.mouseStartY);
|
|
|
}
|
|
|
else if (this.drawerToolType == canvasToolType.ViewWindow) {
|
|
|
event.preventDefault();
|
|
|
this.rubberVisible = true;
|
|
|
|
|
|
const rect = this.$refs.canvas.getBoundingClientRect();
|
|
|
this.mouseStartX = event.clientX - rect.left;
|
|
|
this.mouseStartY = event.clientY - rect.top;
|
|
|
this.rubberbandRectangle.left = this.mouseStartX;
|
|
|
this.rubberbandRectangle.top = this.mouseStartY;
|
|
|
this.rubberbandRectangle.width = 1;
|
|
|
this.rubberbandRectangle.height = 1;
|
|
|
}
|
|
|
else if (this.drawerToolType == canvasToolType.Select) {
|
|
|
const rect = this.$refs.canvas.getBoundingClientRect();
|
|
|
if (this.handleIndex === this.SelectHandle.Nothing) {
|
|
|
// 框选
|
|
|
// this.rubberVisible = true;
|
|
|
}
|
|
|
if (this.handleIndex >= 0 && this.handleIndex <= 9) {
|
|
|
// 发送拖动开始消息
|
|
|
this.sendMessage("SelectDragStart", { x: event.offsetX, y: event.offsetY });
|
|
|
}
|
|
|
|
|
|
// this.sendMessage("SelectMouseDown", { x: this.mouseStartX, y: this.mouseStartY });
|
|
|
}
|
|
|
this.handleMenuAction('cancel');
|
|
|
},
|
|
|
canvasMouseUp(event) {
|
|
|
if (this.drawerToolType == canvasToolType.ViewPan) {
|
|
|
const rect = this.$refs.canvas.getBoundingClientRect();
|
|
|
let endX = event.clientX - rect.left;
|
|
|
let endY = event.clientY - rect.top;
|
|
|
|
|
|
this.sendMessage("ViewPan", {
|
|
|
startX: this.mouseStartX, startY: this.mouseStartY,
|
|
|
endX: endX, endY: endY,
|
|
|
width: this.viewSize.width, height: this.viewSize.height
|
|
|
});
|
|
|
}
|
|
|
else if (this.drawerToolType == canvasToolType.ViewWindow) {
|
|
|
this.rubberVisible = false;
|
|
|
|
|
|
const rect = this.$refs.canvas.getBoundingClientRect();
|
|
|
let endX = event.clientX - rect.left;
|
|
|
let endY = event.clientY - rect.top;
|
|
|
this.sendMessage("ViewWindow", {
|
|
|
startX: this.mouseStartX, startY: this.mouseStartY,
|
|
|
endX: endX, endY: endY,
|
|
|
width: this.viewSize.width, height: this.viewSize.height
|
|
|
});
|
|
|
}
|
|
|
else if (this.drawerToolType == canvasToolType.Select) {
|
|
|
if (this.handleIndex === this.SelectHandle.Body) {
|
|
|
// 拖动结束
|
|
|
let endX = event.offsetX;
|
|
|
let endY = event.offsetY;
|
|
|
this.dragImageVisible = false;
|
|
|
// this.sendMessage("DragElement", { x: endX, y: endY });
|
|
|
this.sendMessage("SelectTransformElements", { handle: this.handleIndex, startX: this.mouseStartX, startY: this.mouseStartY, endX: endX, endY: endY });
|
|
|
}
|
|
|
else if (this.handleIndex >= 0 && this.handleIndex < 8) {
|
|
|
// 变形处理
|
|
|
let endX = event.offsetX;
|
|
|
let endY = event.offsetY;
|
|
|
this.dragImageVisible = false;
|
|
|
this.sendMessage("SelectTransformElements", { handle: this.handleIndex, startX: this.mouseStartX, startY: this.mouseStartY, endX: endX, endY: endY });
|
|
|
}
|
|
|
else if (this.handleIndex === this.SelectHandle.Nothing) {
|
|
|
this.rubberVisible = false;
|
|
|
const rect = this.$refs.canvas.getBoundingClientRect();
|
|
|
let endX = event.offsetX;// - rect.left;
|
|
|
let endY = event.offsetY;// - rect.top;
|
|
|
|
|
|
/* else {
|
|
|
// 图元选择
|
|
|
const rect = this.$refs.canvas.getBoundingClientRect();
|
|
|
let endX = event.offsetX;// - rect.left;
|
|
|
let endY = event.offsetY;// - rect.top;
|
|
|
this.sendMessage("SelectMouseUp", { x: endX, y: endY, keyCode: this.pressedKeyCode });
|
|
|
} */
|
|
|
this.sendMessage("SelectRegion", {
|
|
|
startX: this.lastX,
|
|
|
startY: this.lastY,
|
|
|
endX: endX,
|
|
|
endY: endY,
|
|
|
isAdd: false
|
|
|
});
|
|
|
// mouseThought.value = false;
|
|
|
}
|
|
|
}
|
|
|
this.mouseDown = false;
|
|
|
},
|
|
|
canvasMouseMove(event) {
|
|
|
this.mouseHorizontal = event.offsetX + 20;//-rect.left;
|
|
|
this.mouseVertical = event.offsetY + 20;// - rect.top;
|
|
|
if (this.mouseDown != true) {
|
|
|
if (this.drawerToolType == canvasToolType.Select) {
|
|
|
this.sendMessage("SelectMouseMove", { x: event.offsetX, y: event.offsetY, handleIndex: this.handleIndex });
|
|
|
}
|
|
|
return;
|
|
|
}
|
|
|
// 鼠标按下状态事件处理
|
|
|
if (this.drawerToolType == canvasToolType.ViewPan) {// 执行视图拖动
|
|
|
let offsetX = event.offsetX - this.lastX;
|
|
|
let offsetY = event.offsetY - this.lastY;
|
|
|
const rect = this.canvas.getBoundingClientRect();
|
|
|
if (this.isDragFirst) {
|
|
|
const dataURL = this.canvas.toDataURL('image/png');
|
|
|
this.$refs.image.src = dataURL;
|
|
|
console.log("first before: X" + this.imgPosition.x + " Y" + this.imgPosition.y);
|
|
|
this.imgPosition = { x: this.imgPosition.x + offsetX, y: this.imgPosition.y + offsetY };
|
|
|
console.log("first after: X" + this.imgPosition.x + " Y" + this.imgPosition.y);
|
|
|
requestAnimationFrame(() => {
|
|
|
this.ctx.clearRect(0, 0, rect.width, rect.height);
|
|
|
});
|
|
|
this.isDragFirst = false;
|
|
|
}
|
|
|
else {
|
|
|
this.imgPosition = { x: this.imgPosition.x + offsetX, y: this.imgPosition.y + offsetY };
|
|
|
// console.log("moveing: X" + this.imgPosition.x + " Y" + this.imgPosition.y);
|
|
|
}
|
|
|
this.lastX = event.offsetX;
|
|
|
this.lastY = event.offsetY;
|
|
|
}
|
|
|
else if (this.drawerToolType == canvasToolType.ViewWindow) {
|
|
|
const rect = this.canvas.getBoundingClientRect();
|
|
|
var endX = event.clientX - rect.left;
|
|
|
var endY = event.clientY - rect.top;
|
|
|
var dragStartX = this.mouseStartX;
|
|
|
var dragStartY = this.mouseStartY;
|
|
|
|
|
|
if (endX < dragStartX) {
|
|
|
dragStartX = endX;
|
|
|
endX = this.mouseStartX;
|
|
|
}
|
|
|
if (endY < dragStartY) {
|
|
|
dragStartY = endY;
|
|
|
endY = this.mouseStartY;
|
|
|
}
|
|
|
this.rubberbandRectangle = {
|
|
|
left: dragStartX,
|
|
|
top: dragStartY,
|
|
|
width: endX - dragStartX,
|
|
|
height: endY - dragStartY
|
|
|
};
|
|
|
event.preventDefault();
|
|
|
}
|
|
|
else if (this.drawerToolType == canvasToolType.Select) {
|
|
|
var currentX = event.offsetX;
|
|
|
var currentY = event.offsetY;
|
|
|
event.preventDefault();
|
|
|
if (this.handleIndex === this.SelectHandle.Nothing) {
|
|
|
// 框选框绘制
|
|
|
// const rect = this.canvas.getBoundingClientRect();
|
|
|
// 使用 offsetX/offsetY 获取相对于 canvas 的坐标
|
|
|
|
|
|
var dragStartX = this.lastX;
|
|
|
var dragStartY = this.lastY;
|
|
|
|
|
|
// 确保坐标按左上->右下排列
|
|
|
var left = Math.min(dragStartX, currentX);
|
|
|
var top = Math.min(dragStartY, currentY);
|
|
|
var right = Math.max(dragStartX, currentX);
|
|
|
var bottom = Math.max(dragStartY, currentY);
|
|
|
|
|
|
var rbWidth = right - left;
|
|
|
var rbHeight = bottom - top;
|
|
|
if (rbWidth > 0 || rbHeight > 0) {
|
|
|
if (this.rubberVisible === false) {
|
|
|
this.rubberVisible = true;
|
|
|
}
|
|
|
this.rubberbandRectangle = {
|
|
|
left: left,
|
|
|
top: top,
|
|
|
width: rbWidth,
|
|
|
height: rbHeight
|
|
|
};
|
|
|
}
|
|
|
else {
|
|
|
this.rubberVisible = false;
|
|
|
}
|
|
|
}
|
|
|
else if (this.handleIndex === this.SelectHandle.Right) {
|
|
|
|
|
|
let imgTmp = this.$refs.image;
|
|
|
if (imgTmp && this.imgVisible) {
|
|
|
imgTmp.style.objectFit = 'fill'; // 允许拉伸填充
|
|
|
imgTmp.style.width = `${this.initialRect.width + (currentX - this.mouseStartX)}px`;
|
|
|
imgTmp.style.height = `${this.initialRect.height}px`;
|
|
|
}
|
|
|
}
|
|
|
else if (this.handleIndex === this.SelectHandle.Left) {
|
|
|
let imgTmp = this.$refs.image;
|
|
|
if (imgTmp && this.imgVisible) {
|
|
|
imgTmp.style.objectFit = 'fill'; // 允许拉伸填充
|
|
|
imgTmp.style.width = `${this.initialRect.width - (currentX - this.mouseStartX)}px`;
|
|
|
imgTmp.style.height = `${this.initialRect.height}px`;
|
|
|
|
|
|
this.imgPosition.x = this.initialRect.left + (currentX - this.mouseStartX);
|
|
|
}
|
|
|
}
|
|
|
else if (this.handleIndex === this.SelectHandle.Bottom) {
|
|
|
let imgTmp = this.$refs.image;
|
|
|
if (imgTmp && this.imgVisible) {
|
|
|
imgTmp.style.objectFit = 'fill'; // 允许拉伸填充
|
|
|
imgTmp.style.width = `${this.initialRect.width}px`;
|
|
|
imgTmp.style.height = `${this.initialRect.height + (currentY - this.mouseStartY)}px`;
|
|
|
}
|
|
|
}
|
|
|
else if (this.handleIndex === this.SelectHandle.Top) {
|
|
|
let imgTmp = this.$refs.image;
|
|
|
if (imgTmp && this.imgVisible) {
|
|
|
imgTmp.style.objectFit = 'fill'; // 允许拉伸填充
|
|
|
imgTmp.style.width = `${this.initialRect.width}px`;
|
|
|
imgTmp.style.height = `${this.initialRect.height - (currentY - this.mouseStartY)}px`;
|
|
|
|
|
|
this.imgPosition.y = this.initialRect.top + (currentY - this.mouseStartY);
|
|
|
}
|
|
|
}
|
|
|
else if (this.handleIndex === this.SelectHandle.BottomRight) {
|
|
|
let imgTmp = this.$refs.image;
|
|
|
if (imgTmp && this.imgVisible) {
|
|
|
imgTmp.style.objectFit = 'fill'; // 允许拉伸填充
|
|
|
imgTmp.style.width = `${this.initialRect.width + (currentX - this.mouseStartX)}px`;
|
|
|
imgTmp.style.height = `${this.initialRect.height + (currentY - this.mouseStartY)}px`;
|
|
|
}
|
|
|
}
|
|
|
else if (this.handleIndex === this.SelectHandle.BottomLeft) {
|
|
|
let imgTmp = this.$refs.image;
|
|
|
if (imgTmp && this.imgVisible) {
|
|
|
imgTmp.style.objectFit = 'fill'; // 允许拉伸填充
|
|
|
imgTmp.style.width = `${this.initialRect.width - (currentX - this.mouseStartX)}px`;
|
|
|
imgTmp.style.height = `${this.initialRect.height + (currentY - this.mouseStartY)}px`;
|
|
|
|
|
|
this.imgPosition.x = this.initialRect.left + (currentX - this.mouseStartX);
|
|
|
}
|
|
|
}
|
|
|
else if (this.handleIndex === this.SelectHandle.TopRight) {
|
|
|
let imgTmp = this.$refs.image;
|
|
|
if (imgTmp && this.imgVisible) {
|
|
|
imgTmp.style.objectFit = 'fill'; // 允许拉伸填充
|
|
|
imgTmp.style.width = `${this.initialRect.width + (currentX - this.mouseStartX)}px`;
|
|
|
imgTmp.style.height = `${this.initialRect.height - (currentY - this.mouseStartY)}px`;
|
|
|
|
|
|
this.imgPosition.y = this.initialRect.top + (currentY - this.mouseStartY);
|
|
|
}
|
|
|
}
|
|
|
else if (this.handleIndex === this.SelectHandle.TopLeft) {
|
|
|
let imgTmp = this.$refs.image;
|
|
|
if (imgTmp && this.imgVisible) {
|
|
|
imgTmp.style.objectFit = 'fill'; // 允许拉伸填充
|
|
|
imgTmp.style.width = `${this.initialRect.width - (currentX - this.mouseStartX)}px`;
|
|
|
imgTmp.style.height = `${this.initialRect.height - (currentY - this.mouseStartY)}px`;
|
|
|
|
|
|
this.imgPosition.x = this.initialRect.left + (currentX - this.mouseStartX);
|
|
|
this.imgPosition.y = this.initialRect.top + (currentY - this.mouseStartY);
|
|
|
}
|
|
|
}
|
|
|
else if (this.handleIndex === this.SelectHandle.Body) {
|
|
|
// 拖动
|
|
|
let offsetX = event.offsetX - this.lastX;
|
|
|
let offsetY = event.offsetY - this.lastY;
|
|
|
if (Math.abs(offsetX) > 0 || Math.abs(offsetY) > 0) {
|
|
|
this.imgPosition = { x: this.imgPosition.x + offsetX, y: this.imgPosition.y + offsetY };
|
|
|
this.lastX = event.offsetX;
|
|
|
this.lastY = event.offsetY;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
canvasMouseWheel(event) {
|
|
|
this.count++;
|
|
|
},
|
|
|
/** 放大 */
|
|
|
drawZoomIn() {
|
|
|
this.sendMessage("ZoomIn", { width: this.viewSize.width, height: this.viewSize.height });
|
|
|
//emit('tool-changed', canvasAction.ZoomIn);
|
|
|
console.log("drawZoomIn: " + this.drawerToken);
|
|
|
},
|
|
|
/** 缩小 */
|
|
|
drawZoomOut() {
|
|
|
this.sendMessage("ZoomOut", { width: this.viewSize.width, height: this.viewSize.height });
|
|
|
},
|
|
|
/** 刷新 */
|
|
|
drawRefresh() {
|
|
|
this.sendMessage("Refresh", { width: this.viewSize.width, height: this.viewSize.height });
|
|
|
},
|
|
|
/** 居中 */
|
|
|
drawCenter() {
|
|
|
this.sendMessage("Center", { width: this.viewSize.width, height: this.viewSize.height });
|
|
|
},
|
|
|
viewAll() {
|
|
|
this.sendMessage("ViewAll", { width: this.viewSize.width, height: this.viewSize.height });
|
|
|
},
|
|
|
async redrawCanvas(data) {
|
|
|
if (data.length === 0) {
|
|
|
return;
|
|
|
}
|
|
|
try {
|
|
|
console.log("重新绘制图片数据:", data);
|
|
|
const response = await fetch(data, { cache: 'no-store' });
|
|
|
//const response = await fetch(data, { cache: 'store' });
|
|
|
if (!response.ok) {
|
|
|
throw new Error('Network response was not ok');
|
|
|
}
|
|
|
const blob = await response.blob();
|
|
|
const bitmap = await createImageBitmap(blob);
|
|
|
this.ctx.drawImage(bitmap, 0, 0);
|
|
|
this.imgVisible = false;
|
|
|
|
|
|
// 重绘刻度尺
|
|
|
this.queryDrawRuler = true;
|
|
|
// const rect = this.canvas.getBoundingClientRect();
|
|
|
this.sendMessage("QueryRangeScreen2Real", { startX: 0, endX: this.viewSize.width, startY: 0, endY: this.viewSize.height });
|
|
|
} catch (error) {
|
|
|
console.error('Failed to load the image:', error);
|
|
|
}
|
|
|
},
|
|
|
toolDefault() {
|
|
|
this.drawerToolType = canvasToolType.Default;
|
|
|
},
|
|
|
toolViewMove() {
|
|
|
this.drawerToolType = canvasToolType.ViewPan;
|
|
|
},
|
|
|
toolViewWindow() {
|
|
|
this.drawerToolType = canvasToolType.ViewWindow;
|
|
|
},
|
|
|
toolSelect() {
|
|
|
this.drawerToolType = canvasToolType.Select;
|
|
|
this.toolSwitch(this.drawerToolType);
|
|
|
},
|
|
|
// 工具切换
|
|
|
toolSwitch(newToolType) {
|
|
|
this.sendMessage("SwitchToolType", { toolType: newToolType });
|
|
|
},
|
|
|
GetCursor() {
|
|
|
if (this.drawerToolType === canvasToolType.Select) {
|
|
|
if (this.handleIndex === this.SelectHandle.Body || this.handleIndex === this.SelectHandle.Center) {
|
|
|
return MouseIcons.move;
|
|
|
}
|
|
|
else if (this.handleIndex === this.SelectHandle.TopLeft || this.handleIndex === this.SelectHandle.BottomRight) {
|
|
|
return MouseIcons.resizenw;
|
|
|
}
|
|
|
else if (this.handleIndex === this.SelectHandle.TopRight || this.handleIndex === this.SelectHandle.BottomLeft) {
|
|
|
return MouseIcons.resizene;
|
|
|
}
|
|
|
else if (this.handleIndex === this.SelectHandle.Left || this.handleIndex === this.SelectHandle.Right) {
|
|
|
return MouseIcons.resizee;
|
|
|
}
|
|
|
else if (this.handleIndex === this.SelectHandle.Top || this.handleIndex === this.SelectHandle.Bottom) {
|
|
|
return MouseIcons.resizen;
|
|
|
}
|
|
|
else {
|
|
|
return MouseIcons.pointerSelect;
|
|
|
}
|
|
|
} else if (this.drawerToolType == canvasToolType.ViewPan) {
|
|
|
return MouseIcons.viewPan;
|
|
|
}
|
|
|
else if (this.drawerToolType == canvasToolType.ViewWindow) {
|
|
|
return MouseIcons.crosshair;
|
|
|
}
|
|
|
return MouseIcons.default;
|
|
|
},
|
|
|
handleResize() {
|
|
|
if (this.windowMouseDown === true) {
|
|
|
return;
|
|
|
}
|
|
|
this.$nextTick(() => {
|
|
|
const comWindow = this.$el.parentNode;
|
|
|
var viewWidth = comWindow.offsetWidth - this.rulerHeight;
|
|
|
if (this.layerVisible === true) {
|
|
|
// 总宽度-图层树宽度
|
|
|
viewWidth = comWindow.offsetWidth - this.layerSize.width - this.rulerHeight;
|
|
|
}
|
|
|
// 总高度-菜单高度
|
|
|
var viewHeight = comWindow.offsetHeight - 50 - this.rulerHeight;
|
|
|
|
|
|
this.layerSize.height = viewHeight + this.rulerHeight;
|
|
|
|
|
|
this.viewSize = { width: viewWidth, height: viewHeight };
|
|
|
this.redrawCanvas(this.imageSrc);
|
|
|
});
|
|
|
},
|
|
|
/* onWindowMouseDown() {
|
|
|
this.windowMouseDown = true;
|
|
|
},
|
|
|
onWindowMouseUp() {
|
|
|
this.windowMouseDown = false;
|
|
|
},*/
|
|
|
handleKeyDown(event) {
|
|
|
this.pressedKeyCode = event.keyCode;
|
|
|
},
|
|
|
handleKeyUp(event) {
|
|
|
this.pressedKeyCode = null;
|
|
|
},
|
|
|
},
|
|
|
mounted() {
|
|
|
this.handleResize();
|
|
|
window.addEventListener('resize', this.handleResize);
|
|
|
|
|
|
this.initCanvas();
|
|
|
this.setupWebSocket(); // 创建WebSocket连接
|
|
|
|
|
|
// 全局监听 mousedown 和 mouseup 事件
|
|
|
/* window.addEventListener('mousedown', this.onWindowMouseDown);
|
|
|
window.addEventListener('mouseup', this.onWindowMouseUp); */
|
|
|
// 使用 document.body.onmousedown 和 onmouseup 进行全局监听
|
|
|
/* document.body.onmousedown = this.onWindowMouseDown;
|
|
|
document.body.onmouseup = this.onWindowMouseUp; */
|
|
|
this.openFile = this.openFile.bind(this); // 绑定 this
|
|
|
window.addEventListener('message', function (event) {
|
|
|
// console.log('Message got:' + event.data.action);
|
|
|
|
|
|
if (event.data.action === 'openFile') {
|
|
|
this.isLoading = true;// 显示加载动画
|
|
|
this.openFile(event.data.fileUrl, event.data.token);
|
|
|
}
|
|
|
if (event.data.action === "redraw") {
|
|
|
this.redraw();
|
|
|
}
|
|
|
if (event.data.action === "viewAll") {
|
|
|
this.viewAll();
|
|
|
}
|
|
|
if (event.data.action === "refresh") {
|
|
|
this.redraw();
|
|
|
}
|
|
|
if (event.data.action === "center") {
|
|
|
this.redraw();
|
|
|
}
|
|
|
}.bind(this));
|
|
|
// 全局监听键盘事件
|
|
|
window.addEventListener('keydown', this.handleKeyDown);
|
|
|
window.addEventListener('keyup', this.handleKeyUp);
|
|
|
},
|
|
|
beforeUnmount() {
|
|
|
this.closeDrawer();
|
|
|
this.closeWebSocket(); // 在组件销毁前关闭WebSocket连接
|
|
|
},
|
|
|
unmounted() {
|
|
|
window.removeEventListener('resize', this.handleResize);
|
|
|
window.removeEventListener('openFile', this.openFile);
|
|
|
|
|
|
// 移除全局事件监听
|
|
|
/* window.removeEventListener('mousedown', this.onWindowMouseDown);
|
|
|
window.removeEventListener('mouseup', this.onWindowMouseUp); */
|
|
|
// 移除全局事件监听器
|
|
|
/* document.body.onmousedown = null;
|
|
|
document.body.onmouseup = null; */
|
|
|
window.removeEventListener('keydown', this.handleKeyDown);
|
|
|
window.removeEventListener('keyup', this.handleKeyUp);
|
|
|
|
|
|
console.log('unmounted');
|
|
|
},
|
|
|
/* beforeDestroy() {
|
|
|
this.closeWebSocket(); // 在组件销毁前关闭WebSocket连接
|
|
|
}, */
|
|
|
}
|
|
|
const app = Vue.createApp(VueApp);
|
|
|
app.mount('#app');
|
|
|
</script>
|
|
|
|
|
|
<SCRIPT type="text/javascript">
|
|
|
var setting = {
|
|
|
view: {
|
|
|
dblClickExpand: dblClickExpand
|
|
|
},
|
|
|
check: {
|
|
|
enable: true,
|
|
|
chkStyle: "checkbox", // 使用复选框模式
|
|
|
chkboxType: { "Y": "", "N": "" }, // 关键设置
|
|
|
//nocheckInherit: true // 防止子节点影响父节点
|
|
|
},
|
|
|
edit: {
|
|
|
enable: true,
|
|
|
showRemoveBtn: false,
|
|
|
showRenameBtn: false
|
|
|
},
|
|
|
data: {
|
|
|
simpleData: {
|
|
|
enable: true
|
|
|
}
|
|
|
},
|
|
|
callback: {
|
|
|
beforeDrag: beforeDrag,
|
|
|
beforeDrop: beforeDrop,
|
|
|
/* beforeCheck: zTreeBeforeCheck,
|
|
|
onCheck: onCheck, */
|
|
|
}
|
|
|
};
|
|
|
|
|
|
var zNodes = [
|
|
|
{ Id: 'aa', ParentId: 0, Name: "随意拖拽 1", open: true, children: [] },
|
|
|
{ Id: 11, ParentId: 'aa', Name: "随意拖拽 1-1", children: [] },
|
|
|
{ Id: 12, ParentId: 'aa', Name: "随意拖拽 1-2", open: true, children: [] },
|
|
|
/* { id: 121, pId: 12, name: "随意拖拽 1-2-1" },
|
|
|
{ id: 122, pId: 12, name: "随意拖拽 1-2-2" },
|
|
|
{ id: 123, pId: 12, name: "随意拖拽 1-2-3" },
|
|
|
{ id: 13, pId: 'aa', name: "禁止拖拽 1-3", open: true, drag: false },
|
|
|
{ id: 131, pId: 13, name: "禁止拖拽 1-3-1", drag: false },
|
|
|
{ id: 132, pId: 13, name: "禁止拖拽 1-3-2", drag: false },
|
|
|
{ id: 133, pId: 13, name: "随意拖拽 1-3-3" },
|
|
|
{ id: 2, pId: 0, name: "随意拖拽 2", open: true },
|
|
|
{ id: 21, pId: 2, name: "随意拖拽 2-1" },
|
|
|
{ id: 22, pId: 2, name: "禁止拖拽到我身上 2-2", open: true, drop: false },
|
|
|
{ id: 221, pId: 22, name: "随意拖拽 2-2-1" },
|
|
|
{ id: 222, pId: 22, name: "随意拖拽 2-2-2" },
|
|
|
{ id: 223, pId: 22, name: "随意拖拽 2-2-3" }, */
|
|
|
{ Id: 23, ParentId: 2, Name: "随意拖拽 2-3", children: [] }
|
|
|
];
|
|
|
function dblClickExpand(treeId, treeNode) {
|
|
|
return treeNode.level > 0;
|
|
|
}
|
|
|
|
|
|
function beforeDrag(treeId, treeNodes) {
|
|
|
for (var i = 0, l = treeNodes.length; i < l; i++) {
|
|
|
if (treeNodes[i].drag === false) {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
function beforeDrop(treeId, treeNodes, targetNode, moveType) {
|
|
|
return targetNode ? targetNode.drop !== false : true;
|
|
|
}
|
|
|
/* 设置选中状态 */
|
|
|
function setCheck() {
|
|
|
var zTree = $.fn.zTree.getZTreeObj("treeDemo"),
|
|
|
isCopy = true, //$("#copy").attr("checked"),
|
|
|
isMove = true, // $("#move").attr("checked"),
|
|
|
prev = true, // $("#prev").attr("checked"),
|
|
|
inner = true, // $("#inner").attr("checked"),
|
|
|
next = true; //$("#next").attr("checked");
|
|
|
if (zTree == null) {
|
|
|
return;
|
|
|
}
|
|
|
zTree.setting.edit.drag.isCopy = isCopy;
|
|
|
zTree.setting.edit.drag.isMove = isMove;
|
|
|
//showCode(1, ['setting.edit.drag.isCopy = ' + isCopy, 'setting.edit.drag.isMove = ' + isMove]);
|
|
|
|
|
|
zTree.setting.edit.drag.prev = prev;
|
|
|
zTree.setting.edit.drag.inner = inner;
|
|
|
zTree.setting.edit.drag.next = next;
|
|
|
//showCode(2, ['setting.edit.drag.prev = ' + prev, 'setting.edit.drag.inner = ' + inner, 'setting.edit.drag.next = ' + next]);
|
|
|
}
|
|
|
/* function zTreeBeforeCheck(treeId, treeNode) {
|
|
|
if (treeNode.children && treeNode.children.length > 0) {
|
|
|
return true; // 阻止勾选子节点
|
|
|
}
|
|
|
return false;
|
|
|
}; */
|
|
|
function onCheck(event, treeId, treeNode) {
|
|
|
/* var zTree = $.fn.zTree.getZTreeObj(treeId);
|
|
|
var nodes = zTree.getNodesByFilter(function (node) {
|
|
|
return node.parentTId === treeNode.tId;
|
|
|
});
|
|
|
|
|
|
// 对于每个子节点,如果它被勾选,则保持勾选状态;否则取消勾选
|
|
|
for (var i = 0, l = nodes.length; i < l; i++) {
|
|
|
var node = nodes[i];
|
|
|
if (!node.checked) {
|
|
|
zTree.checkNode(node, false, true);
|
|
|
}
|
|
|
} */
|
|
|
}
|
|
|
|
|
|
function cancelHalf(treeNode) {
|
|
|
/* if (treeNode.checkedEx) return;
|
|
|
var zTree = $.fn.zTree.getZTreeObj("treeDemo");
|
|
|
treeNode.halfCheck = false;
|
|
|
zTree.updateNode(treeNode); */
|
|
|
}
|
|
|
|
|
|
function showCode(id, str) {
|
|
|
var code = $("#code" + id);
|
|
|
code.empty();
|
|
|
for (var i = 0, l = str.length; i < l; i++) {
|
|
|
code.append("<li>" + str[i] + "</li>");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* function SetLayerStatus(status){
|
|
|
var treeObj = $.fn.zTree.getZTreeObj("treeDemo");
|
|
|
var nodes = treeObj.getCheckedNodes(true);
|
|
|
if(nodes){
|
|
|
<scritp src="drawerRuler.js" type="text/javascript"></scritp>
|
|
|
}
|
|
|
} */
|
|
|
function reset(nodesData) {
|
|
|
$.fn.zTree.init($("#treeDemo"), setting, nodesData);
|
|
|
setCheck();
|
|
|
}
|
|
|
$(document).ready(function () {
|
|
|
$.fn.zTree.init($("#treeDemo"), setting, zNodes);
|
|
|
setCheck();
|
|
|
//$("#copy").bind("change", setCheck);
|
|
|
//$("#move").bind("change", setCheck);
|
|
|
//$("#prev").bind("change", setCheck);
|
|
|
//$("#inner").bind("change", setCheck);
|
|
|
//$("#next").bind("change", setCheck);
|
|
|
});
|
|
|
|
|
|
//-->
|
|
|
</SCRIPT>
|
|
|
<script src="drawerRuler.js" type="text/javascript"></script>
|
|
|
<script type="text/javascript">
|
|
|
var ruler_horizontal = new drawerRuler({ container: "ruler-horizontal", orientation: 1 });
|
|
|
var ruler_vertial = new drawerRuler({ container: "ruler-vertical", orientation: 2 });
|
|
|
function redrawRuler(widthS, heightS, leftR, rightR, bottomR, topR) {
|
|
|
ruler_horizontal.api.redraw(widthS, leftR, rightR);
|
|
|
ruler_vertial.api.redraw(heightS, bottomR, topR);
|
|
|
};
|
|
|
|
|
|
</script>
|
|
|
</body>
|
|
|
|
|
|
</html> |