|
|
|
<!DOCTYPE html>
|
|
|
|
<html>
|
|
|
|
|
|
|
|
<head>
|
|
|
|
<meta charset="utf-8">
|
|
|
|
<title>Threejs实现3D场景中添加html网页</title>
|
|
|
|
<!-- <script type="text/javascript" src="libs/statistics.js"></script> -->
|
|
|
|
<!-- <script type="text/javascript" src="libs/steak.js"></script> -->
|
|
|
|
<style>
|
|
|
|
body {
|
|
|
|
background-color: #ffffff;
|
|
|
|
margin: 0;
|
|
|
|
overflow: hidden;
|
|
|
|
}
|
|
|
|
|
|
|
|
</style>
|
|
|
|
<script type="importmap">
|
|
|
|
{
|
|
|
|
"imports": {
|
|
|
|
"three": "./libs/three/three.module.js",
|
|
|
|
"jsm/": "./libs/three/jsm/"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
</head>
|
|
|
|
|
|
|
|
<body ontouchstart="">
|
|
|
|
<div class="info">2D数据表格显示 不旋转 厌氧系统 </div>
|
|
|
|
<script type="module">
|
|
|
|
|
|
|
|
import * as THREE from 'three';
|
|
|
|
// import { APP } from './js/app2.0.js';
|
|
|
|
|
|
|
|
|
|
|
|
import { OrbitControls } from 'jsm/controls/OrbitControls.js';
|
|
|
|
import { GLTFLoader } from 'jsm/loaders/GLTFLoader.js';
|
|
|
|
|
|
|
|
import { CSS3DRenderer, CSS3DObject } from 'jsm/renderers/CSS3DRenderer.js';
|
|
|
|
import { Water } from 'jsm/objects/Water.js';
|
|
|
|
import modellabel from './js/units/modellabel.js'
|
|
|
|
import css3dlabel from './js/units/css3dlabel.js'
|
|
|
|
import config from './js/config.js'
|
|
|
|
|
|
|
|
|
|
|
|
var controls, camera, glScene, cssScene, glRenderer, cssRenderer;
|
|
|
|
|
|
|
|
function createGlRenderer() {
|
|
|
|
var glRenderer = new THREE.WebGLRenderer({
|
|
|
|
antialias: true,
|
|
|
|
alpha: true
|
|
|
|
});
|
|
|
|
|
|
|
|
glRenderer.setClearColor(0xECF8FF);
|
|
|
|
glRenderer.setPixelRatio(window.devicePixelRatio);
|
|
|
|
glRenderer.setSize(window.innerWidth, window.innerHeight);
|
|
|
|
|
|
|
|
glRenderer.domElement.style.position = 'absolute';
|
|
|
|
glRenderer.domElement.style.zIndex = 1;
|
|
|
|
glRenderer.domElement.style.top = 0;
|
|
|
|
|
|
|
|
return glRenderer;
|
|
|
|
}
|
|
|
|
|
|
|
|
function createCssRenderer() {
|
|
|
|
var cssRenderer = new CSS3DRenderer();
|
|
|
|
cssRenderer.setSize(window.innerWidth, window.innerHeight);
|
|
|
|
cssRenderer.domElement.style.position = 'absolute';
|
|
|
|
glRenderer.domElement.style.zIndex = 0;
|
|
|
|
cssRenderer.domElement.style.top = 0;
|
|
|
|
return cssRenderer;
|
|
|
|
}
|
|
|
|
|
|
|
|
function createPlane(w, h, position, rotation) {
|
|
|
|
|
|
|
|
var material = new THREE.MeshBasicMaterial({
|
|
|
|
color: 0x000000,
|
|
|
|
opacity: 0.0,
|
|
|
|
side: THREE.DoubleSide
|
|
|
|
});
|
|
|
|
|
|
|
|
var geometry = new THREE.PlaneGeometry(w, h);
|
|
|
|
|
|
|
|
var mesh = new THREE.Mesh(geometry, material);
|
|
|
|
|
|
|
|
mesh.position.x = position.x;
|
|
|
|
mesh.position.y = position.y;
|
|
|
|
mesh.position.z = position.z;
|
|
|
|
|
|
|
|
mesh.rotation.x = rotation.x;
|
|
|
|
mesh.rotation.y = rotation.y;
|
|
|
|
mesh.rotation.z = rotation.z;
|
|
|
|
|
|
|
|
mesh.scale.set(0.003, 0.003, 0.003);
|
|
|
|
return mesh;
|
|
|
|
}
|
|
|
|
|
|
|
|
function createCssObject(w, h, position, rotation, url) {
|
|
|
|
var iframe = document.createElement('iframe')
|
|
|
|
iframe.src = url;
|
|
|
|
iframe.style.width = w + 'px';
|
|
|
|
iframe.style.height = h + 'px';
|
|
|
|
iframe.style.border = '0px';
|
|
|
|
// const iframe = document.createElement('div');
|
|
|
|
// // iframe.className = 'className';
|
|
|
|
// iframe.name = "csslabeldiv"
|
|
|
|
// iframe.textContent = '测试11111';
|
|
|
|
|
|
|
|
// iframe.style.pointerEvents = 'none';//避免HTML标签遮挡三维场景的鼠标事件
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var cssObject = new CSS3DObject(iframe);
|
|
|
|
cssObject.position.x = position.x;
|
|
|
|
cssObject.position.y = position.y;
|
|
|
|
cssObject.position.z = position.z;
|
|
|
|
|
|
|
|
cssObject.rotation.x = rotation.x;
|
|
|
|
cssObject.rotation.y = rotation.y;
|
|
|
|
cssObject.rotation.z = rotation.z;
|
|
|
|
|
|
|
|
cssObject.scale.set(0.003, 0.003, 0.003);
|
|
|
|
return cssObject;
|
|
|
|
}
|
|
|
|
|
|
|
|
function initModel() {
|
|
|
|
var loader = new GLTFLoader();
|
|
|
|
loader.load('assets/models/gallery.glb', function (gltf) {
|
|
|
|
gltf.scene.traverse(function (child) {
|
|
|
|
switch (child.name) {
|
|
|
|
case 'walls':
|
|
|
|
initWalls(child)
|
|
|
|
break
|
|
|
|
case 'stairs':
|
|
|
|
initStairs(child)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
//设置展画边框贴图
|
|
|
|
if (child.name.includes('paint')) {
|
|
|
|
initFrames(child)
|
|
|
|
}
|
|
|
|
//设置展画图片贴图
|
|
|
|
if (child.name.includes('draw')) {
|
|
|
|
initDraws(child)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
glScene.add(gltf.scene)
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function initDraws(child) { }
|
|
|
|
|
|
|
|
function initFrames(child) {
|
|
|
|
child.material = new THREE.MeshBasicMaterial({
|
|
|
|
color: 0x7f5816,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
function initStairs(child) {
|
|
|
|
child.material = new THREE.MeshStandardMaterial({
|
|
|
|
color: 0xd1cdb7,
|
|
|
|
})
|
|
|
|
child.material.roughness = 0.5
|
|
|
|
child.material.metalness = 0.6
|
|
|
|
}
|
|
|
|
|
|
|
|
function initWalls(child) {
|
|
|
|
child.material = new THREE.MeshStandardMaterial({
|
|
|
|
color: 0xffffff,
|
|
|
|
})
|
|
|
|
child.material.roughness = 0.5
|
|
|
|
child.material.metalness = 0.6
|
|
|
|
}
|
|
|
|
|
|
|
|
function create3dPage(w, h, position, rotation, url) {
|
|
|
|
var plane = createPlane(
|
|
|
|
w, h,
|
|
|
|
position,
|
|
|
|
rotation);
|
|
|
|
glScene.add(plane);
|
|
|
|
|
|
|
|
var cssObject = createCssObject(
|
|
|
|
w, h,
|
|
|
|
position,
|
|
|
|
rotation,
|
|
|
|
url);
|
|
|
|
cssScene.add(cssObject);
|
|
|
|
}
|
|
|
|
|
|
|
|
function createLights() {
|
|
|
|
const light = new THREE.AmbientLight("#ffffff");
|
|
|
|
glScene.add(light);
|
|
|
|
|
|
|
|
const light1 = new THREE.PointLight(0xe0ffff, 0.1, 20)
|
|
|
|
light1.position.set(-2, 3, 2)
|
|
|
|
glScene.add(light1)
|
|
|
|
|
|
|
|
const light2 = new THREE.PointLight(0xe0ffff, 0.1, 20)
|
|
|
|
light2.position.set(0, 3, -6)
|
|
|
|
glScene.add(light2)
|
|
|
|
|
|
|
|
const light3 = new THREE.PointLight(0xe0ffff, 0.1, 20)
|
|
|
|
light3.position.set(-12, 3, 6)
|
|
|
|
glScene.add(light3)
|
|
|
|
|
|
|
|
const light4 = new THREE.PointLight(0xe0ffff, 0.1, 20)
|
|
|
|
light4.position.set(-12, 4, -4)
|
|
|
|
glScene.add(light4)
|
|
|
|
|
|
|
|
const light5 = new THREE.PointLight(0xe0ffff, 0.1, 20)
|
|
|
|
light5.position.set(12, 4, -8)
|
|
|
|
glScene.add(light5)
|
|
|
|
|
|
|
|
const light6 = new THREE.PointLight(0xe0ffff, 0.1, 20)
|
|
|
|
light6.position.set(12, 4, 0)
|
|
|
|
glScene.add(light6)
|
|
|
|
|
|
|
|
const light7 = new THREE.PointLight(0xe0ffff, 0.1, 20)
|
|
|
|
light7.position.set(12, 4, 8)
|
|
|
|
glScene.add(light7)
|
|
|
|
}
|
|
|
|
|
|
|
|
function initialize() {
|
|
|
|
camera = new THREE.PerspectiveCamera(
|
|
|
|
45,
|
|
|
|
window.innerWidth / window.innerHeight,
|
|
|
|
1,
|
|
|
|
10000);
|
|
|
|
|
|
|
|
camera.position.set(-10, 5, -10);
|
|
|
|
|
|
|
|
glRenderer = createGlRenderer();
|
|
|
|
cssRenderer = createCssRenderer();
|
|
|
|
|
|
|
|
controls = new OrbitControls(camera, cssRenderer.domElement);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
document.body.appendChild(glRenderer.domElement);
|
|
|
|
glRenderer.domElement.appendChild(cssRenderer.domElement);
|
|
|
|
|
|
|
|
|
|
|
|
// document.body.appendChild(cssRenderer.domElement);
|
|
|
|
// cssRenderer.domElement.appendChild(glRenderer.domElement);
|
|
|
|
|
|
|
|
glScene = new THREE.Scene();
|
|
|
|
cssScene = glScene//new THREE.Scene();
|
|
|
|
|
|
|
|
var ambientLight = new THREE.AmbientLight(0x555555);
|
|
|
|
glScene.add(ambientLight);
|
|
|
|
|
|
|
|
var directionalLight = new THREE.DirectionalLight(0xffffff);
|
|
|
|
directionalLight.position.set(-.5, .5, -1.5).normalize();
|
|
|
|
glScene.add(directionalLight);
|
|
|
|
|
|
|
|
for (var i = 0; i < 2; i++) {
|
|
|
|
create3dPage(
|
|
|
|
1020, 680,
|
|
|
|
new THREE.Vector3(-2 - i, 1 + i / 3, -4.2 + i),
|
|
|
|
new THREE.Vector3(0, Math.PI, 0),
|
|
|
|
'https://zuoben.blog.csdn.net/');
|
|
|
|
}
|
|
|
|
|
|
|
|
initModel();
|
|
|
|
createLights();
|
|
|
|
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
|
|
|
function update() {
|
|
|
|
|
|
|
|
controls.update();
|
|
|
|
|
|
|
|
glRenderer.render(glScene, camera);
|
|
|
|
|
|
|
|
cssRenderer.render(cssScene, camera);
|
|
|
|
|
|
|
|
requestAnimationFrame(update);
|
|
|
|
}
|
|
|
|
|
|
|
|
initialize();
|
|
|
|
|
|
|
|
|
|
|
|
var raycaster = new THREE.Raycaster()
|
|
|
|
var mouse = new THREE.Vector3()
|
|
|
|
//点击模型
|
|
|
|
// window.addEventListener('click', onMouseClick);
|
|
|
|
window.addEventListener('dblclick', onDBMouseClick);
|
|
|
|
function onMouseClick(event) {
|
|
|
|
var mesh = [];
|
|
|
|
// 点击屏幕创建一个向量
|
|
|
|
var vector = new THREE.Vector3((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window
|
|
|
|
.innerHeight) * 2 + 1, 0.5);
|
|
|
|
vector = vector.unproject(window.camera); // 将屏幕的坐标转换成三维场景中的坐标
|
|
|
|
var raycaster = new THREE.Raycaster(window.camera.position, vector.sub(window.camera.position).normalize());
|
|
|
|
var intersects = raycaster.intersectObjects(mesh, true);
|
|
|
|
// debugger
|
|
|
|
if (intersects.length > 0) {
|
|
|
|
intersects[0].object.material.color.set("#ff0000");
|
|
|
|
alert(JSON.stringify(intersects[0]))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function onDBMouseClick(event) {
|
|
|
|
|
|
|
|
//将鼠标点击位置的屏幕坐标转换成threejs中的标准坐标
|
|
|
|
mouse.x = (event.clientX / window.innerWidth) * 2 - 1
|
|
|
|
mouse.y = -((event.clientY / window.innerHeight) * 2 - 1)
|
|
|
|
//console.log("mouse:"+mouse.x+","+mouse.y)
|
|
|
|
|
|
|
|
// 通过鼠标点的位置和当前相机的矩阵计算出raycaster
|
|
|
|
raycaster.setFromCamera(mouse, window.camera);
|
|
|
|
|
|
|
|
// 获取raycaster直线和所有模型相交的数组集合
|
|
|
|
// debugger
|
|
|
|
var intersects = raycaster.intersectObjects(scene.children);
|
|
|
|
console.log("onclick ", intersects);
|
|
|
|
|
|
|
|
//debugger
|
|
|
|
//将所有的相交的模型的颜色设置为红色
|
|
|
|
for (var i = 0; i < intersects.length; i++) {
|
|
|
|
let obj = intersects[i];
|
|
|
|
if (obj.object) {
|
|
|
|
let tmpobj = obj.object;
|
|
|
|
console.log(tmpobj)
|
|
|
|
//输出 增加标签 位置
|
|
|
|
console.log('{name:"' + tmpobj.name + '1",text:"' + tmpobj.name + '",x:' + obj.point.x.toFixed(2) + ',y:' + obj.point.y.toFixed(2) + ',z:' + obj.point.z.toFixed(2) + ',rx:0,ry:0,rz:0}');
|
|
|
|
if (tmpobj.name.indexOf('水泵M_') > -1) { // 水泵
|
|
|
|
|
|
|
|
openDialog(tmpobj)
|
|
|
|
//alert(tmpobj.name, "双击");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
</script>
|
|
|
|
</body>
|
|
|
|
|
|
|
|
</html>
|