three.js一步一步来--简单交互--点击物体变红

如何让物体点击变色

<template>
  <div class="container">
    <!-- <h1>创建一个小场景点击变红</h1> -->
    <canvas ref="mainCanvas" id="canvas14"></canvas>
  </div>
</template>

<script>
import * as THREE from 'three'
import utils from './js/utils.js'
// const OrbitControls = require('three-orbit-controls')(THREE)
// import MTLLoader from 'three-mtl-loader'
// import OBJLoader from 'three-obj-loader'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
export default {
  props: {},
  data() {
    return {
      // 公共项目1
      scene: new THREE.Scene(),
      camera: null,
      renderer: new THREE.WebGLRenderer(), // 渲染器
      directionalLight: new THREE.DirectionalLight(0xffffff, 1.0, 0),
      controls: OrbitControls,
      cars: [],
       '',
      height: '',
      config: {
        isMobile: false,
        background: 0x282828
      },
      // 公共项目2
      //  交互
      raycaster: new THREE.Raycaster(),
      mouse: new THREE.Vector2(),
      instersected: null
      //  交互
    }
  },
  computed: {},
  watch: {},
  created() {
  },
  mounted() {
    this.width = window.innerWidth
    this.height = window.innerHeight - 50
    this.scene = new THREE.Scene()
    this.camera = new THREE.PerspectiveCamera(
      45, // 视野角fov
      this.width / this.height,
      1,
      5000
    )
    this.camera.position.set(1200, 1200, 1200) // 调大了可以离的远点看
    this.camera.lookAt(this.scene.position)
    this.canvas = this.$refs.mainCanvas
    this.renderer = new THREE.WebGLRenderer({
      antialias: true, // antialias:true/false是否开启反锯齿
      canvas: this.canvas
    })
    document.addEventListener('mouseup', this.onDocumentMouseUp, false) // 交互
    document.addEventListener('mousedown', this.onDocumentMouseDown, false) // 交互
    this.renderer.setSize(this.width, this.height)
    this.renderer.setClearColor(this.config.background)
    this.renderer.shadowMap.enabled = true // 輔助線
    this.renderer.shadowMap.type = THREE.PCFSoftShadowMap // 柔化边缘的软阴影映射
    this.checkUserAgent() // 检测浏览器类型
    this.bulidAuxSystem() // 构建辅助系统
    this.buildLightSystem() // 光线
    this.addMash()
    this.loop()
  },
  methods: {
    // 交互
    onDocumentMouseDown(e) {
      console.log('1e')
      console.log(e)
      console.log('1e.clientX')
      console.log(e.clientX)
      console.log('1e.clientY')
      console.log(e.clientY)
      console.log('1window.innerWidth')
      console.log(window.innerWidth)
      console.log('1window.innerHeight')
      console.log(window.innerHeight)
    },
    onDocumentMouseUp(event) {
      event.preventDefault()
      this.mouse.x = ((event.clientX - 210) / window.innerWidth) * 2 - 1 // 尽量写全屏,要不然不好控制
      // this.mouse.y = -((event.clientY - 50) / window.innerHeight) * 2 + 1
      this.mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
      console.log('this.mouse.x')
      console.log(this.mouse.x)
      console.log('this.mouse.y')
      console.log(this.mouse.y)
    },
    // 交互
    addMash() {
      const planeGeometry = new THREE.BoxBufferGeometry(1000, 6, 1000)
      const plane = utils.makeMesh('lambert', planeGeometry, 0xe2d5d5)
      plane.position.y = -3
      this.scene.add(plane)
      /**
       * 创建网格模型
       */
      //  立方体网格模型
      var geometry1 = new THREE.BoxGeometry(100, 100, 100)
      var material1 = new THREE.MeshLambertMaterial({
        color: 0x0000ff, // 材质颜色半透明蓝色
        transparent: true, // 开启透明度
        opacity: 0.5 // 设置透明度具体值
      }) // 材质对象Material
      var mesh1 = new THREE.Mesh(geometry1, material1) // 网格模型对象Mesh
      mesh1.position.y = 50
      this.scene.add(mesh1) // 网格模型添加到场景中

      //  球体网格模型
      var geometry2 = new THREE.SphereGeometry(60, 40, 40)
      var material2 = new THREE.MeshLambertMaterial({
        color: 0xff00f,
        transparent: true, // 开启透明度
        opacity: 0.5 // 设置透明度具体值
      })
      var mesh2 = new THREE.Mesh(geometry2, material2) // 网格模型对象Mesh
      mesh2.translateY(120) // 球体网格模型沿Y轴正方向平移100
      this.scene.add(mesh2)

      //  圆柱网格模型
      var geometry3 = new THREE.CylinderGeometry(50, 50, 100, 25)
      var material3 = new THREE.MeshLambertMaterial({
        color: 0xffff00,
        transparent: true, // 开启透明度
        opacity: 0.5 // 设置透明度具体值
      })
      var mesh3 = new THREE.Mesh(geometry3, material3) // 网格模型对象Mesh
      mesh3.translateX(120) // 球体网格模型沿Y轴正方向平移100
      mesh3.position.y = 50
      this.scene.add(mesh3)
    },
    // 检测浏览器类型1
    checkUserAgent() {
      const n = navigator.userAgent
      if (
        n.match(/Android/i) ||
        n.match(/webOs/i) ||
        n.match(/iPhone/i) ||
        n.match(/iPad/i) ||
        n.match(/iPod/i) ||
        n.match(/BlackBerry/i)
      ) {
        this.config.isMobile = true
        this.camera.position.set(1000, 420, 420)
        this.renderer.shadowMap.enabled = false // 輔助線
      }
    },
    // 检测浏览器类型2
    // 构建辅助系统1
    bulidAuxSystem() {
      var axisHelper = new THREE.AxisHelper(250)
      this.scene.add(axisHelper)
      // const gridHelper = new THREE.GridHelper(1000, 32) // 这里控制表格的大小长宽
      // this.scene.add(gridHelper)
      this.controls = new OrbitControls(this.camera, this.renderer.domElement)
      this.controls.enableDamping = true
      this.controls.dampingFactor = 0.25
      this.controls.rotateSpeed = 0.35
    },
    // 构建辅助系统2
    buildLightSystem() {
      console.log('是否手机', this.config.isMobile)
      if (!this.config.isMobile) {
        console.log('是否手机11')
        this.directionalLight.position.set(300, 1000, 500)
        this.directionalLight.target.position.set(0, 0, 0)
        this.directionalLight.castShadow = true
        const d = 300
        this.directionalLight.shadow.camera = new THREE.OrthographicCamera(
          -d,
          d,
          d,
          -d,
          500,
          1600
        )
        this.directionalLight.shadow.bias = 0.0001
        this.directionalLight.shadow.mapSize.width = this.directionalLight.shadow.mapSize.height = 1024
        this.scene.add(this.directionalLight)
        const light = new THREE.AmbientLight(0xffffff, 0.3)
        this.scene.add(light)
      } else {
        console.log('是否手机22')
        const hemisphereLight = new THREE.HemisphereLight(0xffffff, 1)
        this.scene.add(hemisphereLight)
        this.scene.add(new THREE.AmbientLight(0xffffff, 0.15))
      }
    },
    loop() {
      this.renderer.render(this.scene, this.camera)
      requestAnimationFrame(this.loop)
      this.raycaster.setFromCamera(this.mouse, this.camera)
      var intersects = this.raycaster.intersectObjects(this.scene.children)
      if (intersects.length > 0) {
        if (this.instersected !== intersects[0].object) {
          if (this.instersected) {
            this.instersected.material.color.setHex(
              this.instersected.currentHex
            )
          }
          this.instersected = intersects[0].object
          this.instersected.currentHex = this.instersected.material.color.getHex()
          this.instersected.material.color.set(0xff0000)
        }
      } else {
        if (this.instersected) {
          this.instersected.material.color.set(this.instersected.currentHex)
        }
        this.instersected = null
      }
    }
  },
  beforeDestory() {
    this.scene.dispose()
    this.controls.dispose()
    this.scene = null
    this.camera = null
    this.directionalLight = null
    this.controls = null
    this.raycaster = null
    this.renderer.dispose()
    this.renderer.forceContextLoss()
    this.renderer.context = null
    this.renderer.domElement = null
    this.renderer = null
    var canvas = document.getElementById('canvas14')
    var gl = canvas.getContext('webgl')
    gl.getExtension('WEBGL_lose_context').loseContext()
  }
}
</script>

<style scoped lang="less">
</style>

原文地址:https://www.cnblogs.com/sugartang/p/13605789.html