共计 2810 个字符,预计需要花费 8 分钟才能阅读完成。
监听鼠标挪动,几何体变大变小
监听鼠标点击,弹出信息
应用办法:Raycaster
import * as THREE from 'three' | |
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls' | |
import Stats from 'three/examples/jsm/libs/stats.module' | |
let container, stats | |
let camera, scene, raycaster, renderer | |
let INTERSECTED | |
const pointer = new THREE.Vector2() | |
let clickPosX = 0, | |
clickPosY = 0 | |
function onPointerMove(event) {pointer.x = (event.clientX / window.innerWidth) * 2 - 1 | |
pointer.y = -(event.clientY / window.innerHeight) * 2 + 1 | |
if (INTERSECTED) {INTERSECTED.scale.set(3, 3, 3) | |
} | |
render()} | |
function onPointerClick(event) {pointer.x = (event.clientX / window.innerWidth) * 2 - 1 | |
pointer.y = -(event.clientY / window.innerHeight) * 2 + 1 | |
if (INTERSECTED) {alert('点击了' + INTERSECTED.name) | |
} | |
render()} | |
function calcMousePosition(event, x, y) { | |
// 决定信息弹窗的定位 | |
var event = event || window.event | |
if (event.pageX || event.pageY) { | |
x = event.pageX | |
y = event.pageY | |
} else if (event.clientX || event.clientY) { | |
x = | |
event.clientX + | |
document.documentElement.scrollLeft + | |
document.body.scrollLeft | |
y = | |
event.clientY + | |
document.documentElement.scrollTop + | |
document.body.scrollTop | |
} | |
return {x: x, y: y} | |
} | |
function createDom() {const geometry = new THREE.BoxBufferGeometry(10, 10, 10) | |
const material = new THREE.MeshBasicMaterial({color: 0x00fa9a}) | |
const mesh = new THREE.Mesh(geometry, material) | |
mesh.name = '几何体 1' | |
scene.add(mesh) | |
mesh.position.set(0, -5, 0) | |
const geometry1 = new THREE.BoxBufferGeometry(10, 10, 10) | |
const mesh1 = new THREE.Mesh(geometry1, material) | |
mesh1.name = '几何体 2' | |
scene.add(mesh1) | |
mesh1.position.set(0, 20, 0) | |
const ambient = new THREE.AmbientLight(0xffffff, 1) | |
scene.add(ambient) | |
// var axesHelper = new THREE.AxesHelper(250) | |
// scene.add(axesHelper) | |
} | |
function init() {scene = new THREE.Scene() | |
scene.background = new THREE.Color(0xffffff) | |
camera = new THREE.PerspectiveCamera( | |
35, | |
window.innerWidth / window.innerHeight, | |
0.1, | |
1000 | |
) | |
camera.position.set(18, 20, 100) | |
renderer = new THREE.WebGLRenderer() | |
renderer.setPixelRatio(window.devicePixelRatio) | |
renderer.setSize(window.innerWidth, window.innerHeight) | |
document.body.appendChild(renderer.domElement) | |
controls = new OrbitControls(camera, renderer.domElement) | |
controls.addEventListener('change', render) | |
window.addEventListener('resize', onWindowResize) | |
document.addEventListener('mousemove', onPointerMove) | |
document.addEventListener('click', onPointerClick) | |
stats = new Stats() | |
document.body.appendChild(stats.dom) | |
raycaster = new THREE.Raycaster() | |
createDom()} | |
function onWindowResize() { | |
camera.aspect = window.innerWidth / window.innerHeight | |
camera.updateProjectionMatrix() | |
renderer.setSize(window.innerWidth, window.innerHeight) | |
} | |
function render() {stats.update() | |
camera.updateMatrixWorld() | |
raycaster.setFromCamera(pointer, camera) | |
const intersects = raycaster.intersectObjects(scene.children, false) | |
if (intersects.length > 0) {if (INTERSECTED != intersects[0].object) {if (INTERSECTED) {INTERSECTED.scale.set(1, 1, 1) | |
INTERSECTED = null | |
} | |
INTERSECTED = intersects[0].object | |
} | |
} else {if (INTERSECTED) {INTERSECTED.scale.set(1, 1, 1) | |
INTERSECTED = null | |
} | |
} | |
renderer.render(scene, camera) | |
} | |
init() | |
render() |
正文完