THREE.JS 使用DragControls实现模型拖动
·
一、原理
DragControls 是在 THREE.JS 官网中提供的一种拖放交互的控制器,可以实现对模型的拖动功能。详见官网。
二、步骤
- 引入拖动控制器
- 在三维空间初始化时创建拖动控制器
- 监听拖动控制器。当开始拖动时,页面不会随着鼠标旋转。
三、代码
<template>
<div class="fa_container">
<!-- 存放three.js的渲染效果 -->
<div class="container" ref="container"></div>
<div class="card" id="cardId">模型标签</div>
</div>
</template>
<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { DragControls } from 'three/examples/jsm/controls/DragControls.js'
// import { CSS2DRenderer, CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'
import { CSS3DRenderer, CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer'
// import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
const scene = new THREE.Scene()
let renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true,
logarithmicDepthBuffer: true
})
let cssRenderer = new CSS3DRenderer()
let camera, control, dControls
// let loader = new GLTFLoader()
export default {
name: 'model',
mounted() {
this.init()
this.render()
},
methods: {
init() {
this.dom = this.$refs['container']
// 坐标轴+灯光
const axes = new THREE.AxesHelper(50)
const directLight = new THREE.AmbientLight(0x404040, 2)
scene.add(axes, directLight)
// 相机
camera = new THREE.PerspectiveCamera(
45,
this.dom.offsetWidth / this.dom.offsetHeight,
0.001,
10000
)
camera.position.set(25, 25, 25)
// 1、WebGLRenderer渲染器:用于渲染三维模型
renderer.setSize(1902, 935)
renderer.outputEncoding = THREE.sRGBEncoding
this.dom.appendChild(renderer.domElement)
// 2、把标签DOM转化为css2D元素,相当于在标签DOM外添加一个div
this.compDiv = document.getElementById('cardId')
this.compTag = new CSS3DObject(this.compDiv)
this.compTag.scale.set(0.04, 0.04, 0.04)
scene.add(this.compTag)
// 3、css2D渲染器:用于渲染模型的2D或者3D标签
cssRenderer.setSize(1902, 935)
cssRenderer.domElement.style.position = 'absolute'
cssRenderer.domElement.style.top = 0
this.dom.appendChild(cssRenderer.domElement)
// 创建一个球
const spherGeometry = new THREE.SphereGeometry(5, 32, 16)
const spherMaterial = new THREE.MeshLambertMaterial({ color: '#95B9F0' })
const sphere = new THREE.Mesh(spherGeometry, spherMaterial)
scene.add(sphere)
// 控制器
control = new OrbitControls(camera, cssRenderer.domElement)
let dragObj = []
dragObj.push(sphere)
dControls = new DragControls(dragObj, camera, cssRenderer.domElement)
dControls.addEventListener('dragstart', function () {
control.enabled = false
})
dControls.addEventListener('dragend', function () {
control.enabled = true
})
},
render() {
requestAnimationFrame(this.render.bind(this))
control.update()
cssRenderer.render(scene, camera)
renderer.render(scene, camera)
}
}
}
</script>
<style>
.container {
width: 1902px;
height: 935px;
overflow: hidden;
background: black;
display: inline-block;
}
.card {
height: 200px;
width: 200px;
/* position: absolute; */
display: inline-block;
color: white;
background: blueviolet;
top: 8px;
}
</style>
四、注意
1、轨道控制器和拖动控制器是一起存在的;
2、轨道控制器的第一个参数是一个数组,如果是一个单独的对象没有拖动效果;
3、为了防止拖动物体时场景会随之改变,将对轨道控制器取消操作。
4、如果这个拖动的物体(提供的模型)console 后,发现是有children的,那么这个拖动就不合适。这样只会拖动 Object 中的一个 Mesh,即模型的一个部分。
5、如果要拖动的物体很小,那么拖动操作会非常困难,不建议使用 DragControl。可以使用transfromControl对物体拖动。参考我的下一篇文章:http://t.csdnimg.cn/0qEx6
五、最终效果
拖动前:
拖动后:
其余关于CSS2D/CSS3D方面的内容,可以看我的上一篇:http://t.csdnimg.cn/VTtc7
更多推荐
已为社区贡献3条内容
所有评论(0)