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);
}
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
}
}
function setContainerSize() {
container.w = window.innerWidth
container.h = window.innerHeight
container.aspect = window.innerWidth / window.innerHeight
}
(function main() {
setContainerSize()
initCamera();
initScene();
initRenderer();
initControls();
initLight();
initHelper();
initModel();
addEL();
animate();
})()
function $id(id) {
return !id ? renderer.domElement : document.getElementById(id);
}
</script>
</html>