汽车网站策划书,企业画册vi设计,巴南市政建设网站,淮安网站网页设计在 Three.js 中#xff0c;实现相机视角的平滑过渡和点击模型切换到查看模型视角是一个常见且有用的功能。这种效果不仅能提升用户体验#xff0c;还能为场景互动添加更多的动态元素。
1. 基本设置
首先#xff0c;我们需要创建一个基本的 Three.js 场景#xff0c;包括相…在 Three.js 中实现相机视角的平滑过渡和点击模型切换到查看模型视角是一个常见且有用的功能。这种效果不仅能提升用户体验还能为场景互动添加更多的动态元素。
1. 基本设置
首先我们需要创建一个基本的 Three.js 场景包括相机、渲染器、光源以及一些示例模型。
创建场景和相机
// 创建场景
const scene new THREE.Scene();
// 创建相机
const camera new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 5, 10);
// 创建渲染器
const renderer new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 创建光源
const light new THREE.DirectionalLight(0xffffff, 1);
light.position.set(0, 10, 10);
scene.add(light);添加示例模型
// 创建一个简单的几何体
const geometry new THREE.BoxGeometry();
const material new THREE.MeshStandardMaterial({ color: 0x00ff00 });
const cube new THREE.Mesh(geometry, material);
cube.position.set(0, 1, 0);
scene.add(cube);
// 创建另一个几何体
const sphereGeometry new THREE.SphereGeometry(0.5, 32, 32);
const sphereMaterial new THREE.MeshStandardMaterial({ color: 0xff0000 });
const sphere new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.set(2, 1, 0);
scene.add(sphere);2. 引入动画库
为了实现平滑过渡我们引入 tween.js 动画库。
npm install tweenjs/tween.js
import * as TWEEN from tweenjs/tween.js
3. 实现相机视角的平滑切换
定义相机切换函数
function smoothCameraTransition(targetPosition, targetLookAt) {// 保存当前相机的位置和朝向const startPosition camera.position.clone();const startLookAt new THREE.Vector3();camera.getWorldDirection(startLookAt);
// 创建 tween 动画new TWEEN.Tween(startPosition).to(targetPosition, 2000) // 动画持续时间为2000毫秒.easing(TWEEN.Easing.Quadratic.InOut) // 使用缓动函数.onUpdate(() {camera.position.copy(startPosition);}).start();
new TWEEN.Tween(startLookAt).to(targetLookAt, 2000).easing(TWEEN.Easing.Quadratic.InOut).onUpdate(() {camera.lookAt(startLookAt);}).start();
}更新渲染循环
确保在渲染循环中更新 tween 动画。
function animate() {requestAnimationFrame(animate);TWEEN.update();renderer.render(scene, camera);
}
animate();4. 实现点击模型切换视角
添加射线投射器
我们需要添加射线投射器来检测用户点击的模型。
const raycaster new THREE.Raycaster();
const mouse new THREE.Vector2();
function onMouseClick(event) {// 将鼠标点击位置转换为标准化设备坐标mouse.x (event.clientX / window.innerWidth) * 2 - 1;mouse.y -(event.clientY / window.innerHeight) * 2 1;
// 更新射线投射器raycaster.setFromCamera(mouse, camera);
// 计算交互对象const intersects raycaster.intersectObjects(scene.children);
if (intersects.length 0) {const intersectedObject intersects[0].object;// 切换相机视角到点击的模型const targetPosition new THREE.Vector3().copy(intersectedObject.position).add(new THREE.Vector3(0, 2, 5));const targetLookAt intersectedObject.position.clone();smoothCameraTransition(targetPosition, targetLookAt);}
}
window.addEventListener(click, onMouseClick, false);5. 完整代码示例
将上述代码片段整合在一起形成一个完整的示例。
templatediv refrendererContainer classrenderer-container/div
/templatescript setup
import { onMounted, ref } from vue;
import * as THREE from three;
import { OrbitControls } from three/examples/jsm/controls/OrbitControls;
import TWEEN from tweenjs/tween.js;// 引用模板中的 DOM 元素
const rendererContainer ref(null);// 初始化场景、相机和渲染器
onMounted(() {const scene new THREE.Scene();const camera new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);camera.position.set(0, 5, 10);const renderer new THREE.WebGLRenderer();renderer.setSize(window.innerWidth, window.innerHeight);rendererContainer.value.appendChild(renderer.domElement);const light new THREE.DirectionalLight(0xffffff, 1);light.position.set(0, 10, 10);scene.add(light);// 添加示例模型const geometry new THREE.BoxGeometry();const material new THREE.MeshStandardMaterial({ color: 0x00ff00 });const cube new THREE.Mesh(geometry, material);cube.position.set(0, 1, 0);scene.add(cube);const sphereGeometry new THREE.SphereGeometry(0.5, 32, 32);const sphereMaterial new THREE.MeshStandardMaterial({ color: 0xff0000 });const sphere new THREE.Mesh(sphereGeometry, sphereMaterial);sphere.position.set(2, 1, 0);scene.add(sphere);// 相机平滑过渡函数function smoothCameraTransition(targetPosition, targetLookAt) {const startPosition camera.position.clone();const startLookAt new THREE.Vector3();camera.getWorldDirection(startLookAt);new TWEEN.Tween(startPosition).to(targetPosition, 2000).easing(TWEEN.Easing.Quadratic.InOut).onUpdate(() {camera.position.copy(startPosition);}).start();new TWEEN.Tween(startLookAt).to(targetLookAt, 2000).easing(TWEEN.Easing.Quadratic.InOut).onUpdate(() {camera.lookAt(startLookAt);}).start();}function animate() {requestAnimationFrame(animate);TWEEN.update();renderer.render(scene, camera);}animate();// 添加射线投射器const raycaster new THREE.Raycaster();const mouse new THREE.Vector2();function onMouseClick(event) {mouse.x (event.clientX / window.innerWidth) * 2 - 1;mouse.y -(event.clientY / window.innerHeight) * 2 1;raycaster.setFromCamera(mouse, camera);const intersects raycaster.intersectObjects(scene.children);if (intersects.length 0) {const intersectedObject intersects[0].object;const targetPosition new THREE.Vector3().copy(intersectedObject.position).add(new THREE.Vector3(0, 2, 5));const targetLookAt intersectedObject.position.clone();smoothCameraTransition(targetPosition, targetLookAt);}}window.addEventListener(click, onMouseClick, false);
});
/scriptstyle
.renderer-container {width: 100%;height: 100vh;
}
/style