交互事件是通过光线投射进行实现的。接下来是一个相关案例。
1.首先准备基本环境
javascript
// 导入three
import * as THREE from 'three' // 导入threejs
//导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
// 创建场景
const scene = new THREE.Scene()
scene.background = new THREE.Color(0x999999)
// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.z = 10
// 创建渲染器
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
//辅助坐标系
const axesHelper = new THREE.AxesHelper(5)
scene.add(axesHelper)
// 创建控制器
const controls = new OrbitControls(camera, renderer.domElement)
//自适应窗口
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
})
// 渲染循环
function animate() {
requestAnimationFrame(animate)
renderer.render(scene, camera)
}
animate()
2.创建三个球体
错开一点位置方便观察
javascript
//创建3个球
const geometry = new THREE.SphereGeometry(1, 32, 32)//球体
const material1 = new THREE.MeshBasicMaterial({ color: 0x00ff00 })
const material2 = new THREE.MeshBasicMaterial({ color: 0xff0000 })
const material3 = new THREE.MeshBasicMaterial({ color: 0x0000ff })
const sphere1 = new THREE.Mesh(geometry, material1)
const sphere2 = new THREE.Mesh(geometry, material2)
const sphere3 = new THREE.Mesh(geometry, material3)
sphere1.position.x = -4
sphere2.position.x = 4
scene.add(sphere1, sphere2, sphere3)
3.实现交互
1.创建一个射线和二维的向量
javascript
// 创建射线
const raycaster = new THREE.Raycaster()
const mouse = new THREE.Vector2()//创建二维向量
2.监听鼠标的点击事件
(1)先将鼠标的位置归一化到-1和1之间
(2)通过通过鼠标和摄像机位置确定射线位置
(3)计算物体和射线的交点
(4)改变交点物体的颜色
javascript
// 监听鼠标移动
window.addEventListener('click', (event) => {
// 将鼠标位置归一化到-1到1之间
mouse.x = (event.clientX / window.innerWidth) * 2 - 1
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
//通过鼠标和摄像机位置设置射线
raycaster.setFromCamera(mouse, camera)
// 计算物体和射线的交点
const intersects = raycaster.intersectObjects([sphere1, sphere2, sphere3])
console.log(intersects)
for (let i = 0; i < intersects.length; i++) {
intersects[i].object.material.color.set(0xffff00)
}
})
大功告成!!!