本文介绍: THREE.JS提供的方式是在标签DOM上另外套了一个DOM,通过对这个外面DOM进行操作从而影响我们标签。从页面效果来看,两者最大区别就是:CSS2Drender不会随着模型缩放而改变,而CSS3Drender相反。

一、原理

    three.js 中有关于 CSS3DRenderer 的描写,如下图

     

     只是看这部分内容可能还是云里雾里,其实就是说:three自己方法,把页面上的DOM元素转化为一种可以加载场景里面元素

二、知识了解:

1、THREE.JS中的CSS2D/CSS3D渲染器

    在安装three包中找到 renderers 文件夹里面包含了THREE.JS提供的渲染器可以看到两个js文件,分别是 CSS2DRenderer 和 CSS3DRenderer。这个js文件返回两个变量:CSS2DObject, CSS2DRenderer (CSS3DObject, CSS3DSprite, CSS3DRenderer),分别是CSS2D 对象渲染器(CSS3D会多一个

2、页面引用CSS2D/CSS3D

     根据上面找到的文件夹路径,把JS文件中的返回对象引用

3、初始化使用

     在三维场景初始化代码中,我们已经确定了三维场景展示的DOM、灯光、坐标轴信息。于此同时我们也应该确定我们的标签DOM应该怎么渲染,怎么展示

     ①  确定标签渲染DOM 

     ②  使用THREE中引用方法,将该DOM转化为一个CSS2D对象

     ③   将该CSS2D对象添加场景中 

   

     在这个步骤中,我们从页面上来看,其实是有两个DOM,一个是存放三维模型、另一个存放CSS2D对象。而且,THREE.JS提供的方式其实是在标签DOM上另外套了一个DOM,通过对这个外面DOM进行操作从而影响我们的标签

   

      基于此,我们要怎样把CSS2D对象标签外面的那层DOM)和三维模型的canvas进行重合?这就用到我们CSS方面的知识了。这个方案其实有很多,我这边只用到了一种。这里尺寸要和三维模型渲染器的尺寸保持一致哈,不然位置不好对应

4、CSS2D 和 CSS3D

    从页面效果来看,我认为两者最大的区别就是:CSS2Drender不会随着模型的缩放而改变,而CSS3Drender相反。

    两者在引用使用上并没有区别,只是换一个渲染器的事儿。

    可以根据具体的业务需求选择对应渲染器。

5、缩放旋转

     在场景初始化完成后,我们肯定是要对三维场景进行旋转或者缩放功能。这样就需要有个方法,对控制器进行改变,从而实现我们视角的改变。

    在这里如果只有模型,我们只需要改变模型渲染器(renderer)。但是如果还有CSS2D或CSS3D对象的话,就还需要css2Renderer或css3Renderer进行改变。否则,标签对象只是添加上去了,不能旋转缩放

三、代码实现

1、CSS2D

    这里有个标签点击事件这里对THREE.JS的版本就有要求:1.130.0,其他版本不满足哈。

<template>
  <div class="fa_container">
    <!-- 存放three.js的渲染效果 -->
    &lt;div class="container" ref="container"&gt;</div&gt;
    <div class="card" id="cardId"&gt;模型标签</div&gt;
  </div&gt;
</template&gt;

<script&gt;
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
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 CSS2DRenderer()
// let css3Renderer = new CSS3DRenderer()
let camera, controls
// 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)

      // 控制器(注意这里第二个参数,如果为renderer.domElement页面不能放大缩小)
      controls = new OrbitControls(camera, cssRenderer.domElement)

      // 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 CSS2DObject(this.compDiv)
      // this.compTag.scale.set(0.04, 0.04, 0.04) // 对标签进行缩放
      scene.add(this.compTag)

      // 3、css2D渲染器:用于渲染模型的2D或者3D标签
      cssRenderer.setSize(1902, 935)
      // 设置positiontop属性,把转化后的css2D标签和原来的页面重叠
      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: new THREE.Color('0xffffff') })
      const circle = new THREE.Mesh(spherGeometry, spherMaterial)
      scene.add(circle)
    },

    render() {
      requestAnimationFrame(this.render.bind(this))
      controls.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;
}
</style>
2、CSS3D:

    把所有的 2 换成 3 即可,上面的引用不要动。

   可能会有标签太大的情况,进行缩小即可。(代码中有)

四、最终效果

1、CSS2D:

2、CSS3D:

原文地址:https://blog.csdn.net/qq_44426236/article/details/132408657

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_19235.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注