Three.js是一个基于WebGL的开源JavaScript库,它可以在网页中创建3D图形并在浏览器中进行渲染。它提供了各种各样的API来实现3D图形的创建、变换和交互等操作,非常适合用于Web上的游戏、动画和其他图形应用。在本篇博客中,我们将介绍如何使用three.js创建一个简单的3D模型,并加入交互。
创建一个简单的3D模型
首先,在HTML文件中引入three.js:
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/build/three.min.js"></script>
然后,在JavaScript文件中编写代码创建一个场景、一个相机和一个立方体模型:
// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
// 创建立方体模型
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
接着,创建渲染器并将其添加到HTML文件中:
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
最后,在渲染循环中进行画面的绘制:
// 渲染循环
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
在上面的代码中,我们通过旋转立方体模型来产生动画效果,并不断地进行渲染。
加入交互
现在我们已经创建了一个简单的3D模型,并成功进行了渲染。接下来,我们将添加一些交互,以便用户可以通过鼠标或触摸屏来控制模型的动态。
首先,我们需要让渲染器捕捉用户的输入事件:
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
function onMouseMove(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
window.addEventListener('mousemove', onMouseMove, false);
window.addEventListener('touchstart', onMouseMove, false);
上面的代码中,我们创建了一个射线检测器raycaster
和一个二维向量mouse
,用于捕捉用户的鼠标或触摸屏移动事件。当用户移动鼠标或触摸屏时,会触发onMouseMove()
函数,该函数将计算出鼠标或触摸屏的位置,并将其保存在二维向量mouse
中。
接下来,我们需要在渲染循环中添加代码,以便检测用户的输入事件:
function doIntersect(event) {
// 计算出射线的起点和方向
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
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, true);
if (intersects.length > 0) {
// 如果找到了相交的模型对象,则执行相关操作
console.log(intersects[0]);
}
}
window.addEventListener('mousemove', doIntersect, false);
window.addEventListener('touchstart', doIntersect, false);
在上面的代码中,doIntersect()
函数将会计算出射线的起点和方向,并查找与射线相交的模型对象。如果找到了相交的模型对象,则会输出相关信息到控制台。
最后,在渲染循环中加入相应的代码,以便响应用户的输入事件:
function animate() {
requestAnimationFrame(animate);
// 旋转立方体模型
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
// 检测用户的输入事件
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(scene.children, true);
if (intersects.length > 0) {
// 如果找到了相交的模型对象,则执行相关操作
cube.material.color.set(0xff0000);
} else {
cube.material.color.set(0x00ff00);
}
// 渲染画面
renderer.render(scene, camera);
}
animate();
在上面的代码中,我们通过检测用户的输入事件,并根据相交的模型对象响应用户的操作。
示例
下面是一个完整的示例代码,您可以将其复制粘贴到自己的HTML文件中并运行:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Three.js示例</title>
<style>
body {
margin: 0;
}
</style>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/build/three.min.js"></script>
<script>
// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
// 创建立方体模型
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 捕捉用户的鼠标或触摸屏移动事件
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
function onMouseMove(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
window.addEventListener('mousemove', onMouseMove, false);
window.addEventListener('touchstart', onMouseMove, false);
// 响应用户的鼠标或触摸屏移动事件
function doIntersect(event) {
// 计算出射线的起点和方向
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
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, true);
if (intersects.length > 0) {
// 如果找到了相交的模型对象,则执行相关操作
cube.material.color.set(0xff0000);
} else {
cube.material.color.set(0x00ff00);
}
}
window.addEventListener('mousemove', doIntersect, false);
window.addEventListener('touchstart', doIntersect, false);
// 渲染循环
function animate() {
requestAnimationFrame(animate);
// 旋转立方体模型
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
// 检测用户的输入事件
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(scene.children, true);
if (intersects.length > 0) {
// 如果找到了相交的模型对象,则执行相关操作
cube.material.color.set(0xff0000);
} else {
cube.material.color.set(0x00ff00);
}
// 渲染画面
renderer.render(scene, camera);
}
animate();
</script>
</body>
</html>
在运行上面的代码后,您将可以看到屏幕中央出现一个绿色的立方体。当您移动鼠标或触摸屏时,立方体会随之而旋转,并根据鼠标或触摸屏位置的变化而改变颜色。