<template>
<div ref="container" id="container"></div>
</template>
<script>
import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
export default {
data() {
return {
camera: {},
renderer: {},
controls: null,
};
},
mounted() {
let that = this;
var fov = 75; // 拍摄距离,视野角值越大,场景中的物体越小
let near = 1; // 最小范围
var far = 1000;
// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(
fov,
window.innerWidth / window.innerHeight,
0.1,
far
);
this.camera = camera;
// camera.position.set(0, 0, 10); // 设置相机在 z 轴上的位置
// 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
this.renderer = renderer;
let dom = this.$refs.container;
this.$refs.container.appendChild(renderer.domElement);
var cub = new THREE.CubeTextureLoader().load(
Array(6).fill(require("@/static/3d/img/backb.jpg"))
);
cub.encoding = THREE.sRGBEncoding;
cub.flipY = false;
scene.background = cub;
// 添加光源
const directionalLight = new THREE.DirectionalLight(0xffffff, 1); // 方向光颜色和强度
directionalLight.position.set(1, 1, 1); // 光源位置
scene.add(directionalLight);
// 创建控制器
const controls = new OrbitControls(camera, renderer.domElement);
this.controls = controls;
controls.enableDamping = true; // 允许阻尼效果,使动画更平滑
controls.dampingFactor = 0.05; // 阻尼系数
controls.rotateSpeed = 0.1; // 旋转速度
// 加载3D模型
const loader = new GLTFLoader();
loader.load("/3D/house2.glb", (gltf) => {
scene.add(gltf.scene);
function animate() {
requestAnimationFrame(animate);
controls.update(); // 更新控制器状态
renderer.render(scene, camera);
}
const object = gltf.scene; // 获取加载的3D模型对象
// 将点击事件绑定到立方体上
object.traverse((child) => {
console.log(child.name);
//child.name可以在three editor中找到
if (child instanceof THREE.Mesh && child.name === "node_id209") {
child.userData.onClick = () => {
// 在这里处理点击事件的逻辑
alert("您好!");
};
child.userData.clickable = true;//将元素设置为可点击
}
if (child instanceof THREE.Mesh && child.name === "node_id183") {
child.userData.onClick = () => {
// 在这里处理点击事件的逻辑
alert("别点我的头!");
};
child.userData.clickable = true;
}
});
scene.add(object);
// 添加点击事件监听器
dom.addEventListener("mousedown", onMouseDown, false);
function onMouseDown(event) {
const mouse = new THREE.Vector2();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
// 创建射线投射器
const raycaster = new THREE.Raycaster();
raycaster.setFromCamera(mouse, camera);
// 检测射线与可点击对象的交互
const intersects = raycaster.intersectObjects(object.children, true);
intersects.forEach((intersect) => {
const { object } = intersect;
// 检查是否为可点击对象
if (
object.userData.clickable &&
typeof object.userData.onClick === "function"
) {
// 调用点击事件处理函数
object.userData.onClick();
}
});
}
animate();
});
// 滚轮事件
dom.addEventListener("mousewheel", mousewheel, false);
function mousewheel(e) {
e.preventDefault();
if (e.deltaY < 0) {
// 当滚轮向上滚动时
camera.position.z -= 1; // 向前移动相机
} else {
// 当滚轮向下滚动时
camera.position.z += 1; // 向后移动相机
}
renderer.render(scene, camera);
}
// 窗口大小改变事件
window.addEventListener("resize", this.handleResize);
},
methods: {
handleResize() {
const width = window.innerWidth;
const height = window.innerHeight;
this.camera.aspect = width / height;
this.camera.updateProjectionMatrix();
this.renderer.setSize(width, height);
},
beforeDestroy() {
window.removeEventListener("resize", this.handleResize);
},
},
};
</script>
<style>
/* 可以自定义样式 */
#container {
margin: 0;
padding: 0;
}
</style>
three.js加vue2实现.glb渲染,旋转元素,放大缩小,以及元素点击事件
于 2023-06-27 10:22:58 首次发布