Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
D
DSMS
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
詹银鑫
DSMS
Commits
e6670372
提交
e6670372
authored
5月 27, 2025
作者:
詹银鑫
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
加载无人机模型并添加点击弹窗和无人机动画
上级
d28ccc7e
显示空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
1132 行增加
和
838 行删除
+1132
-838
Flying_drone..glb
public/assets/json/Flying_drone..glb
+0
-0
Flying_drone.png
public/assets/json/Flying_drone.png
+0
-0
map.js
src/views/gdMap/map.js
+1132
-838
没有找到文件。
public/assets/json/Flying_drone..glb
0 → 100644
浏览文件 @
e6670372
File added
public/assets/json/Flying_drone.png
0 → 100644
浏览文件 @
e6670372
130.0 KB
src/views/gdMap/map.js
浏览文件 @
e6670372
...
@@ -31,8 +31,8 @@ import {
...
@@ -31,8 +31,8 @@ import {
FileLoader
,
FileLoader
,
Shape
,
Shape
,
ExtrudeGeometry
,
ExtrudeGeometry
,
}
from
"three"
}
from
"three"
;
import
*
as
THREE
from
"three"
import
*
as
THREE
from
"three"
;
import
{
import
{
Mini3d
,
Mini3d
,
...
@@ -46,39 +46,39 @@ import {
...
@@ -46,39 +46,39 @@ import {
GradientShader
,
GradientShader
,
DiffuseShader
,
DiffuseShader
,
Focus
,
Focus
,
}
from
"@/mini3d"
}
from
"@/mini3d"
;
import
{
geoMercator
}
from
"d3-geo"
import
{
geoMercator
}
from
"d3-geo"
;
import
labelIcon
from
"@/assets/texture/label-icon.png"
import
labelIcon
from
"@/assets/texture/label-icon.png"
;
import
chinaData
from
"./map/chinaData"
import
chinaData
from
"./map/chinaData"
;
import
provincesData
from
"./map/provincesData"
import
provincesData
from
"./map/provincesData"
;
import
scatterData
from
"./map/scatter"
import
scatterData
from
"./map/scatter"
;
import
infoData
from
"./map/infoData"
import
infoData
from
"./map/infoData"
;
import
gsap
from
"gsap"
import
gsap
from
"gsap"
;
import
emitter
from
"@/utils/emitter"
import
emitter
from
"@/utils/emitter"
;
import
{
InteractionManager
}
from
"three.interactive"
import
{
InteractionManager
}
from
"three.interactive"
;
// 引入模型加载模块
// 引入模型加载模块
import
{
Resource
}
from
"@/mini3d/utils/Resource"
import
{
Resource
}
from
"@/mini3d/utils/Resource"
;
function
sortByValue
(
data
)
{
function
sortByValue
(
data
)
{
data
.
sort
((
a
,
b
)
=>
b
.
value
-
a
.
value
)
data
.
sort
((
a
,
b
)
=>
b
.
value
-
a
.
value
)
;
return
data
return
data
;
}
}
export
class
World
extends
Mini3d
{
export
class
World
extends
Mini3d
{
constructor
(
canvas
,
assets
)
{
constructor
(
canvas
,
assets
)
{
super
(
canvas
)
super
(
canvas
)
;
// 中心坐标
// 中心坐标
// this.geoProjectionCenter = [113.280637, 23.125178]
// this.geoProjectionCenter = [113.280637, 23.125178]
this
.
geoProjectionCenter
=
[
110.840171
,
39.864362
]
this
.
geoProjectionCenter
=
[
110.840171
,
39.864362
]
;
// 缩放比例
// 缩放比例
this
.
geoProjectionScale
=
700
this
.
geoProjectionScale
=
700
;
// this.geoProjectionScale = 120
// this.geoProjectionScale = 120
// 飞线中心
// 飞线中心
// this.flyLineCenter = [113.544372, 23.329249]
// this.flyLineCenter = [113.544372, 23.329249]
this
.
flyLineCenter
=
[
111.319412
,
39.781603
]
this
.
flyLineCenter
=
[
111.319412
,
39.781603
];
// 地图拉伸高度
// 地图拉伸高度
this
.
depth
=
0.5
this
.
depth
=
0.5
;
// this.mapFocusLabelInfo = {
// this.mapFocusLabelInfo = {
// name: "广东省",
// name: "广东省",
// enName: "GUANGDONG PROVINCE",
// enName: "GUANGDONG PROVINCE",
...
@@ -88,76 +88,84 @@ export class World extends Mini3d {
...
@@ -88,76 +88,84 @@ export class World extends Mini3d {
name
:
"准格尔旗"
,
name
:
"准格尔旗"
,
enName
:
"ZHUNGEER QI"
,
enName
:
"ZHUNGEER QI"
,
center
:
[
110.840171
,
39.864362
],
center
:
[
110.840171
,
39.864362
],
}
}
;
// 是否点击
// 是否点击
this
.
clicked
=
false
this
.
clicked
=
false
;
// 雾
// 雾
this
.
scene
.
fog
=
new
Fog
(
0x102736
,
1
,
50
)
this
.
scene
.
fog
=
new
Fog
(
0x102736
,
1
,
50
)
;
// 背景
// 背景
this
.
scene
.
background
=
new
Color
(
0x102736
)
this
.
scene
.
background
=
new
Color
(
0x102736
)
;
// 相机初始位置
// 相机初始位置
// this.camera.instance.position.set(-13.767695123014105, 12.990152163077308, 39.28228164159694)
// this.camera.instance.position.set(-13.767695123014105, 12.990152163077308, 39.28228164159694)
this
.
camera
.
instance
.
position
.
set
(
-
13.767695123014105
,
12.990152163077308
,
19.28228164159694
)
this
.
camera
.
instance
.
position
.
set
(
this
.
camera
.
instance
.
near
=
0.1
-
13.767695123014105
,
this
.
camera
.
instance
.
far
=
10000
12.990152163077308
,
this
.
camera
.
instance
.
updateProjectionMatrix
()
19.28228164159694
);
this
.
camera
.
instance
.
near
=
0.1
;
this
.
camera
.
instance
.
far
=
10000
;
this
.
camera
.
instance
.
updateProjectionMatrix
();
// 创建交互管理
// 创建交互管理
this
.
interactionManager
=
new
InteractionManager
(
this
.
renderer
.
instance
,
this
.
camera
.
instance
,
this
.
canvas
)
this
.
interactionManager
=
new
InteractionManager
(
this
.
renderer
.
instance
,
this
.
camera
.
instance
,
this
.
canvas
);
this
.
assets
=
assets
this
.
assets
=
assets
;
// 创建环境光
// 创建环境光
this
.
initEnvironment
()
this
.
initEnvironment
()
;
this
.
init
()
this
.
init
()
;
console
.
log
(
"执行了 这些代码"
)
console
.
log
(
"执行了 这些代码"
)
;
}
}
init
()
{
init
()
{
// 标签组
// 标签组
this
.
labelGroup
=
new
Group
()
this
.
labelGroup
=
new
Group
()
;
this
.
label3d
=
new
Label3d
(
this
)
this
.
label3d
=
new
Label3d
(
this
)
;
this
.
labelGroup
.
rotation
.
x
=
-
Math
.
PI
/
2
this
.
labelGroup
.
rotation
.
x
=
-
Math
.
PI
/
2
;
this
.
scene
.
add
(
this
.
labelGroup
)
this
.
scene
.
add
(
this
.
labelGroup
)
;
// 飞线焦点光圈组
// 飞线焦点光圈组
this
.
flyLineFocusGroup
=
new
Group
()
this
.
flyLineFocusGroup
=
new
Group
()
;
this
.
flyLineFocusGroup
.
visible
=
false
this
.
flyLineFocusGroup
.
visible
=
false
;
this
.
flyLineFocusGroup
.
rotation
.
x
=
-
Math
.
PI
/
2
this
.
flyLineFocusGroup
.
rotation
.
x
=
-
Math
.
PI
/
2
;
this
.
scene
.
add
(
this
.
flyLineFocusGroup
)
this
.
scene
.
add
(
this
.
flyLineFocusGroup
)
;
// 区域事件元素
// 区域事件元素
this
.
eventElement
=
[]
this
.
eventElement
=
[]
;
// 鼠标移上移除的材质
// 鼠标移上移除的材质
this
.
defaultMaterial
=
null
// 默认材质
this
.
defaultMaterial
=
null
;
// 默认材质
this
.
defaultLightMaterial
=
null
// 高亮材质
this
.
defaultLightMaterial
=
null
;
// 高亮材质
// 创建地形模型初始化
// 创建地形模型初始化
this
.
terrainResource
=
new
Resource
()
this
.
terrainResource
=
new
Resource
()
;
// 创建底部高亮
// 创建底部高亮
this
.
createBottomBg
()
this
.
createBottomBg
()
;
// 模糊边线
// 模糊边线
this
.
createChinaBlurLine
()
this
.
createChinaBlurLine
()
;
// 扩散网格
// 扩散网格
this
.
createGrid
()
this
.
createGrid
()
;
// 旋转圆环
// 旋转圆环
this
.
createRotateBorder
()
this
.
createRotateBorder
()
;
// 创建标签
// 创建标签
this
.
createLabel
(
this
.
mapFocusLabelInfo
)
this
.
createLabel
(
this
.
mapFocusLabelInfo
)
;
// 创建地图
// 创建地图
this
.
createMap
()
this
.
createMap
()
;
// 添加事件
// 添加事件
this
.
createEvent
()
this
.
createEvent
()
;
// 创建飞线
// 创建飞线
this
.
createFlyLine
()
this
.
createFlyLine
()
;
// 创建飞线焦点
// 创建飞线焦点
this
.
createFocus
()
this
.
createFocus
()
;
// 创建粒子
// 创建粒子
this
.
createParticles
()
this
.
createParticles
()
;
// 创建散点图
// 创建散点图
this
.
createScatter
()
this
.
createScatter
()
;
// 创建信息点
// 创建信息点
this
.
createInfoPoint
()
this
.
createInfoPoint
()
;
// 创建轮廓
// 创建轮廓
this
.
createStorke
()
this
.
createStorke
()
;
// 创建圆滑曲线
// 创建圆滑曲线
this
.
createSmoothLine
([
this
.
createSmoothLine
([
[
110.9801
,
39.8002
],
[
110.9801
,
39.8002
],
...
@@ -165,7 +173,14 @@ export class World extends Mini3d {
...
@@ -165,7 +173,14 @@ export class World extends Mini3d {
[
111.1803
,
39.6054
],
[
111.1803
,
39.6054
],
[
110.9008
,
39.8056
],
[
110.9008
,
39.8056
],
[
111.1003
,
39.7386
],
[
111.1003
,
39.7386
],
])
]);
this
.
showDroneAtLngLat
(
"../../../public/assets/json/Flying_drone..glb"
,
110.9801
,
39.8002
,
0.5
,
5
);
// 创造3d地形
// 创造3d地形
// this.createTerrain()
// this.createTerrain()
// 创造geoJson图
// 创造geoJson图
...
@@ -176,12 +191,12 @@ export class World extends Mini3d {
...
@@ -176,12 +191,12 @@ export class World extends Mini3d {
// 创建动画时间线
// 创建动画时间线
let
tl
=
gsap
.
timeline
({
let
tl
=
gsap
.
timeline
({
onComplete
:
()
=>
{},
onComplete
:
()
=>
{},
})
})
;
tl
.
pause
()
tl
.
pause
()
;
this
.
animateTl
=
tl
this
.
animateTl
=
tl
;
tl
.
addLabel
(
"focusMap"
,
1.5
)
tl
.
addLabel
(
"focusMap"
,
1.5
)
;
tl
.
addLabel
(
"focusMapOpacity"
,
2
)
tl
.
addLabel
(
"focusMapOpacity"
,
2
)
;
tl
.
addLabel
(
"bar"
,
3
)
tl
.
addLabel
(
"bar"
,
3
)
;
tl
.
to
(
this
.
camera
.
instance
.
position
,
{
tl
.
to
(
this
.
camera
.
instance
.
position
,
{
duration
:
2
,
duration
:
2
,
x
:
-
0.17427287762525134
,
x
:
-
0.17427287762525134
,
...
@@ -189,9 +204,9 @@ export class World extends Mini3d {
...
@@ -189,9 +204,9 @@ export class World extends Mini3d {
z
:
20.688611202093714
,
z
:
20.688611202093714
,
ease
:
"circ.out"
,
ease
:
"circ.out"
,
onStart
:
()
=>
{
onStart
:
()
=>
{
this
.
flyLineFocusGroup
.
visible
=
false
this
.
flyLineFocusGroup
.
visible
=
false
;
},
},
})
})
;
tl
.
to
(
tl
.
to
(
this
.
focusMapGroup
.
position
,
this
.
focusMapGroup
.
position
,
{
{
...
@@ -201,7 +216,7 @@ export class World extends Mini3d {
...
@@ -201,7 +216,7 @@ export class World extends Mini3d {
z
:
0
,
z
:
0
,
},
},
"focusMap"
"focusMap"
)
)
;
tl
.
to
(
tl
.
to
(
this
.
focusMapGroup
.
scale
,
this
.
focusMapGroup
.
scale
,
...
@@ -212,14 +227,14 @@ export class World extends Mini3d {
...
@@ -212,14 +227,14 @@ export class World extends Mini3d {
z
:
1
,
z
:
1
,
ease
:
"circ.out"
,
ease
:
"circ.out"
,
onComplete
:
()
=>
{
onComplete
:
()
=>
{
this
.
flyLineGroup
.
visible
=
true
this
.
flyLineGroup
.
visible
=
true
;
this
.
scatterGroup
.
visible
=
true
this
.
scatterGroup
.
visible
=
true
;
this
.
InfoPointGroup
.
visible
=
true
this
.
InfoPointGroup
.
visible
=
true
;
this
.
createInfoPointLabelLoop
()
this
.
createInfoPointLabelLoop
()
;
},
},
},
},
"focusMap"
"focusMap"
)
)
;
tl
.
to
(
tl
.
to
(
this
.
focusMapTopMaterial
,
this
.
focusMapTopMaterial
,
...
@@ -229,7 +244,7 @@ export class World extends Mini3d {
...
@@ -229,7 +244,7 @@ export class World extends Mini3d {
ease
:
"circ.out"
,
ease
:
"circ.out"
,
},
},
"focusMapOpacity"
"focusMapOpacity"
)
)
;
tl
.
to
(
tl
.
to
(
this
.
focusMapSideMaterial
,
this
.
focusMapSideMaterial
,
{
{
...
@@ -237,13 +252,13 @@ export class World extends Mini3d {
...
@@ -237,13 +252,13 @@ export class World extends Mini3d {
opacity
:
1
,
opacity
:
1
,
ease
:
"circ.out"
,
ease
:
"circ.out"
,
onComplete
:
()
=>
{
onComplete
:
()
=>
{
this
.
focusMapSideMaterial
.
transparent
=
false
this
.
focusMapSideMaterial
.
transparent
=
false
;
},
},
},
},
"focusMapOpacity"
"focusMapOpacity"
)
)
;
this
.
otherLabel
.
map
((
item
,
index
)
=>
{
this
.
otherLabel
.
map
((
item
,
index
)
=>
{
let
element
=
item
.
element
.
querySelector
(
".other-label"
)
let
element
=
item
.
element
.
querySelector
(
".other-label"
)
;
tl
.
to
(
tl
.
to
(
element
,
element
,
{
{
...
@@ -254,8 +269,8 @@ export class World extends Mini3d {
...
@@ -254,8 +269,8 @@ export class World extends Mini3d {
ease
:
"circ.out"
,
ease
:
"circ.out"
,
},
},
"focusMapOpacity"
"focusMapOpacity"
)
)
;
})
})
;
tl
.
to
(
tl
.
to
(
this
.
mapLineMaterial
,
this
.
mapLineMaterial
,
{
{
...
@@ -264,7 +279,7 @@ export class World extends Mini3d {
...
@@ -264,7 +279,7 @@ export class World extends Mini3d {
opacity
:
1
,
opacity
:
1
,
},
},
"focusMapOpacity"
"focusMapOpacity"
)
)
;
tl
.
to
(
tl
.
to
(
this
.
rotateBorder1
.
scale
,
this
.
rotateBorder1
.
scale
,
{
{
...
@@ -276,7 +291,7 @@ export class World extends Mini3d {
...
@@ -276,7 +291,7 @@ export class World extends Mini3d {
ease
:
"circ.out"
,
ease
:
"circ.out"
,
},
},
"focusMapOpacity"
"focusMapOpacity"
)
)
;
tl
.
to
(
tl
.
to
(
this
.
rotateBorder2
.
scale
,
this
.
rotateBorder2
.
scale
,
{
{
...
@@ -287,15 +302,15 @@ export class World extends Mini3d {
...
@@ -287,15 +302,15 @@ export class World extends Mini3d {
z
:
1
,
z
:
1
,
ease
:
"circ.out"
,
ease
:
"circ.out"
,
onComplete
:
()
=>
{
onComplete
:
()
=>
{
this
.
flyLineFocusGroup
.
visible
=
true
this
.
flyLineFocusGroup
.
visible
=
true
;
emitter
.
$emit
(
"mapPlayComplete"
)
emitter
.
$emit
(
"mapPlayComplete"
)
;
},
},
},
},
"focusMapOpacity"
"focusMapOpacity"
)
)
;
this
.
allBar
.
map
((
item
,
index
)
=>
{
this
.
allBar
.
map
((
item
,
index
)
=>
{
if
(
item
.
userData
.
name
===
"广州市"
)
{
if
(
item
.
userData
.
name
===
"广州市"
)
{
return
false
return
false
;
}
}
tl
.
to
(
tl
.
to
(
item
.
scale
,
item
.
scale
,
...
@@ -308,8 +323,8 @@ export class World extends Mini3d {
...
@@ -308,8 +323,8 @@ export class World extends Mini3d {
ease
:
"circ.out"
,
ease
:
"circ.out"
,
},
},
"bar"
"bar"
)
)
;
})
})
;
this
.
allBarMaterial
.
map
((
item
,
index
)
=>
{
this
.
allBarMaterial
.
map
((
item
,
index
)
=>
{
tl
.
to
(
tl
.
to
(
item
,
item
,
...
@@ -320,16 +335,16 @@ export class World extends Mini3d {
...
@@ -320,16 +335,16 @@ export class World extends Mini3d {
ease
:
"circ.out"
,
ease
:
"circ.out"
,
},
},
"bar"
"bar"
)
)
;
})
})
;
this
.
allProvinceLabel
.
map
((
item
,
index
)
=>
{
this
.
allProvinceLabel
.
map
((
item
,
index
)
=>
{
let
element
=
item
.
element
.
querySelector
(
".provinces-label-wrap"
)
let
element
=
item
.
element
.
querySelector
(
".provinces-label-wrap"
)
;
let
number
=
item
.
element
.
querySelector
(
".number .value"
)
let
number
=
item
.
element
.
querySelector
(
".number .value"
)
;
let
numberVal
=
Number
(
number
.
innerText
)
let
numberVal
=
Number
(
number
.
innerText
)
;
let
numberAnimate
=
{
let
numberAnimate
=
{
score
:
0
,
score
:
0
,
}
}
;
tl
.
to
(
tl
.
to
(
element
,
element
,
{
{
...
@@ -340,7 +355,7 @@ export class World extends Mini3d {
...
@@ -340,7 +355,7 @@ export class World extends Mini3d {
ease
:
"circ.out"
,
ease
:
"circ.out"
,
},
},
"bar"
"bar"
)
)
;
tl
.
to
(
tl
.
to
(
numberAnimate
,
numberAnimate
,
{
{
...
@@ -350,11 +365,11 @@ export class World extends Mini3d {
...
@@ -350,11 +365,11 @@ export class World extends Mini3d {
onUpdate
:
showScore
,
onUpdate
:
showScore
,
},
},
"bar"
"bar"
)
)
;
function
showScore
()
{
function
showScore
()
{
number
.
innerText
=
numberAnimate
.
score
.
toFixed
(
0
)
number
.
innerText
=
numberAnimate
.
score
.
toFixed
(
0
)
;
}
}
})
})
;
this
.
allGuangquan
.
map
((
item
,
index
)
=>
{
this
.
allGuangquan
.
map
((
item
,
index
)
=>
{
tl
.
to
(
tl
.
to
(
item
.
children
[
0
].
scale
,
item
.
children
[
0
].
scale
,
...
@@ -367,7 +382,7 @@ export class World extends Mini3d {
...
@@ -367,7 +382,7 @@ export class World extends Mini3d {
ease
:
"circ.out"
,
ease
:
"circ.out"
,
},
},
"bar"
"bar"
)
)
;
tl
.
to
(
tl
.
to
(
item
.
children
[
1
].
scale
,
item
.
children
[
1
].
scale
,
{
{
...
@@ -379,20 +394,20 @@ export class World extends Mini3d {
...
@@ -379,20 +394,20 @@ export class World extends Mini3d {
ease
:
"circ.out"
,
ease
:
"circ.out"
,
},
},
"bar"
"bar"
)
)
;
})
})
;
}
}
initEnvironment
()
{
initEnvironment
()
{
let
sun
=
new
AmbientLight
(
0xffffff
,
5
)
let
sun
=
new
AmbientLight
(
0xffffff
,
5
)
;
this
.
scene
.
add
(
sun
)
this
.
scene
.
add
(
sun
)
;
let
directionalLight
=
new
DirectionalLight
(
0xffffff
,
5
)
let
directionalLight
=
new
DirectionalLight
(
0xffffff
,
5
)
;
directionalLight
.
position
.
set
(
-
30
,
6
,
-
8
)
directionalLight
.
position
.
set
(
-
30
,
6
,
-
8
)
;
directionalLight
.
castShadow
=
true
directionalLight
.
castShadow
=
true
;
directionalLight
.
shadow
.
radius
=
20
directionalLight
.
shadow
.
radius
=
20
;
directionalLight
.
shadow
.
mapSize
.
width
=
1024
directionalLight
.
shadow
.
mapSize
.
width
=
1024
;
directionalLight
.
shadow
.
mapSize
.
height
=
1024
directionalLight
.
shadow
.
mapSize
.
height
=
1024
;
this
.
scene
.
add
(
directionalLight
)
this
.
scene
.
add
(
directionalLight
)
;
this
.
createPointLight
({
this
.
createPointLight
({
color
:
"#1d5e5e"
,
color
:
"#1d5e5e"
,
intensity
:
800
,
intensity
:
800
,
...
@@ -400,7 +415,7 @@ export class World extends Mini3d {
...
@@ -400,7 +415,7 @@ export class World extends Mini3d {
x
:
-
9
,
x
:
-
9
,
y
:
3
,
y
:
3
,
z
:
-
3
,
z
:
-
3
,
})
})
;
this
.
createPointLight
({
this
.
createPointLight
({
color
:
"#1d5e5e"
,
color
:
"#1d5e5e"
,
intensity
:
200
,
intensity
:
200
,
...
@@ -409,50 +424,54 @@ export class World extends Mini3d {
...
@@ -409,50 +424,54 @@ export class World extends Mini3d {
// y: 2,
// y: 2,
y
:
-
2
,
y
:
-
2
,
z
:
5
,
z
:
5
,
})
})
;
}
}
createPointLight
(
pointParams
)
{
createPointLight
(
pointParams
)
{
const
pointLight
=
new
PointLight
(
0x1d5e5e
,
pointParams
.
intensity
,
pointParams
.
distance
)
const
pointLight
=
new
PointLight
(
pointLight
.
position
.
set
(
pointParams
.
x
,
pointParams
.
y
,
pointParams
.
z
)
0x1d5e5e
,
this
.
scene
.
add
(
pointLight
)
pointParams
.
intensity
,
pointParams
.
distance
);
pointLight
.
position
.
set
(
pointParams
.
x
,
pointParams
.
y
,
pointParams
.
z
);
this
.
scene
.
add
(
pointLight
);
}
}
createMap
()
{
createMap
()
{
let
mapGroup
=
new
Group
()
let
mapGroup
=
new
Group
()
;
let
focusMapGroup
=
new
Group
()
let
focusMapGroup
=
new
Group
()
;
this
.
focusMapGroup
=
focusMapGroup
this
.
focusMapGroup
=
focusMapGroup
;
let
{
china
,
chinaTopLine
}
=
this
.
createChina
()
let
{
china
,
chinaTopLine
}
=
this
.
createChina
()
;
let
{
map
,
mapTop
,
mapLine
}
=
this
.
createProvince
()
let
{
map
,
mapTop
,
mapLine
}
=
this
.
createProvince
()
;
let
{
waterGroup
}
=
this
.
createWater
()
let
{
waterGroup
}
=
this
.
createWater
()
;
let
{
lineWaterGroup
}
=
this
.
createLineWater
()
let
{
lineWaterGroup
}
=
this
.
createLineWater
()
;
china
.
setParent
(
mapGroup
)
china
.
setParent
(
mapGroup
)
;
chinaTopLine
.
setParent
(
mapGroup
)
chinaTopLine
.
setParent
(
mapGroup
)
;
// 创建扩散
// 创建扩散
this
.
createDiffuse
()
this
.
createDiffuse
()
;
map
.
setParent
(
focusMapGroup
)
map
.
setParent
(
focusMapGroup
)
;
mapTop
.
setParent
(
focusMapGroup
)
mapTop
.
setParent
(
focusMapGroup
)
;
mapLine
.
setParent
(
focusMapGroup
)
mapLine
.
setParent
(
focusMapGroup
)
;
focusMapGroup
.
add
(
waterGroup
)
focusMapGroup
.
add
(
waterGroup
)
;
focusMapGroup
.
add
(
lineWaterGroup
)
focusMapGroup
.
add
(
lineWaterGroup
)
;
focusMapGroup
.
position
.
set
(
0
,
0
,
-
0.01
)
focusMapGroup
.
position
.
set
(
0
,
0
,
-
0.01
)
;
focusMapGroup
.
scale
.
set
(
1
,
1
,
0
)
focusMapGroup
.
scale
.
set
(
1
,
1
,
0
)
;
focusMapGroup
.
name
=
"focusMapGroup"
focusMapGroup
.
name
=
"focusMapGroup"
;
mapGroup
.
add
(
focusMapGroup
)
mapGroup
.
add
(
focusMapGroup
)
;
mapGroup
.
rotation
.
x
=
-
Math
.
PI
/
2
mapGroup
.
rotation
.
x
=
-
Math
.
PI
/
2
;
mapGroup
.
position
.
set
(
0
,
0.2
,
0
)
mapGroup
.
position
.
set
(
0
,
0.2
,
0
)
;
this
.
scene
.
add
(
mapGroup
)
this
.
scene
.
add
(
mapGroup
)
;
this
.
createBar
()
this
.
createBar
()
;
}
}
createChina
()
{
createChina
()
{
let
params
=
{
let
params
=
{
chinaBgMaterialColor
:
"#152c47"
,
chinaBgMaterialColor
:
"#152c47"
,
lineColor
:
"#3f82cd"
,
lineColor
:
"#3f82cd"
,
}
}
;
let
chinaData
=
this
.
assets
.
instance
.
getResource
(
"china"
)
let
chinaData
=
this
.
assets
.
instance
.
getResource
(
"china"
)
;
let
chinaBgMaterial
=
new
MeshLambertMaterial
({
let
chinaBgMaterial
=
new
MeshLambertMaterial
({
color
:
new
Color
(
params
.
chinaBgMaterialColor
),
color
:
new
Color
(
params
.
chinaBgMaterialColor
),
transparent
:
true
,
transparent
:
true
,
opacity
:
1
,
opacity
:
1
,
})
})
;
let
china
=
new
BaseMap
(
this
,
{
let
china
=
new
BaseMap
(
this
,
{
//position: new Vector3(0, 0, -0.03),
//position: new Vector3(0, 0, -0.03),
data
:
chinaData
,
data
:
chinaData
,
...
@@ -461,10 +480,10 @@ export class World extends Mini3d {
...
@@ -461,10 +480,10 @@ export class World extends Mini3d {
merge
:
true
,
merge
:
true
,
material
:
chinaBgMaterial
,
material
:
chinaBgMaterial
,
renderOrder
:
2
,
renderOrder
:
2
,
})
})
;
let
chinaTopLineMaterial
=
new
LineBasicMaterial
({
let
chinaTopLineMaterial
=
new
LineBasicMaterial
({
color
:
params
.
lineColor
,
color
:
params
.
lineColor
,
})
})
;
let
chinaTopLine
=
new
Line
(
this
,
{
let
chinaTopLine
=
new
Line
(
this
,
{
// position: new Vector3(0, 0, -0.02),
// position: new Vector3(0, 0, -0.02),
data
:
chinaData
,
data
:
chinaData
,
...
@@ -472,15 +491,15 @@ export class World extends Mini3d {
...
@@ -472,15 +491,15 @@ export class World extends Mini3d {
geoProjectionScale
:
this
.
geoProjectionScale
,
geoProjectionScale
:
this
.
geoProjectionScale
,
material
:
chinaTopLineMaterial
,
material
:
chinaTopLineMaterial
,
renderOrder
:
3
,
renderOrder
:
3
,
})
})
;
chinaTopLine
.
lineGroup
.
position
.
z
+=
0.01
chinaTopLine
.
lineGroup
.
position
.
z
+=
0.01
;
return
{
china
,
chinaTopLine
}
return
{
china
,
chinaTopLine
}
;
}
}
createProvince
()
{
createProvince
()
{
let
mapJsonData
=
this
.
assets
.
instance
.
getResource
(
"mapJson"
)
let
mapJsonData
=
this
.
assets
.
instance
.
getResource
(
"mapJson"
)
;
let
[
topMaterial
,
sideMaterial
]
=
this
.
createProvinceMaterial
()
let
[
topMaterial
,
sideMaterial
]
=
this
.
createProvinceMaterial
()
;
this
.
focusMapTopMaterial
=
topMaterial
this
.
focusMapTopMaterial
=
topMaterial
;
this
.
focusMapSideMaterial
=
sideMaterial
this
.
focusMapSideMaterial
=
sideMaterial
;
let
map
=
new
ExtrudeMap
(
this
,
{
let
map
=
new
ExtrudeMap
(
this
,
{
geoProjectionCenter
:
this
.
geoProjectionCenter
,
geoProjectionCenter
:
this
.
geoProjectionCenter
,
geoProjectionScale
:
this
.
geoProjectionScale
,
geoProjectionScale
:
this
.
geoProjectionScale
,
...
@@ -490,23 +509,23 @@ export class World extends Mini3d {
...
@@ -490,23 +509,23 @@ export class World extends Mini3d {
topFaceMaterial
:
topMaterial
,
topFaceMaterial
:
topMaterial
,
sideMaterial
:
sideMaterial
,
sideMaterial
:
sideMaterial
,
renderOrder
:
9
,
renderOrder
:
9
,
})
})
;
let
faceMaterial
=
new
MeshStandardMaterial
({
let
faceMaterial
=
new
MeshStandardMaterial
({
color
:
0xffffff
,
color
:
0xffffff
,
transparent
:
true
,
transparent
:
true
,
opacity
:
0.5
,
opacity
:
0.5
,
// fog: false,
// fog: false,
})
})
;
let
faceGradientShader
=
new
GradientShader
(
faceMaterial
,
{
let
faceGradientShader
=
new
GradientShader
(
faceMaterial
,
{
// uColor1: 0x2a6e92,
// uColor1: 0x2a6e92,
// uColor2: 0x102736,
// uColor2: 0x102736,
uColor1
:
0x12bbe0
,
uColor1
:
0x12bbe0
,
uColor2
:
0x0094b5
,
uColor2
:
0x0094b5
,
})
})
;
this
.
defaultMaterial
=
faceMaterial
this
.
defaultMaterial
=
faceMaterial
;
this
.
defaultLightMaterial
=
this
.
defaultMaterial
.
clone
()
this
.
defaultLightMaterial
=
this
.
defaultMaterial
.
clone
()
;
this
.
defaultLightMaterial
.
color
=
new
Color
(
"rgba(115,208,255,1)"
)
this
.
defaultLightMaterial
.
color
=
new
Color
(
"rgba(115,208,255,1)"
)
;
this
.
defaultLightMaterial
.
opacity
=
0.8
this
.
defaultLightMaterial
.
opacity
=
0.8
;
// this.defaultLightMaterial.emissive.setHex(new Color("rgba(115,208,255,1)"));
// this.defaultLightMaterial.emissive.setHex(new Color("rgba(115,208,255,1)"));
// this.defaultLightMaterial.emissiveIntensity = 3.5;
// this.defaultLightMaterial.emissiveIntensity = 3.5;
let
mapTop
=
new
BaseMap
(
this
,
{
let
mapTop
=
new
BaseMap
(
this
,
{
...
@@ -516,34 +535,34 @@ export class World extends Mini3d {
...
@@ -516,34 +535,34 @@ export class World extends Mini3d {
data
:
mapJsonData
,
data
:
mapJsonData
,
material
:
faceMaterial
,
material
:
faceMaterial
,
renderOrder
:
2
,
renderOrder
:
2
,
})
})
;
mapTop
.
mapGroup
.
children
.
map
((
group
)
=>
{
mapTop
.
mapGroup
.
children
.
map
((
group
)
=>
{
group
.
name
=
group
.
userData
.
name
group
.
name
=
group
.
userData
.
name
;
group
.
children
.
map
((
mesh
)
=>
{
group
.
children
.
map
((
mesh
)
=>
{
if
(
mesh
.
type
===
"Mesh"
)
{
if
(
mesh
.
type
===
"Mesh"
)
{
this
.
eventElement
.
push
(
mesh
)
this
.
eventElement
.
push
(
mesh
)
;
}
}
})
})
;
})
})
;
this
.
mapLineMaterial
=
new
LineBasicMaterial
({
this
.
mapLineMaterial
=
new
LineBasicMaterial
({
color
:
0xffffff
,
color
:
0xffffff
,
opacity
:
0
,
opacity
:
0
,
transparent
:
true
,
transparent
:
true
,
fog
:
false
,
fog
:
false
,
})
})
;
let
mapLine
=
new
Line
(
this
,
{
let
mapLine
=
new
Line
(
this
,
{
geoProjectionCenter
:
this
.
geoProjectionCenter
,
geoProjectionCenter
:
this
.
geoProjectionCenter
,
geoProjectionScale
:
this
.
geoProjectionScale
,
geoProjectionScale
:
this
.
geoProjectionScale
,
data
:
mapJsonData
,
data
:
mapJsonData
,
material
:
this
.
mapLineMaterial
,
material
:
this
.
mapLineMaterial
,
renderOrder
:
3
,
renderOrder
:
3
,
})
})
;
mapLine
.
lineGroup
.
position
.
z
+=
this
.
depth
+
0.23
mapLine
.
lineGroup
.
position
.
z
+=
this
.
depth
+
0.23
;
return
{
return
{
map
,
map
,
mapTop
,
mapTop
,
mapLine
,
mapLine
,
}
}
;
}
}
createProvinceMaterial
()
{
createProvinceMaterial
()
{
let
topMaterial
=
new
MeshLambertMaterial
({
let
topMaterial
=
new
MeshLambertMaterial
({
...
@@ -552,13 +571,13 @@ export class World extends Mini3d {
...
@@ -552,13 +571,13 @@ export class World extends Mini3d {
opacity
:
0
,
opacity
:
0
,
fog
:
false
,
fog
:
false
,
side
:
DoubleSide
,
side
:
DoubleSide
,
})
})
;
topMaterial
.
onBeforeCompile
=
(
shader
)
=>
{
topMaterial
.
onBeforeCompile
=
(
shader
)
=>
{
shader
.
uniforms
=
{
shader
.
uniforms
=
{
...
shader
.
uniforms
,
...
shader
.
uniforms
,
uColor1
:
{
value
:
new
Color
(
0x2a6e92
)
},
// 419daa
uColor1
:
{
value
:
new
Color
(
0x2a6e92
)
},
// 419daa
uColor2
:
{
value
:
new
Color
(
0x102736
)
},
uColor2
:
{
value
:
new
Color
(
0x102736
)
},
}
}
;
shader
.
vertexShader
=
shader
.
vertexShader
.
replace
(
shader
.
vertexShader
=
shader
.
vertexShader
.
replace
(
"void main() {"
,
"void main() {"
,
`
`
...
@@ -569,7 +588,7 @@ export class World extends Mini3d {
...
@@ -569,7 +588,7 @@ export class World extends Mini3d {
vAlpha = alpha;
vAlpha = alpha;
vPosition = position;
vPosition = position;
`
`
)
)
;
shader
.
fragmentShader
=
shader
.
fragmentShader
.
replace
(
shader
.
fragmentShader
=
shader
.
fragmentShader
.
replace
(
"void main() {"
,
"void main() {"
,
`
`
...
@@ -579,7 +598,7 @@ export class World extends Mini3d {
...
@@ -579,7 +598,7 @@ export class World extends Mini3d {
uniform vec3 uColor2;
uniform vec3 uColor2;
void main() {
void main() {
`
`
)
)
;
shader
.
fragmentShader
=
shader
.
fragmentShader
.
replace
(
shader
.
fragmentShader
=
shader
.
fragmentShader
.
replace
(
"#include <opaque_fragment>"
,
"#include <opaque_fragment>"
,
/* glsl */
`
/* glsl */
`
...
@@ -597,29 +616,29 @@ export class World extends Mini3d {
...
@@ -597,29 +616,29 @@ export class World extends Mini3d {
}
}
gl_FragColor = vec4( outgoingLight, diffuseColor.a );
gl_FragColor = vec4( outgoingLight, diffuseColor.a );
`
`
)
)
;
}
}
;
let
sideMap
=
this
.
assets
.
instance
.
getResource
(
"side"
)
let
sideMap
=
this
.
assets
.
instance
.
getResource
(
"side"
)
;
sideMap
.
wrapS
=
RepeatWrapping
sideMap
.
wrapS
=
RepeatWrapping
;
sideMap
.
wrapT
=
RepeatWrapping
sideMap
.
wrapT
=
RepeatWrapping
;
sideMap
.
repeat
.
set
(
1
,
1.5
)
sideMap
.
repeat
.
set
(
1
,
1.5
)
;
sideMap
.
offset
.
y
+=
0.065
sideMap
.
offset
.
y
+=
0.065
;
let
sideMaterial
=
new
MeshStandardMaterial
({
let
sideMaterial
=
new
MeshStandardMaterial
({
color
:
0xffffff
,
color
:
0xffffff
,
map
:
sideMap
,
map
:
sideMap
,
fog
:
false
,
fog
:
false
,
opacity
:
0
,
opacity
:
0
,
side
:
DoubleSide
,
side
:
DoubleSide
,
})
})
;
this
.
time
.
on
(
"tick"
,
()
=>
{
this
.
time
.
on
(
"tick"
,
()
=>
{
sideMap
.
offset
.
y
+=
0.005
sideMap
.
offset
.
y
+=
0.005
;
})
})
;
sideMaterial
.
onBeforeCompile
=
(
shader
)
=>
{
sideMaterial
.
onBeforeCompile
=
(
shader
)
=>
{
shader
.
uniforms
=
{
shader
.
uniforms
=
{
...
shader
.
uniforms
,
...
shader
.
uniforms
,
uColor1
:
{
value
:
new
Color
(
0x2a6e92
)
},
uColor1
:
{
value
:
new
Color
(
0x2a6e92
)
},
uColor2
:
{
value
:
new
Color
(
0x2a6e92
)
},
uColor2
:
{
value
:
new
Color
(
0x2a6e92
)
},
}
}
;
shader
.
vertexShader
=
shader
.
vertexShader
.
replace
(
shader
.
vertexShader
=
shader
.
vertexShader
.
replace
(
"void main() {"
,
"void main() {"
,
`
`
...
@@ -630,7 +649,7 @@ export class World extends Mini3d {
...
@@ -630,7 +649,7 @@ export class World extends Mini3d {
vAlpha = alpha;
vAlpha = alpha;
vPosition = position;
vPosition = position;
`
`
)
)
;
shader
.
fragmentShader
=
shader
.
fragmentShader
.
replace
(
shader
.
fragmentShader
=
shader
.
fragmentShader
.
replace
(
"void main() {"
,
"void main() {"
,
`
`
...
@@ -640,7 +659,7 @@ export class World extends Mini3d {
...
@@ -640,7 +659,7 @@ export class World extends Mini3d {
uniform vec3 uColor2;
uniform vec3 uColor2;
void main() {
void main() {
`
`
)
)
;
shader
.
fragmentShader
=
shader
.
fragmentShader
.
replace
(
shader
.
fragmentShader
=
shader
.
fragmentShader
.
replace
(
"#include <opaque_fragment>"
,
"#include <opaque_fragment>"
,
/* glsl */
`
/* glsl */
`
...
@@ -654,64 +673,73 @@ export class World extends Mini3d {
...
@@ -654,64 +673,73 @@ export class World extends Mini3d {
outgoingLight = outgoingLight*gradient;
outgoingLight = outgoingLight*gradient;
gl_FragColor = vec4( outgoingLight, diffuseColor.a );
gl_FragColor = vec4( outgoingLight, diffuseColor.a );
`
`
)
)
;
}
}
;
return
[
topMaterial
,
sideMaterial
]
return
[
topMaterial
,
sideMaterial
]
;
}
}
createBar
()
{
createBar
()
{
let
self
=
this
let
self
=
this
;
let
data
=
sortByValue
(
provincesData
).
filter
((
item
,
index
)
=>
index
<
7
)
let
data
=
sortByValue
(
provincesData
).
filter
((
item
,
index
)
=>
index
<
7
)
;
const
barGroup
=
new
Group
()
const
barGroup
=
new
Group
()
;
this
.
barGroup
=
barGroup
this
.
barGroup
=
barGroup
;
const
factor
=
0.7
const
factor
=
0.7
;
const
height
=
4.0
*
factor
const
height
=
4.0
*
factor
;
const
max
=
data
[
0
].
value
const
max
=
data
[
0
].
value
;
this
.
allBar
=
[]
this
.
allBar
=
[]
;
this
.
allBarMaterial
=
[]
this
.
allBarMaterial
=
[]
;
this
.
allGuangquan
=
[]
this
.
allGuangquan
=
[]
;
this
.
allProvinceLabel
=
[]
this
.
allProvinceLabel
=
[]
;
data
.
map
((
item
,
index
)
=>
{
data
.
map
((
item
,
index
)
=>
{
let
geoHeight
=
height
*
(
item
.
value
/
max
)
let
geoHeight
=
height
*
(
item
.
value
/
max
)
;
let
material
=
new
MeshBasicMaterial
({
let
material
=
new
MeshBasicMaterial
({
color
:
0xffffff
,
color
:
0xffffff
,
transparent
:
true
,
transparent
:
true
,
opacity
:
0
,
opacity
:
0
,
depthTest
:
false
,
depthTest
:
false
,
fog
:
false
,
fog
:
false
,
})
})
;
new
GradientShader
(
material
,
{
new
GradientShader
(
material
,
{
uColor1
:
index
>
3
?
0xfbdf88
:
0x50bbfe
,
uColor1
:
index
>
3
?
0xfbdf88
:
0x50bbfe
,
uColor2
:
index
>
3
?
0xfffef4
:
0x77fbf5
,
uColor2
:
index
>
3
?
0xfffef4
:
0x77fbf5
,
size
:
geoHeight
,
size
:
geoHeight
,
dir
:
"y"
,
dir
:
"y"
,
})
});
const
geo
=
new
BoxGeometry
(
0.1
*
factor
,
0.1
*
factor
,
geoHeight
)
const
geo
=
new
BoxGeometry
(
0.1
*
factor
,
0.1
*
factor
,
geoHeight
);
geo
.
translate
(
0
,
0
,
geoHeight
/
2
)
geo
.
translate
(
0
,
0
,
geoHeight
/
2
);
const
mesh
=
new
Mesh
(
geo
,
material
)
const
mesh
=
new
Mesh
(
geo
,
material
);
mesh
.
renderOrder
=
5
mesh
.
renderOrder
=
5
;
let
areaBar
=
mesh
let
areaBar
=
mesh
;
let
[
x
,
y
]
=
this
.
geoProjection
(
item
.
centroid
)
let
[
x
,
y
]
=
this
.
geoProjection
(
item
.
centroid
);
areaBar
.
position
.
set
(
x
,
-
y
,
this
.
depth
+
0.45
)
areaBar
.
position
.
set
(
x
,
-
y
,
this
.
depth
+
0.45
);
areaBar
.
scale
.
set
(
1
,
1
,
0
)
areaBar
.
scale
.
set
(
1
,
1
,
0
);
areaBar
.
userData
=
{
...
item
}
areaBar
.
userData
=
{
...
item
};
let
guangQuan
=
this
.
createQuan
(
new
Vector3
(
x
,
this
.
depth
+
0.44
,
y
),
index
)
let
guangQuan
=
this
.
createQuan
(
let
hg
=
this
.
createHUIGUANG
(
geoHeight
,
index
>
3
?
0xfffef4
:
0x77fbf5
)
new
Vector3
(
x
,
this
.
depth
+
0.44
,
y
),
areaBar
.
add
(...
hg
)
index
barGroup
.
add
(
areaBar
)
);
barGroup
.
rotation
.
x
=
-
Math
.
PI
/
2
let
hg
=
this
.
createHUIGUANG
(
geoHeight
,
index
>
3
?
0xfffef4
:
0x77fbf5
);
let
barLabel
=
labelStyle04
(
item
,
index
,
new
Vector3
(
x
,
-
y
,
this
.
depth
+
1.1
+
geoHeight
))
areaBar
.
add
(...
hg
);
this
.
allBar
.
push
(
areaBar
)
barGroup
.
add
(
areaBar
);
this
.
allBarMaterial
.
push
(
material
)
barGroup
.
rotation
.
x
=
-
Math
.
PI
/
2
;
this
.
allGuangquan
.
push
(
guangQuan
)
let
barLabel
=
labelStyle04
(
this
.
allProvinceLabel
.
push
(
barLabel
)
item
,
})
index
,
this
.
scene
.
add
(
barGroup
)
new
Vector3
(
x
,
-
y
,
this
.
depth
+
1.1
+
geoHeight
)
);
this
.
allBar
.
push
(
areaBar
);
this
.
allBarMaterial
.
push
(
material
);
this
.
allGuangquan
.
push
(
guangQuan
);
this
.
allProvinceLabel
.
push
(
barLabel
);
});
this
.
scene
.
add
(
barGroup
);
function
labelStyle04
(
data
,
index
,
position
)
{
function
labelStyle04
(
data
,
index
,
position
)
{
let
label
=
self
.
label3d
.
create
(
""
,
"provinces-label"
,
false
)
let
label
=
self
.
label3d
.
create
(
""
,
"provinces-label"
,
false
)
;
label
.
init
(
label
.
init
(
`<div class="provinces-label
${
index
>
4
?
"yellow"
:
""
}
">
`<div class="provinces-label
${
index
>
4
?
"yellow"
:
""
}
">
<div class="provinces-label-wrap">
<div class="provinces-label-wrap">
<div class="number"><span class="value">
${
data
.
value
}
</span><span class="unit">万人</span></div>
<div class="number"><span class="value">
${
data
.
value
}
</span><span class="unit">万人</span></div>
<div class="name">
<div class="name">
<span class="zh">
${
data
.
name
}
</span>
<span class="zh">
${
data
.
name
}
</span>
<span class="en">
${
data
.
enName
.
toUpperCase
()}
</span>
<span class="en">
${
data
.
enName
.
toUpperCase
()}
</span>
...
@@ -720,84 +748,86 @@ export class World extends Mini3d {
...
@@ -720,84 +748,86 @@ export class World extends Mini3d {
</div>
</div>
</div>`
,
</div>`
,
position
position
)
)
;
self
.
label3d
.
setLabelStyle
(
label
,
0.01
,
"x"
)
self
.
label3d
.
setLabelStyle
(
label
,
0.01
,
"x"
)
;
label
.
setParent
(
self
.
labelGroup
)
label
.
setParent
(
self
.
labelGroup
)
;
return
label
return
label
;
}
}
}
}
createEvent
()
{
createEvent
()
{
let
objectsHover
=
[]
let
objectsHover
=
[]
;
const
reset
=
(
mesh
)
=>
{
const
reset
=
(
mesh
)
=>
{
mesh
.
traverse
((
obj
)
=>
{
mesh
.
traverse
((
obj
)
=>
{
if
(
obj
.
isMesh
)
{
if
(
obj
.
isMesh
)
{
obj
.
material
=
this
.
defaultMaterial
obj
.
material
=
this
.
defaultMaterial
;
}
})
}
}
});
};
const
move
=
(
mesh
)
=>
{
const
move
=
(
mesh
)
=>
{
mesh
.
traverse
((
obj
)
=>
{
mesh
.
traverse
((
obj
)
=>
{
if
(
obj
.
isMesh
)
{
if
(
obj
.
isMesh
)
{
obj
.
material
=
this
.
defaultLightMaterial
obj
.
material
=
this
.
defaultLightMaterial
;
}
})
}
}
});
};
this
.
eventElement
.
map
((
mesh
)
=>
{
this
.
eventElement
.
map
((
mesh
)
=>
{
this
.
interactionManager
.
add
(
mesh
)
this
.
interactionManager
.
add
(
mesh
)
;
mesh
.
addEventListener
(
"mousedown"
,
(
ev
)
=>
{
mesh
.
addEventListener
(
"mousedown"
,
(
ev
)
=>
{
let
countryName
=
ev
.
target
.
userData
.
name
let
countryName
=
ev
.
target
.
userData
.
name
;
this
.
countryData
=
ev
.
target
.
parent
.
parent
.
children
this
.
countryData
=
ev
.
target
.
parent
.
parent
.
children
;
if
(
ev
.
originalEvent
.
buttons
===
1
)
{
if
(
ev
.
originalEvent
.
buttons
===
1
)
{
console
.
log
(
"label"
,
this
.
label112
)
console
.
log
(
"label"
,
this
.
label112
);
this
.
focusMapGroup
.
children
[
0
].
visible
=
false
this
.
focusMapGroup
.
children
[
0
].
visible
=
false
;
this
.
countryData
.
map
((
item
)
=>
{
this
.
countryData
.
map
((
item
)
=>
{
// console.log("this.mapFocusLabel",this.mapFocusLabel)
// console.log("this.mapFocusLabel",this.mapFocusLabel)
if
(
item
.
name
!=
countryName
)
{
if
(
item
.
name
!=
countryName
)
{
item
.
visible
=
false
// 隐藏其他区域
item
.
visible
=
false
;
// 隐藏其他区域
}
else
{
}
else
{
console
.
log
(
"item"
,
item
)
console
.
log
(
"item"
,
item
);
item
.
visible
=
true
// 显示被点击的区域
item
.
visible
=
true
;
// 显示被点击的区域
const
[
x
,
y
]
=
this
.
geoProjection
([
109.840171
,
38.864362
])
const
[
x
,
y
]
=
this
.
geoProjection
([
109.840171
,
38.864362
])
;
// console.log("mapFocusLabel",this.mapFocusLabel)
// console.log("mapFocusLabel",this.mapFocusLabel)
this
.
mapFocusLabel
.
element
.
innerHTML
=
`<div class="other-label" style="translate: none; rotate: none; scale: none; opacity: 1; transform: translate(0px, 0px);"><span>
${
item
.
name
}
</span><span>ZHUNGEERQI</span></div>`
this
.
mapFocusLabel
.
element
.
innerHTML
=
`<div class="other-label" style="translate: none; rotate: none; scale: none; opacity: 1; transform: translate(0px, 0px);"><span>
${
item
.
name
}
</span><span>ZHUNGEERQI</span></div>`
;
// this.mapFocusLabel.position.set(x, -y, 0.4);
// this.mapFocusLabel.position.set(x, -y, 0.4);
}
}
})
})
;
}
}
})
})
;
mesh
.
addEventListener
(
"mouseover"
,
(
event
)
=>
{
mesh
.
addEventListener
(
"mouseover"
,
(
event
)
=>
{
if
(
!
objectsHover
.
includes
(
event
.
target
.
parent
))
{
if
(
!
objectsHover
.
includes
(
event
.
target
.
parent
))
{
objectsHover
.
push
(
event
.
target
.
parent
)
objectsHover
.
push
(
event
.
target
.
parent
)
;
}
}
document
.
body
.
style
.
cursor
=
"pointer"
document
.
body
.
style
.
cursor
=
"pointer"
;
move
(
event
.
target
.
parent
)
move
(
event
.
target
.
parent
)
;
})
})
;
mesh
.
addEventListener
(
"mouseout"
,
(
event
)
=>
{
mesh
.
addEventListener
(
"mouseout"
,
(
event
)
=>
{
objectsHover
=
objectsHover
.
filter
((
n
)
=>
n
.
userData
.
name
!==
event
.
target
.
parent
.
userData
.
name
)
objectsHover
=
objectsHover
.
filter
(
(
n
)
=>
n
.
userData
.
name
!==
event
.
target
.
parent
.
userData
.
name
);
if
(
objectsHover
.
length
>
0
)
{
if
(
objectsHover
.
length
>
0
)
{
const
mesh
=
objectsHover
[
objectsHover
.
length
-
1
]
const
mesh
=
objectsHover
[
objectsHover
.
length
-
1
]
;
}
}
reset
(
event
.
target
.
parent
)
reset
(
event
.
target
.
parent
)
;
document
.
body
.
style
.
cursor
=
"default"
document
.
body
.
style
.
cursor
=
"default"
;
})
})
;
})
})
;
document
.
addEventListener
(
"contextmenu"
,(
event
)
=>
{
document
.
addEventListener
(
"contextmenu"
,
(
event
)
=>
{
this
.
focusMapGroup
.
children
[
0
].
visible
=
true
this
.
focusMapGroup
.
children
[
0
].
visible
=
true
;
if
(
this
.
countryData
.
length
>
0
)
{
if
(
this
.
countryData
.
length
>
0
)
{
this
.
countryData
.
map
((
item
)
=>
{
this
.
countryData
.
map
((
item
)
=>
{
item
.
visible
=
true
// 显示所有区域
item
.
visible
=
true
;
// 显示所有区域
this
.
mapFocusLabel
.
element
.
innerHTML
=
`<div class="other-label" style="translate: none; rotate: none; scale: none; opacity: 1; transform: translate(0px, 0px);"><span>准格尔旗</span><span>ZHUNGEER QI</span></div>`
this
.
mapFocusLabel
.
element
.
innerHTML
=
`<div class="other-label" style="translate: none; rotate: none; scale: none; opacity: 1; transform: translate(0px, 0px);"><span>准格尔旗</span><span>ZHUNGEER QI</span></div>`
;
})
})
;
}
}
})
})
;
}
}
createHUIGUANG
(
h
,
color
)
{
createHUIGUANG
(
h
,
color
)
{
let
geometry
=
new
PlaneGeometry
(
0.35
,
h
)
let
geometry
=
new
PlaneGeometry
(
0.35
,
h
)
;
geometry
.
translate
(
0
,
h
/
2
,
0
)
geometry
.
translate
(
0
,
h
/
2
,
0
)
;
const
texture
=
this
.
assets
.
instance
.
getResource
(
"huiguang"
)
const
texture
=
this
.
assets
.
instance
.
getResource
(
"huiguang"
)
;
texture
.
colorSpace
=
SRGBColorSpace
texture
.
colorSpace
=
SRGBColorSpace
;
texture
.
wrapS
=
RepeatWrapping
texture
.
wrapS
=
RepeatWrapping
;
texture
.
wrapT
=
RepeatWrapping
texture
.
wrapT
=
RepeatWrapping
;
let
material
=
new
MeshBasicMaterial
({
let
material
=
new
MeshBasicMaterial
({
color
:
color
,
color
:
color
,
map
:
texture
,
map
:
texture
,
...
@@ -806,20 +836,20 @@ export class World extends Mini3d {
...
@@ -806,20 +836,20 @@ export class World extends Mini3d {
depthWrite
:
false
,
depthWrite
:
false
,
side
:
DoubleSide
,
side
:
DoubleSide
,
blending
:
AdditiveBlending
,
blending
:
AdditiveBlending
,
})
})
;
let
mesh
=
new
Mesh
(
geometry
,
material
)
let
mesh
=
new
Mesh
(
geometry
,
material
)
;
mesh
.
renderOrder
=
10
mesh
.
renderOrder
=
10
;
mesh
.
rotateX
(
Math
.
PI
/
2
)
mesh
.
rotateX
(
Math
.
PI
/
2
)
;
let
mesh2
=
mesh
.
clone
()
let
mesh2
=
mesh
.
clone
()
;
let
mesh3
=
mesh
.
clone
()
let
mesh3
=
mesh
.
clone
()
;
mesh2
.
rotateY
((
Math
.
PI
/
180
)
*
60
)
mesh2
.
rotateY
((
Math
.
PI
/
180
)
*
60
)
;
mesh3
.
rotateY
((
Math
.
PI
/
180
)
*
120
)
mesh3
.
rotateY
((
Math
.
PI
/
180
)
*
120
)
;
return
[
mesh
,
mesh2
,
mesh3
]
return
[
mesh
,
mesh2
,
mesh3
]
;
}
}
createQuan
(
position
,
index
)
{
createQuan
(
position
,
index
)
{
const
guangquan1
=
this
.
assets
.
instance
.
getResource
(
"guangquan1"
)
const
guangquan1
=
this
.
assets
.
instance
.
getResource
(
"guangquan1"
)
;
const
guangquan2
=
this
.
assets
.
instance
.
getResource
(
"guangquan2"
)
const
guangquan2
=
this
.
assets
.
instance
.
getResource
(
"guangquan2"
)
;
let
geometry
=
new
PlaneGeometry
(
0.5
,
0.5
)
let
geometry
=
new
PlaneGeometry
(
0.5
,
0.5
)
;
let
material1
=
new
MeshBasicMaterial
({
let
material1
=
new
MeshBasicMaterial
({
color
:
0xffffff
,
color
:
0xffffff
,
map
:
guangquan1
,
map
:
guangquan1
,
...
@@ -829,7 +859,7 @@ export class World extends Mini3d {
...
@@ -829,7 +859,7 @@ export class World extends Mini3d {
depthTest
:
false
,
depthTest
:
false
,
fog
:
false
,
fog
:
false
,
blending
:
AdditiveBlending
,
blending
:
AdditiveBlending
,
})
})
;
let
material2
=
new
MeshBasicMaterial
({
let
material2
=
new
MeshBasicMaterial
({
color
:
0xffffff
,
color
:
0xffffff
,
map
:
guangquan2
,
map
:
guangquan2
,
...
@@ -839,40 +869,40 @@ export class World extends Mini3d {
...
@@ -839,40 +869,40 @@ export class World extends Mini3d {
depthTest
:
false
,
depthTest
:
false
,
fog
:
false
,
fog
:
false
,
blending
:
AdditiveBlending
,
blending
:
AdditiveBlending
,
})
})
;
let
mesh1
=
new
Mesh
(
geometry
,
material1
)
let
mesh1
=
new
Mesh
(
geometry
,
material1
)
;
let
mesh2
=
new
Mesh
(
geometry
,
material2
)
let
mesh2
=
new
Mesh
(
geometry
,
material2
)
;
mesh1
.
renderOrder
=
6
mesh1
.
renderOrder
=
6
;
mesh2
.
renderOrder
=
6
mesh2
.
renderOrder
=
6
;
mesh1
.
rotateX
(
-
Math
.
PI
/
2
)
mesh1
.
rotateX
(
-
Math
.
PI
/
2
)
;
mesh2
.
rotateX
(
-
Math
.
PI
/
2
)
mesh2
.
rotateX
(
-
Math
.
PI
/
2
)
;
mesh1
.
position
.
copy
(
position
)
mesh1
.
position
.
copy
(
position
)
;
mesh2
.
position
.
copy
(
position
)
mesh2
.
position
.
copy
(
position
)
;
mesh2
.
position
.
y
-=
0.001
mesh2
.
position
.
y
-=
0.001
;
mesh1
.
scale
.
set
(
0
,
0
,
0
)
mesh1
.
scale
.
set
(
0
,
0
,
0
)
;
mesh2
.
scale
.
set
(
0
,
0
,
0
)
mesh2
.
scale
.
set
(
0
,
0
,
0
)
;
this
.
quanGroup
=
new
Group
()
this
.
quanGroup
=
new
Group
()
;
this
.
quanGroup
.
add
(
mesh1
,
mesh2
)
this
.
quanGroup
.
add
(
mesh1
,
mesh2
)
;
this
.
scene
.
add
(
this
.
quanGroup
)
this
.
scene
.
add
(
this
.
quanGroup
)
;
this
.
time
.
on
(
"tick"
,
()
=>
{
this
.
time
.
on
(
"tick"
,
()
=>
{
mesh1
.
rotation
.
z
+=
0.05
mesh1
.
rotation
.
z
+=
0.05
;
})
})
;
return
this
.
quanGroup
return
this
.
quanGroup
;
}
}
// 创建扩散
// 创建扩散
createDiffuse
()
{
createDiffuse
()
{
let
geometry
=
new
PlaneGeometry
(
200
,
200
)
let
geometry
=
new
PlaneGeometry
(
200
,
200
)
;
let
material
=
new
MeshBasicMaterial
({
let
material
=
new
MeshBasicMaterial
({
color
:
0x000000
,
color
:
0x000000
,
depthWrite
:
false
,
depthWrite
:
false
,
// depthTest: false,
// depthTest: false,
transparent
:
true
,
transparent
:
true
,
blending
:
CustomBlending
,
blending
:
CustomBlending
,
})
})
;
// 使用CustomBlending 实现混合叠加
// 使用CustomBlending 实现混合叠加
material
.
blendEquation
=
AddEquation
material
.
blendEquation
=
AddEquation
;
material
.
blendSrc
=
DstColorFactor
material
.
blendSrc
=
DstColorFactor
;
material
.
blendDst
=
OneFactor
material
.
blendDst
=
OneFactor
;
let
diffuse
=
new
DiffuseShader
({
let
diffuse
=
new
DiffuseShader
({
material
,
material
,
time
:
this
.
time
,
time
:
this
.
time
,
...
@@ -887,15 +917,15 @@ export class World extends Mini3d {
...
@@ -887,15 +917,15 @@ export class World extends Mini3d {
repeat
:
-
1
,
repeat
:
-
1
,
duration
:
6
,
duration
:
6
,
ease
:
"power1.easeIn"
,
ease
:
"power1.easeIn"
,
})
})
;
},
3
)
},
3
)
;
},
},
})
})
;
let
mesh
=
new
Mesh
(
geometry
,
material
)
let
mesh
=
new
Mesh
(
geometry
,
material
)
;
mesh
.
renderOrder
=
3
mesh
.
renderOrder
=
3
;
mesh
.
rotation
.
x
=
-
Math
.
PI
/
2
mesh
.
rotation
.
x
=
-
Math
.
PI
/
2
;
mesh
.
position
.
set
(
0
,
0.21
,
0
)
mesh
.
position
.
set
(
0
,
0.21
,
0
)
;
this
.
scene
.
add
(
mesh
)
this
.
scene
.
add
(
mesh
)
;
}
}
createGrid
()
{
createGrid
()
{
new
Grid
(
this
,
{
new
Grid
(
this
,
{
...
@@ -906,63 +936,63 @@ export class World extends Mini3d {
...
@@ -906,63 +936,63 @@ export class World extends Mini3d {
shapeColor
:
0x2a5f8a
,
shapeColor
:
0x2a5f8a
,
pointSize
:
0.1
,
pointSize
:
0.1
,
pointColor
:
0x154d7d
,
pointColor
:
0x154d7d
,
})
})
;
}
}
createBottomBg
()
{
createBottomBg
()
{
let
geometry
=
new
PlaneGeometry
(
20
,
20
)
let
geometry
=
new
PlaneGeometry
(
20
,
20
)
;
const
texture
=
this
.
assets
.
instance
.
getResource
(
"ocean"
)
const
texture
=
this
.
assets
.
instance
.
getResource
(
"ocean"
)
;
texture
.
colorSpace
=
SRGBColorSpace
texture
.
colorSpace
=
SRGBColorSpace
;
texture
.
wrapS
=
RepeatWrapping
texture
.
wrapS
=
RepeatWrapping
;
texture
.
wrapT
=
RepeatWrapping
texture
.
wrapT
=
RepeatWrapping
;
texture
.
repeat
.
set
(
1
,
1
)
texture
.
repeat
.
set
(
1
,
1
)
;
let
material
=
new
MeshBasicMaterial
({
let
material
=
new
MeshBasicMaterial
({
map
:
texture
,
map
:
texture
,
opacity
:
1
,
opacity
:
1
,
fog
:
false
,
fog
:
false
,
})
})
;
let
mesh
=
new
Mesh
(
geometry
,
material
)
let
mesh
=
new
Mesh
(
geometry
,
material
)
;
mesh
.
rotation
.
x
=
-
Math
.
PI
/
2
mesh
.
rotation
.
x
=
-
Math
.
PI
/
2
;
mesh
.
position
.
set
(
0
,
-
0.7
,
0
)
mesh
.
position
.
set
(
0
,
-
0.7
,
0
)
;
this
.
scene
.
add
(
mesh
)
this
.
scene
.
add
(
mesh
)
;
}
}
createChinaBlurLine
()
{
createChinaBlurLine
()
{
let
geometry
=
new
PlaneGeometry
(
147
,
147
)
let
geometry
=
new
PlaneGeometry
(
147
,
147
)
;
const
texture
=
this
.
assets
.
instance
.
getResource
(
"chinaBlurLine"
)
const
texture
=
this
.
assets
.
instance
.
getResource
(
"chinaBlurLine"
)
;
texture
.
colorSpace
=
SRGBColorSpace
texture
.
colorSpace
=
SRGBColorSpace
;
texture
.
wrapS
=
RepeatWrapping
texture
.
wrapS
=
RepeatWrapping
;
texture
.
wrapT
=
RepeatWrapping
texture
.
wrapT
=
RepeatWrapping
;
texture
.
generateMipmaps
=
false
texture
.
generateMipmaps
=
false
;
texture
.
minFilter
=
NearestFilter
texture
.
minFilter
=
NearestFilter
;
texture
.
repeat
.
set
(
1
,
1
)
texture
.
repeat
.
set
(
1
,
1
)
;
let
material
=
new
MeshBasicMaterial
({
let
material
=
new
MeshBasicMaterial
({
color
:
0x3f82cd
,
color
:
0x3f82cd
,
alphaMap
:
texture
,
alphaMap
:
texture
,
transparent
:
true
,
transparent
:
true
,
opacity
:
0.5
,
opacity
:
0.5
,
})
})
;
let
mesh
=
new
Mesh
(
geometry
,
material
)
let
mesh
=
new
Mesh
(
geometry
,
material
)
;
mesh
.
rotateX
(
-
Math
.
PI
/
2
)
mesh
.
rotateX
(
-
Math
.
PI
/
2
)
;
mesh
.
position
.
set
(
-
19.3
,
-
0.5
,
-
19.7
)
mesh
.
position
.
set
(
-
19.3
,
-
0.5
,
-
19.7
)
;
this
.
scene
.
add
(
mesh
)
this
.
scene
.
add
(
mesh
)
;
}
}
createLabel
(
val
)
{
createLabel
(
val
)
{
let
self
=
this
let
self
=
this
;
let
labelGroup
=
this
.
labelGroup
let
labelGroup
=
this
.
labelGroup
;
let
label3d
=
this
.
label3d
let
label3d
=
this
.
label3d
;
let
otherLabel
=
[]
let
otherLabel
=
[]
;
chinaData
.
map
((
province
)
=>
{
chinaData
.
map
((
province
)
=>
{
if
(
province
.
hide
==
true
)
return
false
if
(
province
.
hide
==
true
)
return
false
;
let
label
=
labelStyle01
(
province
,
label3d
,
labelGroup
)
let
label
=
labelStyle01
(
province
,
label3d
,
labelGroup
)
;
otherLabel
.
push
(
label
)
otherLabel
.
push
(
label
)
;
})
})
;
this
.
mapFocusLabel
=
labelStyle02
(
this
.
mapFocusLabel
=
labelStyle02
(
{
{
...
val
,
...
val
,
},
},
label3d
,
label3d
,
labelGroup
labelGroup
)
)
;
let
iconLabel1
=
labelStyle03
(
let
iconLabel1
=
labelStyle03
(
{
{
icon
:
labelIcon
,
icon
:
labelIcon
,
...
@@ -973,7 +1003,7 @@ export class World extends Mini3d {
...
@@ -973,7 +1003,7 @@ export class World extends Mini3d {
},
},
label3d
,
label3d
,
labelGroup
labelGroup
)
)
;
let
iconLabel2
=
labelStyle03
(
let
iconLabel2
=
labelStyle03
(
{
{
icon
:
labelIcon
,
icon
:
labelIcon
,
...
@@ -984,47 +1014,55 @@ export class World extends Mini3d {
...
@@ -984,47 +1014,55 @@ export class World extends Mini3d {
},
},
label3d
,
label3d
,
labelGroup
labelGroup
)
)
;
otherLabel
.
push
(
this
.
mapFocusLabel
)
otherLabel
.
push
(
this
.
mapFocusLabel
)
;
otherLabel
.
push
(
iconLabel1
)
otherLabel
.
push
(
iconLabel1
)
;
otherLabel
.
push
(
iconLabel2
)
otherLabel
.
push
(
iconLabel2
)
;
this
.
otherLabel
=
otherLabel
this
.
otherLabel
=
otherLabel
;
function
labelStyle01
(
province
,
label3d
,
labelGroup
)
{
function
labelStyle01
(
province
,
label3d
,
labelGroup
)
{
let
label
=
label3d
.
create
(
""
,
`china-label
${
province
.
blur
?
" blur"
:
""
}
`
,
false
)
let
label
=
label3d
.
create
(
const
[
x
,
y
]
=
self
.
geoProjection
(
province
.
center
)
""
,
`china-label
${
province
.
blur
?
" blur"
:
""
}
`
,
false
);
const
[
x
,
y
]
=
self
.
geoProjection
(
province
.
center
);
label
.
init
(
label
.
init
(
`<div class="other-label"><img class="label-icon" src="
${
labelIcon
}
">
${
province
.
name
}
</div>`
,
`<div class="other-label"><img class="label-icon" src="
${
labelIcon
}
">
${
province
.
name
}
</div>`
,
new
Vector3
(
x
,
-
y
,
0.4
)
new
Vector3
(
x
,
-
y
,
0.4
)
)
)
;
label3d
.
setLabelStyle
(
label
,
0.02
,
"x"
)
label3d
.
setLabelStyle
(
label
,
0.02
,
"x"
)
;
label
.
setParent
(
labelGroup
)
label
.
setParent
(
labelGroup
)
;
return
label
return
label
;
}
}
function
labelStyle02
(
province
,
label3d
,
labelGroup
)
{
function
labelStyle02
(
province
,
label3d
,
labelGroup
)
{
let
label
=
label3d
.
create
(
""
,
"map-label"
,
false
)
let
label
=
label3d
.
create
(
""
,
"map-label"
,
false
)
;
const
[
x
,
y
]
=
self
.
geoProjection
(
province
.
center
)
const
[
x
,
y
]
=
self
.
geoProjection
(
province
.
center
)
;
label
.
init
(
label
.
init
(
`<div class="other-label"><span>
${
province
.
name
}
</span><span>
${
province
.
enName
}
</span></div>`
,
`<div class="other-label"><span>
${
province
.
name
}
</span><span>
${
province
.
enName
}
</span></div>`
,
new
Vector3
(
x
,
-
y
,
0.4
)
new
Vector3
(
x
,
-
y
,
0.4
)
)
)
;
label3d
.
setLabelStyle
(
label
,
0.015
,
"x"
)
label3d
.
setLabelStyle
(
label
,
0.015
,
"x"
)
;
label
.
setParent
(
labelGroup
)
label
.
setParent
(
labelGroup
)
;
return
label
return
label
;
}
}
function
labelStyle03
(
data
,
label3d
,
labelGroup
)
{
function
labelStyle03
(
data
,
label3d
,
labelGroup
)
{
let
label
=
label3d
.
create
(
""
,
`decoration-label
${
data
.
reflect
?
" reflect"
:
""
}
`
,
false
)
let
label
=
label3d
.
create
(
const
[
x
,
y
]
=
self
.
geoProjection
(
data
.
center
)
""
,
`decoration-label
${
data
.
reflect
?
" reflect"
:
""
}
`
,
false
);
const
[
x
,
y
]
=
self
.
geoProjection
(
data
.
center
);
label
.
init
(
label
.
init
(
`<div class="other-label"><img class="label-icon" style="width:
${
data
.
width
}
;height:
${
data
.
height
}
" src="
${
data
.
icon
}
">`
,
`<div class="other-label"><img class="label-icon" style="width:
${
data
.
width
}
;height:
${
data
.
height
}
" src="
${
data
.
icon
}
">`
,
new
Vector3
(
x
,
-
y
,
0.4
)
new
Vector3
(
x
,
-
y
,
0.4
)
)
)
;
label3d
.
setLabelStyle
(
label
,
0.02
,
"x"
)
label3d
.
setLabelStyle
(
label
,
0.02
,
"x"
)
;
label
.
setParent
(
labelGroup
)
label
.
setParent
(
labelGroup
)
;
return
label
return
label
;
}
}
function
labelStyle04
(
data
,
label3d
,
labelGroup
,
index
)
{
function
labelStyle04
(
data
,
label3d
,
labelGroup
,
index
)
{
let
label
=
label3d
.
create
(
""
,
"provinces-label"
,
false
)
let
label
=
label3d
.
create
(
""
,
"provinces-label"
,
false
)
;
const
[
x
,
y
]
=
self
.
geoProjection
(
data
.
center
)
const
[
x
,
y
]
=
self
.
geoProjection
(
data
.
center
)
;
label
.
init
(
label
.
init
(
`<div class="provinces-label">
`<div class="provinces-label">
<div class="provinces-label-wrap">
<div class="provinces-label-wrap">
...
@@ -1037,16 +1075,16 @@ export class World extends Mini3d {
...
@@ -1037,16 +1075,16 @@ export class World extends Mini3d {
</div>
</div>
</div>`
,
</div>`
,
new
Vector3
(
x
,
-
y
,
2.4
)
new
Vector3
(
x
,
-
y
,
2.4
)
)
)
;
label3d
.
setLabelStyle
(
label
,
0.02
,
"x"
)
label3d
.
setLabelStyle
(
label
,
0.02
,
"x"
)
;
label
.
setParent
(
labelGroup
)
label
.
setParent
(
labelGroup
)
;
return
label
return
label
;
}
}
}
}
createRotateBorder
()
{
createRotateBorder
()
{
let
max
=
12
let
max
=
12
;
let
rotationBorder1
=
this
.
assets
.
instance
.
getResource
(
"rotationBorder1"
)
let
rotationBorder1
=
this
.
assets
.
instance
.
getResource
(
"rotationBorder1"
)
;
let
rotationBorder2
=
this
.
assets
.
instance
.
getResource
(
"rotationBorder2"
)
let
rotationBorder2
=
this
.
assets
.
instance
.
getResource
(
"rotationBorder2"
)
;
let
plane01
=
new
Plane
(
this
,
{
let
plane01
=
new
Plane
(
this
,
{
width
:
max
*
1.178
,
width
:
max
*
1.178
,
needRotate
:
true
,
needRotate
:
true
,
...
@@ -1061,11 +1099,11 @@ export class World extends Mini3d {
...
@@ -1061,11 +1099,11 @@ export class World extends Mini3d {
blending
:
AdditiveBlending
,
blending
:
AdditiveBlending
,
}),
}),
position
:
new
Vector3
(
0
,
0.28
,
0
),
position
:
new
Vector3
(
0
,
0.28
,
0
),
})
})
;
plane01
.
instance
.
rotation
.
x
=
-
Math
.
PI
/
2
plane01
.
instance
.
rotation
.
x
=
-
Math
.
PI
/
2
;
plane01
.
instance
.
renderOrder
=
6
plane01
.
instance
.
renderOrder
=
6
;
plane01
.
instance
.
scale
.
set
(
0
,
0
,
0
)
plane01
.
instance
.
scale
.
set
(
0
,
0
,
0
)
;
plane01
.
setParent
(
this
.
scene
)
plane01
.
setParent
(
this
.
scene
)
;
let
plane02
=
new
Plane
(
this
,
{
let
plane02
=
new
Plane
(
this
,
{
width
:
max
*
1.116
,
width
:
max
*
1.116
,
needRotate
:
true
,
needRotate
:
true
,
...
@@ -1080,27 +1118,27 @@ export class World extends Mini3d {
...
@@ -1080,27 +1118,27 @@ export class World extends Mini3d {
blending
:
AdditiveBlending
,
blending
:
AdditiveBlending
,
}),
}),
position
:
new
Vector3
(
0
,
0.3
,
0
),
position
:
new
Vector3
(
0
,
0.3
,
0
),
})
})
;
plane02
.
instance
.
rotation
.
x
=
-
Math
.
PI
/
2
plane02
.
instance
.
rotation
.
x
=
-
Math
.
PI
/
2
;
plane02
.
instance
.
renderOrder
=
6
plane02
.
instance
.
renderOrder
=
6
;
plane02
.
instance
.
scale
.
set
(
0
,
0
,
0
)
plane02
.
instance
.
scale
.
set
(
0
,
0
,
0
)
;
plane02
.
setParent
(
this
.
scene
)
plane02
.
setParent
(
this
.
scene
)
;
this
.
rotateBorder1
=
plane01
.
instance
this
.
rotateBorder1
=
plane01
.
instance
;
this
.
rotateBorder2
=
plane02
.
instance
this
.
rotateBorder2
=
plane02
.
instance
;
}
}
createFlyLine
()
{
createFlyLine
()
{
this
.
flyLineGroup
=
new
Group
()
this
.
flyLineGroup
=
new
Group
()
;
this
.
flyLineGroup
.
visible
=
false
this
.
flyLineGroup
.
visible
=
false
;
this
.
scene
.
add
(
this
.
flyLineGroup
)
this
.
scene
.
add
(
this
.
flyLineGroup
)
;
const
texture
=
this
.
assets
.
instance
.
getResource
(
"mapFlyline"
)
const
texture
=
this
.
assets
.
instance
.
getResource
(
"mapFlyline"
)
;
texture
.
wrapS
=
texture
.
wrapT
=
RepeatWrapping
texture
.
wrapS
=
texture
.
wrapT
=
RepeatWrapping
;
texture
.
repeat
.
set
(
0.5
,
2
)
texture
.
repeat
.
set
(
0.5
,
2
)
;
const
tubeRadius
=
0.1
const
tubeRadius
=
0.1
;
const
tubeSegments
=
32
const
tubeSegments
=
32
;
const
tubeRadialSegments
=
2
const
tubeRadialSegments
=
2
;
const
closed
=
false
const
closed
=
false
;
let
[
centerX
,
centerY
]
=
this
.
geoProjection
(
this
.
flyLineCenter
)
let
[
centerX
,
centerY
]
=
this
.
geoProjection
(
this
.
flyLineCenter
)
;
let
centerPoint
=
new
Vector3
(
centerX
,
-
centerY
,
0
)
let
centerPoint
=
new
Vector3
(
centerX
,
-
centerY
,
0
)
;
const
material
=
new
MeshBasicMaterial
({
const
material
=
new
MeshBasicMaterial
({
map
:
texture
,
map
:
texture
,
// alphaMap: texture,
// alphaMap: texture,
...
@@ -1110,34 +1148,40 @@ export class World extends Mini3d {
...
@@ -1110,34 +1148,40 @@ export class World extends Mini3d {
opacity
:
1
,
opacity
:
1
,
depthTest
:
false
,
depthTest
:
false
,
blending
:
AdditiveBlending
,
blending
:
AdditiveBlending
,
})
})
;
this
.
time
.
on
(
"tick"
,
()
=>
{
this
.
time
.
on
(
"tick"
,
()
=>
{
texture
.
offset
.
x
-=
0.006
texture
.
offset
.
x
-=
0.006
;
})
})
;
provincesData
provincesData
.
filter
((
item
,
index
)
=>
index
<
7
)
.
filter
((
item
,
index
)
=>
index
<
7
)
.
map
((
city
)
=>
{
.
map
((
city
)
=>
{
let
[
x
,
y
]
=
this
.
geoProjection
(
city
.
centroid
)
let
[
x
,
y
]
=
this
.
geoProjection
(
city
.
centroid
);
let
point
=
new
Vector3
(
x
,
-
y
,
0
)
let
point
=
new
Vector3
(
x
,
-
y
,
0
);
const
center
=
new
Vector3
()
const
center
=
new
Vector3
();
center
.
addVectors
(
centerPoint
,
point
).
multiplyScalar
(
0.5
)
center
.
addVectors
(
centerPoint
,
point
).
multiplyScalar
(
0.5
);
center
.
setZ
(
3
)
center
.
setZ
(
3
);
const
curve
=
new
QuadraticBezierCurve3
(
centerPoint
,
center
,
point
)
const
curve
=
new
QuadraticBezierCurve3
(
centerPoint
,
center
,
point
);
const
tubeGeometry
=
new
TubeGeometry
(
curve
,
tubeSegments
,
tubeRadius
,
tubeRadialSegments
,
closed
)
const
tubeGeometry
=
new
TubeGeometry
(
const
mesh
=
new
Mesh
(
tubeGeometry
,
material
)
curve
,
mesh
.
rotation
.
x
=
-
Math
.
PI
/
2
tubeSegments
,
mesh
.
position
.
set
(
0
,
this
.
depth
+
0.44
,
0
)
tubeRadius
,
mesh
.
renderOrder
=
21
tubeRadialSegments
,
this
.
flyLineGroup
.
add
(
mesh
)
closed
})
);
const
mesh
=
new
Mesh
(
tubeGeometry
,
material
);
mesh
.
rotation
.
x
=
-
Math
.
PI
/
2
;
mesh
.
position
.
set
(
0
,
this
.
depth
+
0.44
,
0
);
mesh
.
renderOrder
=
21
;
this
.
flyLineGroup
.
add
(
mesh
);
});
}
}
// 创建焦点
// 创建焦点
createFocus
()
{
createFocus
()
{
let
focusObj
=
new
Focus
(
this
,
{
color1
:
0xbdfdfd
,
color2
:
0xbdfdfd
})
let
focusObj
=
new
Focus
(
this
,
{
color1
:
0xbdfdfd
,
color2
:
0xbdfdfd
})
;
let
[
x
,
y
]
=
this
.
geoProjection
(
this
.
flyLineCenter
)
let
[
x
,
y
]
=
this
.
geoProjection
(
this
.
flyLineCenter
)
;
focusObj
.
position
.
set
(
x
,
-
y
,
this
.
depth
+
0.44
)
focusObj
.
position
.
set
(
x
,
-
y
,
this
.
depth
+
0.44
)
;
focusObj
.
scale
.
set
(
1
,
1
,
1
)
focusObj
.
scale
.
set
(
1
,
1
,
1
)
;
this
.
flyLineFocusGroup
.
add
(
focusObj
)
this
.
flyLineFocusGroup
.
add
(
focusObj
)
;
}
}
// 创建粒子
// 创建粒子
createParticles
()
{
createParticles
()
{
...
@@ -1158,54 +1202,54 @@ export class World extends Mini3d {
...
@@ -1158,54 +1202,54 @@ export class World extends Mini3d {
blending
:
AdditiveBlending
,
blending
:
AdditiveBlending
,
sizeAttenuation
:
true
,
sizeAttenuation
:
true
,
}),
}),
})
})
;
this
.
particleGroup
=
new
Group
()
this
.
particleGroup
=
new
Group
()
;
this
.
scene
.
add
(
this
.
particleGroup
)
this
.
scene
.
add
(
this
.
particleGroup
)
;
this
.
particleGroup
.
rotation
.
x
=
-
Math
.
PI
/
2
this
.
particleGroup
.
rotation
.
x
=
-
Math
.
PI
/
2
;
this
.
particles
.
setParent
(
this
.
particleGroup
)
this
.
particles
.
setParent
(
this
.
particleGroup
)
;
this
.
particles
.
enable
=
true
this
.
particles
.
enable
=
true
;
this
.
particleGroup
.
visible
=
true
this
.
particleGroup
.
visible
=
true
;
}
}
createScatter
()
{
createScatter
()
{
this
.
scatterGroup
=
new
Group
()
this
.
scatterGroup
=
new
Group
()
;
this
.
scatterGroup
.
visible
=
false
this
.
scatterGroup
.
visible
=
false
;
this
.
scatterGroup
.
rotation
.
x
=
-
Math
.
PI
/
2
this
.
scatterGroup
.
rotation
.
x
=
-
Math
.
PI
/
2
;
this
.
scene
.
add
(
this
.
scatterGroup
)
this
.
scene
.
add
(
this
.
scatterGroup
)
;
const
texture
=
this
.
assets
.
instance
.
getResource
(
"arrow"
)
const
texture
=
this
.
assets
.
instance
.
getResource
(
"arrow"
)
;
const
material
=
new
SpriteMaterial
({
const
material
=
new
SpriteMaterial
({
map
:
texture
,
map
:
texture
,
color
:
0xfffef4
,
color
:
0xfffef4
,
fog
:
false
,
fog
:
false
,
transparent
:
true
,
transparent
:
true
,
depthTest
:
false
,
depthTest
:
false
,
})
})
;
let
scatterAllData
=
sortByValue
(
scatterData
)
let
scatterAllData
=
sortByValue
(
scatterData
)
;
let
max
=
scatterAllData
[
0
].
value
let
max
=
scatterAllData
[
0
].
value
;
scatterAllData
.
map
((
data
)
=>
{
scatterAllData
.
map
((
data
)
=>
{
const
sprite
=
new
Sprite
(
material
)
const
sprite
=
new
Sprite
(
material
)
;
sprite
.
renderOrder
=
23
sprite
.
renderOrder
=
23
;
let
scale
=
0.1
+
(
data
.
value
/
max
)
*
0.2
let
scale
=
0.1
+
(
data
.
value
/
max
)
*
0.2
;
sprite
.
scale
.
set
(
scale
,
scale
,
scale
)
sprite
.
scale
.
set
(
scale
,
scale
,
scale
)
;
let
[
x
,
y
]
=
this
.
geoProjection
([
data
.
lng
,
data
.
lat
])
let
[
x
,
y
]
=
this
.
geoProjection
([
data
.
lng
,
data
.
lat
])
;
sprite
.
position
.
set
(
x
,
-
y
,
this
.
depth
+
0.45
)
sprite
.
position
.
set
(
x
,
-
y
,
this
.
depth
+
0.45
)
;
sprite
.
userData
.
position
=
[
x
,
-
y
,
this
.
depth
+
0.45
]
sprite
.
userData
.
position
=
[
x
,
-
y
,
this
.
depth
+
0.45
]
;
this
.
scatterGroup
.
add
(
sprite
)
this
.
scatterGroup
.
add
(
sprite
)
;
})
})
;
}
}
createInfoPoint
()
{
createInfoPoint
()
{
let
self
=
this
let
self
=
this
;
this
.
InfoPointGroup
=
new
Group
()
this
.
InfoPointGroup
=
new
Group
()
;
this
.
scene
.
add
(
this
.
InfoPointGroup
)
this
.
scene
.
add
(
this
.
InfoPointGroup
)
;
this
.
InfoPointGroup
.
visible
=
false
this
.
InfoPointGroup
.
visible
=
false
;
this
.
InfoPointGroup
.
rotation
.
x
=
-
Math
.
PI
/
2
this
.
InfoPointGroup
.
rotation
.
x
=
-
Math
.
PI
/
2
;
this
.
infoPointIndex
=
0
this
.
infoPointIndex
=
0
;
this
.
infoPointLabelTime
=
null
this
.
infoPointLabelTime
=
null
;
this
.
infoLabelElement
=
[]
this
.
infoLabelElement
=
[]
;
let
label3d
=
this
.
label3d
let
label3d
=
this
.
label3d
;
const
texture
=
this
.
assets
.
instance
.
getResource
(
"point"
)
const
texture
=
this
.
assets
.
instance
.
getResource
(
"point"
)
;
let
colors
=
[
0xfffef4
,
0x77fbf5
]
let
colors
=
[
0xfffef4
,
0x77fbf5
]
;
let
infoAllData
=
sortByValue
(
infoData
)
let
infoAllData
=
sortByValue
(
infoData
)
;
let
max
=
infoAllData
[
0
].
value
let
max
=
infoAllData
[
0
].
value
;
infoAllData
.
map
((
data
,
index
)
=>
{
infoAllData
.
map
((
data
,
index
)
=>
{
const
material
=
new
SpriteMaterial
({
const
material
=
new
SpriteMaterial
({
map
:
texture
,
map
:
texture
,
...
@@ -1213,49 +1257,49 @@ export class World extends Mini3d {
...
@@ -1213,49 +1257,49 @@ export class World extends Mini3d {
fog
:
false
,
fog
:
false
,
transparent
:
true
,
transparent
:
true
,
depthTest
:
false
,
depthTest
:
false
,
})
})
;
const
sprite
=
new
Sprite
(
material
)
const
sprite
=
new
Sprite
(
material
)
;
sprite
.
renderOrder
=
23
sprite
.
renderOrder
=
23
;
let
scale
=
0.7
+
(
data
.
value
/
max
)
*
0.4
let
scale
=
0.7
+
(
data
.
value
/
max
)
*
0.4
;
sprite
.
scale
.
set
(
scale
,
scale
,
scale
)
sprite
.
scale
.
set
(
scale
,
scale
,
scale
)
;
let
[
x
,
y
]
=
this
.
geoProjection
([
data
.
lng
,
data
.
lat
])
let
[
x
,
y
]
=
this
.
geoProjection
([
data
.
lng
,
data
.
lat
])
;
let
position
=
[
x
,
-
y
,
this
.
depth
+
0.7
]
let
position
=
[
x
,
-
y
,
this
.
depth
+
0.7
]
;
sprite
.
position
.
set
(...
position
)
sprite
.
position
.
set
(...
position
)
;
sprite
.
userData
.
position
=
[...
position
]
sprite
.
userData
.
position
=
[...
position
]
;
sprite
.
userData
=
{
sprite
.
userData
=
{
position
:
[
x
,
-
y
,
this
.
depth
+
0.7
],
position
:
[
x
,
-
y
,
this
.
depth
+
0.7
],
name
:
data
.
name
,
name
:
data
.
name
,
value
:
data
.
value
,
value
:
data
.
value
,
level
:
data
.
level
,
level
:
data
.
level
,
index
:
index
,
index
:
index
,
}
}
;
this
.
InfoPointGroup
.
add
(
sprite
)
this
.
InfoPointGroup
.
add
(
sprite
)
;
let
label
=
infoLabel
(
data
,
label3d
,
this
.
InfoPointGroup
)
let
label
=
infoLabel
(
data
,
label3d
,
this
.
InfoPointGroup
)
;
this
.
infoLabelElement
.
push
(
label
)
this
.
infoLabelElement
.
push
(
label
)
;
this
.
interactionManager
.
add
(
sprite
)
this
.
interactionManager
.
add
(
sprite
)
;
sprite
.
addEventListener
(
"mousedown"
,
(
ev
)
=>
{
sprite
.
addEventListener
(
"mousedown"
,
(
ev
)
=>
{
if
(
this
.
clicked
||
!
this
.
InfoPointGroup
.
visible
)
return
false
if
(
this
.
clicked
||
!
this
.
InfoPointGroup
.
visible
)
return
false
;
this
.
clicked
=
true
this
.
clicked
=
true
;
this
.
infoPointIndex
=
ev
.
target
.
userData
.
index
this
.
infoPointIndex
=
ev
.
target
.
userData
.
index
;
this
.
infoLabelElement
.
map
((
label
)
=>
{
this
.
infoLabelElement
.
map
((
label
)
=>
{
label
.
visible
=
false
label
.
visible
=
false
;
})
})
;
label
.
visible
=
true
label
.
visible
=
true
;
this
.
createInfoPointLabelLoop
()
this
.
createInfoPointLabelLoop
()
;
})
})
;
sprite
.
addEventListener
(
"mouseup"
,
(
ev
)
=>
{
sprite
.
addEventListener
(
"mouseup"
,
(
ev
)
=>
{
this
.
clicked
=
false
this
.
clicked
=
false
;
})
})
;
sprite
.
addEventListener
(
"mouseover"
,
(
event
)
=>
{
sprite
.
addEventListener
(
"mouseover"
,
(
event
)
=>
{
document
.
body
.
style
.
cursor
=
"pointer"
document
.
body
.
style
.
cursor
=
"pointer"
;
})
})
;
sprite
.
addEventListener
(
"mouseout"
,
(
event
)
=>
{
sprite
.
addEventListener
(
"mouseout"
,
(
event
)
=>
{
document
.
body
.
style
.
cursor
=
"default"
document
.
body
.
style
.
cursor
=
"default"
;
})
})
;
})
})
;
function
infoLabel
(
data
,
label3d
,
labelGroup
)
{
function
infoLabel
(
data
,
label3d
,
labelGroup
)
{
let
label
=
label3d
.
create
(
""
,
"info-point"
,
true
)
let
label
=
label3d
.
create
(
""
,
"info-point"
,
true
)
;
const
[
x
,
y
]
=
self
.
geoProjection
([
data
.
lng
,
data
.
lat
])
const
[
x
,
y
]
=
self
.
geoProjection
([
data
.
lng
,
data
.
lat
])
;
label
.
init
(
label
.
init
(
` <div class="info-point-wrap">
` <div class="info-point-wrap">
<div class="info-point-wrap-inner">
<div class="info-point-wrap-inner">
...
@@ -1273,34 +1317,34 @@ export class World extends Mini3d {
...
@@ -1273,34 +1317,34 @@ export class World extends Mini3d {
</div>
</div>
`
,
`
,
new
Vector3
(
x
,
-
y
,
self
.
depth
+
1.9
)
new
Vector3
(
x
,
-
y
,
self
.
depth
+
1.9
)
)
)
;
label3d
.
setLabelStyle
(
label
,
0.015
,
"x"
)
label3d
.
setLabelStyle
(
label
,
0.015
,
"x"
)
;
label
.
setParent
(
labelGroup
)
label
.
setParent
(
labelGroup
)
;
label
.
visible
=
false
label
.
visible
=
false
;
return
label
return
label
;
}
}
}
}
createInfoPointLabelLoop
()
{
createInfoPointLabelLoop
()
{
clearInterval
(
this
.
infoPointLabelTime
)
clearInterval
(
this
.
infoPointLabelTime
)
;
this
.
infoPointLabelTime
=
setInterval
(()
=>
{
this
.
infoPointLabelTime
=
setInterval
(()
=>
{
this
.
infoPointIndex
++
this
.
infoPointIndex
++
;
if
(
this
.
infoPointIndex
>=
this
.
infoLabelElement
.
length
)
{
if
(
this
.
infoPointIndex
>=
this
.
infoLabelElement
.
length
)
{
this
.
infoPointIndex
=
0
this
.
infoPointIndex
=
0
;
}
}
this
.
infoLabelElement
.
map
((
label
,
i
)
=>
{
this
.
infoLabelElement
.
map
((
label
,
i
)
=>
{
if
(
this
.
infoPointIndex
===
i
)
{
if
(
this
.
infoPointIndex
===
i
)
{
label
.
visible
=
true
label
.
visible
=
true
;
}
else
{
}
else
{
label
.
visible
=
false
label
.
visible
=
false
;
}
}
})
})
;
},
3000
)
},
3000
)
;
}
}
createStorke
()
{
createStorke
()
{
const
mapStroke
=
this
.
assets
.
instance
.
getResource
(
"mapStroke"
)
const
mapStroke
=
this
.
assets
.
instance
.
getResource
(
"mapStroke"
)
;
const
texture
=
this
.
assets
.
instance
.
getResource
(
"pathLine3"
)
const
texture
=
this
.
assets
.
instance
.
getResource
(
"pathLine3"
)
;
texture
.
wrapS
=
texture
.
wrapT
=
RepeatWrapping
texture
.
wrapS
=
texture
.
wrapT
=
RepeatWrapping
;
texture
.
repeat
.
set
(
2
,
1
)
texture
.
repeat
.
set
(
2
,
1
)
;
let
pathLine
=
new
Line
(
this
,
{
let
pathLine
=
new
Line
(
this
,
{
geoProjectionCenter
:
this
.
geoProjectionCenter
,
geoProjectionCenter
:
this
.
geoProjectionCenter
,
...
@@ -1319,18 +1363,21 @@ export class World extends Mini3d {
...
@@ -1319,18 +1363,21 @@ export class World extends Mini3d {
type
:
"Line3"
,
type
:
"Line3"
,
renderOrder
:
22
,
renderOrder
:
22
,
tubeRadius
:
0.03
,
tubeRadius
:
0.03
,
})
})
;
// 设置父级
// 设置父级
this
.
focusMapGroup
.
add
(
pathLine
.
lineGroup
)
this
.
focusMapGroup
.
add
(
pathLine
.
lineGroup
)
;
this
.
time
.
on
(
"tick"
,
()
=>
{
this
.
time
.
on
(
"tick"
,
()
=>
{
texture
.
offset
.
x
+=
0.005
texture
.
offset
.
x
+=
0.005
;
})
})
;
}
}
// 创建地形模型
// 创建地形模型
createTerrain
()
{
createTerrain
()
{
this
.
pngTexture
=
this
.
terrainResource
.
loaders
.
Texture
.
load
(
"../../../public/assets/json/TrueColorImage.png"
);
this
.
pngTexture
=
this
.
terrainResource
.
loaders
.
Texture
.
load
(
"../../../public/assets/json/TrueColorImage.png"
);
this
.
pngTexture
.
flipY
=
false
;
this
.
pngTexture
.
flipY
=
false
;
this
.
terrainResource
.
loaders
.
GLTF
.
load
(
"../../../public/assets/json/Scene_cq15_200.gltf"
,
this
.
terrainResource
.
loaders
.
GLTF
.
load
(
"../../../public/assets/json/Scene_cq15_200.gltf"
,
(
gltf
)
=>
{
(
gltf
)
=>
{
let
terrain
=
gltf
.
scene
;
let
terrain
=
gltf
.
scene
;
// 调整 GLTF 模型的缩放比例和位置
// 调整 GLTF 模型的缩放比例和位置
...
@@ -1351,149 +1398,151 @@ export class World extends Mini3d {
...
@@ -1351,149 +1398,151 @@ export class World extends Mini3d {
this
.
scene
.
add
(
terrain
);
this
.
scene
.
add
(
terrain
);
},
},
(
xhr
)
=>
{
(
xhr
)
=>
{
console
.
log
((
xhr
.
loaded
/
xhr
.
total
*
100
)
+
'% 已加载'
);
console
.
log
((
xhr
.
loaded
/
xhr
.
total
)
*
100
+
"% 已加载"
);
},
},
(
error
)
=>
{
(
error
)
=>
{
console
.
error
(
'加载模型出错:'
,
error
);
console
.
error
(
"加载模型出错:"
,
error
);
}
}
)
)
;
// this.scene.add(barGroup)
// this.scene.add(barGroup)
}
}
// 创建geoJson
// 创建geoJson
createGeoJson
()
{
createGeoJson
()
{
this
.
FileLoader
=
new
FileLoader
()
this
.
FileLoader
=
new
FileLoader
();
this
.
FileLoader
.
load
(
"../../../public/assets/json/surfacewater.json"
,
(
data
)
=>
{
this
.
FileLoader
.
load
(
let
jsonData
=
JSON
.
parse
(
data
)
"../../../public/assets/json/surfacewater.json"
,
(
data
)
=>
{
let
jsonData
=
JSON
.
parse
(
data
);
console
.
log
(
"jsonData"
,
jsonData
);
console
.
log
(
"jsonData"
,
jsonData
);
const
roadGeoJson
=
new
Group
();
const
roadGeoJson
=
new
Group
();
const
roadProjection
=
geoMercator
().
center
(
this
.
geoProjectionCenter
)
const
roadProjection
=
geoMercator
().
center
(
this
.
geoProjectionCenter
);
// 遍历Json的feature
// 遍历Json的feature
jsonData
.
features
.
forEach
((
feature
,
i
)
=>
{
jsonData
.
features
.
forEach
((
feature
,
i
)
=>
{
// 获取feature中的geometry数据,方便引用
// 获取feature中的geometry数据,方便引用
const
geometry
=
feature
.
geometry
;
const
geometry
=
feature
.
geometry
;
const
type
=
geometry
.
type
;
const
type
=
geometry
.
type
;
// 创建分组,把同一个市的形状放在一个分组,便于管理
// 创建分组,把同一个市的形状放在一个分组,便于管理
const
city
=
new
Group
();
const
city
=
new
Group
();
if
(
type
===
'LineString'
)
{
if
(
type
===
"LineString"
)
{
// 遍历geometry中的数据
// 遍历geometry中的数据
geometry
.
coordinates
.
forEach
((
multipolygon
)
=>
{
geometry
.
coordinates
.
forEach
((
multipolygon
)
=>
{
// 创建形状,用于展示地理形状
// 创建形状,用于展示地理形状
const
shape
=
new
Shape
()
const
shape
=
new
Shape
();
// 存储每个坐标,用于绘制边界线
// 存储每个坐标,用于绘制边界线
const
arr
=
[]
const
arr
=
[];
multipolygon
.
forEach
((
polygon
)
=>
{
multipolygon
.
forEach
((
polygon
)
=>
{
polygon
.
forEach
((
item
,
index
)
=>
{
polygon
.
forEach
((
item
,
index
)
=>
{
// 使用d3转换坐标
// 使用d3转换坐标
const
[
x
,
y
]
=
roadProjection
.
translate
([
0
,
0
])(
item
);
const
[
x
,
y
]
=
roadProjection
.
translate
([
0
,
0
])(
item
);
// 根据转换后的坐标绘制形状
// 根据转换后的坐标绘制形状
if
(
index
===
0
)
{
if
(
index
===
0
)
{
shape
.
moveTo
(
x
,
y
)
shape
.
moveTo
(
x
,
y
);
}
else
{
}
else
{
shape
.
lineTo
(
x
,
y
)
shape
.
lineTo
(
x
,
y
);
}
}
arr
.
push
(
x
,
y
,
3
)
arr
.
push
(
x
,
y
,
3
);
});
});
});
})
console
.
log
(
"arr"
,
arr
);
console
.
log
(
"arr"
,
arr
);
// 绘制边界线
// 绘制边界线
createLine
(
arr
,
city
)
createLine
(
arr
,
city
);
// 创建 ExtrudeGeometry用于显示3d效果
// 创建 ExtrudeGeometry用于显示3d效果
const
extrudGeometry
=
new
ExtrudeGeometry
(
shape
,
{
const
extrudGeometry
=
new
ExtrudeGeometry
(
shape
,
{
depth
:
2
// 地图的厚度
depth
:
2
,
// 地图的厚度
})
})
;
// 创建材质,用于显示地图的外观
// 创建材质,用于显示地图的外观
const
material
=
new
MeshBasicMaterial
({
const
material
=
new
MeshBasicMaterial
({
color
:
'#ffff33'
color
:
"#ffff33"
,
});
});
// 创建物体,用于显示地图
// 创建物体,用于显示地图
const
mesh
=
new
Mesh
(
extrudGeometry
,
material
)
const
mesh
=
new
Mesh
(
extrudGeometry
,
material
);
mesh
.
position
.
set
(
0
,
0
,
0
)
mesh
.
position
.
set
(
0
,
0
,
0
);
// 添加到分组
// 添加到分组
city
.
add
(
mesh
)
city
.
add
(
mesh
)
;
})
});
}
}
// 添加到分组
// 添加到分组
roadGeoJson
.
add
(
city
)
roadGeoJson
.
add
(
city
);
})
});
this
.
scene
.
add
(
roadGeoJson
);
this
.
scene
.
add
(
roadGeoJson
);
})
}
);
}
}
// createSmoothLine(lngLatArr) {
// const z = this.depth + 0.5;
// const points = lngLatArr.map(([lng, lat]) => {
// const [x, y] = this.geoProjection([lng, lat]);
// return new THREE.Vector3(x, z, y);
// });
// const curve = new THREE.CatmullRomCurve3(points, false, 'catmullrom', 0.5);
// const curvePoints = curve.getPoints(100);
// createSmoothLine(lngLatArr) {
// // 计算每个点的累积距离
// const z = this.depth + 0.5;
// let distances = [0];
// const points = lngLatArr.map(([lng, lat]) => {
// for (let i = 1; i < curvePoints.length; i++) {
// const [x, y] = this.geoProjection([lng, lat]);
// distances[i] = distances[i - 1] + curvePoints[i].distanceTo(curvePoints[i - 1]);
// return new THREE.Vector3(x, z, y);
// }
// });
// const totalLength = distances[distances.length - 1];
// const curve = new THREE.CatmullRomCurve3(points, false, 'catmullrom', 0.5);
// const curvePoints = curve.getPoints(100);
// // 计算每个点的累积距离
// let distances = [0];
// for (let i = 1; i < curvePoints.length; i++) {
// distances[i] = distances[i - 1] + curvePoints[i].distanceTo(curvePoints[i - 1]);
// }
// const totalLength = distances[distances.length - 1];
// // 添加距离属性
// // 添加距离属性
// const geometry = new THREE.BufferGeometry().setFromPoints(curvePoints);
// const geometry = new THREE.BufferGeometry().setFromPoints(curvePoints);
// const distanceAttr = new Float32Array(distances);
// const distanceAttr = new Float32Array(distances);
// geometry.setAttribute('aDistance', new THREE.BufferAttribute(distanceAttr, 1));
// geometry.setAttribute('aDistance', new THREE.BufferAttribute(distanceAttr, 1));
// // ShaderMaterial
// // ShaderMaterial
// const material = new THREE.ShaderMaterial({
// const material = new THREE.ShaderMaterial({
// uniforms: {
// uniforms: {
// color: { value: new THREE.Color(0xff0000) },
// color: { value: new THREE.Color(0xff0000) },
// dashSize: { value: 0.2 },
// dashSize: { value: 0.2 },
// gapSize: { value: 0.1 },
// gapSize: { value: 0.1 },
// totalLength: { value: totalLength },
// totalLength: { value: totalLength },
// dashOffset: { value: 0 },
// dashOffset: { value: 0 },
// },
// },
// vertexShader: `
// vertexShader: `
// attribute float aDistance;
// attribute float aDistance;
// varying float vDistance;
// varying float vDistance;
// void main() {
// void main() {
// vDistance = aDistance;
// vDistance = aDistance;
// gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
// gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
// }
// }
// `,
// `,
// fragmentShader: `
// fragmentShader: `
// uniform vec3 color;
// uniform vec3 color;
// uniform float dashSize;
// uniform float dashSize;
// uniform float gapSize;
// uniform float gapSize;
// uniform float totalLength;
// uniform float totalLength;
// uniform float dashOffset;
// uniform float dashOffset;
// varying float vDistance;
// varying float vDistance;
// void main() {
// void main() {
// float unitLen = dashSize + gapSize;
// float unitLen = dashSize + gapSize;
// float dist = mod(vDistance + dashOffset * totalLength, unitLen);
// float dist = mod(vDistance + dashOffset * totalLength, unitLen);
// if(dist > dashSize) discard;
// if(dist > dashSize) discard;
// gl_FragColor = vec4(color, 1.0);
// gl_FragColor = vec4(color, 1.0);
// }
// }
// `,
// `,
// transparent: true
// transparent: true
// });
// });
// const line = new THREE.Line(geometry, material);
// const line = new THREE.Line(geometry, material);
// this.scene.add(line);
// this.scene.add(line);
// // 动画
// // 动画
// this.time.on("tick", () => {
// this.time.on("tick", () => {
// material.uniforms.dashOffset.value += 0.001; // 控制流动速度
// material.uniforms.dashOffset.value += 0.001; // 控制流动速度
// if(material.uniforms.dashOffset.value > 1.0) material.uniforms.dashOffset.value -= 1.0;
// if(material.uniforms.dashOffset.value > 1.0) material.uniforms.dashOffset.value -= 1.0;
// });
// });
// return line;
// return line;
// }
// }
createSmoothLine
(
lngLatArr
)
{
createSmoothLine
(
lngLatArr
)
{
const
z
=
this
.
depth
+
0.5
;
const
z
=
this
.
depth
+
0.5
;
// 生成原始曲线
// 生成原始曲线
const
points
=
lngLatArr
.
map
(([
lng
,
lat
])
=>
{
const
points
=
lngLatArr
.
map
(([
lng
,
lat
])
=>
{
const
[
x
,
y
]
=
this
.
geoProjection
([
lng
,
lat
]);
const
[
x
,
y
]
=
this
.
geoProjection
([
lng
,
lat
]);
return
new
THREE
.
Vector3
(
x
,
z
,
y
);
return
new
THREE
.
Vector3
(
x
,
z
,
y
);
});
});
const
curve
=
new
THREE
.
CatmullRomCurve3
(
points
,
false
,
'catmullrom'
,
0.5
);
const
curve
=
new
THREE
.
CatmullRomCurve3
(
points
,
false
,
"catmullrom"
,
0.5
);
// 创建管道几何体(控制宽度)
// 创建管道几何体(控制宽度)
const
radius
=
0.05
;
// 控制线条宽度
const
radius
=
0.05
;
// 控制线条宽度
const
radialSegments
=
8
;
// 控制管道圆滑度
const
radialSegments
=
8
;
// 控制管道圆滑度
...
@@ -1544,7 +1593,7 @@ createSmoothLine(lngLatArr) {
...
@@ -1544,7 +1593,7 @@ createSmoothLine(lngLatArr) {
gl_FragColor = vec4(color, 1.0);
gl_FragColor = vec4(color, 1.0);
}
}
`
,
`
,
transparent
:
true
transparent
:
true
,
});
});
// 创建网格对象
// 创建网格对象
const
mesh
=
new
THREE
.
Mesh
(
tubeGeometry
,
material
);
const
mesh
=
new
THREE
.
Mesh
(
tubeGeometry
,
material
);
...
@@ -1553,31 +1602,37 @@ createSmoothLine(lngLatArr) {
...
@@ -1553,31 +1602,37 @@ createSmoothLine(lngLatArr) {
// 保持原有动画逻辑
// 保持原有动画逻辑
this
.
time
.
on
(
"tick"
,
()
=>
{
this
.
time
.
on
(
"tick"
,
()
=>
{
material
.
uniforms
.
dashOffset
.
value
+=
0.001
;
material
.
uniforms
.
dashOffset
.
value
+=
0.001
;
if
(
material
.
uniforms
.
dashOffset
.
value
>
1.0
)
{
if
(
material
.
uniforms
.
dashOffset
.
value
>
1.0
)
{
material
.
uniforms
.
dashOffset
.
value
-=
1.0
;
material
.
uniforms
.
dashOffset
.
value
-=
1.0
;
}
}
});
});
return
mesh
;
return
mesh
;
}
}
// 创建水面
// 创建水面
createWater
()
{
createWater
()
{
// 获取水面GeoJSON数据
// 获取水面GeoJSON数据
let
mapJsonData
=
this
.
assets
.
instance
.
getResource
(
"surfaceWater"
);
let
mapJsonData
=
this
.
assets
.
instance
.
getResource
(
"surfaceWater"
);
let
waterJson
;
let
waterJson
;
try
{
try
{
waterJson
=
typeof
mapJsonData
===
"string"
?
JSON
.
parse
(
mapJsonData
)
:
mapJsonData
;
waterJson
=
typeof
mapJsonData
===
"string"
?
JSON
.
parse
(
mapJsonData
)
:
mapJsonData
;
}
catch
(
e
)
{
}
catch
(
e
)
{
console
.
error
(
"surfaceWater 解析失败"
,
e
);
console
.
error
(
"surfaceWater 解析失败"
,
e
);
return
{
waterGroup
:
null
};
return
{
waterGroup
:
null
};
}
}
// 创建水面组
// 创建水面组
const
waterGroup
=
new
Group
();
const
waterGroup
=
new
Group
();
const
projection
=
geoMercator
().
center
(
this
.
geoProjectionCenter
).
scale
(
this
.
geoProjectionScale
).
translate
([
0
,
0
]);
const
projection
=
geoMercator
()
.
center
(
this
.
geoProjectionCenter
)
.
scale
(
this
.
geoProjectionScale
)
.
translate
([
0
,
0
]);
// 加载法线贴图
// 加载法线贴图
const
textureLoader
=
new
THREE
.
TextureLoader
();
const
textureLoader
=
new
THREE
.
TextureLoader
();
let
base_url
=
import
.
meta
.
env
.
BASE_URL
||
"/"
;
let
base_url
=
import
.
meta
.
env
.
BASE_URL
||
"/"
;
const
normalMap
=
textureLoader
.
load
(
base_url
+
"assets/json/waternormals.jpg"
);
const
normalMap
=
textureLoader
.
load
(
base_url
+
"assets/json/waternormals.jpg"
);
normalMap
.
wrapS
=
normalMap
.
wrapT
=
THREE
.
RepeatWrapping
;
normalMap
.
wrapS
=
normalMap
.
wrapT
=
THREE
.
RepeatWrapping
;
// 可选:加载一张水面颜色贴图
// 可选:加载一张水面颜色贴图
// const waterMap = textureLoader.load(base_url + "assets/json/watercolor.png");
// const waterMap = textureLoader.load(base_url + "assets/json/watercolor.png");
...
@@ -1595,7 +1650,10 @@ createWater() {
...
@@ -1595,7 +1650,10 @@ createWater() {
const
geometry
=
feature
.
geometry
;
const
geometry
=
feature
.
geometry
;
if
(
!
geometry
)
return
;
if
(
!
geometry
)
return
;
if
(
geometry
.
type
===
"Polygon"
||
geometry
.
type
===
"MultiPolygon"
)
{
if
(
geometry
.
type
===
"Polygon"
||
geometry
.
type
===
"MultiPolygon"
)
{
const
polygons
=
geometry
.
type
===
"Polygon"
?
[
geometry
.
coordinates
]
:
geometry
.
coordinates
;
const
polygons
=
geometry
.
type
===
"Polygon"
?
[
geometry
.
coordinates
]
:
geometry
.
coordinates
;
polygons
.
forEach
((
polygon
)
=>
{
polygons
.
forEach
((
polygon
)
=>
{
polygon
.
forEach
((
ring
)
=>
{
polygon
.
forEach
((
ring
)
=>
{
const
shape
=
new
Shape
();
const
shape
=
new
Shape
();
...
@@ -1631,13 +1689,14 @@ createWater() {
...
@@ -1631,13 +1689,14 @@ createWater() {
return
{
return
{
waterGroup
,
waterGroup
,
};
};
}
}
createLineWater
()
{
createLineWater
()
{
// 获取水的GeoJSON线数据
// 获取水的GeoJSON线数据
let
mapJsonData
=
this
.
assets
.
instance
.
getResource
(
"linewater"
);
let
mapJsonData
=
this
.
assets
.
instance
.
getResource
(
"linewater"
);
let
lineWaterJson
;
let
lineWaterJson
;
try
{
try
{
lineWaterJson
=
typeof
mapJsonData
===
"string"
?
JSON
.
parse
(
mapJsonData
)
:
mapJsonData
;
lineWaterJson
=
typeof
mapJsonData
===
"string"
?
JSON
.
parse
(
mapJsonData
)
:
mapJsonData
;
}
catch
(
e
)
{
}
catch
(
e
)
{
console
.
error
(
"linewater 解析失败"
,
e
);
console
.
error
(
"linewater 解析失败"
,
e
);
return
{
lineWaterGroup
:
null
};
return
{
lineWaterGroup
:
null
};
...
@@ -1646,7 +1705,9 @@ createLineWater() {
...
@@ -1646,7 +1705,9 @@ createLineWater() {
// 加载法线贴图
// 加载法线贴图
const
textureLoader
=
new
THREE
.
TextureLoader
();
const
textureLoader
=
new
THREE
.
TextureLoader
();
let
base_url
=
import
.
meta
.
env
.
BASE_URL
||
"/"
;
let
base_url
=
import
.
meta
.
env
.
BASE_URL
||
"/"
;
const
normalMap
=
textureLoader
.
load
(
base_url
+
"assets/json/waternormals.jpg"
);
const
normalMap
=
textureLoader
.
load
(
base_url
+
"assets/json/waternormals.jpg"
);
normalMap
.
wrapS
=
normalMap
.
wrapT
=
THREE
.
RepeatWrapping
;
normalMap
.
wrapS
=
normalMap
.
wrapT
=
THREE
.
RepeatWrapping
;
// 可选:加载一张水面颜色贴图
// 可选:加载一张水面颜色贴图
// const waterMap = textureLoader.load(base_url + "assets/json/watercolor.png");
// const waterMap = textureLoader.load(base_url + "assets/json/watercolor.png");
...
@@ -1662,7 +1723,10 @@ createLineWater() {
...
@@ -1662,7 +1723,10 @@ createLineWater() {
// 创建线水组
// 创建线水组
const
lineWaterGroup
=
new
Group
();
const
lineWaterGroup
=
new
Group
();
const
projection
=
geoMercator
().
center
(
this
.
geoProjectionCenter
).
scale
(
this
.
geoProjectionScale
).
translate
([
0
,
0
]);
const
projection
=
geoMercator
()
.
center
(
this
.
geoProjectionCenter
)
.
scale
(
this
.
geoProjectionScale
)
.
translate
([
0
,
0
]);
(
lineWaterJson
.
features
||
[]).
forEach
((
feature
)
=>
{
(
lineWaterJson
.
features
||
[]).
forEach
((
feature
)
=>
{
const
geometry
=
feature
.
geometry
;
const
geometry
=
feature
.
geometry
;
if
(
!
geometry
)
return
;
if
(
!
geometry
)
return
;
...
@@ -1723,229 +1787,454 @@ createLineWater() {
...
@@ -1723,229 +1787,454 @@ createLineWater() {
return
{
return
{
lineWaterGroup
,
lineWaterGroup
,
};
};
}
}
// createLineWater() {
// // 获取水的GeoJSON线数据
// let mapJsonData = this.assets.instance.getResource("linewater");
// let lineWaterJson;
// try {
// lineWaterJson = typeof mapJsonData === "string" ? JSON.parse(mapJsonData) : mapJsonData;
// } catch (e) {
// console.error("linewater 解析失败", e);
// return { lineWaterGroup: null };
// }
// // 加载法线贴图
// const textureLoader = new THREE.TextureLoader();
// let base_url = import.meta.env.BASE_URL || "/";
// const normalMap = textureLoader.load(base_url + "assets/json/waternormals.jpg");
// normalMap.wrapS = normalMap.wrapT = THREE.RepeatWrapping;
// const waterMap = textureLoader.load(base_url + "assets/json/watercolor.png"); // 你需要准备一张水波纹PNG
// waterMap.wrapS = waterMap.wrapT = THREE.RepeatWrapping;
// // 动画流动
// this.time.on("tick", () => {
// normalMap.offset.x += 0.002;
// normalMap.offset.y += 0.001;
// waterMap.offset.x += 0.002; // 让颜色贴图也流动
// });
// // 创建线水组
// const lineWaterGroup = new Group();
// const projection = geoMercator().center(this.geoProjectionCenter).scale(this.geoProjectionScale).translate([0, 0]);
// (lineWaterJson.features || []).forEach((feature) => {
// const geometry = feature.geometry;
// if (!geometry) return;
// let lines = [];
// if (geometry.type === "LineString") {
// lines = [geometry.coordinates];
// } else if (geometry.type === "MultiLineString") {
// lines = geometry.coordinates;
// }
// lines.forEach((line) => {
// // 生成带宽度的水带
// const points = line.map(([lng, lat]) => {
// const [x, y] = projection([lng, lat]);
// return new THREE.Vector3(x, -y, this.depth + 0.26); // 保证高于地表
// });
// if (points.length < 2) return;
// // 用TubeGeometry生成带宽度的水带
// const curve = new THREE.CatmullRomCurve3(points);
// const tubeGeometry = new THREE.TubeGeometry(curve, Math.max(32, points.length * 2), 0.01, 16);
// const material = new THREE.MeshStandardMaterial({
// color: 0x4fc3ff,
// transparent: true,
// opacity: 0.35,
// side: DoubleSide,
// depthWrite: false,
// normalMap: normalMap,
// normalScale: new THREE.Vector2(2, 2),
// map: waterMap, // 使用颜色贴图
// metalness: 0.3,
// roughness: 0.7,
// });
// const mesh = new Mesh(tubeGeometry, material);
// mesh.renderOrder = 11;
// lineWaterGroup.add(mesh);
// });
// });
// return {
// lineWaterGroup,
// };
// }
// createLineWater() {
// let mapJsonData = this.assets.instance.getResource("linewater");
// let lineWaterJson;
// try {
// lineWaterJson = typeof mapJsonData === "string" ? JSON.parse(mapJsonData) : mapJsonData;
// } catch (e) {
// console.error("linewater 解析失败", e);
// return { lineWaterGroup: null };
// }
// const textureLoader = new THREE.TextureLoader();
// let base_url = import.meta.env.BASE_URL || "/";
// const normalMap = textureLoader.load(base_url + "assets/json/waternormals.jpg");
// normalMap.wrapS = normalMap.wrapT = THREE.RepeatWrapping;
// const waterMap = textureLoader.load(base_url + "assets/json/watercolor.png");
// waterMap.wrapS = waterMap.wrapT = THREE.RepeatWrapping;
// // 流动速度更快
// this.time.on("tick", () => {
// normalMap.offset.x += 0.03;
// normalMap.offset.y += 0.015;
// waterMap.offset.x += 0.03;
// waterMap.offset.y += 0.015;
// });
// createLineWater() {
// const lineWaterGroup = new Group();
// // 获取水的GeoJSON线数据
// const projection = geoMercator().center(this.geoProjectionCenter).scale(this.geoProjectionScale).translate([0, 0]);
// let mapJsonData = this.assets.instance.getResource("linewater");
// let lineWaterJson;
// try {
// lineWaterJson = typeof mapJsonData === "string" ? JSON.parse(mapJsonData) : mapJsonData;
// } catch (e) {
// console.error("linewater 解析失败", e);
// return { lineWaterGroup: null };
// }
// // 加载法线贴图
// (lineWaterJson.features || []).forEach((feature) => {
// const textureLoader = new THREE.TextureLoader();
// const geometry = feature.geometry;
// let base_url = import.meta.env.BASE_URL || "/";
// if (!geometry) return;
// const normalMap = textureLoader.load(base_url + "assets/json/waternormals.jpg");
// let lines = [];
// normalMap.wrapS = normalMap.wrapT = THREE.RepeatWrapping;
// if (geometry.type === "LineString") {
// const waterMap = textureLoader.load(base_url + "assets/json/watercolor.png"); // 你需要准备一张水波纹PNG
// lines = [geometry.coordinates];
// waterMap.wrapS = waterMap.wrapT = THREE.RepeatWrapping;
// } else if (geometry.type === "MultiLineString") {
// // 动画流动
// lines = geometry.coordinates;
// this.time.on("tick", () => {
// }
// normalMap.offset.x += 0.002;
// lines.forEach((line) => {
// normalMap.offset.y += 0.001;
// const points = line.map(([lng, lat]) => {
// waterMap.offset.x += 0.002; // 让颜色贴图也流动
// const [x, y] = projection([lng, lat]);
// });
// return new THREE.Vector3(x, -y, this.depth + 0.26);
// });
// if (points.length < 2) return;
// // 创建线水组
// // 宽度渐变:首尾变窄
// const lineWaterGroup = new Group();
// const riverWidthMax = 0.08, riverWidthMin = 0.02;
// const projection = geoMercator().center(this.geoProjectionCenter).scale(this.geoProjectionScale).translate([0, 0]);
// const lefts = [], rights = [];
// for (let i = 0; i < points.length; i++) {
// let t = points.length === 1 ? 0 : i / (points.length - 1);
// let width = riverWidthMin + (1 - Math.abs(t * 2 - 1)) * (riverWidthMax - riverWidthMin);
// let dir;
// if (i === 0) {
// dir = points[1].clone().sub(points[0]);
// } else if (i === points.length - 1) {
// dir = points[i].clone().sub(points[i - 1]);
// } else {
// dir = points[i + 1].clone().sub(points[i - 1]);
// }
// dir.z = 0;
// dir.normalize();
// const normal = new THREE.Vector3(-dir.y, dir.x, 0);
// lefts.push(points[i].clone().add(normal.clone().multiplyScalar(width / 2)));
// rights.push(points[i].clone().add(normal.clone().multiplyScalar(-width / 2)));
// }
// (lineWaterJson.features || []).forEach((feature) => {
// // 顶点、uv、透明度
// const geometry = feature.geometry;
// const vertices = [];
// if (!geometry) return;
// const uvs = [];
// let lines = [];
// const alphas = [];
// if (geometry.type === "LineString") {
// let totalLen = 0;
// lines = [geometry.coordinates];
// for (let i = 0; i < points.length; i++) {
// } else if (geometry.type === "MultiLineString") {
// if (i > 0) totalLen += points[i].distanceTo(points[i - 1]);
// lines = geometry.coordinates;
// let t = points.length === 1 ? 0 : i / (points.length - 1);
// }
// let edgeAlpha = 0.7 + 0.3 * (1 - Math.abs(t * 2 - 1));
// lines.forEach((line) => {
// // 左点
// // 生成带宽度的水带
// vertices.push(lefts[i]);
// const points = line.map(([lng, lat]) => {
// uvs.push(totalLen * 2, 0); // UV缩放更密集
// const [x, y] = projection([lng, lat]);
// alphas.push(edgeAlpha);
// return new THREE.Vector3(x, -y, this.depth + 0.26); // 保证高于地表
// // 右点
// });
// vertices.push(rights[i]);
// if (points.length < 2) return;
// uvs.push(totalLen * 2, 1);
// // 用TubeGeometry生成带宽度的水带
// alphas.push(edgeAlpha);
// const curve = new THREE.CatmullRomCurve3(points);
// }
// const tubeGeometry = new THREE.TubeGeometry(curve, Math.max(32, points.length * 2), 0.01, 16);
// const material = new THREE.MeshStandardMaterial({
// color: 0x4fc3ff,
// transparent: true,
// opacity: 0.35,
// side: DoubleSide,
// depthWrite: false,
// normalMap: normalMap,
// normalScale: new THREE.Vector2(2, 2),
// map: waterMap, // 使用颜色贴图
// metalness: 0.3,
// roughness: 0.7,
// });
// const mesh = new Mesh(tubeGeometry, material);
// mesh.renderOrder = 11;
// lineWaterGroup.add(mesh);
// });
// });
// return {
// lineWaterGroup,
// };
// }
// createLineWater() {
// const indices = [];
// let mapJsonData = this.assets.instance.getResource("linewater");
// for (let i = 0; i < points.length - 1; i++) {
// let lineWaterJson;
// const a = i * 2, b = i * 2 + 1, c = i * 2 + 2, d = i * 2 + 3;
// try {
// indices.push(a, b, c, b, d, c);
// lineWaterJson = typeof mapJsonData === "string" ? JSON.parse(mapJsonData) : mapJsonData;
// }
// } catch (e) {
// console.error("linewater 解析失败", e);
// return { lineWaterGroup: null };
// }
// const textureLoader = new THREE.TextureLoader();
// const geometry = new THREE.BufferGeometry();
// let base_url = import.meta.env.BASE_URL || "/";
// const posArr = new Float32Array(vertices.length * 3);
// const normalMap = textureLoader.load(base_url + "assets/json/waternormals.jpg");
// for (let i = 0; i < vertices.length; i++) {
// normalMap.wrapS = normalMap.wrapT = THREE.RepeatWrapping;
// posArr[i * 3] = vertices[i].x;
// const waterMap = textureLoader.load(base_url + "assets/json/watercolor.png");
// posArr[i * 3 + 1] = vertices[i].y;
// waterMap.wrapS = waterMap.wrapT = THREE.RepeatWrapping;
// posArr[i * 3 + 2] = vertices[i].z;
// }
// geometry.setAttribute('position', new THREE.BufferAttribute(posArr, 3));
// geometry.setAttribute('uv', new THREE.BufferAttribute(new Float32Array(uvs), 2));
// geometry.setAttribute('alpha', new THREE.BufferAttribute(new Float32Array(alphas), 1));
// geometry.setIndex(indices);
// // 流动速度更快
// // ShaderMaterial实现边缘羽化和流动水波
// this.time.on("tick", () => {
// const material = new THREE.ShaderMaterial({
// normalMap.offset.x += 0.03;
// uniforms: {
// normalMap.offset.y += 0.015;
// map: { value: waterMap },
// waterMap.offset.x += 0.03;
// normalMap: { value: normalMap },
// waterMap.offset.y += 0.015;
// color: { value: new THREE.Color(0x4fc3ff) },
// });
// opacity: { value: 0.5 },
// },
// vertexShader: `
// attribute float alpha;
// varying vec2 vUv;
// varying float vAlpha;
// void main() {
// vUv = uv;
// vAlpha = alpha;
// gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
// }
// `,
// fragmentShader: `
// uniform sampler2D map;
// uniform sampler2D normalMap;
// uniform vec3 color;
// uniform float opacity;
// varying vec2 vUv;
// varying float vAlpha;
// void main() {
// vec4 texColor = texture2D(map, vUv);
// float alpha = texColor.a * opacity * vAlpha;
// vec3 finalColor = mix(color, texColor.rgb, 0.8); // 贴图主导
// if(alpha < 0.05) discard;
// gl_FragColor = vec4(finalColor, alpha);
// }
// `,
// transparent: true,
// side: DoubleSide,
// depthWrite: false,
// });
// const lineWaterGroup = new Group();
// const mesh = new Mesh(geometry, material);
// const projection = geoMercator().center(this.geoProjectionCenter).scale(this.geoProjectionScale).translate([0, 0]);
// mesh.renderOrder = 11;
// lineWaterGroup.add(mesh);
// });
// });
// return {
// lineWaterGroup,
// };
// }
// 加载3d模型
showDroneAtLngLat
(
url
,
lng
,
lat
,
height
,
scale
)
{
// 经纬度转平面坐标
const
[
x
,
y
]
=
this
.
geoProjection
([
lng
,
lat
]);
// z 轴为地表高度加上无人机高度
const
z
=
this
.
depth
+
height
+
0.5
;
// 创建 THREE.Vector3 位置
const
position
=
new
THREE
.
Vector3
(
x
,
z
,
-
y
);
// 调用已有的加载方法
this
.
loadDroneModel
(
url
,
position
,
scale
);
}
/**
* 加载无人机 glb 模型并添加到场景
* @param {string} url glb模型路径
* @param {THREE.Vector3} position 模型放置位置
* @param {number} scale 模型缩放
*/
loadDroneModel
(
url
,
position
=
new
THREE
.
Vector3
(
0
,
0
,
2
),
scale
=
1
)
{
// 复用 Resource 工具或直接用 THREE.GLTFLoader
const
loader
=
this
.
terrainResource
?.
loaders
?.
GLTF
||
new
THREE
.
GLTFLoader
();
loader
.
load
(
url
,
(
gltf
)
=>
{
const
drone
=
gltf
.
scene
;
drone
.
position
.
copy
(
position
);
drone
.
scale
.
set
(
scale
,
scale
,
scale
);
// 可根据需要调整旋转
// drone.rotation.set(0, Math.PI, 0);
// let propeller1 = drone.getObjectByName("phase8_Master25");
let
propeller1
=
drone
.
getObjectByName
(
"prop_1_jnt34"
);
let
propeller2
=
drone
.
getObjectByName
(
"prop_2_jnt35"
);
let
propeller3
=
drone
.
getObjectByName
(
"prop_3_jnt36"
);
let
propeller4
=
drone
.
getObjectByName
(
"prop_4_jnt37"
);
if
(
propeller1
&&
propeller2
&&
propeller3
&&
propeller4
)
{
// 每帧旋转扇叶
this
.
time
.
on
(
"tick"
,
()
=>
{
propeller1
.
rotation
.
y
+=
0.5
;
// 控制转速
propeller2
.
rotation
.
y
+=
0.5
;
propeller3
.
rotation
.
y
+=
0.5
;
propeller4
.
rotation
.
y
+=
0.5
;
});
}
else
{
console
.
warn
(
"未找到扇叶节点,请确认节点名称"
);
}
this
.
scene
.
add
(
drone
);
// (lineWaterJson.features || []).forEach((feature) => {
// 添加交互事件
// const geometry = feature.geometry;
this
.
interactionManager
.
add
(
drone
);
// if (!geometry) return;
drone
.
addEventListener
(
"mousedown"
,
(
event
)
=>
{
// let lines = [];
this
.
showDronePopup
(
drone
);
// if (geometry.type === "LineString") {
});
// lines = [geometry.coordinates];
this
.
moveDroneAlongPath
(
drone
,
[
// } else if (geometry.type === "MultiLineString") {
[
110.9801
,
39.8002
],
// lines = geometry.coordinates;
[
111.0806
,
39.7005
],
// }
[
111.1803
,
39.6054
],
// lines.forEach((line) => {
[
110.9008
,
39.8056
],
// const points = line.map(([lng, lat]) => {
[
111.1003
,
39.7386
],
// const [x, y] = projection([lng, lat]);
],
20
);
// return new THREE.Vector3(x, -y, this.depth + 0.26);
console
.
log
(
"无人机模型加载完成"
,
drone
);
// });
},
// if (points.length < 2) return;
(
xhr
)
=>
{
// 加载进度
console
.
log
(
`无人机模型加载进度:
${((
xhr
.
loaded
/
xhr
.
total
)
*
100
).
toFixed
(
2
)}
%`
);
},
(
error
)
=>
{
console
.
error
(
"无人机模型加载失败:"
,
error
);
}
);
}
// 显示无人机弹窗
showDronePopup
(
drone
)
{
// 自动插入样式(只插入一次)
if
(
!
document
.
getElementById
(
"drone-popup-style"
))
{
const
style
=
document
.
createElement
(
"style"
);
style
.
id
=
"drone-popup-style"
;
style
.
innerHTML
=
`
.drone-popup {
z-index: 9999;
min-width: 140px;
max-width: 240px;
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
font-size: 14px;
user-select: none;
transition: opacity 0.2s;
position: absolute;
background: rgba(0,0,0,0.8);
color: #fff;
padding: 10px 18px;
border-radius: 8px;
pointer-events: auto;
}
.drone-popup .close-btn {
position: absolute;
right: 8px;
top: 4px;
color: #fff;
cursor: pointer;
font-size: 16px;
opacity: 0.7;
}
.drone-popup .close-btn:hover {
opacity: 1;
}
.drone-popup video {
width: 100%;
margin-top: 8px;
border-radius: 4px;
background: #000;
display: block;
}
`
;
document
.
head
.
appendChild
(
style
);
}
// 如果已存在弹窗,先移除
if
(
this
.
dronePopup
)
{
document
.
body
.
removeChild
(
this
.
dronePopup
);
this
.
time
.
off
(
"tick"
,
this
.
_updateDronePopupPos
);
this
.
dronePopup
=
null
;
}
// // 宽度渐变:首尾变窄
// 创建弹窗
// const riverWidthMax = 0.08, riverWidthMin = 0.02;
const
popup
=
document
.
createElement
(
"div"
);
// const lefts = [], rights = [];
popup
.
className
=
"drone-popup"
;
// for (let i = 0; i < points.length; i++) {
popup
.
innerHTML
=
`
// let t = points.length === 1 ? 0 : i / (points.length - 1);
<span class="close-btn" title="关闭">×</span>
// let width = riverWidthMin + (1 - Math.abs(t * 2 - 1)) * (riverWidthMax - riverWidthMin);
<div style="margin-top:4px;">
// let dir;
<b>无人机信息</b><br>
// if (i === 0) {
位置:
${
drone
.
position
.
x
.
toFixed
(
2
)}
,
${
drone
.
position
.
z
.
toFixed
(
2
)}
<br>
// dir = points[1].clone().sub(points[0]);
<span style="font-size:12px;opacity:0.7;">(内容可自定义)</span>
// } else if (i === points.length - 1) {
<video src="https://media.w3.org/2010/05/sintel/trailer.mp4" controls poster="" preload="metadata" custom-cache="false" ></video>
// dir = points[i].clone().sub(points[i - 1]);
</div>
// } else {
`
;
// dir = points[i + 1].clone().sub(points[i - 1]);
document
.
body
.
appendChild
(
popup
);
// }
this
.
dronePopup
=
popup
;
// dir.z = 0;
// 优化全屏性能卡顿
// dir.normalize();
document
.
addEventListener
(
"fullscreenchange"
,
()
=>
{
// const normal = new THREE.Vector3(-dir.y, dir.x, 0);
if
(
document
.
fullscreenElement
)
{
// lefts.push(points[i].clone().add(normal.clone().multiplyScalar(width / 2)));
// 暂停 Three.js 动画
// rights.push(points[i].clone().add(normal.clone().multiplyScalar(-width / 2)));
this
.
time
.
pause
&&
this
.
time
.
pause
();
// }
}
else
{
// 恢复 Three.js 动画
this
.
time
.
resume
&&
this
.
time
.
resume
();
}
});
// // 顶点、uv、透明度
// 关闭按钮
// const vertices = [];
popup
.
querySelector
(
".close-btn"
).
onclick
=
()
=>
{
// const uvs = [];
if
(
this
.
dronePopup
)
{
// const alphas = [];
document
.
body
.
removeChild
(
this
.
dronePopup
);
// let totalLen = 0;
this
.
time
.
off
(
"tick"
,
this
.
_updateDronePopupPos
);
// for (let i = 0; i < points.length; i++) {
this
.
dronePopup
=
null
;
// if (i > 0) totalLen += points[i].distanceTo(points[i - 1]);
}
// let t = points.length === 1 ? 0 : i / (points.length - 1);
};
// let edgeAlpha = 0.7 + 0.3 * (1 - Math.abs(t * 2 - 1));
// // 左点
// vertices.push(lefts[i]);
// uvs.push(totalLen * 2, 0); // UV缩放更密集
// alphas.push(edgeAlpha);
// // 右点
// vertices.push(rights[i]);
// uvs.push(totalLen * 2, 1);
// alphas.push(edgeAlpha);
// }
// const indices = [];
// 跟随无人机位置
// for (let i = 0; i < points.length - 1; i++) {
this
.
_updateDronePopupPos
=
()
=>
{
// const a = i * 2, b = i * 2 + 1, c = i * 2 + 2, d = i * 2 + 3;
// 获取无人机世界坐标
// indices.push(a, b, c, b, d, c);
const
worldPos
=
new
THREE
.
Vector3
();
// }
drone
.
getWorldPosition
(
worldPos
);
// 转换为屏幕坐标
worldPos
.
project
(
this
.
camera
.
instance
);
let
x
=
(
worldPos
.
x
*
0.5
+
0.5
)
*
window
.
innerWidth
;
let
y
=
(
1
-
(
worldPos
.
y
*
0.5
+
0.5
))
*
window
.
innerHeight
;
// const geometry = new THREE.BufferGeometry();
// 防止弹窗超出屏幕
// const posArr = new Float32Array(vertices.length * 3);
const
rect
=
popup
.
getBoundingClientRect
();
// for (let i = 0; i < vertices.length; i++) {
x
=
Math
.
min
(
// posArr[i * 3] = vertices[i].x;
Math
.
max
(
0
,
x
-
rect
.
width
/
2
),
// posArr[i * 3 + 1] = vertices[i].y;
window
.
innerWidth
-
rect
.
width
// posArr[i * 3 + 2] = vertices[i].z;
);
// }
y
=
Math
.
min
(
// geometry.setAttribute('position', new THREE.BufferAttribute(posArr, 3));
Math
.
max
(
0
,
y
-
rect
.
height
-
20
),
// geometry.setAttribute('uv', new THREE.BufferAttribute(new Float32Array(uvs), 2));
window
.
innerHeight
-
rect
.
height
// geometry.setAttribute('alpha', new THREE.BufferAttribute(new Float32Array(alphas), 1));
);
// geometry.setIndex(indices);
// // ShaderMaterial实现边缘羽化和流动水波
popup
.
style
.
left
=
`
${
x
}
px`
;
// const material = new THREE.ShaderMaterial({
popup
.
style
.
top
=
`
${
y
}
px`
;
// uniforms: {
};
// map: { value: waterMap },
this
.
time
.
on
(
"tick"
,
this
.
_updateDronePopupPos
);
// normalMap: { value: normalMap },
// 初始化一次
// color: { value: new THREE.Color(0x4fc3ff) },
this
.
_updateDronePopupPos
();
// opacity: { value: 0.5 },
}
// },
/**
// vertexShader: `
* 让无人机沿指定经纬度路径平滑移动
// attribute float alpha;
* @param {THREE.Object3D} drone 无人机模型对象
// varying vec2 vUv;
* @param {Array} lngLatArr 经纬度数组
// varying float vAlpha;
* @param {number} duration 动画时长(秒)
// void main() {
*/
// vUv = uv;
moveDroneAlongPath
(
drone
,
lngLatArr
,
duration
=
10
)
{
// vAlpha = alpha;
// 1. 经纬度转three世界坐标
// gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
const
z
=
this
.
depth
+
1
;
// 高度可调整
// }
const
points
=
lngLatArr
.
map
(([
lng
,
lat
])
=>
{
// `,
const
[
x
,
y
]
=
this
.
geoProjection
([
lng
,
lat
]);
// fragmentShader: `
return
new
THREE
.
Vector3
(
x
,
z
,
y
);
// uniform sampler2D map;
});
// uniform sampler2D normalMap;
// 2. 创建平滑曲线
// uniform vec3 color;
const
curve
=
new
THREE
.
CatmullRomCurve3
(
points
,
false
,
"catmullrom"
,
0.5
);
// uniform float opacity;
// varying vec2 vUv;
// varying float vAlpha;
// void main() {
// vec4 texColor = texture2D(map, vUv);
// float alpha = texColor.a * opacity * vAlpha;
// vec3 finalColor = mix(color, texColor.rgb, 0.8); // 贴图主导
// if(alpha < 0.05) discard;
// gl_FragColor = vec4(finalColor, alpha);
// }
// `,
// transparent: true,
// side: DoubleSide,
// depthWrite: false,
// });
// const mesh = new Mesh(geometry, material);
// 3. 动画
// mesh.renderOrder = 11;
let
startTime
=
null
;
// lineWaterGroup.add(mesh);
const
animate
=
(
now
)
=>
{
// });
if
(
!
startTime
)
startTime
=
now
;
// });
const
elapsed
=
(
now
-
startTime
)
/
1000
;
// return {
let
t
=
elapsed
/
duration
;
// lineWaterGroup,
if
(
t
>
1
)
t
=
1
;
// };
// 沿曲线取点
// }
const
pos
=
curve
.
getPoint
(
t
);
drone
.
position
.
copy
(
pos
);
// 可选:让无人机朝向运动方向
if
(
t
<
1
)
{
const
nextPos
=
curve
.
getPoint
(
Math
.
min
(
t
+
0.01
,
1
));
drone
.
lookAt
(
nextPos
);
}
if
(
t
<
1
)
{
drone
.
_moveReq
=
requestAnimationFrame
(
animate
);
}
};
// 停止之前的动画
if
(
drone
.
_moveReq
)
cancelAnimationFrame
(
drone
.
_moveReq
);
drone
.
_moveReq
=
requestAnimationFrame
(
animate
);
}
// 跳转到指定group
// 跳转到指定group
zoomToFocusMapGroup
(
group
)
{
zoomToFocusMapGroup
(
group
)
{
// 创建一个 Box3 来计算 focusMapGroup 的边界盒
// 创建一个 Box3 来计算 focusMapGroup 的边界盒
...
@@ -1966,7 +2255,9 @@ createLineWater() {
...
@@ -1966,7 +2255,9 @@ createLineWater() {
distance
*=
1.2
;
distance
*=
1.2
;
// 设置摄像机位置(沿着 Z 轴方向)
// 设置摄像机位置(沿着 Z 轴方向)
const
cameraPosition
=
center
.
clone
().
add
(
new
THREE
.
Vector3
(
0
,
0
,
distance
));
const
cameraPosition
=
center
.
clone
()
.
add
(
new
THREE
.
Vector3
(
0
,
0
,
distance
));
this
.
camera
.
instance
.
position
.
copy
(
cameraPosition
);
this
.
camera
.
instance
.
position
.
copy
(
cameraPosition
);
// 让摄像机看向 focusMapGroup 的中心
// 让摄像机看向 focusMapGroup 的中心
...
@@ -1976,14 +2267,17 @@ createLineWater() {
...
@@ -1976,14 +2267,17 @@ createLineWater() {
this
.
camera
.
instance
.
updateProjectionMatrix
();
this
.
camera
.
instance
.
updateProjectionMatrix
();
}
}
geoProjection
(
args
)
{
geoProjection
(
args
)
{
return
geoMercator
().
center
(
this
.
geoProjectionCenter
).
scale
(
this
.
geoProjectionScale
).
translate
([
0
,
0
])(
args
)
return
geoMercator
()
.
center
(
this
.
geoProjectionCenter
)
.
scale
(
this
.
geoProjectionScale
)
.
translate
([
0
,
0
])(
args
);
}
}
update
()
{
update
()
{
super
.
update
()
super
.
update
()
;
this
.
interactionManager
&&
this
.
interactionManager
.
update
()
this
.
interactionManager
&&
this
.
interactionManager
.
update
()
;
}
}
destroy
()
{
destroy
()
{
super
.
destroy
()
super
.
destroy
()
;
this
.
label3d
&&
this
.
label3d
.
destroy
()
this
.
label3d
&&
this
.
label3d
.
destroy
()
;
}
}
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论