Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
zghywpc-vue
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
李苏
zghywpc-vue
Commits
e16ac3a2
Commit
e16ac3a2
authored
Sep 11, 2024
by
李苏
💬
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
首页调整
parent
b323f37d
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
653 additions
and
474 deletions
+653
-474
index.vue
src/views/yhlywsytst/yhlywsytst/index.vue
+653
-474
No files found.
src/views/yhlywsytst/yhlywsytst/index.vue
View file @
e16ac3a2
...
...
@@ -2,7 +2,7 @@
* @Description:
* @Author: lisu lisu@gavelinfo.com
* @LastEditors: lisu lisu@gavelinfo.com
* @LastEditTime: 2024-09-11 1
1:19:18
* @LastEditTime: 2024-09-11 1
6:54:41
* @FilePath: /zghywpc-vue/src/views/yhlywsytst/yhlywsytst/index.vue
-->
<
template
>
...
...
@@ -56,11 +56,11 @@
</div>
</div>
</div>
<div
class=
"toolButton3"
>
<
!--
<
div
class=
"toolButton3"
>
<div
class=
"flex1 text-center"
>
<el-checkbox
v-model=
"xzjj"
>
选中时近景
</el-checkbox>
</div>
</div>
</div>
-->
<div
v-show=
"selectedModel.name"
class=
"leftOpt"
style=
"padding-top: 30px;"
>
<div
class=
"sbxxTitle"
style=
"position: absolute;top: 5px;font-weight: 800;"
>
{{
'设备:'
+
selectedModel
.
name
}}
...
...
@@ -221,6 +221,60 @@
</div>
</div>
</div>
<!-- 标高信息-->
<div
class=
"flex1"
style=
"height: 33%;overflow: hidden;"
>
<!-- 设备检修-->
<div
class=
"full"
>
<div
class=
"mktitle"
>
<span>
零部件数据
</span>
<img
:src=
"ksh33"
alt=
""
>
</div>
<div
v-show=
"!selectedModel.name"
class=
"mkbody data-box1 flex-center nosbxxTitle"
>
请选中设备进行查询
</div>
<div
v-show=
"selectedModel.name"
class=
"mkbody data-box1"
>
<!--
<div
class=
"sbxxTitle"
>
{{
'设备:'
+
selectedModel
.
name
}}
</div>
-->
<div
class=
"com-count-body"
style=
" height:calc(100% - 0px);overflow: hidden;"
>
<!-- 标题-->
<div
class=
"lbbt"
style=
"font-size: 13px;"
>
<div
class=
"flex1 text-center "
>
编码
</div>
<div
class=
"flex1 text-center "
>
名称
</div>
<div
class=
"flex1 text-center "
>
机组
</div>
<div
class=
"flex1 text-center "
>
规格
</div>
<div
class=
"flex1 text-center "
>
管径
</div>
</div>
<ScrollSeamless
:class-option=
"optionSingleHeight"
:data=
"lbjlistData"
class=
"lbbody"
style=
"overflow: hidden;"
>
<div
class=
"full lbtit"
>
<div
style=
"line-height: 25px;display: flex;font-size: 12px;text-align: center"
v-for=
"item in lbjlistData"
>
<div
class=
"flex1"
style=
"color: #68D8FE ;"
v-text=
"item.code"
></div>
<div
class=
"flex1"
style=
"color: #68D8FE ;"
v-text=
"item.name"
></div>
ss
<div
class=
"flex1"
style=
"color: #68D8FE ;"
v-text=
"item.jzbm"
></div>
<div
class=
"flex1"
style=
"color: #68D8FE ;"
v-text=
"item.gg"
></div>
<div
class=
"flex1"
style=
"color: #68D8FE ;"
v-text=
"item.gj"
></div>
</div>
</div>
</ScrollSeamless>
</div>
</div>
</div>
</div>
</div>
<!-- 溯源排查-->
...
...
@@ -326,8 +380,24 @@
<span>
设备流向
</span>
<b
class=
"data-title-right"
>
]
</b>
</div>
<div
class=
"full flex "
style=
"height: calc(100% - 14px);padding-top: 12px;"
>
<div
class=
"full flex "
style=
"height: calc(50% - 0px);padding-top: 12px;"
>
<el-row
:gutter=
"20"
class=
"search-row-1"
style=
"width: 100%;"
>
<el-col
:span=
"12"
class=
"search-col"
>
<div
class=
"search-item"
>
<span
class=
"search-span"
>
设备编码:
</span>
<el-input
placeholder=
""
v-model=
"sblxCode"
></el-input>
</div>
</el-col>
<el-col
:span=
"12"
class=
"search-col flex-center"
>
<el-button
style=
"background-color: rgba(7,32,96,0.0);border: 1px solid #68D8FE; color: #68D8FE;"
size=
"mini"
@
click=
"sblxcx()"
type=
"primary"
>
设备查询
</el-button>
<!-- 暂无信息-->
<span
v-if=
"sblxcxwcxdxx"
style=
"color: red;font-size: 12px;padding-left: 10px;"
>
{{
sblxcxwcxdxxText
}}
</span>
</el-col>
</el-row>
</div>
<div
class=
"full flex "
style=
"height: calc(50% - 0px);padding-top: 12px;"
>
<el-row
:gutter=
"20"
class=
"search-row-1"
style=
"width: 100%;"
>
<el-col
:span=
"12"
class=
"search-col"
>
<div
class=
"search-item"
>
...
...
@@ -350,6 +420,7 @@
</el-row>
</div>
</div>
</div>
<!-- 右侧操作边框-->
...
...
@@ -364,7 +435,6 @@
</
template
>
<
script
>
import
ywDialog
from
'./ywDialog.vue'
import
*
as
THREE
from
'three'
import
gsap
from
'gsap'
...
...
@@ -377,6 +447,7 @@
this
.
init
()
this
.
loadAll
()
this
.
tdClick
()
this
.
tdblClick
()
this
.
getData
()
})
...
...
@@ -398,13 +469,17 @@
},
data
()
{
return
{
sblxCode
:
''
,
sblxcxwcxdxx
:
false
,
sblxcxwcxdxxText
:
''
,
/* 弹框控制参数*/
showDialog
:
false
,
DialogTitle
:
'异物信息'
,
DialogWidth
:
'65vw'
,
ywlistData
:
[],
jxlistData
:
[],
bglistData
:[],
bglistData
:
[],
lbjlistData
:
[],
ksh33
:
ksh33
,
queryParams
:
{
jzbm
:
''
,
...
...
@@ -456,6 +531,7 @@
this
.
apiGetJxxx
()
this
.
apiGetYwxx
()
this
.
apiGetBgxx
()
this
.
apiGetLbjxx
()
}
else
{
this
.
fileList
=
[];
return
[];
...
...
@@ -473,6 +549,13 @@
sypc
()
{
this
.
showDialog
=
true
},
apiGetLbjxx
()
{
this
.
$post
(
'sbgl/usbxx/query'
,
{
sbxxCode
:
this
.
selectedModel
.
name
,
}).
then
(
res
=>
{
this
.
lbjlistData
=
res
.
data
.
records
||
[]
})
},
apiGetYwxx
()
{
this
.
$post
(
'ywxxgl/uywxx/query'
,
{
sbxxCode
:
this
.
selectedModel
.
name
,
...
...
@@ -494,12 +577,12 @@
this
.
jxlistData
=
res
.
data
.
records
||
[]
})
},
/**
* @description:选中标签后操作
* @param {String} code
* @return {*}
* @author: lisu
*/
/**
* @description:选中标签后操作
* @param {String} code
* @return {*}
* @author: lisu
*/
clickTag
(
code
)
{
if
(
!
code
)
{
return
...
...
@@ -559,527 +642,623 @@
}
}
},
sbcx
()
{
if
(
!
this
.
sbxxQueryParams
.
code
)
{
this
.
sbcxwcxdxx
=
true
this
.
sbcxwcxdxxText
=
'请输入设备编码!'
setTimeout
(()
=>
{
this
.
sbcxwcxdxx
=
false
},
2000
)
}
else
{
this
.
sbxxQueryParams
.
code
=
this
.
sbxxQueryParams
.
code
.
replace
(
/
\s
+/g
,
''
);
/**
* @description:查询流向信息,没有查询所有
* @return {*}
* @author: lisu
*/
sblxcx
()
{
if
(
true
)
{
this
.
sblxCode
=
this
.
sblxCode
.
replace
(
/
\s
+/g
,
''
);
/* 查询*/
let
iscx
=
false
this
.
viewer
.
scene
.
traverse
((
model
)
=>
{
if
(
model
.
isMesh
)
{
if
(
model
.
name
==
this
.
sbxxQueryParams
.
code
)
{
this
.
$post
(
'sbgl/usblxgx/zbInfo'
,
{
sbxxCode
:
this
.
sblxCode
}).
then
(
res
=>
{
if
(
res
.
success
)
{
let
data
=
res
.
data
.
records
||
[]
if
(
res
.
data
.
records
.
length
==
0
)
{
this
.
sblxcxwcxdxx
=
true
this
.
sblxcxwcxdxxText
=
'未查询到流向!'
setTimeout
(()
=>
{
this
.
sblxcxwcxdxx
=
false
},
2000
)
}
else
{
this
.
selectedModel
=
model
iscx
=
true
/* 执行并情况材料队列 */
this
.
reMaterialQue
.
forEach
(
item
=>
{
item
.
revert
()
})
this
.
reMaterialQue
.
splice
(
0
,
this
.
reMaterialQue
.
length
)
}
this
.
allPieData
=
data
.
filter
((
item
)
=>
{
return
item
.
children
.
some
((
child
)
=>
child
.
data
.
length
>=
2
);
});
if
(
res
.
data
.
records
.
length
!=
0
){
this
.
$success
(
`共查询到
${
res
.
data
.
records
.
length
}
条数据!共绘制
${
this
.
allPieData
.
length
}
条流向!`
)
}
/* 添加材质模型队列*/
let
reMaterialQueItem
=
{
model
,
material
:
model
.
material
.
clone
(),
revert
:
function
()
{
this
.
model
.
material
=
this
.
material
}
}
this
.
reMaterialQue
.
push
(
reMaterialQueItem
)
}
})
}
},
sbcx
()
{
if
(
!
this
.
sbxxQueryParams
.
code
)
{
this
.
sbcxwcxdxx
=
true
this
.
sbcxwcxdxxText
=
'请输入设备编码!'
setTimeout
(()
=>
{
this
.
sbcxwcxdxx
=
false
},
2000
)
}
else
{
this
.
sbxxQueryParams
.
code
=
this
.
sbxxQueryParams
.
code
.
replace
(
/
\s
+/g
,
''
);
/* 查询*/
let
iscx
=
false
this
.
viewer
.
scene
.
traverse
((
model
)
=>
{
if
(
model
.
isMesh
)
{
if
(
model
.
name
==
this
.
sbxxQueryParams
.
code
)
{
this
.
selectedModel
=
model
iscx
=
true
/* 执行并情况材料队列 */
this
.
reMaterialQue
.
forEach
(
item
=>
{
item
.
revert
()
})
this
.
reMaterialQue
.
splice
(
0
,
this
.
reMaterialQue
.
length
)
/* 添加材质模型队列*/
let
reMaterialQueItem
=
{
model
,
material
:
model
.
material
.
clone
(),
revert
:
function
()
{
this
.
model
.
material
=
this
.
material
}
}
this
.
reMaterialQue
.
push
(
reMaterialQueItem
)
model
.
material
=
new
THREE
.
MeshPhongMaterial
({
color
:
new
THREE
.
Color
(
'rgba(255, 255, 0, 0.8)'
),
transparent
:
true
,
opacity
:
0.8
,
wireframe
:
false
,
})
/* */
if
(
this
.
xzjj
)
{
const
object
=
model
;
if
(
object
)
{
this
.
viewer
.
cameraControl
.
fitTo
(
object
);
}
model
.
material
=
new
THREE
.
MeshPhongMaterial
({
color
:
new
THREE
.
Color
(
'rgba(255, 255, 0, 0.8)'
),
transparent
:
true
,
opacity
:
0.8
,
wireframe
:
false
,
})
/* */
if
(
this
.
xzjj
)
{
const
object
=
model
;
if
(
object
)
{
this
.
viewer
.
cameraControl
.
fitTo
(
object
);
}
}
}
}
});
if
(
iscx
==
false
)
{
this
.
sbcxwcxdxx
=
true
this
.
sbcxwcxdxxText
=
'未查询到设备!'
setTimeout
(()
=>
{
this
.
sbcxwcxdxx
=
false
},
2000
)
}
}
});
if
(
iscx
==
false
)
{
this
.
sbcxwcxdxx
=
true
this
.
sbcxwcxdxxText
=
'未查询到设备!'
setTimeout
(()
=>
{
this
.
sbcxwcxdxx
=
false
},
2000
)
}
}
},
apiJzbm
()
{
let
params
=
_
.
cloneDeep
(
this
.
queryParams
)
delete
params
.
sbxxCode
/* 先清空 选中的机组*/
},
apiJzbm
()
{
let
params
=
_
.
cloneDeep
(
this
.
queryParams
)
delete
params
.
sbxxCode
/* 先清空 选中的机组*/
this
.
jzReMaterialQue
.
forEach
(
item
=>
{
item
.
revert
()
})
this
.
jzReMaterialQue
.
splice
(
0
,
this
.
jzReMaterialQue
.
length
)
this
.
$post
(
'ksh/query'
,
params
).
then
(
res
=>
{
if
(
res
.
success
)
{
let
sbxxList
=
res
.
data
.
records
||
[]
this
.
$success
(
`已标记
${
sbxxList
.
length
}
个设备`
)
const
sbxxCodeList
=
sbxxList
.
map
(
item
=>
item
.
sbxxCode
)
/* 解决 先缓存选中色,后渲染黄色,默认选中时颜色不对
bug: 1默认还原为原色
2.高亮为黄色触发默认选中(黄色存储在另一个队列)
3.默认选中会还原上一个颜色
4.还原为原色,触发选中。变为选中色,清除为原色,覆盖了亮色
*/
if
(
sbxxCodeList
.
length
!=
0
)
{
this
.
reMaterialQue
.
forEach
(
item
=>
{
item
.
revert
()
})
}
this
.
reMaterialQue
.
splice
(
0
,
this
.
reMaterialQue
.
length
)
/* 分割,在渲染高亮清空选中的*/
this
.
viewer
.
scene
.
traverse
((
model
)
=>
{
if
(
model
.
isMesh
)
{
if
(
sbxxCodeList
.
includes
(
model
.
name
))
{
let
jzReMaterialQueItem
=
{
model
,
material
:
model
.
oldmaterial
.
clone
(),
revert
:
function
()
{
this
.
model
.
material
=
this
.
material
}
}
this
.
jzReMaterialQue
.
push
(
jzReMaterialQueItem
)
model
.
material
=
new
THREE
.
MeshPhongMaterial
({
color
:
new
THREE
.
Color
(
'rgba(255, 164, 7, 0.8)'
),
transparent
:
true
,
opacity
:
0.8
,
wireframe
:
false
,
})
this
.
jzReMaterialQue
.
forEach
(
item
=>
{
item
.
revert
()
})
this
.
jzReMaterialQue
.
splice
(
0
,
this
.
jzReMaterialQue
.
length
)
this
.
$post
(
'ksh/query'
,
params
).
then
(
res
=>
{
if
(
res
.
success
)
{
let
sbxxList
=
res
.
data
.
records
||
[]
this
.
$success
(
`已标记
${
sbxxList
.
length
}
个设备`
)
const
sbxxCodeList
=
sbxxList
.
map
(
item
=>
item
.
sbxxCode
)
/* 解决 先缓存选中色,后渲染黄色,默认选中时颜色不对
bug: 1默认还原为原色
2.高亮为黄色触发默认选中(黄色存储在另一个队列)
3.默认选中会还原上一个颜色
4.还原为原色,触发选中。变为选中色,清除为原色,覆盖了亮色
*/
if
(
sbxxCodeList
.
length
!=
0
)
{
this
.
reMaterialQue
.
forEach
(
item
=>
{
item
.
revert
()
})
}
this
.
reMaterialQue
.
splice
(
0
,
this
.
reMaterialQue
.
length
)
/* 分割,在渲染高亮清空选中的*/
this
.
viewer
.
scene
.
traverse
((
model
)
=>
{
if
(
model
.
isMesh
)
{
if
(
sbxxCodeList
.
includes
(
model
.
name
))
{
let
jzReMaterialQueItem
=
{
model
,
material
:
model
.
oldmaterial
.
clone
(),
revert
:
function
()
{
this
.
model
.
material
=
this
.
material
}
}
this
.
jzReMaterialQue
.
push
(
jzReMaterialQueItem
)
model
.
material
=
new
THREE
.
MeshPhongMaterial
({
color
:
new
THREE
.
Color
(
'rgba(255, 164, 7, 0.8)'
),
transparent
:
true
,
opacity
:
0.8
,
wireframe
:
false
,
})
}
}
});
if
(
this
.
jzReMaterialQue
.
length
!=
0
)
{
});
if
(
this
.
jzReMaterialQue
.
length
!=
0
)
{
this
.
viewer
.
cameraControl
.
fitTo
(
this
.
jzReMaterialQue
[
0
].
model
);
this
.
sylbshow
=
true
this
.
clickTag
(
this
.
jzReMaterialQue
[
0
].
model
.
name
)
}
else
{
this
.
sylbshow
=
false
}
if
(
sbxxList
.
length
>
0
&&
(
this
.
jzReMaterialQue
.
length
!=
sbxxList
.
length
))
{
this
.
$warning
(
'存在与模型数据不匹配的数据!'
)
}
this
.
viewer
.
cameraControl
.
fitTo
(
this
.
jzReMaterialQue
[
0
].
model
);
this
.
sylbshow
=
true
this
.
clickTag
(
this
.
jzReMaterialQue
[
0
].
model
.
name
)
}
else
{
this
.
sylbshow
=
false
}
if
(
sbxxList
.
length
>
0
&&
(
this
.
jzReMaterialQue
.
length
!=
sbxxList
.
length
))
{
this
.
$warning
(
'存在与模型数据不匹配的数据!'
)
}
}
})
},
/* 解决com和 相机控制器事件冲突的问题*/
canNotMousedown
(
domList
)
{
domList
.
forEach
(
vdom
=>
{
vdom
.
addEventListener
(
'mouseover'
,
function
(
event
)
{
event
.
preventDefault
();
});
})
}
})
},
/* 解决com和 相机控制器事件冲突的问题*/
canNotMousedown
(
domList
)
{
domList
.
forEach
(
vdom
=>
{
vdom
.
addEventListener
(
'mouseover'
,
function
(
event
)
{
event
.
preventDefault
();
});
})
},
flowPieDataChange
(
val
)
{
this
.
handlerAllFlow
()
},
/* 绘制流动方法
},
flowPieDataChange
(
val
)
{
this
.
handlerAllFlow
()
},
/* 绘制流动方法
*/
handlerAllFlow
()
{
if
(
this
.
allFlowObject
.
length
)
{
this
.
allFlowObject
.
forEach
((
item
)
=>
{
item
.
removeFromParent
();
*/
handlerAllFlow
()
{
if
(
this
.
allFlowObject
.
length
)
{
this
.
allFlowObject
.
forEach
((
item
)
=>
{
item
.
removeFromParent
();
});
this
.
allFlowObject
=
[];
}
const
children
=
this
.
allPieData
.
find
((
item
)
=>
item
.
name
===
this
.
flowPieData
)?.
children
;
if
(
!
children
)
{
return
;
}
children
.
forEach
((
item
)
=>
{
if
(
item
.
data
.
length
>=
2
)
{
const
o
=
this
.
drawPipe
(
item
.
data
.
map
((
item
)
=>
[
item
.
x
,
item
.
y
,
item
.
z
]),
item
.
radius
,
this
.
flowDirection
,
});
this
.
allFlowObject
=
[];
}
const
children
=
this
.
allPieData
.
find
((
item
)
=>
item
.
name
===
this
.
flowPieData
)?.
children
;
if
(
!
children
)
{
return
;
}
children
.
forEach
((
item
)
=>
{
if
(
item
.
data
.
length
>=
2
)
{
const
o
=
this
.
drawPipe
(
item
.
data
.
map
((
item
)
=>
[
item
.
x
,
item
.
y
,
item
.
z
]),
item
.
radius
,
this
.
flowDirection
,
);
o
.
traverse
((
node
)
=>
{
if
(
node
.
isMesh
)
{
node
.
_thing_tag
=
"helper"
;
}
});
this
.
allFlowObject
.
push
(
o
);
const
box
=
new
THREE
.
Box3
();
o
.
points
.
forEach
((
item
)
=>
{
box
.
expandByPoint
(
new
THREE
.
Vector3
(...
item
));
});
o
.
points
.
forEach
((
item
)
=>
{
box
.
expandByPoint
(
new
THREE
.
Vector3
(...
item
));
});
this
.
viewer
.
cameraControl
.
control
.
fitToBox
(
box
,
true
,
{
cover
:
true
});
}
});
},
/* 获取流向数据*/
getData
()
{
this
.
$post
(
'sbgl/usblxgx/zbInfo'
,
{}).
then
(
res
=>
{
if
(
res
.
success
)
{
let
data
=
res
.
data
.
records
||
[]
this
.
allPieData
=
data
.
filter
((
item
)
=>
{
return
item
.
children
.
some
((
child
)
=>
child
.
data
.
length
>=
2
);
});
}
})
},
/* 流向动画*/
drawPipe
(
positions
,
radius
,
direction
)
{
const
viewer
=
this
.
viewer
;
const
points
=
positions
.
map
(
/* 根据本身的模型定位来*/
(
item
)
=>
new
THREE
.
Vector3
(
item
[
0
]
/
1000
,
item
[
2
]
/
1000
,
-
item
[
1
]
/
1000
)
);
o
.
traverse
((
node
)
=>
{
const
flowObject
=
new
VT
.
TubeLine
({
points
:
points
,
geometry
:
{
radius
:
radius
/
100
/
2
,
cornerRadius
:
0
,
cornerSplit
:
10
,
},
material
:
{
// color: "#0099ff",
color
:
"lightgreen"
,
side
:
2
,
map
:
{
image
:
"vt/resources/texture/arrow.png"
,
repeat
:
[
1
,
4
],
// rotation: direction ? Math.PI : 0,
wrapS
:
THREE
.
RepeatWrapping
,
wrapT
:
THREE
.
RepeatWrapping
,
},
transparent
:
true
,
depthTest
:
true
,
},
});
flowObject
.
line
.
onBeforeRender
=
()
=>
{
if
(
flowObject
.
line
.
material
.
map
)
{
flowObject
.
line
.
material
.
map
.
offset
.
x
-=
0.05
;
}
};
flowObject
.
traverse
((
node
)
=>
{
if
(
node
.
isMesh
)
{
node
.
_thing_tag
=
"helper"
;
}
});
this
.
allFlowObject
.
push
(
o
);
const
box
=
new
THREE
.
Box3
();
o
.
points
.
forEach
((
item
)
=>
{
box
.
expandByPoint
(
new
THREE
.
Vector3
(...
item
));
});
o
.
points
.
forEach
((
item
)
=>
{
box
.
expandByPoint
(
new
THREE
.
Vector3
(...
item
));
});
this
.
viewer
.
cameraControl
.
control
.
fitToBox
(
box
,
true
,
{
cover
:
true
});
}
});
},
/* 获取流向数据*/
getData
()
{
this
.
$post
(
'sbgl/usblxgx/zbInfo'
,
{}).
then
(
res
=>
{
if
(
res
.
success
)
{
let
data
=
res
.
data
.
records
||
[]
this
.
allPieData
=
data
.
filter
((
item
)
=>
{
return
item
.
children
.
some
((
child
)
=>
child
.
data
.
length
>=
2
);
});
}
})
},
/* 流向动画*/
drawPipe
(
positions
,
radius
,
direction
)
{
const
viewer
=
this
.
viewer
;
const
points
=
positions
.
map
(
/* 根据本身的模型定位来*/
(
item
)
=>
new
THREE
.
Vector3
(
item
[
0
]
/
1000
,
item
[
2
]
/
1000
,
-
item
[
1
]
/
1000
)
);
const
flowObject
=
new
VT
.
TubeLine
({
points
:
points
,
geometry
:
{
radius
:
radius
/
100
/
2
,
cornerRadius
:
0
,
cornerSplit
:
10
,
viewer
.
scene
.
add
(
flowObject
);
return
flowObject
;
},
material
:
{
// color: "#0099ff",
color
:
"lightgreen"
,
side
:
2
,
map
:
{
image
:
"vt/resources/texture/arrow.png"
,
repeat
:
[
1
,
4
],
// rotation: direction ? Math.PI : 0,
wrapS
:
THREE
.
RepeatWrapping
,
wrapT
:
THREE
.
RepeatWrapping
,
},
transparent
:
true
,
depthTest
:
true
,
},
});
flowObject
.
line
.
onBeforeRender
=
()
=>
{
if
(
flowObject
.
line
.
material
.
map
)
{
flowObject
.
line
.
material
.
map
.
offset
.
x
-=
0.05
;
}
};
flowObject
.
traverse
((
node
)
=>
{
if
(
node
.
isMesh
)
{
node
.
_thing_tag
=
"helper"
;
}
});
viewer
.
scene
.
add
(
flowObject
);
return
flowObject
;
},
clearSelected
()
{
// this.viewer.scene.traverse(function(obj) {
// console.log(obj,'模型对象')
// if (obj.isMesh) {
// obj.material = new THREE.MeshPhysicalMaterial({
// clearcoat: 1.0, //物体表面清漆层或者说透明涂层的厚度
// clearcoatRoughness: 0.1, //透明涂层表面的粗糙度
// color: obj.material.color, //默认颜色
// metalness: 0.9, //车外壳金属度
// roughness: 0.5, //车外壳粗糙度
// envMapIntensity: 2.5, //环境贴图对Mesh表面影响程度
// })
// }
// })
this
.
selectedModel
=
{
name
:
''
}
this
.
reMaterialQue
.
forEach
(
item
=>
{
item
.
revert
()
})
clearSelected
()
{
// this.viewer.scene.traverse(function(obj) {
// console.log(obj,'模型对象')
// if (obj.isMesh) {
// obj.material = new THREE.MeshPhysicalMaterial({
// clearcoat: 1.0, //物体表面清漆层或者说透明涂层的厚度
// clearcoatRoughness: 0.1, //透明涂层表面的粗糙度
// color: obj.material.color, //默认颜色
// metalness: 0.9, //车外壳金属度
// roughness: 0.5, //车外壳粗糙度
// envMapIntensity: 2.5, //环境贴图对Mesh表面影响程度
// })
// }
// })
this
.
selectedModel
=
{
name
:
''
}
this
.
reMaterialQue
.
forEach
(
item
=>
{
item
.
revert
()
})
},
viewCenter
()
{
this
.
cameraTo
(
this
.
viewer
.
camera
.
position
.
x
,
this
.
viewer
.
camera
.
position
.
y
,
this
.
viewer
.
camera
.
position
.
z
,
0
,
0
,
0
)
},
reView
()
{
this
.
cameraTo
(
0
,
32
,
-
82
,
0
,
0
,
0
)
},
viewCenter
()
{
this
.
cameraTo
(
this
.
viewer
.
camera
.
position
.
x
,
this
.
viewer
.
camera
.
position
.
y
,
this
.
viewer
.
camera
.
position
.
z
,
0
,
0
,
0
)
},
reView
()
{
this
.
cameraTo
(
0
,
32
,
-
82
,
0
,
0
,
0
)
},
init
()
{
/* scene*/
// this.scene = new Viewer('scene')
// this.scene.camera.position.set(0, 17, -60)
/* viewer*/
// this.viewer = new Viewer('container')
// this.viewer.camera.position.set(0, 17, -60)
// const manager = new THREE.LoadingManager();
// manager.onProgress = (item, loaded, total) => {
// let process = (loaded / total * 100).toFixed(2)
// if (process == 100) {
// this.loading = false
// }
// // 这里可以根据加载进度执行其他操作
// };
// this.modelLoader = new ModelLoader(this.viewer, manager)
// const lights = new Lights(this.viewer)
// const ambientLight = lights.addAmbientLight() // 添加环境光
// ambientLight.setOption({
// color: 0xff0000,
// intensity: 6 // 环境光强度
// })
// ambientLight.light.name = 'AmbientLight'
// // 添加平行光
// lights.addDirectionalLight([200, 200, 200], {
// color: 'rgb(253,253,253)',
// intensity: 3,
// castShadow: false // 是否投射阴影
// })
// this.loadDm()
this
.
viewer
=
new
VT
.
Viewer
({
container
:
this
.
$refs
.
container
,
scene
:
{
helper
:
{
grid
:
{
visible
:
true
,
},
init
()
{
/* scene*/
// this.scene = new Viewer('scene')
// this.scene.camera.position.set(0, 17, -60)
/* viewer*/
// this.viewer = new Viewer('container')
// this.viewer.camera.position.set(0, 17, -60)
// const manager = new THREE.LoadingManager();
// manager.onProgress = (item, loaded, total) => {
// let process = (loaded / total * 100).toFixed(2)
// if (process == 100) {
// this.loading = false
// }
// // 这里可以根据加载进度执行其他操作
// };
// this.modelLoader = new ModelLoader(this.viewer, manager)
// const lights = new Lights(this.viewer)
// const ambientLight = lights.addAmbientLight() // 添加环境光
// ambientLight.setOption({
// color: 0xff0000,
// intensity: 6 // 环境光强度
// })
// ambientLight.light.name = 'AmbientLight'
// // 添加平行光
// lights.addDirectionalLight([200, 200, 200], {
// color: 'rgb(253,253,253)',
// intensity: 3,
// castShadow: false // 是否投射阴影
// })
// this.loadDm()
this
.
viewer
=
new
VT
.
Viewer
({
container
:
this
.
$refs
.
container
,
scene
:
{
helper
:
{
grid
:
{
visible
:
true
,
},
},
background
:
{
skyboxPath
:
"dark"
,
},
},
view
:
{
position
:
[
44.81080132492321
,
48.62916741352805
,
-
75.73966237503983
],
center
:
[
48.15565686619112
,
5.221820594458009
,
5.975771281142078
],
far
:
10000
,
near
:
0.1
,
aspect
:
null
,
fov
:
45
,
isOrtho
:
false
,
zoom
:
1
,
rotation
:
[
-
2.6532966628149923
,
-
0.036133545863119475
,
-
3.1224049976510337
,
"XYZ"
],
},
},
background
:
{
skyboxPath
:
"dark"
,
},
});
},
loadAll
()
{
var
model
=
new
VT
.
Model
({
modelType
:
"gltf"
,
src
:
"/gltf/all.gltf"
,
})
model
.
addEventListener
(
"loaded"
,
()
=>
{
this
.
loading
=
false
this
.
viewer
.
scene
.
traverse
(
model
=>
{
if
(
model
.
isMesh
)
{
model
.
oldmaterial
=
model
.
material
.
clone
()
}
})
});
this
.
viewer
.
scene
.
add
(
model
);
// this.modelLoader.loadModelToScene('/glb/all.glb', (model) => {
// model.object.position.set(-42, -10, 0)
// model.object.scale.set(1, 1, 1)
// model.object.updateMatrixWorld(true);
// console.log(model,'console.log(model)console.log(model)')
// }, (num) => {
// let showNum = num * 100
// if (showNum == 100) {
// this.loadingText = `模型加载完毕,请稍等!`
// /* 机组高亮测试*/
// setTimeout(() => {
// this.apiJzbm()
// }, 2000)
// } else {
// this.loadingText = `正在加载模型${showNum}%!`
// }
// /* */
// })
},
view
:
{
position
:
[
44.81080132492321
,
48.62916741352805
,
-
75.73966237503983
],
center
:
[
48.15565686619112
,
5.221820594458009
,
5.975771281142078
],
far
:
10000
,
near
:
0.1
,
aspect
:
null
,
fov
:
45
,
isOrtho
:
false
,
zoom
:
1
,
rotation
:
[
-
2.6532966628149923
,
-
0.036133545863119475
,
-
3.1224049976510337
,
"XYZ"
],
loadDm
()
{
const
geometry
=
new
THREE
.
PlaneGeometry
(
1000
,
1000
,
500
,
500
);
// 创建一个100x100的平面,水平和垂直各10条线
const
material
=
new
THREE
.
LineBasicMaterial
({
color
:
0x585858
,
linewidth
:
0.5
});
const
grid
=
new
THREE
.
LineSegments
(
geometry
,
material
);
grid
.
rotation
.
x
=
-
Math
.
PI
/
2
;
// 旋转网格,使其平铺在x-z平面上
grid
.
position
.
y
=
-
18
;
// 将网格向下移动一点,使其位于底部
grid
.
name
=
'地面'
this
.
viewer
.
scene
.
add
(
grid
);
},
});
/* 点击*/
tdClick
()
{
this
.
viewer
.
renderer
.
domElement
.
addEventListener
(
'click'
,
(
e
)
=>
{
const
rayCaster
=
new
THREE
.
Raycaster
()
const
mouse
=
new
THREE
.
Vector2
()
mouse
.
x
=
(
e
.
offsetX
/
this
.
viewer
.
renderer
.
domElement
.
clientWidth
)
*
2
-
1
mouse
.
y
=
-
(
e
.
offsetY
/
this
.
viewer
.
renderer
.
domElement
.
clientHeight
)
*
2
+
1
rayCaster
.
setFromCamera
(
mouse
,
this
.
viewer
.
camera
)
const
intersects
=
rayCaster
.
intersectObject
(
this
.
viewer
.
scene
,
true
)
// 计算物体和射线的焦点
if
(
intersects
[
0
])
{
if
(
intersects
[
0
].
object
.
name
==
'地面'
)
{
return
}
let
model
if
(
intersects
[
0
].
object
.
name
==
''
)
{
model
=
intersects
[
1
].
object
}
else
{
model
=
intersects
[
0
].
object
}
this
.
selectedModel
=
model
},
loadAll
()
{
var
model
=
new
VT
.
Model
({
modelType
:
"gltf"
,
src
:
"/gltf/all.gltf"
,
})
/* 执行并情况材料队列 */
this
.
reMaterialQue
.
forEach
(
item
=>
{
item
.
revert
()
})
this
.
reMaterialQue
.
splice
(
0
,
this
.
reMaterialQue
.
length
)
model
.
addEventListener
(
"loaded"
,
()
=>
{
this
.
loading
=
false
this
.
viewer
.
scene
.
traverse
(
model
=>
{
if
(
model
.
isMesh
)
{
model
.
oldmaterial
=
model
.
material
.
clone
()
}
})
});
this
.
viewer
.
scene
.
add
(
model
);
// this.modelLoader.loadModelToScene('/glb/all.glb', (model) => {
// model.object.position.set(-42, -10, 0)
// model.object.scale.set(1, 1, 1)
// model.object.updateMatrixWorld(true);
// console.log(model,'console.log(model)console.log(model)')
// }, (num) => {
// let showNum = num * 100
// if (showNum == 100) {
// this.loadingText = `模型加载完毕,请稍等!`
// /* 机组高亮测试*/
// setTimeout(() => {
// this.apiJzbm()
// }, 2000)
// } else {
// this.loadingText = `正在加载模型${showNum}%!`
// }
// /* */
// })
},
loadDm
()
{
const
geometry
=
new
THREE
.
PlaneGeometry
(
1000
,
1000
,
500
,
500
);
// 创建一个100x100的平面,水平和垂直各10条线
const
material
=
new
THREE
.
LineBasicMaterial
({
color
:
0x585858
,
linewidth
:
0.5
});
const
grid
=
new
THREE
.
LineSegments
(
geometry
,
material
);
grid
.
rotation
.
x
=
-
Math
.
PI
/
2
;
// 旋转网格,使其平铺在x-z平面上
grid
.
position
.
y
=
-
18
;
// 将网格向下移动一点,使其位于底部
grid
.
name
=
'地面'
this
.
viewer
.
scene
.
add
(
grid
);
},
/* 点击*/
tdClick
()
{
this
.
viewer
.
renderer
.
domElement
.
addEventListener
(
'click'
,
(
e
)
=>
{
const
rayCaster
=
new
THREE
.
Raycaster
()
const
mouse
=
new
THREE
.
Vector2
()
mouse
.
x
=
(
e
.
offsetX
/
this
.
viewer
.
renderer
.
domElement
.
clientWidth
)
*
2
-
1
mouse
.
y
=
-
(
e
.
offsetY
/
this
.
viewer
.
renderer
.
domElement
.
clientHeight
)
*
2
+
1
rayCaster
.
setFromCamera
(
mouse
,
this
.
viewer
.
camera
)
const
intersects
=
rayCaster
.
intersectObject
(
this
.
viewer
.
scene
,
true
)
// 计算物体和射线的焦点
if
(
intersects
[
0
])
{
if
(
intersects
[
0
].
object
.
name
==
'地面'
)
{
return
}
let
model
if
(
intersects
[
0
].
object
.
name
==
''
)
{
model
=
intersects
[
1
].
object
}
else
{
model
=
intersects
[
0
].
object
}
this
.
selectedModel
=
model
/* 添加材质模型队列*/
let
reMaterialQueItem
=
{
model
,
material
:
model
.
material
.
clone
(),
revert
:
function
()
{
this
.
model
.
material
=
this
.
material
}
}
/* 执行并情况材料队列 */
this
.
reMaterialQue
.
forEach
(
item
=>
{
item
.
revert
()
})
this
.
reMaterialQue
.
splice
(
0
,
this
.
reMaterialQue
.
length
)
this
.
reMaterialQue
.
push
(
reMaterialQueItem
)
/* 添加材质模型队列*/
let
reMaterialQueItem
=
{
model
,
material
:
model
.
material
.
clone
(),
revert
:
function
()
{
this
.
model
.
material
=
this
.
material
}
}
model
.
material
=
new
THREE
.
MeshPhongMaterial
({
color
:
new
THREE
.
Color
(
'rgba(255, 255, 0, 0.8)'
),
transparent
:
true
,
opacity
:
0.8
,
wireframe
:
false
,
})
/* */
// if (this.xzjj) {
// const object = model;
// if (object) {
// this.viewer.cameraControl.fitTo(object);
// }
// }
this
.
reMaterialQue
.
push
(
reMaterialQueItem
)
model
.
material
=
new
THREE
.
MeshPhongMaterial
({
color
:
new
THREE
.
Color
(
'rgba(255, 255, 0, 0.8)'
),
transparent
:
true
,
opacity
:
0.8
,
wireframe
:
false
,
})
/* */
if
(
this
.
xzjj
)
{
const
object
=
model
;
if
(
object
)
{
this
.
viewer
.
cameraControl
.
fitTo
(
object
);
}
})
},
tdblClick
()
{
this
.
viewer
.
renderer
.
domElement
.
addEventListener
(
'dblclick'
,
(
e
)
=>
{
const
rayCaster
=
new
THREE
.
Raycaster
()
const
mouse
=
new
THREE
.
Vector2
()
mouse
.
x
=
(
e
.
offsetX
/
this
.
viewer
.
renderer
.
domElement
.
clientWidth
)
*
2
-
1
mouse
.
y
=
-
(
e
.
offsetY
/
this
.
viewer
.
renderer
.
domElement
.
clientHeight
)
*
2
+
1
rayCaster
.
setFromCamera
(
mouse
,
this
.
viewer
.
camera
)
const
intersects
=
rayCaster
.
intersectObject
(
this
.
viewer
.
scene
,
true
)
// 计算物体和射线的焦点
if
(
intersects
[
0
])
{
if
(
intersects
[
0
].
object
.
name
==
'地面'
)
{
return
}
let
model
if
(
intersects
[
0
].
object
.
name
==
''
)
{
model
=
intersects
[
1
].
object
}
else
{
model
=
intersects
[
0
].
object
}
this
.
selectedModel
=
model
}
/* 执行并情况材料队列 */
this
.
reMaterialQue
.
forEach
(
item
=>
{
item
.
revert
()
})
this
.
reMaterialQue
.
splice
(
0
,
this
.
reMaterialQue
.
length
)
/* 添加材质模型队列*/
let
reMaterialQueItem
=
{
model
,
material
:
model
.
material
.
clone
(),
revert
:
function
()
{
this
.
model
.
material
=
this
.
material
}
}
this
.
reMaterialQue
.
push
(
reMaterialQueItem
)
}
})
},
/* reMaterialQue 相关操作*/
getCameraPosition
(
d
,
point
)
{
// 确保point是一个对象,并且包含x, y, z属性
if
(
!
point
||
typeof
point
.
x
!==
'number'
||
typeof
point
.
y
!==
'number'
||
typeof
point
.
z
!==
'number'
)
{
throw
new
Error
(
'Invalid point object'
);
}
model
.
material
=
new
THREE
.
MeshPhongMaterial
({
color
:
new
THREE
.
Color
(
'rgba(255, 255, 0, 0.8)'
),
transparent
:
true
,
opacity
:
0.8
,
wireframe
:
false
,
})
/* */
const
object
=
model
;
if
(
object
)
{
this
.
viewer
.
cameraControl
.
fitTo
(
object
);
}
// 计算从原点(0,0,0)到模型点的向量
const
vector
=
{
x
:
point
.
x
-
0
,
y
:
point
.
y
-
0
,
z
:
point
.
z
-
0
};
// 计算向量的长度(模)
const
length
=
Math
.
sqrt
(
vector
.
x
*
vector
.
x
+
vector
.
y
*
vector
.
y
+
vector
.
z
*
vector
.
z
);
// 如果长度为0(即模型点就是原点),则返回一个错误或默认位置
if
(
length
===
0
)
{
throw
new
Error
(
'Model point is at the origin'
);
}
}
})
},
/* reMaterialQue 相关操作*/
getCameraPosition
(
d
,
point
)
{
// 确保point是一个对象,并且包含x, y, z属性
if
(
!
point
||
typeof
point
.
x
!==
'number'
||
typeof
point
.
y
!==
'number'
||
typeof
point
.
z
!==
'number'
)
{
throw
new
Error
(
'Invalid point object'
);
}
// 计算单位向量(将向量除以它的长度)
const
unitVector
=
{
x
:
vector
.
x
/
length
,
y
:
vector
.
y
/
length
,
z
:
vector
.
z
/
length
};
// 计算相机位置:模型点位置加上单位向量乘以距离d(但注意,这里我们实际上是将相机放在模型点之后d的位置)
// 如果想要相机在模型点和原点之间,可以调整d的符号或计算方式
const
cameraPosition
=
{
x
:
point
.
x
-
d
*
unitVector
.
x
,
y
:
point
.
y
-
d
*
unitVector
.
y
,
z
:
point
.
z
-
d
*
unitVector
.
z
};
return
cameraPosition
;
},
/* 封装相机转向方法动画*/
cameraTo
(
x
,
y
,
z
,
px
,
py
,
pz
)
{
let
_camera
=
this
.
viewer
.
cameraControl
.
camera
let
currentPosition
=
_camera
.
position
.
clone
();
let
oldx
=
currentPosition
.
x
let
oldy
=
currentPosition
.
y
let
oldz
=
currentPosition
.
z
let
coldx
=
this
.
viewer
.
controls
.
target
.
x
let
coldy
=
this
.
viewer
.
controls
.
target
.
y
let
coldz
=
this
.
viewer
.
controls
.
target
.
z
let
viewer
=
this
.
viewer
/* 计算过渡差值*/
let
tl
=
gsap
.
timeline
();
tl
.
to
({},
{
duration
:
1.5
,
// 动画持续时间
ease
:
"power1.inOut"
,
// 缓动函数
onUpdate
:
function
()
{
let
progress
=
this
.
progress
();
// 获取当前进度(0到1之间)
_camera
.
position
.
set
(
oldx
+
(
x
-
oldx
)
*
progress
,
oldy
+
(
y
-
oldy
)
*
progress
,
oldz
+
(
z
-
oldz
)
*
progress
);
viewer
.
controls
.
target
.
set
(
coldx
+
(
px
-
coldx
)
*
progress
,
coldy
+
(
py
-
coldy
)
*
progress
,
coldz
+
(
pz
-
coldz
)
*
progress
)
// 计算从原点(0,0,0)到模型点的向量
const
vector
=
{
x
:
point
.
x
-
0
,
y
:
point
.
y
-
0
,
z
:
point
.
z
-
0
};
// 计算向量的长度(模)
const
length
=
Math
.
sqrt
(
vector
.
x
*
vector
.
x
+
vector
.
y
*
vector
.
y
+
vector
.
z
*
vector
.
z
);
// 如果长度为0(即模型点就是原点),则返回一个错误或默认位置
if
(
length
===
0
)
{
throw
new
Error
(
'Model point is at the origin'
);
}
// 计算单位向量(将向量除以它的长度)
const
unitVector
=
{
x
:
vector
.
x
/
length
,
y
:
vector
.
y
/
length
,
z
:
vector
.
z
/
length
};
// 计算相机位置:模型点位置加上单位向量乘以距离d(但注意,这里我们实际上是将相机放在模型点之后d的位置)
// 如果想要相机在模型点和原点之间,可以调整d的符号或计算方式
const
cameraPosition
=
{
x
:
point
.
x
-
d
*
unitVector
.
x
,
y
:
point
.
y
-
d
*
unitVector
.
y
,
z
:
point
.
z
-
d
*
unitVector
.
z
};
return
cameraPosition
;
},
/* 封装相机转向方法动画*/
cameraTo
(
x
,
y
,
z
,
px
,
py
,
pz
)
{
let
_camera
=
this
.
viewer
.
cameraControl
.
camera
let
currentPosition
=
_camera
.
position
.
clone
();
let
oldx
=
currentPosition
.
x
let
oldy
=
currentPosition
.
y
let
oldz
=
currentPosition
.
z
let
coldx
=
this
.
viewer
.
controls
.
target
.
x
let
coldy
=
this
.
viewer
.
controls
.
target
.
y
let
coldz
=
this
.
viewer
.
controls
.
target
.
z
let
viewer
=
this
.
viewer
/* 计算过渡差值*/
let
tl
=
gsap
.
timeline
();
tl
.
to
({},
{
duration
:
1.5
,
// 动画持续时间
ease
:
"power1.inOut"
,
// 缓动函数
onUpdate
:
function
()
{
let
progress
=
this
.
progress
();
// 获取当前进度(0到1之间)
_camera
.
position
.
set
(
oldx
+
(
x
-
oldx
)
*
progress
,
oldy
+
(
y
-
oldy
)
*
progress
,
oldz
+
(
z
-
oldz
)
*
progress
);
viewer
.
controls
.
target
.
set
(
coldx
+
(
px
-
coldx
)
*
progress
,
coldy
+
(
py
-
coldy
)
*
progress
,
coldz
+
(
pz
-
coldz
)
*
progress
)
}
});
}
});
}
}
}
</
script
>
<
style
scoped
lang=
"scss"
>
...
...
@@ -1292,7 +1471,7 @@
right
:
15px
;
/* 使元素居中 */
position
:
absolute
;
height
:
9
0px
;
height
:
18
0px
;
width
:
28%
;
z-index
:
12
;
background-color
:
rgba
(
0
,
0
,
0
,
0
.6
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment