three添加标签

1,720 阅读1分钟

three添加标签

three日常开发中不可避免的要添加各种各样的标签,已显示响应的模型信息等,目前个人总结使用的有以下3种方式。

CSS2DRenderer,CSS2DObject方法

  • new CSS2DObject(DOM)方法创建 labelDOM 为需要创建的标签 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)方法创建 labelDOM 为需要创建的标签 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)方法创建 labelDOM 为需要创建的标签 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>

1684290006029.png