|
@@ -3,7 +3,7 @@ import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader';
|
|
|
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader';
|
|
|
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader';
|
|
|
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; //导入控制器模块,轨道控制器
|
|
|
-import { CSS3DSprite } from 'three/examples/jsm/renderers/CSS3DRenderer.js';
|
|
|
+import { CSS3DRenderer, CSS3DSprite } from 'three/examples/jsm/renderers/CSS3DRenderer.js';
|
|
|
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js';
|
|
|
import { getBottomMaterial } from './material.js';
|
|
|
// 定义一个 class类
|
|
@@ -100,12 +100,17 @@ class renderModel {
|
|
|
this.renderer.setSize(clientWidth, clientHeight);
|
|
|
this.container.appendChild(this.renderer.domElement);
|
|
|
|
|
|
- // 创建一个CSS3DRenderer
|
|
|
- // this.css3DRenderer = new CSS3DRenderer()
|
|
|
- // this.css3DRenderer.setSize(clientWidth, clientHeight)
|
|
|
- // this.css3DRenderer.domElement.style.position = 'absolute'
|
|
|
- // this.css3DRenderer.domElement.style.pointerEvents = 'none'
|
|
|
- // this.css3DRenderer.domElement.style.top = 0
|
|
|
+ // 创建一个CSS3渲染器CSS3DRenderer
|
|
|
+ this.css3DRenderer = new CSS3DRenderer();
|
|
|
+ this.css3DRenderer.setSize(clientWidth, clientHeight);
|
|
|
+ // HTML标签<div id="tag"></div>外面父元素叠加到canvas画布上且重合
|
|
|
+ this.css3DRenderer.domElement.style.position = 'absolute';
|
|
|
+ this.css3DRenderer.domElement.style.top = '0px';
|
|
|
+ this.css3DRenderer.domElement.style.zIndex = '9999';
|
|
|
+ //设置.pointerEvents=none,解决HTML元素标签对threejs canvas画布鼠标事件的遮挡
|
|
|
+ this.css3DRenderer.domElement.style.pointerEvents = 'none';
|
|
|
+ this.css3DRenderer.domElement.style.className = 'css3DRenderer';
|
|
|
+ this.container.appendChild(this.css3DRenderer.domElement);
|
|
|
}
|
|
|
// 创建光源
|
|
|
createLight() {
|
|
@@ -115,17 +120,15 @@ class renderModel {
|
|
|
this.controls = new OrbitControls(this.camera, this.renderer.domElement);
|
|
|
this.controls.enableDamping = true;
|
|
|
this.controls.maxDistance = 1000;
|
|
|
- this.controls.update();
|
|
|
//标签控制器
|
|
|
- // this.css3dControls = new OrbitControls(this.camera, this.css3DRenderer.domElement)
|
|
|
- // this.css3dControls.enablePan = false
|
|
|
- // this.css3dControls.enableDamping = true
|
|
|
- // this.css3dControls.target.set(0, 0, 0)
|
|
|
- // this.css3dControls.update()
|
|
|
+ this.css3dControls = new OrbitControls(this.camera, this.css3DRenderer.domElement);
|
|
|
+ this.css3dControls.enablePan = false;
|
|
|
+ this.css3dControls.enableDamping = true;
|
|
|
}
|
|
|
animate() {
|
|
|
this.renderer.render(this.scene, this.camera);
|
|
|
this.controls.update();
|
|
|
+ this.css3DRenderer.render(this.scene, this.camera);
|
|
|
}
|
|
|
// 使用动画器不断更新场景
|
|
|
sceneAnimation() {
|
|
@@ -135,33 +138,28 @@ class renderModel {
|
|
|
// 创建div元素(作为标签)
|
|
|
let div = document.createElement('div');
|
|
|
div.innerHTML = name;
|
|
|
- div.style.color = '#000';
|
|
|
- // div.classList.add("tag");
|
|
|
+ div.classList.add('tag3d');
|
|
|
//div元素包装为CSS3模型对象CSS3DObject
|
|
|
let label = new CSS3DSprite(div);
|
|
|
div.style.pointerEvents = 'none'; //避免HTML标签遮挡三维场景的鼠标事件
|
|
|
- // 设置HTML元素标签在three.js世界坐标中位置
|
|
|
- // label.position.set(x, y, z);
|
|
|
//缩放CSS3DObject模型对象
|
|
|
- // label.scale.set(0.02, 0.02, 0.02); //根据相机渲染范围控制HTML 3D标签尺寸
|
|
|
- // label.rotateY(Math.PI / 2); //控制HTML标签CSS3对象姿态角度
|
|
|
- // label.rotateX(-Math.PI/2);
|
|
|
+ label.scale.set(0.15, 0.15, 0.15); //根据相机渲染范围控制HTML 3D标签尺寸
|
|
|
+ label.rotateY(Math.PI / 2); //控制HTML标签CSS3对象姿态角度
|
|
|
return label; //返回CSS3模型标签
|
|
|
}
|
|
|
|
|
|
- dialog(html) {
|
|
|
+ createDialog(html) {
|
|
|
//div元素包装为CSS3模型对象CSS3DSprite
|
|
|
const element = document.createElement('div');
|
|
|
- element.className = 'tag';
|
|
|
+ element.className = 'customDialog';
|
|
|
element.innerHTML = html;
|
|
|
const dialog = new CSS3DSprite(element);
|
|
|
element.style.pointerEvents = 'none'; //避免HTML标签遮挡三维场景的鼠标事件
|
|
|
// 设置HTML元素标签在three.js世界坐标中位置
|
|
|
// label.position.set(x, y, z);
|
|
|
//缩放CSS3DSprite模型对象
|
|
|
- dialog.scale.set(0.01, 0.01, 0.01); //根据相机渲染范围控制HTML 3D标签尺寸
|
|
|
+ dialog.scale.set(0.15, 0.15, 0.15); //根据相机渲染范围控制HTML 3D标签尺寸
|
|
|
dialog.rotateY(Math.PI / 2); //控制HTML标签CSS3对象姿态角度
|
|
|
- // dialog.rotateX(-Math.PI/2);
|
|
|
return dialog; //返回CSS3模型标签
|
|
|
}
|
|
|
/**
|
|
@@ -227,31 +225,15 @@ class renderModel {
|
|
|
// 将模型添加到场景中去
|
|
|
this.scene.add(this.model);
|
|
|
// 初始化 GUI 控件
|
|
|
- const camFolder = new GUI().addFolder('Camera');
|
|
|
- camFolder.add(this.camera.position, 'x', -6500, 6500, 10).name('X Axis');
|
|
|
- camFolder.add(this.camera.position, 'y', -6500, 6500, 10).name('Y Axis');
|
|
|
- camFolder.add(this.camera.position, 'z', -6500, 6500, 10).name('Z Axis');
|
|
|
- camFolder.open();
|
|
|
- // const div = document.createElement('div');
|
|
|
- // div.className = 'workshop-text';
|
|
|
- // div.innerHTML = '<p>仓库2</p>';
|
|
|
- // // 创建CSS3DSprite
|
|
|
- // const tag = new CSS3DSprite(div);
|
|
|
- // tag.position.set(8, 3, 38); // 调整标签位置
|
|
|
- // this.model.add(tag);
|
|
|
+ // const camFolder = new GUI().addFolder('Camera');
|
|
|
+ // camFolder.add(this.camera.position, 'x', -6500, 6500, 10).name('X Axis');
|
|
|
+ // camFolder.add(this.camera.position, 'y', -6500, 6500, 10).name('Y Axis');
|
|
|
+ // camFolder.add(this.camera.position, 'z', -6500, 6500, 10).name('Z Axis');
|
|
|
+ // camFolder.open();
|
|
|
//在GUI中添加一个用于调整tag位置的文件夹
|
|
|
- // const tagFolder = new GUI().addFolder('食堂标签');
|
|
|
- // // 将tag.position对象中的x, y, z属性添加到GUI中
|
|
|
- // tagFolder.add(tag.position, 'x', -200, 200).name('X Position');
|
|
|
- // tagFolder.add(tag.position, 'y', -200, 200).name('Y Position');
|
|
|
- // tagFolder.add(tag.position, 'z', -200, 200).name('Z Position');
|
|
|
- // tagFolder.open(); // 打开此文件夹以默认显示控制器
|
|
|
- // const label3D = this.tag3D('光伏11111111'); //设置标签名称
|
|
|
- // // label3D.position.copy(this.model.position);
|
|
|
- // label3D.position.y += 0;
|
|
|
- // label3D.position.x += 0;
|
|
|
- // label3D.position.z = 20;
|
|
|
- // this.model.add(label3D);
|
|
|
+ this.createGuangfuLabel()
|
|
|
+ this.createFuheLabel()
|
|
|
+ this.createStorageLabel()
|
|
|
});
|
|
|
}
|
|
|
onWindowResizes() {
|
|
@@ -278,6 +260,98 @@ class renderModel {
|
|
|
group.position.y = 0;
|
|
|
group.position.z = 17;
|
|
|
}
|
|
|
+ createGuangfuLabel () {
|
|
|
+ const label3D = this.tag3D('光伏');
|
|
|
+ const dialog3D = this.createDialog(`
|
|
|
+ <div class="load-container" >
|
|
|
+<div class="title">光伏</div>
|
|
|
+<div class="data-grid">
|
|
|
+ <div class="data-item">
|
|
|
+ <span>装机容量:</span>
|
|
|
+ <span class="value">461kW·h</span>
|
|
|
+ </div>
|
|
|
+ <div class="data-item">
|
|
|
+ <span>发电量:</span>
|
|
|
+ <span class="value">1465kW·h</span>
|
|
|
+ </div>
|
|
|
+ <div class="data-item">
|
|
|
+ <span>发电功率:</span>
|
|
|
+ <span class="value">245kW·h</span>
|
|
|
+ </div>
|
|
|
+ <div class="data-item">
|
|
|
+ <span>上网功率:</span>
|
|
|
+ <span class="value">245kW·h</span>
|
|
|
+ </div>
|
|
|
+</div>
|
|
|
+</div>`); //设置标签名称
|
|
|
+ label3D.position.y += 0;
|
|
|
+ label3D.position.x += 93;
|
|
|
+ label3D.position.z += 30;
|
|
|
+ dialog3D.position.copy(label3D.position);
|
|
|
+ dialog3D.position.z = 50;
|
|
|
+ this.scene.add(label3D);
|
|
|
+ this.scene.add(dialog3D);
|
|
|
+ }
|
|
|
+ createStorageLabel () {
|
|
|
+ const label3D = this.tag3D('储能');
|
|
|
+ const dialog3D = this.createDialog(`
|
|
|
+ <div class="load-container" >
|
|
|
+<div class="title">储能</div>
|
|
|
+<div class="data-grid">
|
|
|
+ <div>
|
|
|
+ <span>电池容量:</span>
|
|
|
+ <span class="value">200kW·h</span>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <span>电池电量:</span>
|
|
|
+ <span class="value">17kW·h</span>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <span>有功功率:</span>
|
|
|
+ <span class="value">0.00kW·h</span>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <span>储能soc:</span>
|
|
|
+ <span class="value">9%</span>
|
|
|
+ </div>
|
|
|
+</div>
|
|
|
+</div>`); //设置标签名称
|
|
|
+ label3D.position.y += -30;
|
|
|
+ label3D.position.x += -34;
|
|
|
+ label3D.position.z += 30;
|
|
|
+ dialog3D.position.copy(label3D.position);
|
|
|
+ dialog3D.position.z = 50;
|
|
|
+ this.scene.add(label3D);
|
|
|
+ this.scene.add(dialog3D);
|
|
|
+ }
|
|
|
+ createFuheLabel () {
|
|
|
+ const label3D = this.tag3D('负荷');
|
|
|
+ const dialog3D = this.createDialog(`
|
|
|
+ <div class="load-container" >
|
|
|
+<div class="title">负荷</div>
|
|
|
+<div class="data-grid">
|
|
|
+ <div>
|
|
|
+ <span>用电负荷:</span>
|
|
|
+ <span class="value">461kW·h</span>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <span>总用电量:</span>
|
|
|
+ <span class="value">1465kW·h</span>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <span>自发自用:</span>
|
|
|
+ <span class="value">245kW·h</span>
|
|
|
+ </div>
|
|
|
+</div>
|
|
|
+</div>`); //设置标签名称
|
|
|
+ label3D.position.y += 0;
|
|
|
+ label3D.position.x += -115;
|
|
|
+ label3D.position.z += 30;
|
|
|
+ dialog3D.position.copy(label3D.position);
|
|
|
+ dialog3D.position.z = 50;
|
|
|
+ this.scene.add(label3D);
|
|
|
+ this.scene.add(dialog3D);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
export default renderModel;
|