three.js 结合控制器,TWEEN插件,FLTF加载器实现加载glb格式模型,模型的热点的点击、相机在场景中的移动效果,

it2023-07-31  69

1. 技术点:结合控制器,TWEEN插件,FLTF加载器实现加载glb格式模型,模型的热点的点击、相机在场景中的移动效果,

2. 效果地址

案例地址(只做了pc端移动端不兼容)

3.全部代码

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link type="text/css" rel="stylesheet" href="../../three.js-r115/examples/main.css"> </head> <body> <div id="container" style="width: 100%; height: 100%;"></div> </body> <script type="module"> import * as THREE from '../../three.js-r115/build/three.module.js'; import {OrbitControls} from "../../three.js-r115/examples/jsm/controls/OrbitControls.js"; import Stats from '../../three.js-r115/examples/jsm/libs/stats.module.js' import {GLTFLoader} from "../../three.js-r115/examples/jsm/loaders/GLTFLoader.js"; import {TWEEN} from "../../three.js-r115/examples/jsm/libs/tween.module.min.js"; let nowLookModel = {x: 0, y: 0, z: 0}; // 当前位置 let scene, camera, renderer, orbitControls, state = new Stats(), // 场景、相机、加载器、控制器、性能检测器 raycaster = new THREE.Raycaster(), mouse = new THREE.Vector2(), container = {}; // 射线、鼠标或触摸位置、容器大小 let isMove = false; // 判断鼠标是否移动 function initCamera() { camera = new THREE.PerspectiveCamera(90, container.aspect, 0.1, 1000); // camera.position.setY(100) } // 初始化相机 function initScene() { scene = new THREE.Scene(); scene.position.set(...Object.values(nowLookModel)) } // 初始化场景 function initRenderer() { renderer = new THREE.WebGLRenderer({antialias: true}); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(container.w, container.h); $id('container').appendChild(renderer.domElement); } // 初始化渲染器 function initControls() { orbitControls = new OrbitControls(camera, renderer.domElement); orbitControls.target.set(0, 0, 0.01) } // 初始化控制器 function initLight() { let ambientLight = new THREE.AmbientLight(0xffffff, 5); ambientLight.position.set(200, 200, 0); scene.add(ambientLight); } // 初始化灯光 function initModel() { let loader = new GLTFLoader(); let imageLoader = new THREE.TextureLoader(); loader.load('../../static/models/sh_hot_floor.glb', function (gltf) { gltf = gltf.scene gltf.position.setY(-2) let texture = imageLoader.load('../../static/images/floor.jpeg', (t) => { scene.getObjectByName('floor_1').material = new THREE.MeshBasicMaterial({map: t,}); }) texture.wrapS = texture.wrapT = THREE.RepeatWrapping; texture.repeat.set(100, 100); gltf.name = 'gltf' scene.add(gltf); }) } // 初始化模型 function initHelper() { $id('container').appendChild(state.domElement) } // 初始化辅助线 function onWindowResize() { setContainerSize() camera.aspect = container.aspect; camera.updateProjectionMatrix(); renderer.setSize(container.w, container.h); } // 调整窗口大小 function animate() { requestAnimationFrame(animate); render() state.update() } //动画 function render() { orbitControls.update(); scene.position.set(...Object.values(nowLookModel)) renderer.render(scene, camera); TWEEN.update() } //渲染 function onDown(event) { setMouseXYZ(event) isMove = false } // 按下 function onMove(event) { setMouseXYZ(event) } // 移动 function onUp(event) { setMouseXYZ(event) if (!isMove) { raycaster.setFromCamera(mouse, camera); let intersectObjects = raycaster.intersectObject(scene.getObjectByName('gltf'), true); console.log(intersectObjects); let move = raycaster.intersectObject(scene.getObjectByName('gltf'), true); let hot = raycaster.intersectObject(scene.getObjectByName('gltf'), true); if (hot[0] && hot[0].object.name.indexOf('热点') != -1) { alert(hot[0].object.name) } else if (move[0] && move[0].object.name == 'floor_1') { new TWEEN.Tween(nowLookModel).to({ x: nowLookModel.x - move[0].point.x, z: nowLookModel.z - move[0].point.z, }, 300).start(); } } } // 弹起 function addEL() { window.addEventListener('resize', onWindowResize, false); $id().addEventListener('mousedown', onDown, false); $id().addEventListener('mousemove', onMove, false); $id().addEventListener('mouseup', onUp, false); } //添加监听器 function setMouseXYZ(event) { event.preventDefault(); if (Math.abs(event.movementX) > 1 || Math.abs(event.movementY) > 1) { mouse.x = (event.offsetX / $id().offsetWidth) * 2 - 1; mouse.y = -(event.offsetY / $id().offsetHeight) * 2 + 1; isMove = true } // 处理点击的时候可能会移动的误差 }// 设置mouse的坐标 function setContainerSize() { container.w = window.innerWidth container.h = window.innerHeight container.aspect = window.innerWidth / window.innerHeight } // 获取容器大小并设置给container (function main() { setContainerSize() // 打开的窗口容器大小 initCamera(); // 初始化相机 initScene(); // 初始化场景 initRenderer(); // 初始化渲染器 initControls(); // 初始化控制器 initLight(); // 初始化灯光 initHelper(); // 初始化辅助线 initModel(); // 初始化模型 addEL(); // 添加监听器 animate(); // 动画 })() // 方法运行的main函数 function $id(id) { return !id ? renderer.domElement : document.getElementById(id); } // 获取画布或者根据id获取document对象 </script> </html>
最新回复(0)