您的位置:首页 > 财经 > 金融 > 中国住房和城乡建设网官网_seo经验_seo提高关键词_中国站长

中国住房和城乡建设网官网_seo经验_seo提高关键词_中国站长

2024/12/23 10:19:04 来源:https://blog.csdn.net/mad970906/article/details/144127754  浏览:    关键词:中国住房和城乡建设网官网_seo经验_seo提高关键词_中国站长
中国住房和城乡建设网官网_seo经验_seo提高关键词_中国站长

在 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. 完整代码示例

将上述代码片段整合在一起,形成一个完整的示例。

<template><div ref="rendererContainer" class="renderer-container"></div>
</template><script 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);
});
</script><style>
.renderer-container {width: 100%;height: 100vh;
}
</style>

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com