关于three.js:ThreeJS学习记录三监听鼠标点击和移动

6次阅读

共计 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()
正文完
 0