因为是片段代码,所以我只能说问题的原因,需要把click点击事件和mousemove分开写,处理逻辑写在click事件中。
示例代码:
<script setup>
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import { onMounted, ref } from 'vue'
/**
* scene
*/
const scene = new THREE.Scene()
/**
* camera
*/
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
100
)
camera.position.z = 3
/**
* object
*/
const object1 = new THREE.Mesh(
new THREE.SphereGeometry(0.5, 16, 16),
new THREE.MeshBasicMaterial({ color: '#ff0000' })
)
object1.position.x = - 2
const object2 = new THREE.Mesh(
new THREE.SphereGeometry(0.5, 16, 16),
new THREE.MeshBasicMaterial({ color: '#ff0000' })
)
const object3 = new THREE.Mesh(
new THREE.SphereGeometry(0.5, 16, 16),
new THREE.MeshBasicMaterial({ color: '#ff0000' })
)
object3.position.x = 2
scene.add(object1, object2, object3)
/**
* renderer
*/
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
})
/**
* axesHelper
*/
const axesHelper = new THREE.AxesHelper(5)
scene.add(axesHelper)
/**
* control
*/
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true
/**
* raycaster
*/
const raycaster = new THREE.Raycaster()
/**
* mouse
*/
const mouse = new THREE.Vector2(1, 1)
window.addEventListener('mousemove', (event) => {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1
mouse.y = - (event.clientY / window.innerHeight) * 2 + 1
})
/**
* render
*/
const clock = new THREE.Clock()
let currentIntersect = null
const tick = () => {
const elapsedTime = clock.getElapsedTime()
const objectsToTest = [object1, object2, object3]
const intersects = raycaster.intersectObjects(objectsToTest)
raycaster.setFromCamera(mouse, camera) // 根据camera的位置设置方向
if (intersects.length > 0) {
// console.log('enter');
currentIntersect = intersects[0]
} else {
// console.log('leave');
currentIntersect = null
}
for (const object of objectsToTest) {
object.material.color.set(0xff0000)
}
for (const intersect of intersects) {
intersect.object.material.color.set('#0000ff')
}
// update
controls.update()
requestAnimationFrame(tick)
renderer.render(scene, camera)
}
document.addEventListener('click', () => {
if (currentIntersect) {
switch (currentIntersect.object) {
case object1:
console.log('click obj1');
break
case object2:
console.log('click obj2');
break
case object3:
console.log('click obj3');
break
}
}
})
onMounted(() => {
tick()
})
</script>
问 有偿,针对 threejs的raycaster进行获取当前 mesh 选中