地理视图等瓦片加载完再淡入,避免逐块弹出

This commit is contained in:
2026-09-19 14:20:37 +08:00
parent 86ee03f4a6
commit 0715b38b81
2 changed files with 41 additions and 7 deletions
+23 -7
View File
@@ -54,6 +54,9 @@ export class App {
this.cameraTween = null; this.cameraTween = null;
this._animate = this._animate.bind(this); this._animate = this._animate.bind(this);
requestAnimationFrame(this._animate); requestAnimationFrame(this._animate);
// 首屏渲染后,分帧生成时间轴文字标签(避免阻塞首屏加载环)
requestAnimationFrame(() => requestAnimationFrame(() => this.timeline.initLabels()));
} }
// 首屏加载完成后由 main.js 调用:后台预载地理视图,就绪后激活“地理”按钮 // 首屏加载完成后由 main.js 调用:后台预载地理视图,就绪后激活“地理”按钮
@@ -208,6 +211,7 @@ export class App {
if (this.view === 'timeline') { if (this.view === 'timeline') {
// 时间轴:按下开始拖拽左右滑动;未移动的抬起才视为点击选中 // 时间轴:按下开始拖拽左右滑动;未移动的抬起才视为点击选中
this.timelineSlide = null; // 手动拖拽时取消居中动画 this.timelineSlide = null; // 手动拖拽时取消居中动画
this.timeline.setPausedGeneration(true); // 拖拽期间暂停纹理生成,保持流畅
this._drag = { active: true, startX: e.clientX, startY: e.clientY, moved: false, offset: this.timelineOffset }; this._drag = { active: true, startX: e.clientX, startY: e.clientY, moved: false, offset: this.timelineOffset };
canvas.setPointerCapture(e.pointerId); canvas.setPointerCapture(e.pointerId);
} else { } else {
@@ -240,6 +244,7 @@ export class App {
const wasClick = !this._drag.moved; const wasClick = !this._drag.moved;
this._drag.active = false; this._drag.active = false;
canvas.style.cursor = 'grab'; canvas.style.cursor = 'grab';
this.timeline.setPausedGeneration(false); // 拖拽结束,恢复纹理生成
if (wasClick) this._pick(); if (wasClick) this._pick();
} }
}); });
@@ -247,6 +252,7 @@ export class App {
canvas.addEventListener('pointercancel', () => { canvas.addEventListener('pointercancel', () => {
if (this._drag) this._drag.active = false; if (this._drag) this._drag.active = false;
canvas.style.cursor = 'grab'; canvas.style.cursor = 'grab';
this.timeline.setPausedGeneration(false);
}); });
window.addEventListener('resize', () => this._onResize()); window.addEventListener('resize', () => this._onResize());
@@ -328,10 +334,12 @@ export class App {
const { view, index } = hit.object.userData; const { view, index } = hit.object.userData;
if (view === 'binder') { if (view === 'binder') {
const cur = this.binder.current; const cur = this.binder.current;
if (index === cur) { const f = this.binder.flip;
this.binder.flipForward(); // 点击当前右页:翻到下一页 // 翻页进行中:把“正在翻的页”与“即将露出的下一页”都视为向前翻的目标,点击不阻断
if (index === cur || (f && index === f.nextCurrent)) {
this.binder.flipForward();
} else if (index === cur - 1) { } else if (index === cur - 1) {
this.binder.flipBackward(); // 点击左页:翻回上一页 this.binder.flipBackward();
} else { } else {
this._select(index, { syncBinder: true }); this._select(index, { syncBinder: true });
} }
@@ -395,10 +403,15 @@ export class App {
iris.style.opacity = '1'; iris.style.opacity = '1';
const doSwap = () => { const doSwap = () => {
this._setView(view); this._setView(view);
// 等新视图渲染一两帧后再淡出,避免半透明时看到切换瞬间 if (view === 'globe') {
requestAnimationFrame(() => { // 地理视图:等影像/地形瓦片加载完成再淡出,让球体与标记/标签一起出现
requestAnimationFrame(() => { iris.style.opacity = '0'; }); this.globe.waitUntilViewReady(4000).then(() => { iris.style.opacity = '0'; });
}); } else {
// 等新视图渲染一两帧后再淡出,避免半透明时看到切换瞬间
requestAnimationFrame(() => {
requestAnimationFrame(() => { iris.style.opacity = '0'; });
});
}
}; };
setTimeout(doSwap, 200); // 与 0.18s 的淡入匹配,完全变黑后再切换 setTimeout(doSwap, 200); // 与 0.18s 的淡入匹配,完全变黑后再切换
} }
@@ -412,6 +425,9 @@ export class App {
this.binder.group.visible = view === 'binder'; this.binder.group.visible = view === 'binder';
this.timeline.group.visible = view === 'timeline'; this.timeline.group.visible = view === 'timeline';
// 阴影仅在活页本视图启用:时间轴/地理无投影,降低滑动时阴影贴图重绘开销
this.renderer.shadowMap.enabled = view === 'binder';
// Cesium 地球:地理视图显示 Cesium 画布,其余视图显示 Three.js 画布 // Cesium 地球:地理视图显示 Cesium 画布,其余视图显示 Three.js 画布
document.getElementById('scene').style.display = isGlobe ? 'none' : 'block'; document.getElementById('scene').style.display = isGlobe ? 'none' : 'block';
document.getElementById('cesium-container').classList.toggle('visible', isGlobe); document.getElementById('cesium-container').classList.toggle('visible', isGlobe);
+18
View File
@@ -510,6 +510,24 @@ export class CesiumGlobe {
if (visible && this.viewer) this.viewer.scene.requestRender(); if (visible && this.viewer) this.viewer.scene.requestRender();
} }
// 等待当前视图的影像/地形瓦片加载完成(超时兜底),用于切换时“一起出现”
waitUntilViewReady(timeout = 4000) {
return new Promise((resolve) => {
const globe = this.viewer.scene.globe;
let done = false;
const finish = () => {
if (done) return;
done = true;
globe.tileLoadProgressEvent.removeEventListener(onProgress);
resolve();
};
const onProgress = (remaining) => { if (remaining <= 0) finish(); };
globe.tileLoadProgressEvent.addEventListener(onProgress);
if (globe.tilesLoaded) finish();
setTimeout(finish, timeout);
});
}
resize() { resize() {
if (this.viewer) this.viewer.resize(); if (this.viewer) this.viewer.resize();
} }