通过网格对象Mesh的属性实现立方体的缩放、移动、旋转、平移、隐藏(vue中使用three.js05)

一、网格对象属性和方法介绍

我们知道创建一个网格对象需要一个几何体以及一个或多个材质对象,创建好网格对象就可以把它添加到场景中了,但我们怎么实现网格对象的缩放、移动,旋转和平移操作呢,接下来给大家介绍一下它的属性

1.缩放-scale

属性scale表示网格对象的缩放比例,可以对x轴、y轴、z轴单个进行缩放也可以多个同时缩放,由于scale属性的类型是Vector3,所以可以通过三种方式改变scale的值

  1. 直接通过scale属性的x、y、z属性设置
mesh.scale.x = x
mesh.scale.y = y
mesh.scale.z = z
  1. 通过scale属性的set方法设置
mesh.scale.set(x,y,z) 
  1. 通过创建THREE.Vector对象赋给scale属性
mesh.scale = new THREE.Vector3(x,y,z) 

2.位置-position

Mesh对象的属性position表示网格对象在立体空间中的位置,主要作用是来确定mesh对象在立体空间中的位置,可以分别对x轴、y轴、z轴进行单个设置或者多个设置,由于position属性的类型也是Vector3,同样可以通过三种方式设置位置

  1. 直接通过position属性的x、y、z属性设置
mesh.position.x = x
mesh.position.y = y
mesh.position.z = z
  1. 通过position属性的set方法设置
mesh.position.set(x,y,z) 
  1. 通过创建THREE.Vector对象赋给position属性
mesh.position = new THREE.Vector3(x,y,z) 

3.旋转-rotation

mesh对象的rotation属性是用来控制旋转角度的,同样可以只绕x轴、y轴、z轴旋转也可绕多个轴组合旋转,设置mesh对象的旋转角度的方式有两种

  1. 直接通过rotation属性的x、y、z属性设置
mesh.rotation.x = x
mesh.rotation.y = y
mesh.rotation.z = z
  1. 通过rotation属性的set方法设置
mesh.rotation.set(x,y,z) 

4.平移-translateX()、translateY()、translateZ()

mesh对象没有translate属性,只提供了沿x轴、y轴、z轴平移的三个方法,使用起来非常简单,只需要传入要平移的距离

mesh.translateX(distance)
mesh.translateY(distance)
mesh.translateZ(distance)

5.可见-visible

属性visible用来控制mesh对象是否显示,该值为布尔值,true代表显示,false表示隐藏

//显示mesh对象
mesh.visible = true;
//隐藏mesh对象
mesh.visible = false;

二、通过demo深入理解Mesh属性和方法

<template>
  <div>
    <div id="container"></div>
    <div class="controls-box">
      <el-collapse accordion>
        <div>
          <el-collapse-item :title="item.name" v-for="(item) in properties" :key="item.name">
            <el-col>
              <el-col :span="5">
                <span class="vertice-span">{{item.properties.nameX}}</span>
              </el-col>
              <el-col :span="16">
                <el-slider v-model="item.value.x" :min="item.name=='比例-scale'?0:-10" :max="10" :format-tooltip="formatTooltip"></el-slider>
              </el-col>
              <el-col :span="3">
                <span class="vertice-span">{{item.value.x}}</span>
              </el-col>
            </el-col>
            <el-col>
              <el-col :span="5">
                <span class="vertice-span">{{item.properties.nameY}}</span>
              </el-col>
              <el-col :span="16">
                <el-slider v-model="item.value.y" :min="item.name=='比例-scale'?0:-10" :max="10" :format-tooltip="formatTooltip"></el-slider>
              </el-col>
              <el-col :span="3">
                <span class="vertice-span">{{item.value.y}}</span>
              </el-col>
            </el-col>
            <el-col>
              <el-col :span="5">
                <span class="vertice-span">{{item.properties.nameZ}}</span>
              </el-col>
              <el-col :span="16">
                <el-slider v-model="item.value.z" :min="item.name=='比例-scale'?0:-10" :max="10" :format-tooltip="formatTooltip"></el-slider>
              </el-col>
              <el-col :span="3">
                <span class="vertice-span">{{item.value.z}}</span>
              </el-col>
            </el-col>

          </el-collapse-item>
        </div>
      </el-collapse>
      <el-checkbox v-model="cubeVisible">是否可见</el-checkbox>
    </div>
  </div>
</template>

<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
export default {
  data () {
    return {
      properties: {
        scale: {
          name: '比例-scale',
          properties: {
            nameX: 'scaleX',
            nameY: 'scaleY',
            nameZ: 'scaleZ'
          },
          value: {
            x: 1,
            y: 1,
            z: 1
          }
        },
        position: {
          name: '位置-position',
          properties: {
            nameX: 'positionX',
            nameY: 'positionY',
            nameZ: 'positionZ'
          },
          value: {
            x: 0,
            y: 4,
            z: 0
          }
        },
        rotation: {
          name: '旋转-rotation',
          properties: {
            nameX: 'rotationX',
            nameY: 'rotationY',
            nameZ: 'rotationZ'
          },
          value: {
            x: 0,
            y: 0,
            z: 0
          }
        },
        translate: {
          name: '平移-translate',
          properties: {
            nameX: 'translateX',
            nameY: 'translateY',
            nameZ: 'translateZ'
          },
          value: {
            x: 0,
            y: 0,
            z: 0
          }
        }
      },
      cubeVisible: true,
      cube: null,
      camera: null,
      scene: null,
      renderer: null,
      controls: null
    }
  },
  mounted () {
    this.init()
  },
  methods: {
    formatTooltip (val) {
      return val
    },
    // 初始化
    init () {
      this.createScene() // 创建场景
      this.createMesh() // 创建网格模型
      this.createCube() // 创建方块
      this.createLight() // 创建光源
      this.createCamera() // 创建相机
      this.createRender() // 创建渲染器
      this.createControls() // 创建控件对象
      this.render() // 渲染
    },
    // 创建场景
    createScene () {
      this.scene = new THREE.Scene()
    },
    // 创建网格模型
    createMesh () {
      const planeGeometry = new THREE.PlaneGeometry(60, 40, 1, 1) // 创建一个平面对象PlaneGeometry
      const planeMaterial = new THREE.MeshLambertMaterial({
        color: 0xffffff
      }) // 材质对象Material
      const plane = new THREE.Mesh(planeGeometry, planeMaterial)
      plane.receiveShadow = true

      // 设置平面位置
      plane.rotation.x = -0.5 * Math.PI
      plane.position.set(0, 0, 0)

      // 平面对象添加到场景中
      this.scene.add(plane)
    },
    // 创建光源
    createLight () {
      // 添加聚光灯
      const spotLight = new THREE.SpotLight(0xffffff)
      spotLight.position.set(-40, 60, 20)
      spotLight.castShadow = true
      this.scene.add(spotLight) // 聚光灯添加到场景中
      // 环境光
      const ambientLight = new THREE.AmbientLight(0x0c0c0c)
      this.scene.add(ambientLight)
    },
    // 创建相机
    createCamera () {
      const element = document.getElementById('container')
      const width = element.clientWidth // 窗口宽度
      const height = element.clientHeight // 窗口高度
      const k = width / height // 窗口宽高比
      // PerspectiveCamera( fov, aspect, near, far )
      this.camera = new THREE.PerspectiveCamera(45, k, 0.1, 1000)

      this.camera.position.set(-30, 40, 30) // 设置相机位置
      this.camera.lookAt(new THREE.Vector3(5, 0, 0)) // 设置相机方向
      this.scene.add(this.camera)
    },
    // 创建渲染器
    createRender () {
      const element = document.getElementById('container')
      this.renderer = new THREE.WebGLRenderer()
      this.renderer.setSize(element.clientWidth, element.clientHeight) // 设置渲染区域尺寸
      this.renderer.setClearColor(0x3f3f3f, 1) // 设置背景颜色
      element.appendChild(this.renderer.domElement)
    },
    // 更新方块的属性
    updateCubeProperties () {
      // 更新缩放属性方式1
      /* this.cube.scale.x = this.properties.scale.value.x
      this.cube.scale.y = this.properties.scale.value.y
      this.cube.scale.z = this.properties.scale.value.z */

      // 更新缩放属性方式2
      /* this.cube.scale.set(
        this.properties.scale.value.x,
        this.properties.scale.value.y,
        this.properties.scale.value.z
      ) */

      // 更新缩放属性方式3
      this.cube.scale = new THREE.Vector3(
        this.properties.scale.value.x,
        this.properties.scale.value.y,
        this.properties.scale.value.z
      )

      // 更新位置属性
      this.cube.position.x = this.properties.position.value.x
      this.cube.position.y = this.properties.position.value.y
      this.cube.position.z = this.properties.position.value.z

      // 更新旋转属性
      /* this.cube.rotation.x = this.properties.rotation.value.x
      this.cube.rotation.y = this.properties.rotation.value.y
      this.cube.rotation.z = this.properties.rotation.value.z */
      this.cube.rotation.set(
        this.properties.rotation.value.x,
        this.properties.rotation.value.y,
        this.properties.rotation.value.z
      )

      // 更新平移属性
      this.cube.translateX(this.properties.translate.value.x)
      this.cube.translateY(this.properties.translate.value.y)
      this.cube.translateZ(this.properties.translate.value.z)

      this.cube.visible = this.cubeVisible
    },
    createCube () {
      const material = new THREE.MeshLambertMaterial({ color: 0x44ff44 }) // 创建材质对象material
      const geom = new THREE.BoxGeometry(5, 4, 3) // 创建几何对象geom
      this.cube = new THREE.Mesh(geom, material) // 创建网格对象cube
      this.cube.castShadow = true
      this.scene.add(this.cube) // 将网格对象添加到场景
      console.log(this.cube)
    },
    render () {
      this.updateCubeProperties()
      this.renderer.render(this.scene, this.camera)
      requestAnimationFrame(this.render)
    },
    // 创建控件对象
    createControls () {
      this.controls = new OrbitControls(this.camera, this.renderer.domElement)
    }
  }
}
</script>

<style>
#container {
  position: absolute;
  width: 100%;
  height: 100%;
}
.controls-box {
  position: absolute;
  right: 5px;
  top: 5px;
  width: 300px;
  padding: 10px;
  background-color: #fff;
  border: 1px solid #c3c3c3;
}
.vertice-span {
  line-height: 38px;
  padding: 0 2px;
}
</style>

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值