|
|
@@ -227,45 +227,51 @@ class NitrogenUnderground {
|
|
|
}
|
|
|
if (this.nitrogenNum > 0) {
|
|
|
for (let i = 0; i < 2; i++) {
|
|
|
- if (this.group && !this.group.getObjectByName('monitorNitrogenText' + i)) {
|
|
|
- const element = document.getElementById('nitrogenMonitor' + (i + 1)) as HTMLElement;
|
|
|
- if (element) {
|
|
|
- const nitrogenMonitorCSS3D = new CSS3DSprite(element);
|
|
|
- nitrogenMonitorCSS3D.name = 'monitorNitrogenText' + i;
|
|
|
- nitrogenMonitorCSS3D.scale.set(0.005, 0.005, 0.005);
|
|
|
- if (i == 0) nitrogenMonitorCSS3D.position.set(-0.89, 0.31, 0);
|
|
|
- if (i == 1) nitrogenMonitorCSS3D.position.set(1.44, 0.31, 0.04);
|
|
|
- // if (i == 2) nitrogenMonitorCSS3D.position.set(-0.89, 0.31, 0.08);
|
|
|
- // if (i == 3) nitrogenMonitorCSS3D.position.set(-0.89, 0.31, 0.12);
|
|
|
- this.group.add(nitrogenMonitorCSS3D);
|
|
|
- }
|
|
|
+ const element = document.getElementById('nitrogenMonitor' + (i + 1)) as HTMLElement;
|
|
|
+ let sprite = this.group?.getObjectByName('monitorNitrogenText' + i) as CSS3DSprite | undefined;
|
|
|
+ // 节点被 Vue 重建过(机数变化时 v-for 增删)→ 换成挂到当前节点;旧节点已是孤儿,可以安全移除
|
|
|
+ if (sprite && element && sprite.element !== element) {
|
|
|
+ sprite.removeFromParent();
|
|
|
+ sprite = undefined;
|
|
|
}
|
|
|
- // 而如若此项超出了已绑定的注氮机数量,则隐藏或销毁
|
|
|
- if (this.group && i >= this.nitrogenNum && this.group.getObjectByName('monitorNitrogenText' + i)) {
|
|
|
- this.group.remove(this.group.getObjectByName('monitorNitrogenText' + i) as THREE.Object3D);
|
|
|
+ if (!sprite && element) {
|
|
|
+ sprite = new CSS3DSprite(element);
|
|
|
+ sprite.name = 'monitorNitrogenText' + i;
|
|
|
+ sprite.scale.set(0.005, 0.005, 0.005);
|
|
|
+ if (i == 0) sprite.position.set(-0.89, 0.31, 0);
|
|
|
+ if (i == 1) sprite.position.set(1.44, 0.31, 0.04);
|
|
|
+ this.group.add(sprite);
|
|
|
}
|
|
|
+ // 超出已绑定机数的槽位置为不可见(不能销毁:CSS3DObject 一被移除会连带把 DOM 元素删掉,之后再也挂不回来)
|
|
|
+ if (sprite) sprite.visible = i < this.nitrogenNum;
|
|
|
}
|
|
|
}
|
|
|
- if (this.group && !this.group.getObjectByName('downWindMonitor')) {
|
|
|
+ if (this.group) {
|
|
|
const element = document.getElementById('downWindMonitor') as HTMLElement;
|
|
|
- if (element) {
|
|
|
- const downWindMonitorCSS3D = new CSS3DSprite(element);
|
|
|
- downWindMonitorCSS3D.name = 'downWindMonitor';
|
|
|
- downWindMonitorCSS3D.scale.set(0.005, 0.005, 0.005);
|
|
|
- downWindMonitorCSS3D.position.set(-2.95, 0.57, 0);
|
|
|
- this.group.add(downWindMonitorCSS3D);
|
|
|
+ let downWindMonitor = this.group.getObjectByName('downWindMonitor') as CSS3DSprite | undefined;
|
|
|
+ // 与机位框同样处理:节点被 Vue 重建过就换成挂到当前节点(旧节点是孤儿,可安全移除)
|
|
|
+ if (downWindMonitor && element && downWindMonitor.element !== element) {
|
|
|
+ downWindMonitor.removeFromParent();
|
|
|
+ downWindMonitor = undefined;
|
|
|
+ }
|
|
|
+ if (!downWindMonitor && element) {
|
|
|
+ downWindMonitor = new CSS3DSprite(element);
|
|
|
+ downWindMonitor.name = 'downWindMonitor';
|
|
|
+ downWindMonitor.scale.set(0.005, 0.005, 0.005);
|
|
|
+ downWindMonitor.position.set(-2.95, 0.57, 0);
|
|
|
+ this.group.add(downWindMonitor);
|
|
|
}
|
|
|
+ // 无机数时不显示下风侧框(CSS3D 渲染器会把已接管对象的 display 强制置空,隐藏要用 visible)
|
|
|
+ if (downWindMonitor) downWindMonitor.visible = this.nitrogenNum > 0;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
clearCssText = () => {
|
|
|
- if (this.nitrogenNum > 0) {
|
|
|
- for (let i = 0; i < 2; i++) {
|
|
|
- const mesh = this.group.getObjectByName('monitorNitrogenText' + i);
|
|
|
- if (this.group && mesh) {
|
|
|
- this.group.remove(mesh);
|
|
|
- }
|
|
|
- }
|
|
|
+ // 只隐藏、不移除:CSS3DObject 被移除时会把它手里的 DOM 元素一并从文档删掉,之后再 addCssText 就取不到元素
|
|
|
+ if (this.nitrogenNum <= 0) return;
|
|
|
+ for (let i = 0; i < 2; i++) {
|
|
|
+ const sprite = this.group.getObjectByName('monitorNitrogenText' + i);
|
|
|
+ if (sprite) (sprite as THREE.Object3D).visible = false;
|
|
|
}
|
|
|
};
|
|
|
|