huweili-cesium 1.2.97 → 1.2.99
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/js/glbInfoBadge.js +47 -28
- package/package.json +1 -1
package/js/glbInfoBadge.js
CHANGED
|
@@ -7,9 +7,12 @@
|
|
|
7
7
|
import * as Cesium from 'cesium'
|
|
8
8
|
import { getDroneLabelBatchManager } from './cardPool'
|
|
9
9
|
|
|
10
|
-
const STYLE_ID = 'glb-info-badge-style'
|
|
10
|
+
const STYLE_ID = 'glb-info-badge-style-v2'
|
|
11
11
|
const DEFAULT_LABEL_OFFSET = 1
|
|
12
|
-
const DEFAULT_PIXEL_GAP =
|
|
12
|
+
const DEFAULT_PIXEL_GAP = 0
|
|
13
|
+
const DEFAULT_HEIGHT_SCALE = 0.72
|
|
14
|
+
/** 包围球半径折算到车顶的系数(中心点已在模型中部,无需再加整颗半径) */
|
|
15
|
+
const BOUNDING_SPHERE_TOP_FACTOR = 0.22
|
|
13
16
|
|
|
14
17
|
const scratchBoundingSphere = new Cesium.BoundingSphere()
|
|
15
18
|
const scratchEnu = new Cesium.Matrix4()
|
|
@@ -35,16 +38,16 @@ const ensureGlbInfoBadgeStyle = () => {
|
|
|
35
38
|
position: relative;
|
|
36
39
|
display: inline-flex;
|
|
37
40
|
align-items: center;
|
|
38
|
-
gap:
|
|
39
|
-
padding:
|
|
41
|
+
gap: 4px;
|
|
42
|
+
padding: 2px 8px 2px 6px;
|
|
40
43
|
border-radius: 999px;
|
|
41
44
|
background: linear-gradient(135deg, rgba(8, 20, 40, 0.92) 0%, rgba(12, 32, 58, 0.88) 100%);
|
|
42
45
|
border: 1px solid rgba(0, 229, 255, 0.45);
|
|
43
46
|
box-shadow:
|
|
44
|
-
inset 0 0
|
|
45
|
-
0 0
|
|
47
|
+
inset 0 0 8px rgba(0, 229, 255, 0.08),
|
|
48
|
+
0 0 10px rgba(0, 229, 255, 0.15);
|
|
46
49
|
overflow: hidden;
|
|
47
|
-
backdrop-filter: blur(
|
|
50
|
+
backdrop-filter: blur(4px);
|
|
48
51
|
white-space: nowrap;
|
|
49
52
|
}
|
|
50
53
|
.glb-info-badge-scan {
|
|
@@ -58,27 +61,28 @@ const ensureGlbInfoBadgeStyle = () => {
|
|
|
58
61
|
pointer-events: none;
|
|
59
62
|
}
|
|
60
63
|
.glb-info-badge-dot {
|
|
61
|
-
width:
|
|
62
|
-
height:
|
|
64
|
+
width: 5px;
|
|
65
|
+
height: 5px;
|
|
63
66
|
border-radius: 50%;
|
|
64
67
|
flex-shrink: 0;
|
|
65
|
-
box-shadow: 0 0
|
|
68
|
+
box-shadow: 0 0 5px currentColor;
|
|
66
69
|
}
|
|
67
70
|
.glb-info-badge-text {
|
|
68
|
-
font-size:
|
|
71
|
+
font-size: 10px;
|
|
69
72
|
font-weight: 600;
|
|
70
|
-
|
|
73
|
+
line-height: 1;
|
|
74
|
+
letter-spacing: 0.06em;
|
|
71
75
|
color: #e8f7ff;
|
|
72
|
-
text-shadow: 0 0
|
|
76
|
+
text-shadow: 0 0 4px rgba(0, 229, 255, 0.5);
|
|
73
77
|
}
|
|
74
78
|
.glb-info-badge-pointer {
|
|
75
79
|
width: 0;
|
|
76
80
|
height: 0;
|
|
77
|
-
margin:
|
|
78
|
-
border-left:
|
|
79
|
-
border-right:
|
|
80
|
-
border-top:
|
|
81
|
-
filter: drop-shadow(0 0
|
|
81
|
+
margin: 1px auto 0;
|
|
82
|
+
border-left: 4px solid transparent;
|
|
83
|
+
border-right: 4px solid transparent;
|
|
84
|
+
border-top: 5px solid rgba(0, 229, 255, 0.55);
|
|
85
|
+
filter: drop-shadow(0 0 3px rgba(0, 229, 255, 0.4));
|
|
82
86
|
}
|
|
83
87
|
.glb-info-badge.is-online .glb-info-badge-inner {
|
|
84
88
|
border-color: rgba(0, 255, 170, 0.55);
|
|
@@ -174,8 +178,11 @@ const resolveModelTopWorldPosition = (map, entity, basePos, fallbackOffset) => {
|
|
|
174
178
|
if (entity && dataSourceDisplay?.getBoundingSphere) {
|
|
175
179
|
const ok = dataSourceDisplay.getBoundingSphere(entity, true, scratchBoundingSphere)
|
|
176
180
|
if (ok && scratchBoundingSphere.radius > 0) {
|
|
177
|
-
Cesium.Cartesian3.
|
|
178
|
-
|
|
181
|
+
Cesium.Cartesian3.subtract(scratchBoundingSphere.center, basePos, scratchOffset)
|
|
182
|
+
const centerAlongUp = Math.max(0, Cesium.Cartesian3.dot(scratchOffset, scratchUp))
|
|
183
|
+
const topAlongUp = centerAlongUp + scratchBoundingSphere.radius * BOUNDING_SPHERE_TOP_FACTOR
|
|
184
|
+
Cesium.Cartesian3.multiplyByScalar(scratchUp, topAlongUp, scratchOffset)
|
|
185
|
+
return Cesium.Cartesian3.add(basePos, scratchOffset, scratchTop)
|
|
179
186
|
}
|
|
180
187
|
}
|
|
181
188
|
|
|
@@ -190,28 +197,37 @@ const resolveModelTopWorldPosition = (map, entity, basePos, fallbackOffset) => {
|
|
|
190
197
|
* @param {Cesium.Cartesian3} topWorldPos
|
|
191
198
|
* @param {number} minPixelSize
|
|
192
199
|
* @param {number} pixelGap
|
|
200
|
+
* @param {number} heightScale
|
|
193
201
|
* @returns {{ x: number, y: number }|null}
|
|
194
202
|
*/
|
|
195
|
-
const resolveBadgeScreenPosition = (scene, basePos, topWorldPos, minPixelSize, pixelGap) => {
|
|
203
|
+
const resolveBadgeScreenPosition = (scene, basePos, topWorldPos, minPixelSize, pixelGap, heightScale) => {
|
|
196
204
|
const anchorWin = scene.cartesianToCanvasCoordinates(basePos)
|
|
197
205
|
if (!anchorWin || Number.isNaN(anchorWin.x) || Number.isNaN(anchorWin.y)) {
|
|
198
206
|
return null
|
|
199
207
|
}
|
|
200
208
|
|
|
201
|
-
const topWin = scene.cartesianToCanvasCoordinates(topWorldPos)
|
|
209
|
+
const topWin = topWorldPos ? scene.cartesianToCanvasCoordinates(topWorldPos) : null
|
|
202
210
|
let offsetY = 0
|
|
203
211
|
|
|
204
212
|
if (topWin && !Number.isNaN(topWin.y)) {
|
|
205
|
-
offsetY = anchorWin.y - topWin.y
|
|
213
|
+
offsetY = (anchorWin.y - topWin.y) * heightScale
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// 包围球常大于实际 mesh,对过大偏移做软压缩
|
|
217
|
+
if (offsetY > 0 && minPixelSize > 0 && offsetY > minPixelSize * 0.5) {
|
|
218
|
+
const base = minPixelSize * 0.3
|
|
219
|
+
offsetY = base + (offsetY - base) * 0.35
|
|
206
220
|
}
|
|
207
221
|
|
|
208
|
-
// minimumPixelSize 会让远景模型在屏幕上被抬高,仅用世界高度会产生“飘”感
|
|
209
222
|
if (minPixelSize > 0) {
|
|
210
|
-
|
|
223
|
+
const visualRoofOffset = minPixelSize * 0.28
|
|
224
|
+
if (offsetY <= 0 || offsetY < visualRoofOffset) {
|
|
225
|
+
offsetY = visualRoofOffset
|
|
226
|
+
}
|
|
211
227
|
}
|
|
212
228
|
|
|
213
229
|
if (offsetY <= 0) {
|
|
214
|
-
offsetY = minPixelSize > 0 ? minPixelSize * 0.
|
|
230
|
+
offsetY = minPixelSize > 0 ? minPixelSize * 0.28 : 16
|
|
215
231
|
}
|
|
216
232
|
|
|
217
233
|
return {
|
|
@@ -230,7 +246,8 @@ const resolveBadgeScreenPosition = (scene, basePos, topWorldPos, minPixelSize, p
|
|
|
230
246
|
* @param {Function} [options.getVisible] 是否显示信息牌
|
|
231
247
|
* @param {boolean} [options.isOffline=false] true=离线,false=在线
|
|
232
248
|
* @param {number} [options.labelOffset=1] 模型未加载完成时的兜底高度(米)
|
|
233
|
-
* @param {number} [options.pixelGap=
|
|
249
|
+
* @param {number} [options.pixelGap=0] 信息牌与车顶之间的像素间距
|
|
250
|
+
* @param {number} [options.heightScale=0.72] 屏幕偏移收紧系数(越小越贴近车顶)
|
|
234
251
|
*/
|
|
235
252
|
export function createGlbInfoBadge(options = {}) {
|
|
236
253
|
const {
|
|
@@ -242,6 +259,7 @@ export function createGlbInfoBadge(options = {}) {
|
|
|
242
259
|
isOffline = false,
|
|
243
260
|
labelOffset = DEFAULT_LABEL_OFFSET,
|
|
244
261
|
pixelGap = DEFAULT_PIXEL_GAP,
|
|
262
|
+
heightScale = DEFAULT_HEIGHT_SCALE,
|
|
245
263
|
} = options
|
|
246
264
|
|
|
247
265
|
if (!map || typeof getPosition !== 'function') {
|
|
@@ -302,7 +320,8 @@ export function createGlbInfoBadge(options = {}) {
|
|
|
302
320
|
basePos,
|
|
303
321
|
topWorldPos,
|
|
304
322
|
minPixelSize,
|
|
305
|
-
pixelGap
|
|
323
|
+
pixelGap,
|
|
324
|
+
heightScale
|
|
306
325
|
)
|
|
307
326
|
|
|
308
327
|
if (!screenPos) {
|