fl-web-component 0.1.1 → 1.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.
Files changed (78) hide show
  1. package/dist/fl-web-component.common.js +14751 -54489
  2. package/dist/fl-web-component.common.js.map +1 -1
  3. package/dist/fl-web-component.css +1 -1
  4. package/dist/fl-web-component.umd.js +14751 -54489
  5. package/dist/fl-web-component.umd.js.map +1 -1
  6. package/dist/fl-web-component.umd.min.js +3 -3
  7. package/dist/fl-web-component.umd.min.js.map +1 -1
  8. package/package.json +26 -5
  9. package/packages/components/button/index.vue +18 -17
  10. package/packages/components/com-card/card-page.vue +51 -49
  11. package/packages/components/com-card/index.vue +20 -21
  12. package/packages/components/com-dialogWrapper/index.vue +18 -21
  13. package/packages/components/com-flcanvas/components/bspline.js +91 -0
  14. package/packages/components/com-flcanvas/components/entityFormatting.js +503 -0
  15. package/packages/components/com-flcanvas/components/round10.js +24 -0
  16. package/packages/components/com-flcanvas/index.vue +259 -0
  17. package/packages/components/com-formDialog/index.vue +76 -75
  18. package/packages/components/com-graphics/index.vue +1059 -226
  19. package/packages/components/com-graphics/per-control.vue +109 -0
  20. package/packages/components/com-graphics/pid.vue +168 -0
  21. package/packages/components/com-page/index.vue +33 -33
  22. package/packages/components/com-selectTree/index.vue +61 -63
  23. package/packages/components/com-table/column-default.vue +9 -14
  24. package/packages/components/com-table/column-dynamic.vue +4 -8
  25. package/packages/components/com-table/column-menu.vue +8 -8
  26. package/packages/components/com-table/column-slot.vue +4 -4
  27. package/packages/components/com-table/column.vue +7 -15
  28. package/packages/components/com-table/config.js +9 -9
  29. package/packages/components/com-table/index.vue +35 -35
  30. package/packages/components/com-table/table-page.vue +17 -17
  31. package/packages/components/com-tabs/index.vue +19 -19
  32. package/packages/components/com-treeDynamic/index.vue +45 -45
  33. package/packages/components/model/api/index.js +59 -67
  34. package/packages/components/model/api/mock/detecttree.js +38 -38
  35. package/packages/components/model/api/mock/getmodel-line.js +15830 -79332
  36. package/packages/components/model/api/mock/init.js +1 -1
  37. package/packages/components/model/api/mock/pbstree.js +486 -495
  38. package/packages/components/model/components/TextOverTooltip/index.vue +3 -3
  39. package/packages/components/model/components/annotation-toolbar.vue +4 -19
  40. package/packages/components/model/components/check-proofing-model.vue +26 -29
  41. package/packages/components/model/components/clipping-type.vue +22 -14
  42. package/packages/components/model/components/com-dialogWrapper/index.vue +22 -25
  43. package/packages/components/model/components/detect-panel.vue +38 -26
  44. package/packages/components/model/components/detect-tree.vue +9 -24
  45. package/packages/components/model/components/firstPer-panel.vue +23 -25
  46. package/packages/components/model/components/header-button.vue +31 -107
  47. package/packages/components/model/components/imageViewer/index.vue +34 -35
  48. package/packages/components/model/components/import-model.vue +127 -127
  49. package/packages/components/model/components/location-panel.vue +25 -29
  50. package/packages/components/model/components/measure-type.vue +15 -15
  51. package/packages/components/model/components/pbs-tree.vue +139 -144
  52. package/packages/components/model/components/proof-config.vue +2 -10
  53. package/packages/components/model/components/proof-for-pc.vue +35 -32
  54. package/packages/components/model/components/proof-history.vue +136 -154
  55. package/packages/components/model/components/proof-panel-detail.vue +166 -165
  56. package/packages/components/model/components/proof-panel.vue +281 -205
  57. package/packages/components/model/components/proof-project-user.vue +13 -50
  58. package/packages/components/model/components/proof-publish.vue +130 -130
  59. package/packages/components/model/components/proof-role.vue +93 -124
  60. package/packages/components/model/components/props-panel.vue +63 -54
  61. package/packages/components/model/index.vue +3225 -3213
  62. package/packages/components/model/utils/annotation-tool.js +75 -82
  63. package/packages/components/model/utils/cursor.js +15 -10
  64. package/packages/components/model/utils/detect-v1.js +23 -35
  65. package/packages/components/model/utils/index.js +25 -25
  66. package/packages/components/model/utils/threejs/measure-angle.js +180 -180
  67. package/packages/components/model/utils/threejs/measure-area.js +196 -184
  68. package/packages/components/model/utils/threejs/measure-distance.js +154 -152
  69. package/packages/components/model/utils/threejs/measure-volume.js +64 -61
  70. package/src/assets/test.png +0 -0
  71. package/src/assets/worker.glb +0 -0
  72. package/src/main.js +11 -8
  73. package/src/utils/flgltf-parser.js +141 -0
  74. package/src/utils/instance-parser.js +402 -0
  75. package/src/utils/mock.js +84746 -0
  76. package/src/utils/threejs/measure-angle.js +240 -0
  77. package/src/utils/threejs/measure-area.js +249 -0
  78. package/src/utils/threejs/measure-distance.js +195 -0
@@ -0,0 +1,240 @@
1
+ import * as THREE from 'three'
2
+ import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'
3
+ var _this = null
4
+ var MeasureAngle = function(renderer, scene, camera, width, height) {
5
+ this.renderer = renderer
6
+ this.scene = scene
7
+ this.camera = camera
8
+ this.pointArray = [] // 保存当前操作所添加的点
9
+ this.raycaster = new THREE.Raycaster()
10
+ this.points = [] // 保存页面中所添加的点
11
+ this.polyline = [] //保存页面中所添加的直线
12
+ this.labels = [] // 保存页面中所添加的文本
13
+ this.curves = [] // 保存页面所有的曲线
14
+ this.tempPoints = undefined
15
+ this.tempLine = undefined
16
+ this.tempLabel = undefined
17
+ this.tipsLabel = undefined
18
+ this.isCompleted = false
19
+ this.curveLine = undefined
20
+ this.timer = null
21
+ this.width = width
22
+ this.height = height
23
+ // this.POINT_MATERIAL = new THREE.PointsMaterial({ color: 0xff5000, size: 1, opacity: 0.6, transparent: true, depthWrite: false, depthTest: false })
24
+ // this.LINE_MATERIAL = new THREE.LineBasicMaterial({ color: 0xff0000, linewidth: 3, opacity: 0.8, transparent: true, side: THREE.DoubleSide, depthWrite: false, depthTest: false })
25
+ }
26
+
27
+ MeasureAngle.prototype = {
28
+ start() {
29
+ _this = this
30
+ this.renderer.domElement.style.cursor = 'crosshair'
31
+ this.renderer.domElement.addEventListener('click', this.click, false)
32
+ this.renderer.domElement.addEventListener('mousemove', this.mousemove, false)
33
+ this.renderer.domElement.addEventListener('contextmenu', this.rightClick, false)
34
+ },
35
+ updateParams(width, height) {
36
+ this.camera.aspect = width / height
37
+ this.camera.updateProjectionMatrix()
38
+ this.renderer.setSize(width, height, true)
39
+ this.width = width
40
+ this.height = height
41
+ },
42
+ getPosition(e) {
43
+ const mouse = new THREE.Vector2()
44
+ mouse.x = (e.clientX / _this.width) * 2 - 1
45
+ mouse.y = -(e.clientY / _this.height) * 2 + 1
46
+ _this.raycaster.setFromCamera(mouse, this.camera)
47
+ let intersects = _this.raycaster.intersectObjects(_this.scene.children, true)
48
+ if(intersects.length > 0) {
49
+ return intersects[0].point
50
+ }
51
+ return null
52
+ },
53
+ createPoints(pos, config = {color: 0x009bea, size: 0.3}) {
54
+ const mesh = new THREE.MeshBasicMaterial({color: config.color || 0x009bea})
55
+ const geom = new THREE.SphereGeometry(config.size || 0.3, 28, 28)
56
+ const sphere = new THREE.Mesh(geom, mesh)
57
+ sphere.frustumCulled = false
58
+ sphere.position.set(pos.x, pos.y, pos.z)
59
+ return sphere
60
+ },
61
+ createLine(p1, p2, config={color: 0xff0000}) {
62
+ const lineMaterial = new THREE.LineBasicMaterial({ color: config.color, linewidth: 10 })
63
+ const lineGeometry = new THREE.BufferGeometry().setFromPoints([p1, p2])
64
+ const line = new THREE.Line(lineGeometry, lineMaterial)
65
+ line.frustumCulled = false
66
+ return line
67
+ },
68
+ createLabel(name, text, position) {
69
+ const div = document.createElement('div')
70
+ div.className = name
71
+ div.textContent = text
72
+ const divLabel = new CSS2DObject(div)
73
+ divLabel.position.set(position.x, position.y, position.z)
74
+ return divLabel
75
+ },
76
+ mousemove(e) {
77
+ if (_this.isCompleted || _this.pointArray.length === 0) return
78
+ const point = _this.getPosition(e)
79
+ if (point) {
80
+ _this.pointArray.length === 1 ? _this.pointArray.push(point) : _this.pointArray.splice(_this.pointArray.length - 1, 1, point)
81
+ const length = _this.pointArray.length
82
+ const p1 = _this.pointArray[length - 2]
83
+ const p2 = _this.pointArray[length - 1]
84
+ if (_this.tempPoints) {
85
+ _this.tempPoints.position.set(point.x, point.y, point.z)
86
+ } else {
87
+ const geom = _this.createLabel('circle-tag', '', point)
88
+ _this.tempPoints = geom
89
+ _this.points.push(geom)
90
+ _this.scene.add(geom)
91
+ }
92
+ if (_this.tempLine) {
93
+ _this.tempLine.geometry.setFromPoints([p1, p2])
94
+ } else {
95
+ _this.tempLine = _this.createLine(p1, p2)
96
+ _this.polyline.push(_this.tempLine)
97
+ _this.scene.add(_this.tempLine)
98
+ }
99
+ // 三点构成一个角
100
+ if (_this.pointArray.length === 3) {
101
+ const angle = _this.calculateAngle().toFixed(2) + '°'
102
+ const p0 = _this.pointArray[0]
103
+ const p1 = _this.pointArray[1]
104
+ const p2 = _this.pointArray[2]
105
+ const v1 = new THREE.Vector3((p0.x + p1.x) / 2, (p0.y + p1.y) / 2, (p0.z + p1.z) / 2)
106
+ const v2 = new THREE.Vector3((p1.x + p2.x) / 2, (p1.y + p2.y) / 2, (p1.z + p2.z) / 2)
107
+ const curve = new THREE.CatmullRomCurve3(
108
+ [v1, v2]
109
+ )
110
+ const points = curve.getPoints(50)
111
+ if (_this.tempLabel) {
112
+ _this.tempLabel.element.textContent = angle
113
+ _this.tempLabel.position.set(p1.x, p1.y, p1.z)
114
+ _this.curveLine.geometry.setFromPoints(points)
115
+ } else {
116
+ _this.tempLabel = _this.createLabel('measure-label', angle, p1)
117
+ _this.labels.push(_this.tempLabel)
118
+ _this.scene.add(_this.tempLabel)
119
+ _this.createCurve(points)
120
+ }
121
+ }
122
+ if (_this.tipsLabel) {
123
+ _this.tipsLabel.position.set(point.x + 0.1, point.y, point.z + 0.05)
124
+ }
125
+ }
126
+ },
127
+ createTipsLabel(label, position) {
128
+ const div = document.createElement('div')
129
+ div.className = 'tips-label'
130
+ div.textContent = label
131
+ const tipsLabel = new CSS2DObject(div)
132
+ tipsLabel.position.set(position.x + 0.1, position.y, position.z + 0.05)
133
+ return tipsLabel
134
+ },
135
+ click(e) {
136
+ if (_this.isCompleted) {
137
+ _this.renderer.domElement.addEventListener('mousemove', _this.mousemove)
138
+ }
139
+ clearTimeout(_this.timer)
140
+ _this.timer = setTimeout(() => {
141
+ _this.isCompleted = false
142
+ const point = _this.getPosition(e)
143
+ if (point) {
144
+ if(_this.tipsLabel) {
145
+ _this.tipsLabel.position.set(point.x + 0.1, point.y, point.z + 0.05)
146
+ } else {
147
+ _this.tipsLabel = _this.createTipsLabel('左击绘制右击结束', point)
148
+ _this.scene.add(_this.tipsLabel)
149
+ }
150
+ if (_this.tempPoints) {
151
+ _this.tempPoints.position.set(point.x, point.y, point.z)
152
+ _this.tempPoints = undefined
153
+ } else {
154
+ const geom =_this.createLabel('circle-tag', '', point)
155
+ _this.points.push(geom)
156
+ _this.scene.add(geom)
157
+ }
158
+ _this.tempLine = undefined
159
+ _this.tempLabel = undefined
160
+ _this.pointArray.push(point)
161
+ }
162
+ })
163
+ },
164
+ rightClick(e) {
165
+ if(_this.tipsLabel) {
166
+ _this.scene.remove(_this.tipsLabel)
167
+ _this.tipsLabel = undefined
168
+ }
169
+ clearTimeout(_this.timer)
170
+ const point = _this.getPosition(e)
171
+ if (point) {
172
+ _this.isCompleted = true
173
+ _this.tempPoints = undefined
174
+ _this.tempLine = undefined
175
+ _this.tempLabel = undefined
176
+ _this.pointArray.splice(0)
177
+ _this.renderer.domElement.removeEventListener('mousemove', _this.mousemove)
178
+ }
179
+ },
180
+ close() {
181
+ this.renderer.domElement.removeEventListener('mousemove', this.mousemove)
182
+ this.renderer.domElement.removeEventListener('click', this.click)
183
+ this.renderer.domElement.removeEventListener('contextmenu', this.rightClick)
184
+ this.remove(this.points)
185
+ this.remove(this.polyline)
186
+ this.remove(this.labels)
187
+ this.remove(this.curves)
188
+ this.pointArray.splice(0)
189
+ this.points.splice(0)
190
+ this.polyline.splice(0)
191
+ this.labels.splice(0)
192
+ this.curves.splice(0)
193
+ this.tempPoints = undefined
194
+ this.tempLabel = undefined
195
+ this.tempLine = undefined
196
+ this.scene.remove(this.tipsLabel)
197
+ this.tipsLabel = undefined
198
+ this.renderer.domElement.style.cursor = 'pointer'
199
+ },
200
+ remove(array) {
201
+ for (let index = 0; index < array.length; index++) {
202
+ const element = array[index]
203
+ if (element.geometry) {
204
+ element.geometry.dispose()
205
+ }
206
+ this.scene.remove(element)
207
+ }
208
+ },
209
+ calculateAngle() {
210
+ const p1 = _this.pointArray[1].clone()
211
+ const p2 = _this.pointArray[1].clone()
212
+ const dir0 = p1.sub(_this.pointArray[0]).clone()
213
+ const dir1 = p2.sub(_this.pointArray[2]).clone()
214
+ const angle = dir0.angleTo(dir1)
215
+ return angle * 180 / Math.PI
216
+ },
217
+ createCurve(points) {
218
+ const geom = new THREE.BufferGeometry().setFromPoints(points)
219
+ const material = new THREE.LineBasicMaterial({color: 0xff0000})
220
+ _this.curveLine = new THREE.Line(geom, material)
221
+ _this.curveLine.frustumCulled = false
222
+ _this.curves.push(_this.curveLine)
223
+ _this.scene.add(_this.curveLine)
224
+ },
225
+ numberToString(num) {
226
+ if (num < 0.0001) {
227
+ return num.toString()
228
+ }
229
+ let fractionDigits = 2
230
+ if (num < 0.01) {
231
+ fractionDigits = 4
232
+ } else if (num < 0.1) {
233
+ fractionDigits = 3
234
+ }
235
+ return num.toFixed(fractionDigits)
236
+ }
237
+ }
238
+ export default {
239
+ MeasureAngle
240
+ }
@@ -0,0 +1,249 @@
1
+ import * as THREE from 'three'
2
+ import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'
3
+ var _this = null
4
+ var MeasureArea = function(renderer, scene, camera, width, height) {
5
+ this.renderer = renderer
6
+ this.scene = scene
7
+ this.camera = camera
8
+ this.pointArray = [] // 保存当前操作所添加的点
9
+ this.raycaster = new THREE.Raycaster()
10
+ this.points = [] // 保存页面中所添加的点
11
+ this.polyline = [] //保存页面中所添加的直线
12
+ this.labels = [] // 保存页面中所添加的文本
13
+ this.tempPoints = undefined
14
+ this.tempLine = undefined
15
+ this.tempLabel = undefined
16
+ this.tipsLabel = undefined
17
+ this.isCompleted = false
18
+ this.timer = null
19
+ this.polygonMesh = undefined
20
+ this.polygons = []
21
+ this.width = width
22
+ this.height = height
23
+ }
24
+
25
+ MeasureArea.prototype = {
26
+ start() {
27
+ _this = this
28
+ this.renderer.domElement.style.cursor = 'crosshair'
29
+ this.renderer.domElement.addEventListener('click', this.click, false)
30
+ this.renderer.domElement.addEventListener('mousemove', this.mousemove, false)
31
+ this.renderer.domElement.addEventListener('contextmenu', this.rightClick, false)
32
+ },
33
+ updateParams(width, height) {
34
+ this.camera.aspect = width / height
35
+ this.camera.updateProjectionMatrix()
36
+ this.renderer.setSize(width, height, true)
37
+ this.width = width
38
+ this.height = height
39
+ },
40
+ getPosition(e) {
41
+ const mouse = new THREE.Vector2()
42
+ mouse.x = (e.clientX / _this.width) * 2 - 1
43
+ mouse.y = -(e.clientY / _this.height) * 2 + 1
44
+ _this.raycaster.setFromCamera(mouse, _this.camera)
45
+ let intersects =_this.raycaster.intersectObjects(_this.scene.children, true)
46
+ if(intersects.length > 0) {
47
+ return intersects[0].point
48
+ }
49
+ return null
50
+ },
51
+ createLine(p1, p2, config = {color:0xff0000}) {
52
+ const lineMaterial = new THREE.LineBasicMaterial({ color: config.color, linewidth: 20 })
53
+ const lineGeometry = new THREE.BufferGeometry().setFromPoints([p1, p2])
54
+ const line = new THREE.Line(lineGeometry, lineMaterial)
55
+ line.frustumCulled = false
56
+ return line
57
+ },
58
+ createLabel(name, text, position) {
59
+ const div = document.createElement('div')
60
+ div.className = name
61
+ div.textContent = text
62
+ const divLabel = new CSS2DObject(div)
63
+ divLabel.position.set(position.x, position.y, position.z)
64
+ return divLabel
65
+ },
66
+ mousemove(e) {
67
+ if (_this.isCompleted || _this.pointArray.length === 0) return
68
+ const point =_this.getPosition(e)
69
+ if (point) {
70
+ _this.pointArray.length === 1 ? _this.pointArray.push(point) : _this.pointArray.splice(_this.pointArray.length - 1, 1, point)
71
+ const length = _this.pointArray.length
72
+ if (_this.tempPoints) {
73
+ _this.tempPoints.position.set(point.x, point.y, point.z)
74
+ } else {
75
+ const geom = _this.createLabel('circle-tag', '', point)
76
+ _this.tempPoints = geom
77
+ _this.points.push(geom)
78
+ _this.scene.add(geom)
79
+ }
80
+ const p1 = _this.pointArray[length - 2]
81
+ const p2 = _this.pointArray[length - 1]
82
+ if (_this.tempLine) {
83
+ _this.tempLine.geometry.setFromPoints([p1, p2])
84
+ } else {
85
+ _this.tempLine = _this.createLine(p1, p2)
86
+ _this.polyline.push(_this.tempLine)
87
+ _this.scene.add(_this.tempLine)
88
+ }
89
+ if (_this.pointArray.length > 2) {
90
+ const area = _this.calculateArea(_this.pointArray)
91
+ _this.createPolygon(_this.pointArray)
92
+ if (_this.tempLabel) {
93
+ _this.polygonMesh.geometry.computeBoundingSphere()
94
+ _this.tempLabel.element.textContent = _this.numberToString(area) // + '㎡'
95
+ _this.tempLabel.position.set(_this.polygonMesh.geometry.boundingSphere.center.x, _this.polygonMesh.geometry.boundingSphere.center.y, _this.polygonMesh.geometry.boundingSphere.center.z)
96
+ } else {
97
+ _this.polygonMesh.geometry.computeBoundingSphere()
98
+ console.log(_this.polygonMesh.geometry)
99
+ _this.tempLabel = _this.createLabel('measure-label', area, _this.polygonMesh.geometry.boundingSphere.center)
100
+ _this.labels.push(_this.tempLabel)
101
+ _this.scene.add(_this.tempLabel)
102
+ }
103
+ }
104
+ if (_this.tipsLabel) {
105
+ _this.tipsLabel.position.set(point.x + 0.1, point.y, point.z + 0.05)
106
+ }
107
+ }
108
+ },
109
+ createTipsLabel(label, position) {
110
+ const div = document.createElement('div')
111
+ div.className = 'tips-label'
112
+ div.textContent = label
113
+ const tipsLabel = new CSS2DObject(div)
114
+ tipsLabel.position.set(position.x + 0.1, position.y, position.z + 0.05)
115
+ return tipsLabel
116
+ },
117
+ click(e) {
118
+ if (_this.isCompleted) {
119
+ _this.renderer.domElement.addEventListener('mousemove', _this.mousemove)
120
+ }
121
+ clearTimeout(_this.timer)
122
+ _this.timer = setTimeout(() => {
123
+ _this.isCompleted = false
124
+ const point = _this.getPosition(e)
125
+ if (point) {
126
+ if(_this.tipsLabel) {
127
+ _this.tipsLabel.position.set(point.x + 0.01, point.y, point.z + 0.05)
128
+ } else {
129
+ _this.tipsLabel = _this.createTipsLabel('左击绘制右击结束', point)
130
+ _this.scene.add(_this.tipsLabel)
131
+ }
132
+ if (_this.tempPoints) {
133
+ _this.tempPoints.position.set(point.x, point.y, point.z)
134
+ _this.tempPoints = undefined
135
+ } else {
136
+ const geom = _this.createLabel('circle-tag', '', point)
137
+ _this.points.push(geom)
138
+ _this.scene.add(geom)
139
+ }
140
+ _this.tempLine = undefined
141
+ _this.pointArray.push(point)
142
+ }
143
+ }, 100)
144
+
145
+ },
146
+ rightClick (e) {
147
+ if(_this.tipsLabel) {
148
+ _this.scene.remove(_this.tipsLabel)
149
+ _this.tipsLabel = undefined
150
+ }
151
+ clearTimeout(_this.timer)
152
+ const point = _this.getPosition(e)
153
+ if (point) {
154
+ _this.isCompleted = true
155
+ if (_this.tempPoints) {
156
+ _this.tempPoints.position.set(point.x, point.y, point.z)
157
+ _this.tempPoints = undefined
158
+ }
159
+ _this.tempLine = undefined
160
+ _this.tempLabel = undefined
161
+ _this.polygonMesh = undefined
162
+ _this.pointArray.splice(0)
163
+ _this.renderer.domElement.removeEventListener('mousemove', _this.mousemove)
164
+ }
165
+ },
166
+ close() {
167
+ this.renderer.domElement.removeEventListener('mousemove', this.mousemove)
168
+ this.renderer.domElement.removeEventListener('click',this.click)
169
+ this.renderer.domElement.removeEventListener('contextmenu',this.rightClick)
170
+ this.remove(this.points)
171
+ this.remove(this.polyline)
172
+ this.remove(this.labels)
173
+ this.remove(this.polygons)
174
+ this.pointArray.splice(0)
175
+ this.points.splice(0)
176
+ this.polyline.splice(0)
177
+ this.labels.splice(0)
178
+ this.tempPoints = undefined
179
+ this.tempLabel = undefined
180
+ this.tempLine = undefined
181
+ this.scene.remove(this.tipsLabel)
182
+ this.tipsLabel = undefined
183
+ this.renderer.domElement.style.cursor = 'pointer'
184
+ },
185
+ remove(array) {
186
+ for (let index = 0; index < array.length; index++) {
187
+ const element = array[index]
188
+ if (element.geometry) {
189
+ element.geometry.dispose()
190
+ }
191
+ this.scene.remove(element)
192
+ }
193
+ },
194
+ calculateArea(points) {
195
+ let area = 0
196
+ for (let i = 0, j = 1, k = 2; k < points.length; j++, k++) {
197
+ const a = points[i].distanceTo(points[j])
198
+ const b = points[j].distanceTo(points[k])
199
+ const c = points[k].distanceTo(points[i])
200
+ const p = (a + b + c) / 2
201
+ area += Math.sqrt(p * (p - a) * (p - b) * (p - c))
202
+ }
203
+ return area
204
+ },
205
+ numberToString(num) {
206
+ if (num < 0.0001) {
207
+ return num.toString()
208
+ }
209
+ let fractionDigits = 2
210
+ if (num < 0.01) {
211
+ fractionDigits = 4
212
+ } else if (num < 0.1) {
213
+ fractionDigits = 3
214
+ }
215
+ return num.toFixed(fractionDigits)
216
+ },
217
+ createPolygon(points) {
218
+ const length = points.length
219
+ const faces = []
220
+ for (let i = 0; i < length - 2; i++) {
221
+ faces.push(points[0].x, points[0].y, points[0].z)
222
+ faces.push(points[i+1].x, points[i+1].y, points[i+1].z)
223
+ faces.push(points[i+2].x, points[i+2].y, points[i+2].z)
224
+ }
225
+ if (faces.length > 3) {
226
+ if (_this.polygonMesh) {
227
+ _this.polygonMesh.geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(faces), 3 ))
228
+ } else {
229
+ const geom = new THREE.BufferGeometry()
230
+ geom.setAttribute('position', new THREE.BufferAttribute(new Float32Array(faces), 3 ))
231
+ const material = new THREE.MeshBasicMaterial({
232
+ color: 0xffffff,
233
+ transparent: true,
234
+ opacity: 0.5,
235
+ side: THREE.DoubleSide
236
+ })
237
+ const mesh = new THREE.Mesh(geom, material)
238
+ mesh.frustumCulled = false
239
+ mesh.name = 'polygonMesh'
240
+ _this.polygonMesh = mesh
241
+ _this.scene.add(mesh)
242
+ _this.polygons.push(mesh)
243
+ }
244
+ }
245
+ }
246
+ }
247
+ export default {
248
+ MeasureArea
249
+ }
@@ -0,0 +1,195 @@
1
+ import * as THREE from 'three'
2
+ import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'
3
+ var _this = null
4
+ var MeasureDistance = function(renderer, scene, camera, width, height) {
5
+ this.renderer = renderer
6
+ this.scene = scene
7
+ this.camera = camera
8
+ this.pointArray = [] // 保存当前操作所添加的点
9
+ this.raycaster = new THREE.Raycaster()
10
+ this.points = [] // 保存页面中所添加的点
11
+ this.polyline = [] //保存页面中所添加的直线
12
+ this.labels = [] // 保存页面中所添加的文本
13
+ this.tempPoints = undefined
14
+ this.tempLine = undefined
15
+ this.tempLabel = undefined
16
+ this.tipsLabel = undefined
17
+ this.isCompleted = false
18
+ this.timer = null
19
+ this.width = width
20
+ this.height = height
21
+ }
22
+
23
+ MeasureDistance.prototype = {
24
+ start() {
25
+ _this = this
26
+ this.renderer.domElement.style.cursor = 'crosshair'
27
+ this.renderer.domElement.addEventListener('click', this.click, false)
28
+ this.renderer.domElement.addEventListener('mousemove', this.mousemove, false)
29
+ this.renderer.domElement.addEventListener('contextmenu', this.rightClick, false)
30
+ },
31
+ updateParams(width, height) {
32
+ this.camera.aspect = width / height
33
+ this.camera.updateProjectionMatrix()
34
+ this.renderer.setSize(width, height, true)
35
+ this.width = width
36
+ this.height = height
37
+ },
38
+ getPosition(e) {
39
+ const mouse = new THREE.Vector2()
40
+ mouse.x = (e.clientX / _this.width) * 2 - 1
41
+ mouse.y = -(e.clientY / _this.height) * 2 + 1
42
+ _this.raycaster.setFromCamera(mouse, this.camera)
43
+ let intersects = _this.raycaster.intersectObjects(_this.scene.children, true)
44
+ if(intersects.length > 0) {
45
+ return intersects[0].point
46
+ }
47
+ return null
48
+ },
49
+ createLine(p1, p2, config = {color: 0xff0000}) {
50
+ const lineMaterial = new THREE.LineBasicMaterial({ color: config.color, linewidth: 15 })
51
+ const lineGeometry = new THREE.BufferGeometry().setFromPoints([p1, p2])
52
+ const line = new THREE.Line(lineGeometry, lineMaterial)
53
+ line.frustumCulled = false
54
+ return line
55
+ },
56
+ createLabel(name, text, position) {
57
+ const div = document.createElement('div')
58
+ div.className = name
59
+ div.textContent = text
60
+ const divLabel = new CSS2DObject(div)
61
+ divLabel.position.set(position.x, position.y, position.z)
62
+ return divLabel
63
+ },
64
+ mousemove(e) {
65
+ if (_this.isCompleted || _this.pointArray.length === 0) return
66
+ const point = _this.getPosition(e)
67
+ if (point) {
68
+ _this.pointArray.length === 1 ? _this.pointArray.push(point) : _this.pointArray.splice(_this.pointArray.length - 1, 1, point)
69
+ const length = _this.pointArray.length
70
+ if (_this.tempPoints) {
71
+ _this.tempPoints.position.set(point.x, point.y, point.z)
72
+ } else {
73
+ const geom = _this.createLabel('circle-tag', '', point)
74
+ _this.tempPoints = geom
75
+ _this.points.push(geom)
76
+ _this.scene.add(geom)
77
+ }
78
+ const p1 = _this.pointArray[length - 2]
79
+ const p2 = _this.pointArray[length - 1]
80
+ const dist = p1.distanceTo(p2)
81
+ const label = `${_this.numberToString(dist)}`
82
+ const position = new THREE.Vector3((p1.x + p2.x) / 2, (p1.y + p2.y) / 2, (p1.z + p2.z) / 2)
83
+ if (_this.tempLine) {
84
+ _this.tempLine.geometry.setFromPoints([p1, p2])
85
+ _this.tempLabel.element.textContent = label
86
+ _this.tempLabel.position.set(position.x, position.y, position.z)
87
+ } else {
88
+ _this.tempLine = _this.createLine(p1, p2)
89
+ _this.tempLabel = _this.createLabel('measure-label', label, position)
90
+ _this.polyline.push(_this.tempLine)
91
+ _this.labels.push(_this.tempLabel)
92
+ _this.scene.add(_this.tempLine)
93
+ _this.scene.add(_this.tempLabel)
94
+ }
95
+ if (_this.tipsLabel) {
96
+ _this.tipsLabel.position.set(point.x + 0.1, point.y, point.z + 0.05)
97
+ }
98
+ }
99
+ },
100
+ createTipsLabel(label, position) {
101
+ const div = document.createElement('div')
102
+ div.className = 'tips-label'
103
+ div.textContent = label
104
+ const tipsLabel = new CSS2DObject(div)
105
+ tipsLabel.position.set(position.x + 0.1, position.y, position.z + 0.05)
106
+ return tipsLabel
107
+ },
108
+ click(e) {
109
+ if (_this.isCompleted) {
110
+ _this.renderer.domElement.addEventListener('mousemove', _this.mousemove)
111
+ }
112
+ clearTimeout(_this.timer)
113
+ _this.timer = setTimeout(() => {
114
+ _this.isCompleted = false
115
+ const point = _this.getPosition(e)
116
+ if (point) {
117
+ if(_this.tipsLabel) {
118
+ _this.tipsLabel.position.set(point.x + 0.1, point.y, point.z + 0.05)
119
+ } else {
120
+ _this.tipsLabel = _this.createTipsLabel('左击绘制右击结束', point)
121
+ _this.scene.add(_this.tipsLabel)
122
+ }
123
+ if (_this.tempPoints) {
124
+ _this.tempPoints.position.set(point.x, point.y, point.z)
125
+ _this.tempPoints = undefined
126
+ } else {
127
+ const geom = _this.createLabel('circle-tag', '', point)
128
+ _this.points.push(geom)
129
+ _this.scene.add(geom)
130
+ }
131
+ _this.tempLine = undefined
132
+ _this.tempLabel = undefined
133
+ _this.pointArray.push(point)
134
+ }
135
+ })
136
+ },
137
+ rightClick(e) {
138
+ if(_this.tipsLabel) {
139
+ _this.scene.remove(_this.tipsLabel)
140
+ _this.tipsLabel = undefined
141
+ }
142
+ clearTimeout(_this.timer)
143
+ const point = _this.getPosition(e)
144
+ if (point) {
145
+ _this.isCompleted = true
146
+ _this.tempPoints = undefined
147
+ _this.tempLine = undefined
148
+ _this.tempLabel = undefined
149
+ _this.pointArray.splice(0)
150
+ _this.renderer.domElement.removeEventListener('mousemove', _this.mousemove)
151
+ }
152
+ },
153
+ close() {
154
+ this.renderer.domElement.removeEventListener('mousemove', this.mousemove)
155
+ this.renderer.domElement.removeEventListener('click', this.click)
156
+ this.renderer.domElement.removeEventListener('contextmenu', this.rightClick)
157
+ this.remove(this.points)
158
+ this.remove(this.polyline)
159
+ this.remove(this.labels)
160
+ this.pointArray.splice(0)
161
+ this.points.splice(0)
162
+ this.polyline.splice(0)
163
+ this.labels.splice(0)
164
+ this.tempPoints = undefined
165
+ this.tempLabel = undefined
166
+ this.tempLine = undefined
167
+ this.scene.remove(this.tipsLabel)
168
+ this.tipsLabel = undefined
169
+ this.renderer.domElement.style.cursor = 'pointer'
170
+ },
171
+ remove(array) {
172
+ for (let index = 0; index < array.length; index++) {
173
+ const element = array[index]
174
+ if (element.geometry) {
175
+ element.geometry.dispose()
176
+ }
177
+ this.scene.remove(element)
178
+ }
179
+ },
180
+ numberToString(num) {
181
+ if (num < 0.0001) {
182
+ return num.toString()
183
+ }
184
+ let fractionDigits = 2
185
+ if (num < 0.01) {
186
+ fractionDigits = 4
187
+ } else if (num < 0.1) {
188
+ fractionDigits = 3
189
+ }
190
+ return num.toFixed(fractionDigits)
191
+ }
192
+ }
193
+ export default {
194
+ MeasureDistance
195
+ }