vue3+threejs,做一个给模型批量CSS2D标签的案例,在导入模型的js文件里,跟着课程写的代码如下:
import * as THREE from 'three';
// 引入gltf模型加载库GLTFLoader.js
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
// 引入CSS2模型对象CSS2DObject
import {
CSS2DObject
} from 'three/addons/renderers/CSS2DRenderer.js';
const model = new THREE.Group();
const loader = new GLTFLoader();
// 路径要特别注意,默认是从public读取的,模型文件必须放在public下,并且路径前的public要省略
loader.load('models/简易小区.glb', gltf => {
gltf.scene.getObjectByName("小区房子").traverse(function (obj) {
if (obj.isMesh) {
let label = tag(obj.name);
const pos = new THREE.Vector3();
obj.getWorldPosition(pos);
label.position.copy(pos);
label.name = obj.name;
model.add(label);
}
});
model.add(gltf.scene);
}, undefined, error => {
console.error(error);
});
function tag(name) {
// 创建dom元素(作为标签)
let div = document.createElement('div');
div.innerHTML = name;
div.classList.add('css2dtag');
//使用dom元素生成CSS2模型对象CSS2DObject
let label = new CSS2DObject(div);
div.style.pointerEvents = 'none';//避免HTML标签遮挡三维场景的鼠标事件
return label;//返回CSS2模型标签
}
export default model;
在vue文件里设置css。
<template>
</template>
<script setup>
import { scene } from './init.js';
</script>
<style scoped>
.css2dtag {
background: #ffffff;
color: orangered;
}
</style>
运行代码后发现css没有生效。
查了资料,找到一篇参考文章:
threejs 代码创建div设置样式不生效的问题原因探讨 - 简书
尝试去掉scoped,确实生效了,但是这种处理并不理想。
在继续学习threejs课程的时候,发现老师教了另一种批量创建的办法。
对vue文件修改如何:
增加一个id为css2dtag的div,css加上scoped。
<template>
<div id="css2dtag" style="display: none;"></div>
</template>
<script setup>
import { scene } from './init.js';
</script>
<style scoped>
#css2dtag {
background: #ffffff;
color: orangered;
}
</style>
然后在导入模型的js文件里,通过克隆这个div来批量创建dom元素。
import * as THREE from 'three';
// 引入gltf模型加载库GLTFLoader.js
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
// 引入CSS2模型对象CSS2DObject
import {
CSS2DObject
} from 'three/addons/renderers/CSS2DRenderer.js';
const model = new THREE.Group();
const loader = new GLTFLoader();
// 路径要特别注意,默认是从public读取的,模型文件必须放在public下,并且路径前的public要省略
loader.load('models/简易小区.glb', gltf => {
gltf.scene.getObjectByName("小区房子").traverse(function (obj) {
if (obj.isMesh) {
let label = tag(obj.name);
const pos = new THREE.Vector3();
obj.getWorldPosition(pos);
label.position.copy(pos);
label.name = obj.name;
model.add(label);
}
});
model.add(gltf.scene);
}, undefined, error => {
console.error(error);
});
function tag(name) {
// 通过克隆来批量创建div
let div = document.getElementById('css2dtag').cloneNode();
div.innerHTML = name;
//使用dom元素生成CSS2模型对象CSS2DObject
let label = new CSS2DObject(div);
div.style.pointerEvents = 'none';//避免HTML标签遮挡三维场景的鼠标事件
return label;//返回CSS2模型标签
}
export default model;
再次运行代码,css生效了。