• 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>
    
    
  • 相关阅读:
    Linux 多进程锁的几种实现方案
    Linux man手册没有pthread_mutex_init的解决办法
    IP地址结构信息与字符串相互转化:inet_pton和inet_ntop, etc.
    Linux 将计算md5值功能做成md5命令
    Unix/Linux inet守护进程
    Unix/Linux syslogd守护进程 & 日志记录syslog
    UNP 学习笔记 #11 名字与地址转换
    git 使用总结
    AUPE 输出致标准错误的出错函数分析与实现 err_sys, err_quit, err_doit etc.
    Linux C常见数I/O函数比较: printf, sprintf, fprintf, write...
  • 原文地址:https://www.cnblogs.com/sugartang/p/13605789.html
Copyright © 2020-2023  润新知