three 基础库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

349 lines
12 KiB

2 years ago
<!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);
2 years ago
document.body.appendChild(glRenderer.domElement);
glRenderer.domElement.appendChild(cssRenderer.domElement);
// document.body.appendChild(cssRenderer.domElement);
// cssRenderer.domElement.appendChild(glRenderer.domElement);
2 years ago
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();
2 years ago
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;
}
}
}
2 years ago
</script>
</body>
</html>