二 Three光线检测-实现摄像机向鼠标点击位置滑动动画( 二 )

//光线检测 , 获取点击物体的坐标值rayClick() {const raycaster = new THREE.Raycaster();const mouse = new THREE.Vector2();const camera = this.camera;const scene = this.scene;//对页面进行鼠标点击事件绑定window.addEventListener("mouseup", mouseup);//添加点击方法function mouseup(e) {// 将鼠标位置归一化为设备坐标 。x 和 y 方向的取值范围是 (-1 to +1)mouse.x = (e.clientX / window.innerWidth) * 2 - 1;mouse.y = -(e.clientY / window.innerHeight) * 2 + 1;// 通过摄像机和鼠标位置更新射线//这里的摄像机要将外部定义的摄像机通过新的变量接受到,再次赋值使用,同下方的scene//因为鼠标点击事件的this指的是windows , 不是这个场景Scene,解决办法可以在 const mouse = new THREE.Vector2();// 后重新赋值一下:const _this = this; 在点击函数中就可以使用_this.scene、_this.cameraraycaster.setFromCamera(mouse, camera);// 计算物体和射线的焦点const intersects = raycaster.intersectObjects(scene.children);console.log(intersects);//选中后进行操作if (intersects.length) {var selected = intersects[0];//点击世界中的物体,改变摄像机位置到物体前,实现从远景到近景的切换效果TweenMax.to(camera.position, 2, {x: selected.point.x + 50,y: selected.point.y,z: selected.point.z + 100,ease:Expo.easeInOut,onComplete: function (){}})console.log("x坐标" + selected.point.x);console.log("y坐标" + selected.point.y);console.log("z坐标" + selected.point.z);}}}1.5完整代码html部分<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Three实现摄像机动画</title><link rel="stylesheet" href="https://www.huyubaike.com/biancheng/assets/css/index.css"></head><body><canvas id="canvasScene"></canvas><script src="https://www.huyubaike.com/biancheng/js/index.js" type="module"></script></body></html>index.js部分import Scene from "./Scene";const canvasEL = document.getElementById('canvasScene');new Scene(canvasEL);Scene.js部分import * as THREE from "three";//导入鼠标控制器控件import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";//导入fbx模型加载器import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader";//导入TweenMax动画控件import { TweenMax } from "gsap/gsap-core";import { Expo } from "gsap";export default class Scene {canvas;scene;camera;render;controls;light;constructor(el) {this.canvas = el;this.init();}init() {this.setRender();this.setScene();this.setCamera();this.setControls();this.setLight();this.animate();this.setFbx();this.rayClick();}setScene() {this.scene = new THREE.Scene();this.scene.background = new THREE.Color(0x002222);}// 设置相机setCamera() {this.camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,3000);this.camera.position.set(300, 200, 1000);this.camera.aspect = window.innerWidth / window.innerHeight;this.camera.updateProjectionMatrix();this.scene.add(this.camera);}// 设置渲染器setRender() {this.render = new THREE.WebGL1Renderer({canvas: this.canvas,//设置抗锯齿antialias: true,});//设置渲染编码this.render.outputEncoding = THREE.sRGBEncoding;//设置渲染宽高this.render.setSize(window.innerWidth, window.innerHeight);//监听页面大小变化,修改器的宽高、摄像机的比例window.addEventListener("resize", () => {this.camera.aspect = window.innerWidth / window.innerHeight;this.camera.updateProjectionMatrix();this.render.setSize(window.innerWidth, window.innerHeight);});}//设置控制器setControls() {this.controls = new OrbitControls(this.camera, this.render.domElement);}//设置灯光setLight() {this.light = new THREE.SpotLight();this.light.position.set(100, 500, 300);this.scene.add(this.light);}//设置渲染函数animate = () => {this.render.render(this.scene, this.camera);window.requestAnimationFrame(this.animate);};//添加fbx模型setFbx() {const fbxLoader = new FBXLoader();fbxLoader.load("./model/house.fbx", (house) => {const scale = 0.05;house.scale.set(scale, scale, scale);this.scene.add(house);house.position.set(0, 0, 0);});}//光线检测,获取点击物体的坐标值rayClick() {const raycaster = new THREE.Raycaster();const mouse = new THREE.Vector2();const camera = this.camera;const scene = this.scene;//对页面进行鼠标点击事件绑定window.addEventListener("mouseup", mouseup);//添加点击方法function mouseup(e) {// 将鼠标位置归一化为设备坐标 。x 和 y 方向的取值范围是 (-1 to +1)mouse.x = (e.clientX / window.innerWidth) * 2 - 1;mouse.y = -(e.clientY / window.innerHeight) * 2 + 1;// 通过摄像机和鼠标位置更新射线//这里的摄像机要将外部定义的摄像机通过新的变量接受到,再次赋值使用,同下方的sceneraycaster.setFromCamera(mouse, camera);// 计算物体和射线的焦点const intersects = raycaster.intersectObjects(scene.children);console.log(intersects);//选中后进行操作if (intersects.length) {var selected = intersects[0];//点击世界中的物体,改变摄像机位置到物体前,实现从远景到近景的切换效果TweenMax.to(camera.position, 2, {x: selected.point.x + 50,y: selected.point.y,z: selected.point.z + 100,ease:Expo.easeInOut,onComplete: function (){}})console.log("x坐标" + selected.point.x);console.log("y坐标" + selected.point.y);console.log("z坐标" + selected.point.z);}}}}

推荐阅读