fl-web-component 2.0.0-beta.9 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fl-web-component.common.js +34592 -1519
- package/dist/fl-web-component.common.js.map +1 -1
- package/dist/fl-web-component.css +1 -1
- package/package.json +4 -15
- package/packages/components/com-card/index.vue +1 -1
- package/packages/components/com-flcanvas/components/bspline.js +31 -34
- package/packages/components/com-flcanvas/components/entityFormatting.js +810 -823
- package/packages/components/com-flcanvas/components/round10.js +17 -17
- package/packages/components/com-flcanvas/index.vue +314 -333
- package/packages/components/com-formDialog/index.vue +6 -4
- package/packages/components/com-graphics/component/ann-tool.vue +263 -208
- package/packages/components/com-graphics/index.vue +366 -773
- package/packages/components/com-graphics/pid.vue +304 -295
- package/packages/components/com-table/column-default.vue +2 -3
- package/packages/components/com-table/column-dynamic.vue +7 -4
- package/packages/components/com-table/column.vue +1 -2
- package/packages/components/com-table/index.vue +6 -5
- package/packages/components/com-tabs/index.vue +1 -2
- package/packages/components/com-tiles/index.vue +134 -136
- package/packages/components/com-treeDynamic/index.vue +1 -1
- package/packages/utils/StreamLoader.js +1548 -1489
- package/packages/utils/StreamLoaderParser.worker.js +9 -14
- package/src/main.js +2 -8
- package/src/utils/cloud.js +28 -28
- package/src/utils/cursor.js +11 -9
- package/src/utils/flgltf-parser.js +257 -245
- package/src/utils/instance-parser.js +20 -22
- package/src/utils/mini-devtool.js +94 -39
- package/src/utils/threejs/measure-angle.js +51 -13
- package/src/utils/threejs/measure-area.js +43 -12
- package/src/utils/threejs/measure-distance.js +43 -12
- package/src/utils/threejs/rain-shader.js +10 -10
- package/src/utils/threejs/snow-shader.js +9 -9
|
@@ -1,40 +1,87 @@
|
|
|
1
|
-
|
|
2
1
|
<template>
|
|
3
2
|
<div class="main_body">
|
|
4
3
|
<!-- 绘制工具栏 -->
|
|
5
4
|
<div class="toolbar" v-if="toolbarShow">
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
5
|
+
<el-button
|
|
6
|
+
type="text"
|
|
7
|
+
:style="`background-image: url(${btnBg.text})`"
|
|
8
|
+
class="icon_toolbar icon_title"
|
|
9
|
+
:class="[type === 'text' ? 'icon_active' : '']"
|
|
10
|
+
title="文本"
|
|
11
|
+
@click="handleDrawCanvas('text', '文本', 'text')"
|
|
12
|
+
/>
|
|
13
|
+
<!-- <el-button type="text" class="icon_toolbar icon_line" :class="[type === 'line' ? 'icon_active' : '']" title="折线" @click="handleDrawCanvas('crosshair', '折线', 'line')" />-->
|
|
14
|
+
<!-- <el-button type="text" class="icon_toolbar icon_rectangle" :class="[type === 'rectangle' ? 'icon_active' : '']" title="矩形" @click="handleDrawCanvas('crosshair', '矩形', 'rectangle')" /> -->
|
|
15
|
+
<!-- <el-button type="text" class="icon_toolbar icon_circle" :class="[type === 'circle' ? 'icon_active' : '']" title="圆形" @click="handleDrawCanvas('crosshair', '圆形', 'circle')" /> -->
|
|
16
|
+
<el-button
|
|
17
|
+
type="text"
|
|
18
|
+
class="icon_toolbar icon_rectangle"
|
|
19
|
+
:class="[type === 'cloud' ? 'icon_active' : '']"
|
|
20
|
+
title="云线"
|
|
21
|
+
:style="`background-image: url(${btnBg.cloud})`"
|
|
22
|
+
@click="handleDrawCanvas('crosshair', '云线', 'cloud')"
|
|
23
|
+
/>
|
|
24
|
+
<!-- <el-button type="text" class="icon_toolbar icon_rubber" :class="[type === 'rubber' ? 'icon_active' : '']" title="橡皮擦" @click="handleDrawCanvas('eraser', '橡皮', 'rubber')" />-->
|
|
25
|
+
<el-button type="text" class="icon_toolbar icon_color" title="颜色">
|
|
26
|
+
<el-color-picker
|
|
27
|
+
v-model="defaultColor"
|
|
28
|
+
popper-class="popperClass"
|
|
29
|
+
@change="colorChange"
|
|
30
|
+
></el-color-picker>
|
|
31
|
+
</el-button>
|
|
32
|
+
<el-button
|
|
33
|
+
type="text"
|
|
34
|
+
:style="`background-image: url(${btnBg.clear})`"
|
|
35
|
+
class="text_toolbar icon_clear"
|
|
36
|
+
@click="clearAnn"
|
|
37
|
+
title="清除"
|
|
38
|
+
></el-button>
|
|
39
|
+
<el-button
|
|
40
|
+
type="text"
|
|
41
|
+
:style="`background-image: url(${btnBg.cancel})`"
|
|
42
|
+
class="text_toolbar icon_cancel"
|
|
43
|
+
@click="cancel"
|
|
44
|
+
title="取消"
|
|
45
|
+
></el-button>
|
|
46
|
+
<el-button
|
|
47
|
+
type="text"
|
|
48
|
+
:style="`background-image: url(${btnBg.save})`"
|
|
49
|
+
class="text_toolbar icon_save"
|
|
50
|
+
@click="saveDrawing"
|
|
51
|
+
title="保存"
|
|
52
|
+
></el-button>
|
|
25
53
|
</div>
|
|
26
54
|
<div class="canvas_container" id="canvas_container">
|
|
27
55
|
<canvas id="ctx_base" ref="ctx_base" :style="'cursor:' + cursorStyle"></canvas>
|
|
28
|
-
<input
|
|
56
|
+
<input
|
|
57
|
+
name="text"
|
|
58
|
+
id="text"
|
|
59
|
+
@keyup.enter="handleTextBlur"
|
|
60
|
+
@blur="handleTextBlur"
|
|
61
|
+
v-model="text"
|
|
62
|
+
autofocus
|
|
63
|
+
autocomplete="off"
|
|
64
|
+
:style="'font-size:' + (this.slide * 10 + 14) + 'pxcolor:' + defaultColor"
|
|
65
|
+
placeholder="输入完成请按回车键"
|
|
66
|
+
/>
|
|
29
67
|
</div>
|
|
30
68
|
</div>
|
|
31
69
|
</template>
|
|
32
70
|
|
|
33
71
|
<script>
|
|
34
|
-
var canvas_base = null,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
var
|
|
72
|
+
var canvas_base = null,
|
|
73
|
+
ctx_base = null,
|
|
74
|
+
recordImg = null;
|
|
75
|
+
var canvas_container = null,
|
|
76
|
+
startPoint = null,
|
|
77
|
+
currentPoint = null;
|
|
78
|
+
let originalImageWidth = 0,
|
|
79
|
+
originalImageHeight = 0,
|
|
80
|
+
displayImageWidth = 0,
|
|
81
|
+
displayImageHeight = 0,
|
|
82
|
+
translateX = 0,
|
|
83
|
+
translateY = 0;
|
|
84
|
+
var annList = [];
|
|
38
85
|
let scale = 1.0; // 当前缩放比例
|
|
39
86
|
const MIN_SCALE = 0.1; // 最小缩放比例
|
|
40
87
|
const MAX_SCALE = 8.0; // 最大缩放比例
|
|
@@ -45,28 +92,28 @@ let isPanning = false; // 是否正在平移
|
|
|
45
92
|
let panStartX = 0; // 平移起始X坐标
|
|
46
93
|
let panStartY = 0; // 平移起始Y坐标
|
|
47
94
|
let isSpacePressed = false; // 空格键是否按下
|
|
48
|
-
import cursors from
|
|
49
|
-
import { drawCloudLines } from '@/utils/cloud'
|
|
95
|
+
import cursors from '@/utils/cursor';
|
|
96
|
+
import { drawCloudLines } from '@/utils/cloud';
|
|
50
97
|
export default {
|
|
51
98
|
name: 'DrawToolbar',
|
|
52
99
|
props: {
|
|
53
100
|
src: {
|
|
54
101
|
type: String,
|
|
55
|
-
default: ''
|
|
56
|
-
}
|
|
102
|
+
default: '',
|
|
103
|
+
},
|
|
57
104
|
},
|
|
58
105
|
data() {
|
|
59
106
|
return {
|
|
60
107
|
currentImg: {
|
|
61
108
|
url: null,
|
|
62
|
-
width:
|
|
63
|
-
height:
|
|
109
|
+
width: '',
|
|
110
|
+
height: '',
|
|
64
111
|
scale: 1,
|
|
65
112
|
index: 0,
|
|
66
113
|
},
|
|
67
114
|
tl: 0,
|
|
68
115
|
tt: 0,
|
|
69
|
-
slide: 1
|
|
116
|
+
slide: 1, // 2,
|
|
70
117
|
text: '',
|
|
71
118
|
toolbarShow: true,
|
|
72
119
|
ctx_base: null,
|
|
@@ -80,183 +127,181 @@ export default {
|
|
|
80
127
|
defaultColor: '#A90A0A', // 颜色选取
|
|
81
128
|
cursorStyle: 'default', // 鼠标样式
|
|
82
129
|
btnBg: {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
}
|
|
130
|
+
text: require('@static/ann-img/mark_font@2x.png'),
|
|
131
|
+
cloud: require('@static/ann-img/mark_cloud@2x.png'),
|
|
132
|
+
clear: require('@static/ann-img/mark_clear@2x.png'),
|
|
133
|
+
cancel: require('@static/ann-img/mark_exit@2x.png'),
|
|
134
|
+
save: require('@static/ann-img/mark_finish@2x.png'),
|
|
135
|
+
},
|
|
136
|
+
};
|
|
90
137
|
},
|
|
91
138
|
mounted() {
|
|
92
139
|
this.$nextTick(() => {
|
|
93
|
-
this.handleInitCanvas()
|
|
94
|
-
})
|
|
140
|
+
this.handleInitCanvas();
|
|
141
|
+
});
|
|
95
142
|
},
|
|
96
143
|
created() {
|
|
97
|
-
console.log('created')
|
|
144
|
+
console.log('created');
|
|
98
145
|
},
|
|
99
146
|
methods: {
|
|
100
147
|
clearAnn() {
|
|
101
|
-
annList.splice(0)
|
|
102
|
-
this.redraw()
|
|
148
|
+
annList.splice(0);
|
|
149
|
+
this.redraw();
|
|
103
150
|
},
|
|
104
151
|
// 初始化图纸
|
|
105
152
|
handleInitCanvas() {
|
|
106
|
-
console.log('handleInitCanvas')
|
|
153
|
+
console.log('handleInitCanvas');
|
|
107
154
|
this.currentImg = {
|
|
108
155
|
url: this.src,
|
|
109
|
-
width:
|
|
110
|
-
height:
|
|
156
|
+
width: '',
|
|
157
|
+
height: '',
|
|
111
158
|
scale: 1,
|
|
112
159
|
index: 0,
|
|
113
|
-
}
|
|
114
|
-
canvas_container = document.getElementById(
|
|
115
|
-
canvas_base = document.getElementById(
|
|
116
|
-
ctx_base = canvas_base.getContext(
|
|
117
|
-
ctx_base.strokeStyle = this.defaultColor
|
|
160
|
+
};
|
|
161
|
+
canvas_container = document.getElementById('canvas_container');
|
|
162
|
+
canvas_base = document.getElementById('ctx_base');
|
|
163
|
+
ctx_base = canvas_base.getContext('2d');
|
|
164
|
+
ctx_base.strokeStyle = this.defaultColor;
|
|
118
165
|
|
|
119
|
-
let img = new Image()
|
|
120
|
-
img.src = this.currentImg.url
|
|
121
|
-
let _this = this
|
|
166
|
+
let img = new Image();
|
|
167
|
+
img.src = this.currentImg.url;
|
|
168
|
+
let _this = this;
|
|
122
169
|
img.onload = function () {
|
|
123
|
-
|
|
124
|
-
recordImg = this
|
|
170
|
+
recordImg = this;
|
|
125
171
|
originalImageWidth = img.naturalWidth || img.width;
|
|
126
172
|
originalImageHeight = img.naturalHeight || img.height;
|
|
127
|
-
_this.resetView()
|
|
128
|
-
}
|
|
129
|
-
canvas_base.width = canvas_container.clientWidth
|
|
130
|
-
canvas_base.height = canvas_container.clientHeight
|
|
131
|
-
canvas_base.addEventListener('wheel',
|
|
132
|
-
e.preventDefault()
|
|
173
|
+
_this.resetView();
|
|
174
|
+
};
|
|
175
|
+
canvas_base.width = canvas_container.clientWidth;
|
|
176
|
+
canvas_base.height = canvas_container.clientHeight;
|
|
177
|
+
canvas_base.addEventListener('wheel', e => {
|
|
178
|
+
e.preventDefault();
|
|
133
179
|
const rect = canvas_base.getBoundingClientRect();
|
|
134
180
|
const mouseX = e.clientX - rect.left;
|
|
135
181
|
const mouseY = e.clientY - rect.top;
|
|
136
|
-
let imagePointBeforeZoom = this.screenToImage(mouseX, mouseY)
|
|
137
|
-
const zoomFactor = e.deltaY > 0 ? 0.8 : 1.2
|
|
138
|
-
const newScale = Math.max(MIN_SCALE, Math.min(MAX_SCALE, scale * zoomFactor))
|
|
139
|
-
scale = newScale
|
|
140
|
-
const imagePointAfterZoom = this.screenToImage(mouseX, mouseY)
|
|
141
|
-
translateX += (imagePointAfterZoom.x - imagePointBeforeZoom.x) * scale
|
|
142
|
-
translateY += (imagePointAfterZoom.y - imagePointBeforeZoom.y) * scale
|
|
143
|
-
this.redraw()
|
|
144
|
-
})
|
|
145
|
-
canvas_base.addEventListener('mousedown',
|
|
182
|
+
let imagePointBeforeZoom = this.screenToImage(mouseX, mouseY);
|
|
183
|
+
const zoomFactor = e.deltaY > 0 ? 0.8 : 1.2;
|
|
184
|
+
const newScale = Math.max(MIN_SCALE, Math.min(MAX_SCALE, scale * zoomFactor));
|
|
185
|
+
scale = newScale;
|
|
186
|
+
const imagePointAfterZoom = this.screenToImage(mouseX, mouseY);
|
|
187
|
+
translateX += (imagePointAfterZoom.x - imagePointBeforeZoom.x) * scale;
|
|
188
|
+
translateY += (imagePointAfterZoom.y - imagePointBeforeZoom.y) * scale;
|
|
189
|
+
this.redraw();
|
|
190
|
+
});
|
|
191
|
+
canvas_base.addEventListener('mousedown', e => {
|
|
146
192
|
if (e.button === 0) {
|
|
147
193
|
// ctx_base.strokeStyle = this.defaultColor
|
|
148
194
|
// ctx_base.lineWidth = this.slide * 2
|
|
149
|
-
e = e || window.event
|
|
150
|
-
let rect = canvas_base.getBoundingClientRect()
|
|
151
|
-
let screenX = e.clientX - rect.left
|
|
152
|
-
let screenY = e.clientY - rect.top
|
|
153
|
-
let imagePoint = this.screenToImage(screenX, screenY)
|
|
195
|
+
e = e || window.event;
|
|
196
|
+
let rect = canvas_base.getBoundingClientRect();
|
|
197
|
+
let screenX = e.clientX - rect.left;
|
|
198
|
+
let screenY = e.clientY - rect.top;
|
|
199
|
+
let imagePoint = this.screenToImage(screenX, screenY);
|
|
154
200
|
startPoint = imagePoint;
|
|
155
201
|
currentPoint = imagePoint;
|
|
156
202
|
switch (this.type) {
|
|
157
203
|
case 'rubber':
|
|
158
|
-
ctx_front.putImageData(
|
|
204
|
+
ctx_front.putImageData(cbx, e.offsetX - 12, e.offsetY - 12);
|
|
159
205
|
// this.ctx_back.putImageData(cbx, e.offsetX - 12, e.offsetY - 12)
|
|
160
|
-
break
|
|
206
|
+
break;
|
|
161
207
|
case 'text':
|
|
162
|
-
let text = document.getElementById(
|
|
208
|
+
let text = document.getElementById('text');
|
|
163
209
|
// this.handleTextBlur()
|
|
164
|
-
this.text =
|
|
165
|
-
text.style.fontSize = 14 + this.slide * 10 +
|
|
166
|
-
text.style.color = this.defaultColor
|
|
167
|
-
text.style.left = screenX - 5 +
|
|
168
|
-
text.style.top = screenY - 20 +
|
|
169
|
-
text.style.zIndex = 10
|
|
170
|
-
text.style.display =
|
|
171
|
-
let textPos = this.screenToImage(screenX - 5, screenY + 10)
|
|
172
|
-
this.tl = textPos.x // currentPoint.x
|
|
173
|
-
this.tt = textPos.y // currentPoint.y
|
|
210
|
+
this.text = '';
|
|
211
|
+
text.style.fontSize = 14 + this.slide * 10 + 'px';
|
|
212
|
+
text.style.color = this.defaultColor;
|
|
213
|
+
text.style.left = screenX - 5 + 'px';
|
|
214
|
+
text.style.top = screenY - 20 + 'px';
|
|
215
|
+
text.style.zIndex = 10;
|
|
216
|
+
text.style.display = 'block';
|
|
217
|
+
let textPos = this.screenToImage(screenX - 5, screenY + 10);
|
|
218
|
+
this.tl = textPos.x; // currentPoint.x
|
|
219
|
+
this.tt = textPos.y; // currentPoint.y
|
|
174
220
|
break;
|
|
175
221
|
case 'cloud':
|
|
176
|
-
this.canDraw = true
|
|
222
|
+
this.canDraw = true;
|
|
177
223
|
break;
|
|
178
224
|
}
|
|
179
|
-
this.redraw()
|
|
225
|
+
this.redraw();
|
|
180
226
|
}
|
|
181
|
-
})
|
|
182
|
-
canvas_base.addEventListener('contextmenu',
|
|
183
|
-
e.preventDefault()
|
|
184
|
-
})
|
|
185
|
-
canvas_base.addEventListener('mousemove',
|
|
227
|
+
});
|
|
228
|
+
canvas_base.addEventListener('contextmenu', e => {
|
|
229
|
+
e.preventDefault();
|
|
230
|
+
});
|
|
231
|
+
canvas_base.addEventListener('mousemove', e => {
|
|
186
232
|
if (e.button === 0) {
|
|
187
|
-
e = e || window.event
|
|
188
|
-
let rect = canvas_base.getBoundingClientRect()
|
|
233
|
+
e = e || window.event;
|
|
234
|
+
let rect = canvas_base.getBoundingClientRect();
|
|
189
235
|
let screenX = e.clientX - rect.left;
|
|
190
236
|
let screenY = e.clientY - rect.top;
|
|
191
237
|
if (this.canDraw) {
|
|
192
|
-
let imagePoint = this.screenToImage(screenX, screenY)
|
|
193
|
-
currentPoint = imagePoint
|
|
194
|
-
this.redraw()
|
|
238
|
+
let imagePoint = this.screenToImage(screenX, screenY);
|
|
239
|
+
currentPoint = imagePoint;
|
|
240
|
+
this.redraw();
|
|
195
241
|
}
|
|
196
242
|
}
|
|
197
|
-
})
|
|
198
|
-
canvas_base.addEventListener('mouseup',
|
|
243
|
+
});
|
|
244
|
+
canvas_base.addEventListener('mouseup', e => {
|
|
199
245
|
if (e.button === 0 && this.canDraw) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
}
|
|
216
|
-
startPoint = null
|
|
217
|
-
currentPoint = null
|
|
246
|
+
this.canDraw = false;
|
|
247
|
+
if (this.type === 'cloud') {
|
|
248
|
+
let width = Math.abs(currentPoint.x - startPoint.x);
|
|
249
|
+
let height = Math.abs(currentPoint.y - startPoint.y);
|
|
250
|
+
let minSize = 5 / scale;
|
|
251
|
+
if (width > minSize && height > minSize) {
|
|
252
|
+
annList.push({
|
|
253
|
+
x: Math.min(startPoint.x, currentPoint.x),
|
|
254
|
+
y: Math.min(startPoint.y, currentPoint.y),
|
|
255
|
+
ex: Math.max(startPoint.x, currentPoint.x),
|
|
256
|
+
ey: Math.max(startPoint.y, currentPoint.y),
|
|
257
|
+
type: 'cloud',
|
|
258
|
+
color: this.defaultColor,
|
|
259
|
+
lineWidth: ctx_base.lineWidth,
|
|
260
|
+
});
|
|
218
261
|
}
|
|
219
|
-
|
|
262
|
+
startPoint = null;
|
|
263
|
+
currentPoint = null;
|
|
264
|
+
}
|
|
265
|
+
this.redraw();
|
|
220
266
|
}
|
|
221
|
-
})
|
|
222
|
-
|
|
267
|
+
});
|
|
223
268
|
},
|
|
224
269
|
resetView() {
|
|
225
|
-
if (!recordImg) return
|
|
270
|
+
if (!recordImg) return;
|
|
226
271
|
const containerWidth = canvas_base.width;
|
|
227
272
|
const containerHeight = canvas_base.height;
|
|
228
|
-
|
|
273
|
+
|
|
229
274
|
// 计算保持比例的最大尺寸
|
|
230
275
|
const widthRatio = containerWidth / originalImageWidth;
|
|
231
276
|
const heightRatio = containerHeight / originalImageHeight;
|
|
232
277
|
const scaleRatio = Math.min(widthRatio, heightRatio);
|
|
233
|
-
|
|
278
|
+
|
|
234
279
|
displayImageWidth = originalImageWidth * scaleRatio;
|
|
235
280
|
displayImageHeight = originalImageHeight * scaleRatio;
|
|
236
|
-
|
|
281
|
+
|
|
237
282
|
// 居中显示
|
|
238
283
|
translateX = (containerWidth - displayImageWidth) / 2;
|
|
239
284
|
translateY = (containerHeight - displayImageHeight) / 2;
|
|
240
285
|
scale = scaleRatio;
|
|
241
|
-
this.redraw()
|
|
286
|
+
this.redraw();
|
|
242
287
|
},
|
|
243
288
|
redraw() {
|
|
244
|
-
if (!recordImg) return
|
|
245
|
-
ctx_base.clearRect(0, 0, canvas_base.width, canvas_base.height)
|
|
246
|
-
ctx_base.save()
|
|
247
|
-
ctx_base.translate(translateX, translateY)
|
|
248
|
-
ctx_base.scale(scale, scale)
|
|
249
|
-
ctx_base.drawImage(recordImg, 0, 0, originalImageWidth, originalImageHeight)
|
|
289
|
+
if (!recordImg) return;
|
|
290
|
+
ctx_base.clearRect(0, 0, canvas_base.width, canvas_base.height);
|
|
291
|
+
ctx_base.save();
|
|
292
|
+
ctx_base.translate(translateX, translateY);
|
|
293
|
+
ctx_base.scale(scale, scale);
|
|
294
|
+
ctx_base.drawImage(recordImg, 0, 0, originalImageWidth, originalImageHeight);
|
|
250
295
|
annList.forEach(item => {
|
|
251
296
|
switch (item.type) {
|
|
252
297
|
case 'cloud':
|
|
253
|
-
this.drawCloudAnn(item)
|
|
298
|
+
this.drawCloudAnn(item);
|
|
254
299
|
break;
|
|
255
300
|
case 'text':
|
|
256
|
-
this.drawTextAnn(item)
|
|
301
|
+
this.drawTextAnn(item);
|
|
257
302
|
break;
|
|
258
303
|
}
|
|
259
|
-
})
|
|
304
|
+
});
|
|
260
305
|
if (this.canDraw && startPoint && currentPoint) {
|
|
261
306
|
if (this.type === 'cloud') {
|
|
262
307
|
let tempAnn = {
|
|
@@ -266,99 +311,108 @@ export default {
|
|
|
266
311
|
ey: Math.max(startPoint.y, currentPoint.y),
|
|
267
312
|
type: 'cloud',
|
|
268
313
|
color: this.defaultColor,
|
|
269
|
-
lineWidth: ctx_base.lineWidth
|
|
270
|
-
}
|
|
271
|
-
this.drawCloudAnn(tempAnn)
|
|
314
|
+
lineWidth: ctx_base.lineWidth,
|
|
315
|
+
};
|
|
316
|
+
this.drawCloudAnn(tempAnn);
|
|
272
317
|
}
|
|
273
318
|
}
|
|
274
|
-
ctx_base.restore()
|
|
319
|
+
ctx_base.restore();
|
|
275
320
|
},
|
|
276
321
|
// 绘制云线
|
|
277
322
|
drawCloudAnn(annotation) {
|
|
278
|
-
ctx_base.save()
|
|
279
|
-
ctx_base.strokeStyle = annotation.color
|
|
323
|
+
ctx_base.save();
|
|
324
|
+
ctx_base.strokeStyle = annotation.color;
|
|
280
325
|
ctx_base.lineWidth = annotation.lineWidth || ctx_base.lineWidth;
|
|
281
|
-
ctx_base.setLineDash([])
|
|
282
|
-
ctx_base.beginPath()
|
|
283
|
-
drawCloudLines(
|
|
284
|
-
|
|
326
|
+
ctx_base.setLineDash([]);
|
|
327
|
+
ctx_base.beginPath();
|
|
328
|
+
drawCloudLines(
|
|
329
|
+
ctx_base,
|
|
330
|
+
[
|
|
331
|
+
{ x: annotation.ex, y: annotation.y },
|
|
332
|
+
{ x: annotation.ex, y: annotation.ey },
|
|
333
|
+
{ x: annotation.x, y: annotation.ey },
|
|
334
|
+
{ x: annotation.x, y: annotation.y },
|
|
335
|
+
],
|
|
336
|
+
true
|
|
337
|
+
);
|
|
338
|
+
ctx_base.restore();
|
|
285
339
|
},
|
|
286
340
|
drawTextAnn(annotation) {
|
|
287
|
-
ctx_base.save()
|
|
288
|
-
ctx_base.strokeStyle = annotation.color
|
|
289
|
-
ctx_base.fillStyle = annotation.color
|
|
290
|
-
ctx_base.fillText(annotation.text, annotation.x, annotation.y)
|
|
291
|
-
ctx_base.restore()
|
|
341
|
+
ctx_base.save();
|
|
342
|
+
ctx_base.strokeStyle = annotation.color;
|
|
343
|
+
ctx_base.fillStyle = annotation.color;
|
|
344
|
+
ctx_base.fillText(annotation.text, annotation.x, annotation.y);
|
|
345
|
+
ctx_base.restore();
|
|
292
346
|
},
|
|
293
347
|
// 屏幕坐标转换为图像坐标
|
|
294
348
|
screenToImage(screenX, screenY) {
|
|
295
|
-
const imageX = (screenX - translateX) / scale
|
|
296
|
-
const imageY = (screenY - translateY) / scale
|
|
297
|
-
return { x: imageX, y: imageY }
|
|
349
|
+
const imageX = (screenX - translateX) / scale;
|
|
350
|
+
const imageY = (screenY - translateY) / scale;
|
|
351
|
+
return { x: imageX, y: imageY };
|
|
298
352
|
},
|
|
299
353
|
// 当前显示的颜色发生改变时
|
|
300
|
-
colorChange
|
|
301
|
-
if (this.defaultColor === null) this.defaultColor = '#A90A0A'
|
|
302
|
-
this.redraw()
|
|
354
|
+
colorChange(val) {
|
|
355
|
+
if (this.defaultColor === null) this.defaultColor = '#A90A0A';
|
|
356
|
+
this.redraw();
|
|
303
357
|
},
|
|
304
|
-
saveDrawing() {
|
|
358
|
+
saveDrawing() {
|
|
305
359
|
const link = document.createElement('a');
|
|
306
360
|
link.download = `图纸批注_${new Date().toISOString().slice(0, 19).replace(/[:T]/g, '-')}.png`;
|
|
307
361
|
link.href = canvas_base.toDataURL('image/png', 1.0);
|
|
308
362
|
link.click();
|
|
309
363
|
},
|
|
310
364
|
handleDrawCanvas(style, type, actived) {
|
|
311
|
-
if (actived !== this.type) {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
this.
|
|
365
|
+
if (actived !== this.type) {
|
|
366
|
+
this.type = actived;
|
|
367
|
+
}
|
|
368
|
+
if (style !== 'eraser') this.cursorStyle = style;
|
|
369
|
+
else if (style === 'eraser') this.cursorStyle = `url('${cursors.eraser}') 15 15, auto`;
|
|
370
|
+
this.canDraw = false;
|
|
315
371
|
},
|
|
316
372
|
/** 失焦或者回车绘制文本,框隐藏*/
|
|
317
373
|
handleTextBlur() {
|
|
318
|
-
let realTxt = this.text.replace(/^\s+|\s+$/g, '')
|
|
319
|
-
if (realTxt === '') return
|
|
320
|
-
let text = document.getElementById(
|
|
321
|
-
let fontSize = 1.2 // text.style.fontSize / 10
|
|
374
|
+
let realTxt = this.text.replace(/^\s+|\s+$/g, '');
|
|
375
|
+
if (realTxt === '') return;
|
|
376
|
+
let text = document.getElementById('text');
|
|
377
|
+
let fontSize = 1.2; // text.style.fontSize / 10
|
|
322
378
|
annList.push({
|
|
323
379
|
type: 'text',
|
|
324
380
|
x: this.tl,
|
|
325
381
|
y: this.tt,
|
|
326
382
|
text: realTxt,
|
|
327
383
|
color: this.defaultColor,
|
|
328
|
-
font: `100 ${fontSize} sans-serif
|
|
384
|
+
font: `100 ${fontSize} sans-serif`,
|
|
329
385
|
});
|
|
330
|
-
text.style.display =
|
|
331
|
-
this.text =
|
|
332
|
-
text.value =
|
|
333
|
-
this.redraw()
|
|
334
|
-
|
|
386
|
+
text.style.display = 'none';
|
|
387
|
+
this.text = '';
|
|
388
|
+
text.value = '';
|
|
389
|
+
this.redraw();
|
|
335
390
|
},
|
|
336
391
|
cancel() {
|
|
337
|
-
canvas_base = null
|
|
338
|
-
ctx_base = null
|
|
339
|
-
recordImg = null
|
|
340
|
-
canvas_container = null
|
|
341
|
-
startPoint = null
|
|
342
|
-
currentPoint = null
|
|
343
|
-
originalImageWidth = 0
|
|
344
|
-
originalImageHeight = 0
|
|
345
|
-
displayImageWidth = 0
|
|
346
|
-
displayImageHeight = 0
|
|
347
|
-
translateX = 0
|
|
348
|
-
translateY = 0
|
|
349
|
-
annList.splice(0
|
|
350
|
-
scale = 1.0 // 当前缩放比例
|
|
351
|
-
offsetX = 0 // X轴平移
|
|
352
|
-
offsetY = 0 // Y轴平移
|
|
392
|
+
canvas_base = null;
|
|
393
|
+
ctx_base = null;
|
|
394
|
+
recordImg = null;
|
|
395
|
+
canvas_container = null;
|
|
396
|
+
startPoint = null;
|
|
397
|
+
currentPoint = null;
|
|
398
|
+
originalImageWidth = 0;
|
|
399
|
+
originalImageHeight = 0;
|
|
400
|
+
displayImageWidth = 0;
|
|
401
|
+
displayImageHeight = 0;
|
|
402
|
+
translateX = 0;
|
|
403
|
+
translateY = 0;
|
|
404
|
+
annList.splice(0);
|
|
405
|
+
scale = 1.0; // 当前缩放比例
|
|
406
|
+
offsetX = 0; // X轴平移
|
|
407
|
+
offsetY = 0; // Y轴平移
|
|
353
408
|
isPanning = false; // 是否正在平移
|
|
354
|
-
panStartX =
|
|
355
|
-
|
|
356
|
-
isSpacePressed = false // 空格键是否按下
|
|
357
|
-
this.$emit('closeAnn')
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
}
|
|
409
|
+
panStartX = // 平移起始X坐标
|
|
410
|
+
panStartY = 0; // 平移起始Y坐标
|
|
411
|
+
isSpacePressed = false; // 空格键是否按下
|
|
412
|
+
this.$emit('closeAnn');
|
|
413
|
+
},
|
|
414
|
+
},
|
|
415
|
+
};
|
|
362
416
|
</script>
|
|
363
417
|
<style scoped lang="scss">
|
|
364
418
|
.main_body {
|
|
@@ -383,14 +437,14 @@ export default {
|
|
|
383
437
|
width: 520px;
|
|
384
438
|
padding: 8px 16px;
|
|
385
439
|
border-radius: 6px;
|
|
386
|
-
box-shadow: 0px 2px 10px 0px rgba(6,29,44,0.25);
|
|
440
|
+
box-shadow: 0px 2px 10px 0px rgba(6, 29, 44, 0.25);
|
|
387
441
|
background-color: #fff;
|
|
388
442
|
top: 10px;
|
|
389
443
|
left: 50%;
|
|
390
444
|
box-sizing: border-box;
|
|
391
445
|
transform: translateX(-50%);
|
|
392
446
|
display: flex;
|
|
393
|
-
justify-content: space-around
|
|
447
|
+
justify-content: space-around;
|
|
394
448
|
}
|
|
395
449
|
// 工具栏图标
|
|
396
450
|
.icon_toolbar,
|
|
@@ -403,7 +457,9 @@ export default {
|
|
|
403
457
|
background-size: 24px;
|
|
404
458
|
background-position: center;
|
|
405
459
|
}
|
|
406
|
-
.icon_toolbar:hover,
|
|
460
|
+
.icon_toolbar:hover,
|
|
461
|
+
.text_toolbar:hover,
|
|
462
|
+
.icon_active {
|
|
407
463
|
background-color: rgba(238, 238, 238, 1);
|
|
408
464
|
}
|
|
409
465
|
|
|
@@ -411,7 +467,7 @@ export default {
|
|
|
411
467
|
::v-deep.icon_color .el-color-picker__trigger {
|
|
412
468
|
height: 24px;
|
|
413
469
|
margin-top: 4px;
|
|
414
|
-
width: 24px !important
|
|
470
|
+
width: 24px !important;
|
|
415
471
|
// opacity: 0;
|
|
416
472
|
// filter: alpha(opacity=0);
|
|
417
473
|
}
|
|
@@ -438,10 +494,9 @@ export default {
|
|
|
438
494
|
}
|
|
439
495
|
#ctx_front {
|
|
440
496
|
z-index: 5;
|
|
441
|
-
background-color: transparent
|
|
497
|
+
background-color: transparent;
|
|
442
498
|
}
|
|
443
499
|
#ctx_back {
|
|
444
|
-
|
|
445
500
|
z-index: 3;
|
|
446
501
|
}
|
|
447
502
|
#ctx_base {
|
|
@@ -459,7 +514,7 @@ export default {
|
|
|
459
514
|
line-height: 30px;
|
|
460
515
|
display: none;
|
|
461
516
|
}
|
|
462
|
-
#text:hover{
|
|
463
|
-
border: 1px dashed #53a8ff
|
|
517
|
+
#text:hover {
|
|
518
|
+
border: 1px dashed #53a8ff;
|
|
464
519
|
}
|
|
465
520
|
</style>
|