性能优化:精简便签每帧计算、地理视图跳过 Three.js 每帧逻辑
This commit is contained in:
+15
-2
@@ -252,8 +252,11 @@ export class App {
|
||||
window.addEventListener('resize', () => this._onResize());
|
||||
|
||||
window.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'ArrowRight') this._step(1);
|
||||
else if (e.key === 'ArrowLeft') this._step(-1);
|
||||
if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') {
|
||||
const dir = e.key === 'ArrowRight' ? 1 : -1;
|
||||
if (this.view === 'timeline') this._stepTimeline(dir);
|
||||
else this._step(dir);
|
||||
}
|
||||
else if (e.key === '1') this.switchView('binder');
|
||||
else if (e.key === '2') this.switchView('timeline');
|
||||
else if (e.key === '3') this.switchView('globe');
|
||||
@@ -357,6 +360,15 @@ export class App {
|
||||
else this.binder.flipBackward();
|
||||
}
|
||||
|
||||
// 时间轴:左右键选择上一张/下一张,动画与点击一致(居中 + 翻面)
|
||||
_stepTimeline(dir) {
|
||||
const next = clamp(this.selected + dir, 0, ENTRIES.length - 1);
|
||||
if (next === this.selected) return;
|
||||
this._select(next, { syncBinder: true });
|
||||
this._centerTimeline(next);
|
||||
this.timeline.flip(next);
|
||||
}
|
||||
|
||||
_select(index, { syncBinder = false } = {}) {
|
||||
this.selected = clamp(index, 0, ENTRIES.length - 1);
|
||||
const entry = ENTRIES[this.selected];
|
||||
@@ -492,6 +504,7 @@ export class App {
|
||||
|
||||
_animate() {
|
||||
requestAnimationFrame(this._animate);
|
||||
if (this.view === 'globe') return; // 地理视图由 Cesium 渲染,跳过 Three.js 每帧逻辑
|
||||
const dt = Math.min(this.clock.getDelta(), 0.05);
|
||||
|
||||
// 是否有进行中的动画(决定本帧是否需要重绘)
|
||||
|
||||
+12
-11
@@ -275,7 +275,13 @@ export class CesiumGlobe {
|
||||
const position = Cesium.Cartesian3.fromDegrees(entry.lng, entry.lat);
|
||||
const noteNormal = makeStickyNote(entry.name, 16, false);
|
||||
const noteSelected = makeStickyNote(entry.name, 16, true);
|
||||
this.markers.push({ position, noteNormal, noteSelected, index: i });
|
||||
this.markers.push({
|
||||
position,
|
||||
r2: Cesium.Cartesian3.magnitudeSquared(position),
|
||||
noteNormal,
|
||||
noteSelected,
|
||||
index: i,
|
||||
});
|
||||
});
|
||||
this._initMarkerLayer();
|
||||
}
|
||||
@@ -313,6 +319,7 @@ export class CesiumGlobe {
|
||||
_updateMarkerLayer() {
|
||||
const scene = this.viewer.scene;
|
||||
const camera = scene.camera;
|
||||
const camPos = camera.positionWC; // 每帧只取一次相机位置
|
||||
|
||||
for (const m of this.markers) {
|
||||
const el = m.el;
|
||||
@@ -321,16 +328,10 @@ export class CesiumGlobe {
|
||||
const win = Cesium.SceneTransforms.worldToWindowCoordinates(scene, m.position);
|
||||
if (!win) { el.style.display = 'none'; continue; }
|
||||
|
||||
// 前/后半球判断 + 地平线附近渐变淡出(固定 ~3° 渐变带,避免拖拽时闪烁/突隐)
|
||||
const dotPC = Cesium.Cartesian3.dot(m.position, camera.positionWC);
|
||||
const pMag = Math.sqrt(Cesium.Cartesian3.magnitudeSquared(m.position));
|
||||
const cMag = Cesium.Cartesian3.magnitude(camera.positionWC);
|
||||
const cosPhi = dotPC / (pMag * cMag);
|
||||
const phi = Math.acos(Math.max(-1, Math.min(1, cosPhi)));
|
||||
const phiHorizon = Math.acos(Math.max(-1, Math.min(1, pMag / cMag)));
|
||||
const margin = phiHorizon - phi; // > 0 为前半球
|
||||
if (margin <= 0) { el.style.display = 'none'; continue; }
|
||||
const opacity = Math.min(1, margin / 0.05); // 0.05 rad ≈ 3°
|
||||
// 前/后半球:dot(P, C) > |P|²;地平线附近用 frontness 渐变淡出(避免 acos)
|
||||
const frontness = Cesium.Cartesian3.dot(m.position, camPos) - m.r2;
|
||||
if (frontness <= 0) { el.style.display = 'none'; continue; }
|
||||
const opacity = Math.min(1, frontness / (m.r2 * 0.02));
|
||||
|
||||
el.style.display = 'block';
|
||||
el.style.opacity = String(opacity);
|
||||
|
||||
Reference in New Issue
Block a user