three添加标签
three日常开发中不可避免的要添加各种各样的标签,已显示响应的模型信息等,目前个人总结使用的有以下3种方式。
CSS2DRenderer,CSS2DObject方法
new CSS2DObject(DOM)方法创建 label,DOM为需要创建的标签html。new CSS2DRenderer()方法创建 label 渲染器。
- 该方法创建的标签不会随场景缩放而放大和缩小,只会响应相机的视角变化,标签永远朝向相机。
<template>
<div ref="container"></div>
</template>
<script setup>
import * as THREE from "three";
import { CSS2DObject, CSS2DRenderer } from 'three/addons/renderers/CSS2DRenderer';
let container = shallowRef(null), // 模型渲染的Demo节点
renderer, // WebGLRenderer渲染器
scene, // 场景
camera, // 相机
labelRenderer;
// 组件宽高
let width, height;
useResizeObserver(container, (entries) => {
width = entries[0].contentRect.width;
height = entries[0].contentRect.height;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
labelRenderer.setSize(width, height);
});
// 初始化生命周期
onMounted(() => {
init();
});
onBeforeUnmount(() => {
cancelAnimationFrame(requestAnimationFrameIndex);
// 释放显存
renderer?.dispose();
// 释放内存
scene.clear();
container = null;
scene = null;
labelRenderer = null;
});
function init() {
// 场景
scene = new THREE.Scene();
// 相机
camera = new THREE.PerspectiveCamera(45, container.value.offsetWidth / container.value.offsetHeight, 1, 2000);
camera.position.set(109.63564910104216, 86.72574213762547, 96.25213350271133);
scene.add(camera);
// 渲染器 antialias开启抗锯齿 alpha开启背景透明
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.outputColorSpace = THREE.SRGBColorSpace;
renderer.setPixelRatio(window.devicePixelRatio);
container.value.appendChild(renderer.domElement);
// label 渲染器
labelRenderer = new CSS2DRenderer();
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = 0;
labelRenderer.domElement.style.pointerEvents = 'none';
container.value.appendChild(labelRenderer.domElement);
// 灯光
lights();
// 标签
data.value.forEach((item,i)=>{
labelFn(item,i)
})
}
// 添加label逻辑
const position = [
[99.1077263429123, 8.24890132993459702, -10.28176099837259],
[110.60365415557996, 8.24890132993459702, 40.15225244267442],
];
let data = ref([
{
name: '11205综采面',
p1: 25,
p2: '5224',
p3: '2114',
img: '../assets/img/label/cutterIcon.png',
},
{
name: '11207掘进面',
p1: 25,
p2: '5224',
p3: '2114',
img: '../assets/img/label/tunnellerIcon.png',
},
]);
function labelFn(data,i) {
const dom = createApp(labelDemo, {data}).mount(document.createElement('div')).$el;
const pointLabel = new CSS2DObject(dom);
pointLabel.position.set(...position[i]);
pointLabel.center = new THREE.Vector2(0.5, 1);
scene.add(pointLabel);
}
/**
* 灯光
*/
function lights() {
scene.add(new THREE.AmbientLight('#ffffff', 0.8));
}
// 渲染逻辑
let requestAnimationFrameIndex;
// 创建一个时钟对象Clock
const clock = new THREE.Clock();
let speed = 0.02;
function render() {
labelRenderer?.render(scene, camera);
renderer?.render(scene, camera);
requestAnimationFrameIndex = requestAnimationFrame(render);
}
</script>
CSS3DRenderer,CSS3DSprite方法
new CSS3DSprite(DOM)方法创建 label,DOM为需要创建的标签html。new CSS3DRenderer()方法创建 label 渲染器。
- 该方法创建的标签会随场景缩放而放大和缩小,标签永远朝向相机。
<template>
<div ref="container"></div>
</template>
<script setup>
import * as THREE from "three";
import { CSS3DRenderer, CSS3DSprite } from 'three/addons/renderers/CSS3DRenderer';
let container = shallowRef(null), // 模型渲染的Demo节点
renderer, // WebGLRenderer渲染器
scene, // 场景
camera, // 相机
labelRenderer;
// 组件宽高
let width, height;
useResizeObserver(container, (entries) => {
width = entries[0].contentRect.width;
height = entries[0].contentRect.height;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
labelRenderer.setSize(width, height);
});
// 初始化生命周期
onMounted(() => {
init();
});
onBeforeUnmount(() => {
cancelAnimationFrame(requestAnimationFrameIndex);
// 释放显存
renderer?.dispose();
// 释放内存
scene.clear();
container = null;
scene = null;
labelRenderer = null;
});
function init() {
// 场景
scene = new THREE.Scene();
// 相机
camera = new THREE.PerspectiveCamera(45, container.value.offsetWidth / container.value.offsetHeight, 1, 2000);
camera.position.set(109.63564910104216, 86.72574213762547, 96.25213350271133);
scene.add(camera);
// 渲染器 antialias开启抗锯齿 alpha开启背景透明
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.outputColorSpace = THREE.SRGBColorSpace;
renderer.setPixelRatio(window.devicePixelRatio);
container.value.appendChild(renderer.domElement);
// label 渲染器
labelRenderer = new CSS3DRenderer();
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = 0;
labelRenderer.domElement.style.pointerEvents = 'none';
container.value.appendChild(labelRenderer.domElement);
// 灯光
lights();
// 标签
data.value.forEach((item,i)=>{
labelFn(item,i)
})
}
// 添加label逻辑
const position = [
[99.1077263429123, 8.24890132993459702, -10.28176099837259],
[110.60365415557996, 8.24890132993459702, 40.15225244267442],
];
let data = ref([
{
name: '11205综采面',
p1: 25,
p2: '5224',
p3: '2114',
img: '../assets/img/label/cutterIcon.png',
},
{
name: '11207掘进面',
p1: 25,
p2: '5224',
p3: '2114',
img: '../assets/img/label/tunnellerIcon.png',
},
]);
function labelFn(data,i) {
const dom = createApp(labelDemo, {data}).mount(document.createElement('div')).$el;
const pointLabel = new CSS3DSprite(dom);
pointLabel.position.set(...position[i]);
// 控制标签的大小
pointLabel.scale.set(0.01, 0.01, 0.01);
scene.add(pointLabel);
}
/**
* 灯光
*/
function lights() {
scene.add(new THREE.AmbientLight('#ffffff', 0.8));
}
// 渲染逻辑
let requestAnimationFrameIndex;
// 创建一个时钟对象Clock
const clock = new THREE.Clock();
let speed = 0.02;
function render() {
labelRenderer?.render(scene, camera);
renderer?.render(scene, camera);
requestAnimationFrameIndex = requestAnimationFrame(render);
}
</script>
CSS3DRenderer,CSS3DObject方法
new CSS3DObject(DOM)方法创建 label,DOM为需要创建的标签html。new CSS3DRenderer()方法创建 label 渲染器。
- 该方法创建的标签会随场景缩放而放大和缩小,标签不朝向相机。
<template>
<div ref="container"></div>
</template>
<script setup>
import * as THREE from "three";
import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer';
let container = shallowRef(null), // 模型渲染的Demo节点
renderer, // WebGLRenderer渲染器
scene, // 场景
camera, // 相机
labelRenderer;
// 组件宽高
let width, height;
useResizeObserver(container, (entries) => {
width = entries[0].contentRect.width;
height = entries[0].contentRect.height;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
labelRenderer.setSize(width, height);
});
// 初始化生命周期
onMounted(() => {
init();
});
onBeforeUnmount(() => {
cancelAnimationFrame(requestAnimationFrameIndex);
// 释放显存
renderer?.dispose();
// 释放内存
scene.clear();
container = null;
scene = null;
labelRenderer = null;
});
function init() {
// 场景
scene = new THREE.Scene();
// 相机
camera = new THREE.PerspectiveCamera(45, container.value.offsetWidth / container.value.offsetHeight, 1, 2000);
camera.position.set(109.63564910104216, 86.72574213762547, 96.25213350271133);
scene.add(camera);
// 渲染器 antialias开启抗锯齿 alpha开启背景透明
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.outputColorSpace = THREE.SRGBColorSpace;
renderer.setPixelRatio(window.devicePixelRatio);
container.value.appendChild(renderer.domElement);
// label 渲染器
labelRenderer = new CSS3DRenderer();
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = 0;
labelRenderer.domElement.style.pointerEvents = 'none';
container.value.appendChild(labelRenderer.domElement);
// 灯光
lights();
// 标签
data.value.forEach((item,i)=>{
labelFn(item,i)
})
}
// 添加label逻辑
const position = [
[99.1077263429123, 8.24890132993459702, -10.28176099837259],
[110.60365415557996, 8.24890132993459702, 40.15225244267442],
];
let data = ref([
{
name: '11205综采面',
p1: 25,
p2: '5224',
p3: '2114',
img: '../assets/img/label/cutterIcon.png',
},
{
name: '11207掘进面',
p1: 25,
p2: '5224',
p3: '2114',
img: '../assets/img/label/tunnellerIcon.png',
},
]);
function labelFn(data,i) {
const dom = createApp(labelDemo, {data}).mount(document.createElement('div')).$el;
const pointLabel = new CSS3DObject(dom);
pointLabel.position.set(...position[i]);
// 控制标签的大小
pointLabel.scale.set(0.01, 0.01, 0.01);
scene.add(pointLabel);
}
/**
* 灯光
*/
function lights() {
scene.add(new THREE.AmbientLight('#ffffff', 0.8));
}
// 渲染逻辑
let requestAnimationFrameIndex;
// 创建一个时钟对象Clock
const clock = new THREE.Clock();
let speed = 0.02;
function render() {
labelRenderer?.render(scene, camera);
renderer?.render(scene, camera);
requestAnimationFrameIndex = requestAnimationFrame(render);
}
</script>