赞
踩
three.js 中有关于 CSS3DRenderer 的描写,如下图:
只是看这部分内容可能还是云里雾里,其实就是说:three有自己的方法,把页面上的DOM元素转化为一种可以被加载到场景里面的元素。
在安装的three包中找到 renderers 文件夹,里面包含了THREE.JS提供的渲染器。可以看到有两个js文件,分别是 CSS2DRenderer 和 CSS3DRenderer。这个js文件会返回两个变量:CSS2DObject, CSS2DRenderer (CSS3DObject, CSS3DSprite, CSS3DRenderer),分别是CSS2D 对象和渲染器(CSS3D会多一个)
根据上面找到的文件夹路径,把JS文件中的返回对象引用。
在三维场景初始化的代码中,我们已经确定了三维场景会展示的DOM、灯光、坐标轴等信息。于此同时我们也应该确定我们的标签DOM应该怎么渲染,怎么展示。
① 确定标签渲染DOM
② 使用THREE中引用的方法,将该DOM转化为一个CSS2D对象
③ 将该CSS2D对象添加进场景中
在这个步骤中,我们从页面上来看,其实是有两个DOM,一个是存放三维模型、另一个存放CSS2D对象。而且,THREE.JS提供的方式其实是在标签DOM上另外套了一个DOM,通过对这个外面DOM进行操作从而影响我们的标签。
基于此,我们要怎样把CSS2D对象(标签外面的那层DOM)和三维模型的canvas进行重合?这就用到我们CSS方面的知识了。这个方案其实有很多,我这边只用到了一种。这里的尺寸要和三维模型渲染器的尺寸保持一致哈,不然位置不好对应。
从页面效果来看,我认为两者最大的区别就是:CSS2Drender不会随着模型的缩放而改变,而CSS3Drender相反。
两者在引用和使用上并没有区别,只是换一个渲染器的事儿。
可以根据具体的业务需求选择对应的渲染器。
在场景初始化完成后,我们肯定是要对三维场景进行旋转或者缩放等功能。这样就需要有个方法,对控制器进行改变,从而实现我们视角的改变。
在这里如果只有模型,我们只需要改变模型渲染器(renderer)。但是如果还有CSS2D或CSS3D对象的话,就还需要对css2Renderer或css3Renderer进行改变。否则,标签对象只是添加上去了,不能旋转缩放。
这里有个标签的点击事件,这里对THREE.JS的版本就有要求:1.130.0,其他版本不满足哈。
- <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 { 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)
- // 设置position和top属性,把转化后的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 换成 3 即可,上面的引用不要动。
可能会有标签太大的情况,进行缩小即可。(代码中有)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。