123
parent
59bbb8358c
commit
07189fa6a7
|
@ -42,7 +42,8 @@
|
|||
"vue": "3.2.45",
|
||||
"vue-cropper": "1.0.3",
|
||||
"vue-router": "4.1.4",
|
||||
"mitt": "^3.0.1"
|
||||
"mitt": "^3.0.1",
|
||||
"gsap": "^3.11.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "3.1.0",
|
||||
|
|
Binary file not shown.
|
@ -1392,7 +1392,7 @@
|
|||
-54.6457,
|
||||
1
|
||||
],
|
||||
"name": "4",
|
||||
"name": "set3",
|
||||
"extras": {
|
||||
"name": "4"
|
||||
},
|
||||
|
|
|
@ -37,6 +37,7 @@ import homeIcon from '@/assets/image/bg7.jpg'
|
|||
import TWEEN from "@tweenjs/tween.js";
|
||||
import Bus from '@/utils/bus.js'
|
||||
import bimStore from '@/store/modules/bim';
|
||||
import gsap from "gsap";
|
||||
|
||||
let scene = ref(null);
|
||||
let renderer = ref(null);
|
||||
|
@ -50,6 +51,7 @@ let labelRenderer = new CSS2DRenderer(); //新建CSS2DRenderer
|
|||
let positionObj = ref(null);
|
||||
// 选中的模型
|
||||
let selectedObjects = ref([]);
|
||||
let curve = ref(null);
|
||||
|
||||
const props = defineProps({
|
||||
background: { // 背景颜色
|
||||
|
@ -94,10 +96,12 @@ Bus.on('clickBuild', (isParent) => {
|
|||
// })
|
||||
// 高亮轮廓
|
||||
outlineObj([Floor]);
|
||||
// 拉近场景
|
||||
nearCamera(Floor);
|
||||
return;
|
||||
}
|
||||
// 父级
|
||||
toHomeView();
|
||||
// toHomeView();
|
||||
})
|
||||
// 设备树点击
|
||||
Bus.on('clickDevice', (isParent) => {
|
||||
|
@ -107,10 +111,12 @@ Bus.on('clickDevice', (isParent) => {
|
|||
console.log(1, Floor);
|
||||
// 高亮轮廓
|
||||
outlineObj([Floor])
|
||||
// 拉近距离
|
||||
// nearCamera(Floor);
|
||||
return;
|
||||
}
|
||||
// 父级
|
||||
toHomeView();
|
||||
// toHomeView();
|
||||
})
|
||||
|
||||
// 系统树点击
|
||||
|
@ -124,65 +130,11 @@ onMounted(() => {
|
|||
loadSence();
|
||||
// 启动动画
|
||||
renderScene();
|
||||
document.addEventListener("click", onMouseDown);
|
||||
// document.addEventListener("click", onMouseDown);
|
||||
document.addEventListener("mousemove", onMouseDown);
|
||||
});
|
||||
|
||||
|
||||
const setLabel = () => {
|
||||
if(isAddLabel.value) {
|
||||
addLabel();
|
||||
} else {
|
||||
removeLabel();
|
||||
}
|
||||
isAddLabel.value = !isAddLabel.value;
|
||||
}
|
||||
|
||||
const removeLabel = () => {
|
||||
document.body.removeChild(labelRenderer.domElement);
|
||||
}
|
||||
// 添加标签
|
||||
|
||||
const addLabel = () => {
|
||||
let obj = gltfObj.value.scene.getObjectByName('set2');
|
||||
let text = "设备二";
|
||||
let pointLabel = createLableObj(text);
|
||||
obj.add(pointLabel);
|
||||
labelRenderer.setSize(window.innerWidth, window.innerHeight);
|
||||
labelRenderer.domElement.style.position = "absolute";
|
||||
labelRenderer.domElement.style.top = 0;
|
||||
labelRenderer.domElement.style.pointerEvents = 'none';// 必须加上
|
||||
document.body.appendChild(labelRenderer.domElement);
|
||||
|
||||
// 将呈现器的输出添加到HTML元素
|
||||
document.getElementById("dom").appendChild(renderer.domElement);
|
||||
};
|
||||
|
||||
const createLableObj = (text) => {
|
||||
let laberDiv = document.createElement("div"); //创建div容器
|
||||
laberDiv.className = "laber_name";
|
||||
laberDiv.innerHTML = `<div class="arrow_outer"></div><span>设备名称:${text}</span><span>状态:启用</span><span>压力:50 Pa</span>`
|
||||
let pointLabel = new CSS2DObject(laberDiv);
|
||||
return pointLabel;
|
||||
};
|
||||
// 清除模型颜色
|
||||
const cleanColor = () => {
|
||||
|
||||
// 恢复之前被选中模型的材质
|
||||
if (objArr.length > 0 && objM.length > 0) {
|
||||
objArr.forEach((ele, index) => {
|
||||
console.log(objM[index]);
|
||||
ele.material = objM[index]
|
||||
})
|
||||
objArr = [];
|
||||
objM = [];
|
||||
}
|
||||
gltfObj.value.scene.traverse(e => {
|
||||
objArr.push(e);
|
||||
objM.push(e.material);
|
||||
})
|
||||
}
|
||||
const init = () => {
|
||||
// 环境球
|
||||
// scene = new THREE.Scene("#00ffff");
|
||||
// const texture = new THREE.TextureLoader().load(homeIcon);
|
||||
// texture.mapping = THREE.EquirectangularReflectionMapping;
|
||||
|
@ -190,46 +142,44 @@ const init = () => {
|
|||
// scene.environment = texture
|
||||
|
||||
scene = new THREE.Scene();
|
||||
console.log(123, props.background);
|
||||
scene.background = new THREE.Color(props.background);
|
||||
const canvas = document.querySelector("#three");
|
||||
var cubeLoader = new THREE.CubeTextureLoader();
|
||||
// 创建一个渲染器并设置大小,WebGLRenderer将会使用电脑显卡来渲染场景
|
||||
renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: true, preserveDrawingBuffer: true });
|
||||
//曝光
|
||||
renderer.toneMappingExposure = 2;
|
||||
renderer.shadowMap.enabled = true;
|
||||
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
||||
|
||||
//相机
|
||||
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.25, 2000)
|
||||
// 将摄像机对准场景的中心
|
||||
camera.position.set(-92.936, 180.990, -28.179);
|
||||
camera.lookAt(scene.position);
|
||||
// 创建控件对象
|
||||
|
||||
// 创建控件对象 限制controls的上下角度范围
|
||||
orbit = new OrbitControls(camera, renderer.domElement);
|
||||
orbit.autoRotate = true;
|
||||
setTimeout(function () {
|
||||
orbit.autoRotate = false;
|
||||
}, 7000);
|
||||
// renderer.setClearColor(new THREE.Color("#0e0934"));
|
||||
orbit.maxPolarAngle = Math.PI / 2.1;
|
||||
orbit.maxDistance = 12;
|
||||
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
// 环境光 光源颜色从0x444444更改为0x888888,可以看到threejs场景中的网格模型表面变的更亮。
|
||||
// intensity 强度属性0.5
|
||||
var alight = new THREE.AmbientLight(props.light, 1);
|
||||
alight.name = "aLight";
|
||||
scene.add(alight);
|
||||
};
|
||||
|
||||
// 增加漫游路线
|
||||
makeCurve();
|
||||
|
||||
};
|
||||
// 加载场景
|
||||
const loadSence = () => {
|
||||
const gltfLoader = new GLTFLoader();
|
||||
gltfLoader.load(props.sceneUrl, (gltf) => {
|
||||
// model.value = gltf.scene;
|
||||
gltfObj.value = gltf;
|
||||
var model = gltf.scene;
|
||||
scene.add(model);
|
||||
});
|
||||
};
|
||||
|
||||
// 渲染
|
||||
const renderScene = () => {
|
||||
// orbit.update(); // 拖动
|
||||
// 使用requestAnimationFrame函数进行渲染
|
||||
|
@ -242,40 +192,46 @@ const renderScene = () => {
|
|||
}
|
||||
};
|
||||
// 相机移动动画
|
||||
const initTween = (targetX, targetY, targetZ) => {
|
||||
let initPosition = {
|
||||
x: camera.position.x,
|
||||
y: camera.position.y,
|
||||
z: camera.position.z,
|
||||
};
|
||||
let tween = new TWEEN.Tween(initPosition)
|
||||
.to({ x: targetX, y: targetY, z: targetZ }, 2000)
|
||||
.easing(TWEEN.Easing.Sinusoidal.InOut);
|
||||
let onUpdate = (pos) => {
|
||||
let x = pos.x;
|
||||
let y = pos.y;
|
||||
let z = pos.z;
|
||||
if (pos.z < 0) {
|
||||
camera.position.set(x, y, z - 12);
|
||||
} else {
|
||||
camera.position.set(x, y, z + 12);
|
||||
const makeCurve = () => {
|
||||
curve = new THREE.CatmullRomCurve3([
|
||||
new THREE.Vector3(11.5, 0, 18),
|
||||
new THREE.Vector3(11.5, 0, 34),
|
||||
new THREE.Vector3(35, 0, 34),
|
||||
new THREE.Vector3(35, 0, 31),
|
||||
new THREE.Vector3(11.5, 0, 31),
|
||||
]);
|
||||
// 为曲线添加材质在场景中显示出来,不显示也不会影响运动轨迹,相当于一个Helper
|
||||
const points = curve.getPoints(0.1);
|
||||
const geometry = new THREE.BufferGeometry().setFromPoints(points);
|
||||
const material = new THREE.LineBasicMaterial({
|
||||
color: 0xff0000,
|
||||
});
|
||||
|
||||
// 线条模型对象
|
||||
const line = new THREE.Line(geometry, material);
|
||||
scene.add(line)
|
||||
|
||||
}
|
||||
};
|
||||
tween.onUpdate(onUpdate);
|
||||
tween.start();
|
||||
if (positionObj.z < 0) {
|
||||
orbit.target.set(
|
||||
positionObj.x,
|
||||
positionObj.y - 0.4,
|
||||
-12
|
||||
);
|
||||
} else {
|
||||
orbit.target.set(
|
||||
positionObj.x,
|
||||
positionObj.y - 0.4,
|
||||
12
|
||||
);
|
||||
|
||||
const changePosition = (t) => {
|
||||
const position = curve.getPointAt(t); // t: 当前点在线条上的位置百分比,后面计算
|
||||
mesh.position.copy(position);
|
||||
}
|
||||
|
||||
const changeLookAt = (t) => {
|
||||
const tangent = curve.getTangentAt(t);
|
||||
const lookAtVec = tangent.add(mesh.position); // 位置向量和切线向量相加即为所需朝向的点向量
|
||||
mesh.lookAt(lookAtVec);
|
||||
}
|
||||
|
||||
const loopTime = 10 * 1000; // loopTime: 循环一圈的时间
|
||||
const walk = () => {
|
||||
let time = Date.now();
|
||||
setInterval(() => {
|
||||
let t = (time % loopTime) / loopTime; // 计算当前时间进度百分比
|
||||
changePosition(t);
|
||||
changeLookAt(t);
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
// 储存被选中的模型和材质
|
||||
|
@ -360,54 +316,75 @@ const outlineObj = (selectedObject_list) => {
|
|||
composer.addPass(effectFXAA)
|
||||
}
|
||||
|
||||
const nearCamera = (intersects) => {
|
||||
console.log(5555, intersects)
|
||||
// 拉近场景
|
||||
if (!intersects[0]) {
|
||||
return;
|
||||
} else {
|
||||
if (intersects[0].object.name) {
|
||||
selectedObjects = [];
|
||||
selectedObjects.push(intersects[0].object);
|
||||
positionObj = {
|
||||
x: intersects[0].object.position.x,
|
||||
y: intersects[0].object.position.y,
|
||||
z: intersects[0].object.position.z,
|
||||
};
|
||||
const nearCamera = (floor) => {
|
||||
orbit.reset();
|
||||
gsap.to(camera.position, {
|
||||
x: floor.position.x - 40,
|
||||
y: floor.position.y + 60,
|
||||
z: floor.position.z,
|
||||
duration: 2,
|
||||
ease: "power1.inOut",
|
||||
onComplete: () => {
|
||||
},
|
||||
});
|
||||
|
||||
initTween(
|
||||
positionObj.x,
|
||||
positionObj.y,
|
||||
positionObj.z + 10
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
const toHomeView = () => {
|
||||
camera.position.set(-92.936, 180.990, -28.179);
|
||||
camera.lookAt(scene.position);
|
||||
// cleanColor();
|
||||
orbit.reset();
|
||||
outlineObj([]);
|
||||
}
|
||||
// 返回主页
|
||||
const toHomeView1 = () => {
|
||||
let initPosition = {
|
||||
x: camera.position.x,
|
||||
y: camera.position.y,
|
||||
z: camera.position.z,
|
||||
|
||||
|
||||
const setLabel = () => {
|
||||
if(isAddLabel.value) {
|
||||
addLabel();
|
||||
} else {
|
||||
removeLabel();
|
||||
}
|
||||
isAddLabel.value = !isAddLabel.value;
|
||||
}
|
||||
|
||||
const removeLabel = () => {
|
||||
document.body.removeChild(labelRenderer.domElement);
|
||||
}
|
||||
// 添加标签
|
||||
const addLabel = () => {
|
||||
let obj = gltfObj.value.scene.getObjectByName('set2');
|
||||
let text = "设备二";
|
||||
let pointLabel = createLableObj(text);
|
||||
obj.add(pointLabel);
|
||||
labelRenderer.setSize(window.innerWidth, window.innerHeight);
|
||||
labelRenderer.domElement.style.position = "absolute";
|
||||
labelRenderer.domElement.style.top = 0;
|
||||
labelRenderer.domElement.style.pointerEvents = 'none';// 必须加上
|
||||
document.body.appendChild(labelRenderer.domElement);
|
||||
|
||||
// 将呈现器的输出添加到HTML元素
|
||||
document.getElementById("dom").appendChild(renderer.domElement);
|
||||
};
|
||||
let tween = new TWEEN.Tween(initPosition)
|
||||
.to({ x: 0, y: -(5 * 24) / 12, z: (6 * 100) / 5 }, 2000)
|
||||
.easing(TWEEN.Easing.Sinusoidal.InOut);
|
||||
let onUpdate = (pos) => {
|
||||
let x = pos.x;
|
||||
let y = pos.y;
|
||||
let z = pos.z;
|
||||
camera.position.set(x, y, z);
|
||||
|
||||
const createLableObj = (text) => {
|
||||
let laberDiv = document.createElement("div"); //创建div容器
|
||||
laberDiv.className = "laber_name";
|
||||
laberDiv.innerHTML = `<div class="arrow_outer"></div><span>设备名称:${text}</span><span>状态:启用</span><span>压力:50 Pa</span>`
|
||||
let pointLabel = new CSS2DObject(laberDiv);
|
||||
return pointLabel;
|
||||
};
|
||||
tween.onUpdate(onUpdate);
|
||||
tween.start();
|
||||
orbit.target.set(0, 0, 0);
|
||||
// 清除模型颜色
|
||||
const cleanColor = () => {
|
||||
// 恢复之前被选中模型的材质
|
||||
if (objArr.length > 0 && objM.length > 0) {
|
||||
objArr.forEach((ele, index) => {
|
||||
console.log(objM[index]);
|
||||
ele.material = objM[index]
|
||||
})
|
||||
objArr = [];
|
||||
objM = [];
|
||||
}
|
||||
gltfObj.value.scene.traverse(e => {
|
||||
objArr.push(e);
|
||||
objM.push(e.material);
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style lang='scss'>
|
||||
|
|
Loading…
Reference in New Issue